MQTT-Publish-Node-RED-BMP280


MQTT-Publish-Node-RED-BMP280

參考文獻-https://randomnerdtutorials.com/esp32-mqtt-publish-subscribe-arduino-ide/

這次實作是使用MQTT發送BMP280的數據到樹莓派上的Node-RED儀錶版上

我是參考這篇文章-https://randomnerdtutorials.com/esp32-mqtt-publish-subscribe-arduino-ide/

所以會使用類似的程式碼手法來完成項目。

開始之前先備妥樹莓派上所須的軟硬體

  1. 安裝Mosquitto broker(如果沒玩過樹莓派,請連結這裡安裝樹莓派系統和
  2. 何使用SSH和VNC鏡像)
  3. 安裝 Node-RED installed  和 Node-RED Dashboard在樹莓派上。
  4. _備註:安裝Node-RED時若出現錯誤訊息改用下面所附下載 _****bash <(curl -sL https://raw.githubusercontent.com/node-red/linux-installers/master/deb/update-nodejs-and-nodered)
  5. 接下來先測試BMP280是否可正常測溫度和壓力-請參考之前的紀錄(點我傳送)。

先來看一下整個發送原理比較容易理解自己要學的重點在哪裡

此次實驗我只寫從ESP32發送數據到樹莓派的Mosquitto代理接收/發送

然後通過MQTT通信協議去控制ESP32發送數據到Node-RED,其實我覺

得和ThingSpeak很類似,只是使用Node-RED更能客製化。

看一下這張圖


知道原理後就是開始進入寫程式的主軸

首先要有網路可以連到數莓派和ESP32,然後判斷是否已經連線

如果連不上就再自動重連,連上後印出IP,連上網路後,就是

要去和樹莓派的Mosquitto Broker連線,一樣就是判斷是否成功

連線做出對應的動作。WiFi和Mosquitto Broker都連線之後,就開

始從ESP32客戶端發送溫度和壓力的數據到Node-RED的介面上。


布署Node-RED

程式碼

#include <WiFi.h>

#include <PubSubClient.h>

#include <Adafruit_BMP280.h>

#include <Adafruit_Sensor.h>

#include <Wire.h>


Adafruit_BMP280 bmp; // I2C

  
WiFiClient espClient;

PubSubClient client(espClient);


//wifi帳密

const char* ssid = "---";

const char* password = "------";

//mqttServer

const char* mqttServer = "---.---.---.--";

  

//設定wifi

void setupWifi(){

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED){

    delay(50);

    Serial.print(".");

  }

  Serial.println("connected successful");

  Serial.println(WiFi.localIP());

  }

  
  

void reconnect(){

  while (! client.connected()){

    Serial.print("Attempting MQTT connection...");

    if (client.connect("esp32Client")){

      Serial.println("connected");

    }else {

      Serial.print("failed connected is : ");

      Serial.println(client.state());

      delay(2000);

    }

  }

}

  

void setup() {

  Serial.begin(115200);

  Serial.println(F("BMP280 test"));

  setupWifi();

  client.setServer(mqttServer, 1883);

  if (!bmp.begin()) {

    Serial.println(F("Could not find a valid BMP280 sensor, check wiring or "

                      "try a different address!"));

    while (1) delay(10);

  }

}


void loop() {

    if (! client.connected()){

      reconnect();

    }

    client.loop();

    long lastTime = 0;

    long currentTime = millis();

    float temp = 0;

    float pressure = 0;

    float humi = 0;

    if (currentTime - lastTime > 5000){

      lastTime = currentTime;

      temp = bmp.readTemperature();

      humi = 1.8 * temp + 32;

      pressure = bmp.readPressure();

      char tempStr\[8\] = "";

      char pressStr\[24\] = "";

      char humiStr\[8\] = "";

      dtostrf(temp, 1, 2, tempStr);

      dtostrf(pressure, 1, 2, pressStr);

      dtostrf(humi, 1, 2, humiStr);

      Serial.print("Temp: ");

      Serial.println(tempStr);

      Serial.print("humi: ");

      Serial.println(humiStr);

      Serial.print("Pressure: ");

      Serial.println(pressStr);

      client.publish("esp32/temp", tempStr);

      client.publish("esp32/pressure", pressStr);

      client.publish("esp32/humi", humiStr);

      delay(1000);
    }
}

解析

匯入所須的程式庫

#include <WiFi.h>

#include <PubSubClient.h>

#include <Adafruit_BMP280.h>

#include <Adafruit_Sensor.h>

#include <Wire.h>

建立bmp280,wifi客戶端及MQTT客戶端代數

Adafruit_BMP280 bmp; // I2C

WiFiClient espClient;

PubSubClient client(espClient);

  

MQTTserver的IP即是樹莓派的IP

//wifi帳密

const char* ssid = "---";

const char* password = "------";

//mqttServer

const char* mqttServer = "---.---.---.---";

  

//設定wifi

void setupWifi(){

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED){

    delay(50);

    Serial.print(".");

  }

  Serial.println("connected successful");

  Serial.println(WiFi.localIP());

  }

連線至MQTT伺服器成功與無法連線的對應動作

void reconnect(){

  while (! client.connected()){

    Serial.print("Attempting MQTT connection...");

    if (client.connect("esp32Client")){

      Serial.println("connected");

    }else {

      Serial.print("failed connected is : ");

      Serial.println(client.state());

      delay(2000);

    }

  }

void setup(){}裡面的一些必要初始化

void setup() {

  Serial.begin(115200);

  Serial.println(F("BMP280 test"));

  setupWifi();

  client.setServer(mqttServer, 1883);

  if (!bmp.begin()) {

    Serial.println(F("Could not find a valid BMP280 sensor, check wiring or "

                      "try a different address!"));

    while (1) delay(10);

  }

}

void loop(){}裡

無法連線就重複連線

if (! client.connected()){

      reconnect();

    }

    client.loop();

關於數值轉字元的函式

char* dtostrf(double _val,signed char _width, unsigned char prec, char* _s)  

引數說明:
_val:要轉換的float或者double值。

_width:轉換後整數部分長度。

_prec:轉換後小數部分長度。

_s:儲存到該char陣列中。

其中這個是轉成對應的字元

char tempStr[8] = "";

char pressStr[24] = "";

char humiStr[8] = "";

dtostrf(temp, 1, 2, tempStr);

dtostrf(pressure, 1, 2, pressStr);

dtostrf(humi, 1, 2, humiStr);

取得溫度/壓力數值後每5秒發送到MQTT的Node-RED

if (currentTime - lastTime > 5000){

      lastTime = currentTime;

      temp = bmp.readTemperature();

      humi = 1.8 * temp + 32;

      pressure = bmp.readPressure();

      char tempStr[8] = "";

      char pressStr[24] = "";

      char humiStr[8] = "";

      dtostrf(temp, 1, 2, tempStr);

      dtostrf(pressure, 1, 2, pressStr);

      dtostrf(humi, 1, 2, humiStr);

      Serial.print("Temp: ");

      Serial.println(tempStr);

      Serial.print("humi: ");

      Serial.println(humiStr);

      Serial.print("Pressure: ");

      Serial.println(pressStr);

      client.publish("esp32/temp", tempStr);

      client.publish("esp32/pressure", pressStr);

      client.publish("esp32/humi", humiStr);

      delay(1000);

    }



文章作者: blairan
版權聲明: 本博客所有文章除特別聲明外,均採用 CC BY 4.0 許可協議。轉載請註明來源 blairan !
评论
  目錄