2018年7月25日 星期三

ESP8266 MQTT IoT應用範例介紹

如何把溫濕度sensor讀取到的資料傳送到雲端呢?如何從雲端來控制RGB LED呢?不需要自己架設雲端,使用免費的server及瞭解MQTT協定就可以實現物聯網IoT架構。 先準備硬體零件,電路圖如下圖示,並把電路接好。 1.NodeMCU x 1 pcs 2.DHT11 x 1 pcs 3.RGB LED x 1 pcs nodemcu_dht11.png 安裝ArduinoIDE 與註冊Server帳號 Arduino IDE https://www.arduino.cc/en/Main/Software 免費註冊Server帳號 https://www.adafruit.com/ NodeMCU的範例程式如下,用Arduino IDE去編譯,程式有幾各地方要去修改。 1.WLAN_SSID 請輸入你的wifi SSID 2.WLAN_PASS 請輸入你的wifi 密碼 3.AIO_USERNAME 請輸入註冊Server的帳號 https://www.adafruit.com/ 4.AIO_KEY 請先登入 https://io.adafruit.com ,點選View AIO Key,複製Active Key,如下圖示。 adafruit_1 程式內容就請大家自行研究了,不另外說明了。
關於MQTT協定,可以參考以下路徑的文章。
MQTT教學(一):認識MQTT
在編譯程式之前,請先在Arduino IDE自行匯入以下的程式庫(草稿碼->匯入程式庫->管理程式庫),這樣編譯才不會出現錯誤。 1.Adafruit_ESP8266 2.Adafruit_MQTT_Library 3.DHT_sensor_library
/****************************************************/
#include "ESP8266WiFi.h"
#include "Adafruit_MQTT.h"
#include "Adafruit_MQTT_Client.h"
#include "DHT.h"

/************************* LED *********************************************/
#define G_LED    2
#define B_LED    0
#define R_LED    4

/*********************** DHT11 **********************************************/

#define DHTPIN 5 // what digital pin we're connected to
#define DHTTYPE DHT11 // DHT 11
DHT dht(DHTPIN, DHTTYPE);

/************************* WiFi Access Point *********************************/

#define WLAN_SSID  "...your SSID..."
#define WLAN_PASS  "..your password..."

/************************* Adafruit.io Setup *********************************/

#define AIO_SERVER "io.adafruit.com"
#define AIO_SERVERPORT 1883 // use 1883 for SSL
#define AIO_USERNAME "...your AIO username (see https://accounts.adafruit.com)..."
#define AIO_KEY "...your AIO key..."

/************ Global State (you don't need to change this!) ******************/

// Create an ESP8266 WiFiClient class to connect to the MQTT server.
WiFiClient client;
// or... use WiFiFlientSecure for SSL
//WiFiClientSecure client;

// Setup the MQTT client class by passing in the WiFi client and MQTT server and login details.
Adafruit_MQTT_Client mqtt(&client, AIO_SERVER, AIO_SERVERPORT, AIO_USERNAME, AIO_KEY);

/****************************** Feeds ***************************************/

// Setup a feed called 'photocell' for publishing.
// Notice MQTT paths for AIO follow the form: /feeds/
Adafruit_MQTT_Publish Humidity = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/Humidity");
Adafruit_MQTT_Publish Temperature = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/Temperature");
// Setup a feed called 'onoff' for subscribing to changes.
Adafruit_MQTT_Subscribe onoffbutton = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME "/feeds/onoff");

/*************************** Sketch Code ************************************/

// Bug workaround for Arduino 1.6.6, it seems to need a function declaration
// for some reason (only affects ESP8266, likely an arduino-builder bug).
void MQTT_connect();

void setup() {
pinMode(G_LED, OUTPUT);
pinMode(B_LED, OUTPUT);
pinMode(R_LED, OUTPUT);
digitalWrite(G_LED, LOW);
digitalWrite(B_LED, LOW);
digitalWrite(R_LED, LOW);
Serial.begin(115200);
dht.begin();
delay(10);

Serial.println(F("Adafruit MQTT demo"));

// Connect to WiFi access point.
Serial.println(); Serial.println();
Serial.print("Connecting to ");
Serial.println(WLAN_SSID);

WiFi.begin(WLAN_SSID, WLAN_PASS);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println();

Serial.println("WiFi connected");
Serial.println("IP address: "); Serial.println(WiFi.localIP());

// Setup MQTT subscription for onoff feed.
mqtt.subscribe(&onoffbutton);
digitalWrite(G_LED, HIGH);
digitalWrite(B_LED, HIGH);
digitalWrite(R_LED, HIGH);

}

//uint32_t x=0;
//uint32_t y=0;
void loop() {
// Ensure the connection to the MQTT server is alive (this will make the first
// connection and automatically reconnect when disconnected). See the MQTT_connect
// function definition further below.
MQTT_connect();

// this is our 'wait for incoming subscription packets' busy subloop
// try to spend your time here

Adafruit_MQTT_Subscribe *subscription;
while ((subscription = mqtt.readSubscription(5000))) {
if (subscription == &onoffbutton) {
Serial.print(F("Got: "));
Serial.println((char *)onoffbutton.lastread);
if( *onoffbutton.lastread == '1')
{
   digitalWrite(G_LED, LOW);
}
else if( *onoffbutton.lastread == '2')
{
   digitalWrite(B_LED, LOW);
}
else if( *onoffbutton.lastread == '3')
{
   digitalWrite(R_LED, LOW);
}
else if( *onoffbutton.lastread == '0')
{
   digitalWrite(G_LED, HIGH);
   digitalWrite(B_LED, HIGH);
   digitalWrite(R_LED, HIGH);
}
}
}

// Now we can publish stuff!
float h = dht.readHumidity();
Serial.print(F("\nHumidity : "));
Serial.print(h);
Serial.print("%");
if (! Humidity.publish(h)) {
Serial.println(F("\nSending Humidty is Failed"));
} else {
Serial.println(F("\nSending Humidty is OK!"));
}

//
float t = dht.readTemperature();
float hic = dht.computeHeatIndex(t, h, false);
Serial.print(F("\nTemperature : "));
Serial.print(hic);
Serial.print("*C");
if (! Temperature.publish(hic)) {
Serial.println(F("\nSending Temperature is Failed"));
} else {
Serial.println(F("\nSending Temperature is OK!"));
}
// ping the server to keep the mqtt connection alive
// NOT required if you are publishing once every KEEPALIVE seconds
/*
if(! mqtt.ping()) {
mqtt.disconnect();
}
*/
}

// Function to connect and reconnect as necessary to the MQTT server.
// Should be called in the loop function and it will take care if connecting.
void MQTT_connect() {
int8_t ret;

// Stop if already connected.
if (mqtt.connected()) {
return;
}

Serial.print("Connecting to MQTT... ");

uint8_t retries = 3;
while ((ret = mqtt.connect()) != 0) { // connect will return 0 for connected
Serial.println(mqtt.connectErrorString(ret));
Serial.println("Retrying MQTT connection in 5 seconds...");
mqtt.disconnect();
delay(5000); // wait 5 seconds
retries--;
if (retries == 0) {
// basically die and wait for WDT to reset me
while (1);
}
}
Serial.println("MQTT Connected!");
}

影片demo


沒有留言:

張貼留言