ESP32 MQTT – Publish BME280 Sensor Readings (Arduino IDE)
源自於https://randomnerdtutorials.com/esp32-mqtt-publish-bme280-arduino/
Arduino程式
#include <Wire.h> // include Wire library, required for I2C devices
#include <Adafruit_Sensor.h> // include Adafruit sensor library
#include <Adafruit_BMP280.h> // include adafruit library for BMP280 sensor
//=========================================
#include <WiFi.h>
#include <PubSubClient.h>
#include <AutoConnect.h>
#include <WebServer.h>
WebServer server;
AutoConnect Portal(server);
//=========================================
// define device I2C address: 0x76 or 0x77 (0x77 is library default address)
#define BMP280_I2C_ADDRESS 0x76
//=========================================
#define MQTTid "" //id of this mqtt client
#define MQTTip "broker.mqtt-dashboard.com" //ip address or hostname of the mqtt broker
#define MQTTport 1883 //port of the mqtt broker
#define MQTTuser "alex9ufo" //username of this mqtt client
#define MQTTpsw "alex1234" //password of this mqtt client
//#define MQTTuser "your_username" //username of this mqtt client
//#define MQTTpsw "your_password" //password of this mqtt client
#define MQTTpubQos 2 //qos of publish (see README)
#define MQTTsubQos 1 //qos of subscribe
Adafruit_BMP280 bmp280;
//Variables
long lastMsg = 0;
String json = "";
char jsonChar1[50];
char jsonChar2[50];
char jsonChar3[50];
char jsonChar4[50];
//=============================================================================
boolean pendingDisconnect = false;
void mqttConnectedCb(); // on connect callback
void mqttDisconnectedCb(); // on disconnect callback
void mqttDataCb(char* topic, byte* payload, unsigned int length); // on new message callback
WiFiClient wclient;
PubSubClient client(MQTTip, MQTTport, mqttDataCb, wclient);
//======================================================
void rootPage() {
char content[] = "Hello, world";
server.send(200, "text/plain", content);
}
//=======================================================
void mqttConnectedCb() {
Serial.println("connected");
// Once connected, publish an announcement...
client.publish("alex9ufo/BMP280/TempC", jsonChar1, MQTTpubQos, true); // true means retain
// Once connected, publish an announcement...
client.publish("alex9ufo/BMP280/TempF", jsonChar2, MQTTpubQos, true); // true means retain
// Once connected, publish an announcement...
client.publish("alex9ufo/BMP280/Pressure", jsonChar3, MQTTpubQos, true); // true means retain
// Once connected, publish an announcement...
client.publish("alex9ufo/BMP280/FAltitude", jsonChar4, MQTTpubQos, true); // true means retain
// ... and resubscribe
}
//=======================================================
void mqttDisconnectedCb() {
Serial.println("disconnected");
}
//=======================================================
void mqttDataCb(char* topic, byte* payload, unsigned int length) {
Serial.println("mqttDataCb --> subscribe 無訂閱");
}
//======================================================
void process_mqtt() {
if (WiFi.status() == WL_CONNECTED) {
if (client.connected()) {
client.loop();
} else {
// client id, client username, client password, last will topic, last will qos, last will retain, last will message
if (client.connect(MQTTid, MQTTuser, MQTTpsw, MQTTid "/status", 2, true, "0")) {
pendingDisconnect = false;
mqttConnectedCb();
}
}
} else {
if (client.connected())
client.disconnect();
}
if (!client.connected() && !pendingDisconnect) {
pendingDisconnect = true;
mqttDisconnectedCb();
}
}
//======================================================
void setup() {
Serial.begin(115200);
Serial.println("Configuring ESP32...");
Serial.println(F("Arduino + BMP280"));
//=================================================
Serial.println("Configuring your Mobile WiFi to esp32ap...");
Serial.println("Configuring another WiFi SSID,PWD...");
server.on("/", rootPage);
if (Portal.begin()) {
Serial.println("HTTP server:" + WiFi.localIP().toString());
}
else {
Serial.println("Connection failed");
while(true) {yield();}
}
if (!bmp280.begin(BMP280_I2C_ADDRESS))
{
Serial.println("Could not find a valid BMP280 sensor, check wiring!");
while (1);
}
}
//======================================================
// main loop
void loop()
{
process_mqtt();
long now = millis();
if (now - lastMsg > 3000) { //等3秒
lastMsg = now;
// get temperature, pressure and altitude from library
float temperature = bmp280.readTemperature(); // get temperature
float pressure = bmp280.readPressure(); // get pressure
float altitude_ = bmp280.readAltitude(1013.25); // get altitude (this should be adjusted to your local forecast)
//1013.15需修正
//該1013.25值應為數百Pa處的海平面局部壓力。
//如果要顯示高於地面的高度,則需要知道該位置,並編寫代碼以計算高度偏移。
//海平面:泛指我們所處的高度,即1大氣壓(1atm或1013.25hPa 或 1013.25mb)
//That 1013.25 value should be the local pressure at sea level in hundreds of Pa.
//If want to show altitude above ground level, you will need to know that for your location and write your code to calculate the altitude offset.
// print data on the serial monitor software
// 1: print temperature
Serial.print("Temperature CELSIUS 攝氏溫度= ");
Serial.print(temperature);
Serial.println(" °C");
float TempF = (temperature*1.8)+32;
Serial.print("Temperature FAHRENHEIT 華氏溫度= ");
Serial.print(TempF);
Serial.println(" °F");
// 2: print pressure
Serial.print("Pressure 大氣壓力百帕(hPa)= ");
Serial.print(pressure/100);
Serial.println(" hPa");
// 3: print altitude
Serial.print("Approx Altitude 大概海拔高度= ");
Serial.print(altitude_);
Serial.println(" m");
Serial.println(); // start a new line
String json1 = String(temperature);
String json2 = String(TempF);
String json3 = String(pressure/100);
String json4 = String(altitude_);
json1.toCharArray(jsonChar1, json1.length()+1);
json2.toCharArray(jsonChar2, json2.length()+1);
json3.toCharArray(jsonChar3, json3.length()+1);
json4.toCharArray(jsonChar4, json4.length()+1);
if (client.connected()) {
Serial.println("Publish message:攝氏溫度 華氏溫度 大氣壓力百帕 海拔高度 ");
Serial.println(json1+','+json2+','+json3+','+json4);
// Publish JSON character array to MQTT topic
client.publish("alex9ufo/BMP280/TempC",jsonChar1);
client.publish("alex9ufo/BMP280/TempF",jsonChar2);
client.publish("alex9ufo/BMP280/Pressure",jsonChar3);
client.publish("alex9ufo/BMP280/FAltitude",jsonChar4);
}
}// if (now - lastMsg > 3000) 等3秒
}
// end of code.
Node-Red程式
[{"id":"cf1bcee.62c9b3","type":"mqtt in","z":"6e2fed4b.325c24","name":"","topic":"alex9ufo/BMP280/TempC","qos":"2","datatype":"auto","broker":"e4d9b72d.d14398","x":130,"y":40,"wires":[["dc6fdc66.f71fb","8754c0da.c5f9c","2bf8d29e.8bf13e"]]},{"id":"7ef09837.92cbe8","type":"mqtt in","z":"6e2fed4b.325c24","name":"","topic":"alex9ufo/BMP280/TempF","qos":"2","datatype":"auto","broker":"e4d9b72d.d14398","x":130,"y":160,"wires":[["2914dd13.33f262","67fdbfea.b0ff1","682d2ef2.23766"]]},{"id":"ebbe39a4.ec43c8","type":"mqtt in","z":"6e2fed4b.325c24","name":"","topic":"alex9ufo/BMP280/Pressure","qos":"2","datatype":"auto","broker":"e4d9b72d.d14398","x":130,"y":240,"wires":[["9c7a94d2.676388","91c23ee3.44a0f","5e43499b.2cba48"]]},{"id":"ffd75aa6.973ad8","type":"mqtt in","z":"6e2fed4b.325c24","name":"","topic":"alex9ufo/BMP280/FAltitude","qos":"2","datatype":"auto","broker":"e4d9b72d.d14398","x":130,"y":360,"wires":[["7c55d2fe.0c519c","73f96b.3b607694","e4970484.1a0838"]]},{"id":"8754c0da.c5f9c","type":"ui_chart","z":"6e2fed4b.325c24","name":"","group":"699c61b6.51c8e","order":2,"width":0,"height":0,"label":"C Temp","chartType":"line","legend":"false","xformat":"HH:mm","interpolate":"linear","nodata":"","dot":false,"ymin":"0","ymax":"50","removeOlder":1,"removeOlderPoints":"","removeOlderUnit":"3600","cutout":0,"useOneColor":false,"useUTC":false,"colors":["#1f77b4","#aec7e8","#ff8040","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5"],"outputs":1,"x":420,"y":80,"wires":[[]]},{"id":"67fdbfea.b0ff1","type":"ui_chart","z":"6e2fed4b.325c24","name":"","group":"699c61b6.51c8e","order":1,"width":0,"height":0,"label":"F temp","chartType":"line","legend":"false","xformat":"HH:mm","interpolate":"linear","nodata":"","dot":false,"ymin":"32","ymax":"122","removeOlder":1,"removeOlderPoints":"","removeOlderUnit":"3600","cutout":0,"useOneColor":false,"useUTC":false,"colors":["#1f77b4","#aec7e8","#ff7f0e","#2ca02c","#98df8a","#a61e1e","#ff9896","#9467bd","#c5b0d5"],"outputs":1,"x":420,"y":160,"wires":[[]]},{"id":"91c23ee3.44a0f","type":"ui_chart","z":"6e2fed4b.325c24","name":"","group":"6d81d54e.2e9c4c","order":1,"width":0,"height":0,"label":"Pressure","chartType":"bar","legend":"false","xformat":"HH:mm:ss","interpolate":"linear","nodata":"","dot":false,"ymin":"0","ymax":"1500","removeOlder":1,"removeOlderPoints":"","removeOlderUnit":"3600","cutout":0,"useOneColor":false,"useUTC":false,"colors":["#1f77b4","#aec7e8","#ff7f0e","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5"],"outputs":1,"x":380,"y":280,"wires":[[]]},{"id":"7c55d2fe.0c519c","type":"ui_chart","z":"6e2fed4b.325c24","name":"","group":"6d81d54e.2e9c4c","order":2,"width":0,"height":0,"label":"Altitude","chartType":"line","legend":"false","xformat":"HH:mm","interpolate":"linear","nodata":"","dot":false,"ymin":"0","ymax":"500","removeOlder":1,"removeOlderPoints":"","removeOlderUnit":"60","cutout":0,"useOneColor":false,"useUTC":false,"colors":["#1f77b4","#aec7e8","#ff7f0e","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5"],"outputs":1,"x":380,"y":360,"wires":[[]]},{"id":"dc6fdc66.f71fb","type":"debug","z":"6e2fed4b.325c24","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":430,"y":40,"wires":[]},{"id":"2914dd13.33f262","type":"debug","z":"6e2fed4b.325c24","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":430,"y":120,"wires":[]},{"id":"9c7a94d2.676388","type":"debug","z":"6e2fed4b.325c24","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":390,"y":240,"wires":[]},{"id":"73f96b.3b607694","type":"debug","z":"6e2fed4b.325c24","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":390,"y":400,"wires":[]},{"id":"9284055c.420db8","type":"join","z":"6e2fed4b.325c24","name":"","mode":"custom","build":"object","property":"payload","propertyType":"msg","key":"topic","joiner":"","joinerType":"str","accumulate":true,"timeout":"4","count":"4","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"","reduceFixup":"","x":170,"y":500,"wires":[["a2ed8c13.c2f8c"]]},{"id":"d2abecc.983171","type":"function","z":"6e2fed4b.325c24","name":"","func":"p = JSON.parse(msg.payload);\nnode.log(typeof p);\nmsg.payload = p;\nreturn msg;","outputs":1,"noerr":0,"x":430,"y":500,"wires":[["c665b986.34e148"]]},{"id":"a2ed8c13.c2f8c","type":"json","z":"6e2fed4b.325c24","name":"","property":"payload","action":"","pretty":false,"x":310,"y":500,"wires":[["d2abecc.983171"]]},{"id":"c665b986.34e148","type":"debug","z":"6e2fed4b.325c24","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":570,"y":500,"wires":[]},{"id":"2bf8d29e.8bf13e","type":"link out","z":"6e2fed4b.325c24","name":"","links":["aa673acc.cb8478"],"x":295,"y":100,"wires":[]},{"id":"aa673acc.cb8478","type":"link in","z":"6e2fed4b.325c24","name":"","links":["2bf8d29e.8bf13e","682d2ef2.23766","5e43499b.2cba48","e4970484.1a0838"],"x":55,"y":500,"wires":[["9284055c.420db8"]]},{"id":"682d2ef2.23766","type":"link out","z":"6e2fed4b.325c24","name":"","links":["aa673acc.cb8478"],"x":295,"y":180,"wires":[]},{"id":"5e43499b.2cba48","type":"link out","z":"6e2fed4b.325c24","name":"","links":["aa673acc.cb8478"],"x":295,"y":320,"wires":[]},{"id":"e4970484.1a0838","type":"link out","z":"6e2fed4b.325c24","name":"","links":["aa673acc.cb8478"],"x":315,"y":440,"wires":[]},{"id":"b0978186.a37a8","type":"mqtt out","z":"6e2fed4b.325c24","name":"","topic":"alex9ufo/BMP280/TempC","qos":"1","retain":"","broker":"e4d9b72d.d14398","x":950,"y":80,"wires":[]},{"id":"aef92e29.341c8","type":"inject","z":"6e2fed4b.325c24","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":570,"y":200,"wires":[["e82a3e.0c2ce5c","b6cc6afe.dfe0a8","60219d14.f7d0a4"]]},{"id":"e82a3e.0c2ce5c","type":"function","z":"6e2fed4b.325c24","name":"","func":"var max=50;\nvar min=0;\nmsg.payload= Math.floor(Math.random()*(max-min+1))+min;\nreturn msg;\n","outputs":1,"noerr":0,"initialize":"","finalize":"","x":730,"y":80,"wires":[["b0978186.a37a8","95412341.d816c"]]},{"id":"ff05f33a.8976","type":"mqtt out","z":"6e2fed4b.325c24","name":"","topic":"alex9ufo/BMP280/TempF","qos":"1","retain":"","broker":"e4d9b72d.d14398","x":950,"y":160,"wires":[]},{"id":"c9433d5.14408c","type":"mqtt out","z":"6e2fed4b.325c24","name":"","topic":"alex9ufo/BMP280/Pressure","qos":"1","retain":"","broker":"e4d9b72d.d14398","x":940,"y":240,"wires":[]},{"id":"3963a196.aacdbe","type":"mqtt out","z":"6e2fed4b.325c24","name":"","topic":"alex9ufo/BMP280/FAltitude","qos":"1","retain":"","broker":"e4d9b72d.d14398","x":940,"y":300,"wires":[]},{"id":"95412341.d816c","type":"function","z":"6e2fed4b.325c24","name":"","func":"//華氏= (攝氏乘9/5) + 32 \nvar c1= Number(msg.payload);\nvar f1= Number((c1 * 9) / 5) +32 ;\nmsg.payload=f1;\nreturn msg;\n","outputs":1,"noerr":0,"initialize":"","finalize":"","x":750,"y":160,"wires":[["ff05f33a.8976"]]},{"id":"b6cc6afe.dfe0a8","type":"function","z":"6e2fed4b.325c24","name":"","func":"var max=1500;\nvar min=300;\nmsg.payload= Math.floor(Math.random()*(max-min+1))+min;\nreturn msg;\n","outputs":1,"noerr":0,"initialize":"","finalize":"","x":750,"y":240,"wires":[["c9433d5.14408c"]]},{"id":"60219d14.f7d0a4","type":"function","z":"6e2fed4b.325c24","name":"","func":"var max=500;\nvar min=10;\nmsg.payload= Math.floor(Math.random()*(max-min+1))+min;\nreturn msg;\n","outputs":1,"noerr":0,"initialize":"","finalize":"","x":750,"y":300,"wires":[["3963a196.aacdbe"]]},{"id":"e4d9b72d.d14398","type":"mqtt-broker","name":"","broker":"broker.mqtt-dashboard.com","port":"1883","clientid":"","usetls":false,"compatmode":true,"keepalive":"15","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closePayload":"","willTopic":"","willQos":"0","willPayload":""},{"id":"699c61b6.51c8e","type":"ui_group","name":"Group 1","tab":"f4a73006.d45dc","order":1,"disp":true,"width":6},{"id":"6d81d54e.2e9c4c","type":"ui_group","name":"Group 2","tab":"f4a73006.d45dc","order":2,"disp":true,"width":6},{"id":"f4a73006.d45dc","type":"ui_tab","name":"Altitude","icon":"dashboard","order":3}]
沒有留言:
張貼留言