Arduino筆記(45):AM2320溫濕度值使用MQTT上傳樹莓派的Node-RED儀表板(下)

接續前一篇,本篇要實作將 NodeMCU 連接 AM2320,並上傳程式。在上傳程式前,看一下線路連接方式。

[材料]

• NodeMCU x 1
• AM2320 溫濕度感測器 x 1
• 麵包板(含電源模組) x 1
• 連接線  x 4

[線路連接]

NodeMCU
AM2320
3.3 V
VCC(Pin1)
GND
GND(Pin3)
D1
SCL(Pin4)
D2
SDA(Pin2)


[安裝PubSubClient Library]

PubSubClient 函式庫提供客戶端,透過簡單的發布/訂閱訊息與 MQTT 的服務器連接,等於讓你的 NodeMCU 與 Node-RED 直接交談。

先到 Github 下載 knolleary/pubsubclient,按右邊綠色選項「Clone or download」,再選「Download ZIP」。

• 將下載的壓縮檔解壓縮,放在 Arduino 主程式下的 libraries目錄內,以我的電腦來說,Arduino安裝在  C:\User\[登入的帳號]\Documents\Arduino,點進目錄有一個 libraries的子目錄,下載後解壓縮的目錄,整個放進  libraries 目錄,重新啟動 Arduino即可。

[程式]

#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <AM2320.h>

AM2320 sensor;

// 設定無線基地台SSID跟密碼
const char* ssid     = "MyHome";
const char* password = "ceiling4895";

// 設定樹莓派 MQTT Broker 的 IP
const char* mqtt_server = "192.168.1.128";

// 初始化 espClient.
WiFiClient espClient;
PubSubClient client(espClient);

const int lamp = 4;
float temper, humidity;

// 當設備發訊息給一個標題(topic)時,這段函式會被執行
void callback(String topic, byte* message, unsigned int length) {
  Serial.print("Message arrived on topic: ");
  Serial.print(topic);
  Serial.print(". Message: ");
  String messageTemp;
  
  for (int i = 0; i < length; i++) {
    Serial.print((char)message[i]);
    messageTemp += (char)message[i];
  }
  Serial.println();

  // 假使收到訊息給主題 room/lamp, 可以檢查訊息是 on 或 off. 根據訊息開啟 GPIO
  if(topic=="room/lamp"){
      Serial.print("Changing Room lamp to ");
      if(messageTemp == "on"){
        digitalWrite(lamp, HIGH);
        Serial.print("On");
      }
      else if(messageTemp == "off"){
        digitalWrite(lamp, LOW);
        Serial.print("Off");
      }
  }
  Serial.println();
}

// ESP8266 重新連接到 MQTT Broker 
void reconnect() {

  // 持續迴圈直到連線
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");

    if (client.connect("ESP8266Client")) {
      Serial.println("connected");  
      // 訂閱一個主題,可以設定多個主題
      client.subscribe("room/lamp");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      delay(5000);
    }
  }
}

void setup() {
  pinMode(lamp, OUTPUT);
  Serial.begin(115200);
  
  // 連接無線網路
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("WiFi connected - ESP IP address: ");
  Serial.println(WiFi.localIP());

// 設定 mqtt server 及連接 port
  client.setServer(mqtt_server, 1883);

// 設定 mqtt broker 並設定 callback function
  client.setCallback(callback);
}

void loop() {

  if (!client.connected()) {
    reconnect();
  }
  if(!client.loop())
    client.connect("ESP8266Client");
    
  sensor.begin();
  if (sensor.measure()) {
     temper = sensor.getTemperature();
    humidity = sensor.getHumidity();
  }
  else {
       int errorCode = sensor.getErrorCode();
       switch (errorCode) {
         case 1: Serial.println("ERR: Sensor is offline"); break;
         case 2: Serial.println("ERR: CRC validation failed."); break;
       }    
  }

  // dtostrf 將 float 數字改成文字
  static char temperatureTemp[7];
  dtostrf(temper, 6, 2, temperatureTemp);
  static char humidityTemp[7];
  dtostrf(humidity, 6, 2, humidityTemp);

  // Publishes Temperature and Humidity values
  client.publish("room/temperature", temperatureTemp);
  client.publish("room/humidity", humidityTemp);
  Serial.print("Humidity: ");
  Serial.print(humidity);
  Serial.print(" %\t Temperature: ");
  Serial.print(temper);
  Serial.println(" *C ");
  delay(5000);     // 等待5秒
} 

[執行結果]

Console連線結果:

左圖是開始執行約40分鐘的圖,右圖是關掉冷氣後的溫度變化:

[參考資料]

Randomnerdtutorials:ESP8266 and Node-RED with MQTT (Publish and Subscribe)

Post a Comment

較新的 較舊