前言
之前總是沒時間整理這一部分的內容,現在抽空整理一下arduino使用esp8266連接自己搭建的emqx服務器的內容吧!關于如何自建emqx服務器,可以自己百度百度,抽空我再整理一下如何連接emqx服務器!敬請期待,
為什么要連接emqx呢?優點如下:
(1)大部分的物聯網平臺對設備連接數量或者訊息轉發數量是有限制的,比如blinker是設備連接有限,而阿里云IOT平臺的訊息轉發數量有限,還收到阿里云IOT的很多限制,那不如嘗試一下自己購買一個云服務器,然后搭建一個自己的emqx服務器!
(2)自己搭建一個物聯網服務器不酷嗎?
硬體準備
- nodemcu 開發板一塊! 當然也可以使用esp01!用做聯網,
- DHT11溫濕度傳感器(其他傳感器也可以),資料上行,
- WIFI繼電器一個(不用繼電器用LED燈也可以),資料下行,
- 其他硬體若干,
硬體連線
| nodemcu | 系統外設 |
|---|---|
| D7 | DHT11 |
| D0 | LED1 |
| D5 | LED2 |
| D10 | 繼電器 (LED3) |
硬體程式
說明:由于時間原因,該代碼沒有使用smartConfig技術一鍵配網,感興趣的同學可以嘗試修改連接wifi部分的代碼!
(1)首先必不可少頭檔案,老規矩,一定要把需要用到的第三方頭檔案放到檔案->arduino->libraries下,否則程式原始碼讀不到該頭檔案的內容, 白費了就!具體的頭檔案這里就不再給出,
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>
//系統外設
#include <DHT.h>//包含DHT頭檔案
(2)宏定義,為了方便一些引腳編號和變數的后期修改!
#define DHTPIN 13 //D7
#define LED1 16 //D0
#define LED2 14 //D5
#define jidianqi 1 //D10
#define DHTTYPE DHT11 // 使用溫度濕度模塊的型別為DHT11
#define wifi_ssid "*****" //wifi名稱
#define wifi_password "******" //wifi密碼
#define mqtt_server "changyuan.store" // EMQX服務器的域名
#define publish_topic "/client2/pub" //發布訊息主題
#define subscribe_topic "/client2/sub" //訂閱訊息的主題
(3)連接emqx服務器的最首先也是需要連接wifi的,這里不再描述smartConfig一鍵配網,如果有用安信可一鍵配網的同學,最好把手機熱點的AP頻段設定為2.4HZ,目前不支持5GHZ,
void setup_wifi() {
delay(10);
WiFi.begin(wifi_ssid, wifi_password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
}
(4)連接emqx服務器首先需要自己的emqx服務器的域名,mqtt_server為自己的域名,一定要連接1883埠,這是emqx默認的埠號,其他埠無效,
client.setServer(mqtt_server, 1883);
(5)上行資料的上報,資料上行資料的上報一般是上報JSON字串型別的資料,通過JSON字串的拼接,代碼如下所示,其中sprintf函式可以理解為printf()函式,功能差不多吧,然后通過publish函式上報主題訊息,
#define BODY_FORMAT "{\"clientId\":\"%s\",\"params\":{\"humi\":\"%d\",\"temp\":\"%d\"}}"
char jsonBuf[128];//存放payload主題內容
sprintf(jsonBuf,BODY_FORMAT,clientId.c_str(),humiData,tempData);
client.publish(publish_topic, jsonBuf);
(6)下行資料的決議,下行資料的決議首先是訂閱服務器下發的主題資訊,然后客戶端監聽服務器下發的訊息,最后是決議下發訊息并做出回應的動作,其中決議JSON的方式和python中鍵值對的取值方法又差不多,
client.subscribe(subscribe_topic); //訂閱主題
client.setCallback(callback); //監聽服務器下發的訊息
DynamicJsonBuffer jsonBuffer;
JsonObject& root = jsonBuffer.parseObject(message);
String LED1State = root["LED1"];
String LED2State = root["LED2"];
String LED3State = root["LED3"];
(7)代碼總結!全部代碼可以參考如下代碼,可包畢設,有意者聯系,
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>
//系統外設
#include <DHT.h>//包含DHT頭檔案
#define DHTPIN 13 //D7
#define LED1 16 //D0
#define LED2 14 //D5
#define jidianqi 1 //D10
#define DHTTYPE DHT11 // 使用溫度濕度模塊的型別為DHT11
DHT dht(DHTPIN, DHTTYPE); //定義dht
#define wifi_ssid "*****" //wifi名稱
#define wifi_password "******" //wifi密碼
#define mqtt_server "changyuan.store" // EMQX服務器的域名
#define publish_topic "/client2/pub" //發布訊息主題
#define subscribe_topic "/client2/sub" //訂閱訊息的主題
#define BODY_FORMAT "{\"clientId\":\"%s\",\"params\":{\"humi\":\"%d\",\"temp\":\"%d\"}}"
WiFiClient espClient;
PubSubClient client(espClient);
String clientId="client2";
int tempData;
int humiData;
String state;
void setup() {
Serial.begin(115200);
dht.begin();//初始化DHT傳感器
pinMode(jidianqi, OUTPUT);//定義io口為輸出
digitalWrite(jidianqi,HIGH);
pinMode(LED2, OUTPUT);//定義io口為輸出
digitalWrite(LED2,HIGH);
pinMode(LED1, OUTPUT);//定義io口為輸出
digitalWrite(LED1,HIGH);
setup_wifi();
client.setServer(mqtt_server, 1883);
client.setCallback(callback); //監聽服務器下發的訊息
}
void loop() {
if (!client.connected()) {
reconnect();
}
else{
DHTWORK();
Serial.print("溫度:");
Serial.print(tempData);
Serial.print(",濕度:");
Serial.print(humiData);
char jsonBuf[128];//存放payload主題內容
sprintf(jsonBuf,BODY_FORMAT,clientId.c_str(),humiData,tempData,lux,state.c_str());
client.publish(publish_topic, jsonBuf);
client.subscribe(subscribe_topic);
}
client.loop();
delay(1000);
}
void setup_wifi() {
delay(10);
WiFi.begin(wifi_ssid, wifi_password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
}
void DHTWORK(){
float h = dht.readHumidity();//讀取DHT11傳感器的濕度 并賦值給h
float t = dht.readTemperature();//讀取傳感器的溫度 并賦值給t
if (isnan(h) || isnan(t))//判斷是否成功讀取到溫濕度資料
{
Serial.println("error");
}else{
tempData=(int)t;
humiData=(int)h;
}
}
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
if (client.connect("nodeMcuRFID")) {
Serial.println("connected");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
delay(5000);
}
}
}
void callback(char *topic, byte *payload, unsigned int length) {
Serial.print("Message arrived in topic: ");
Serial.println(topic);
Serial.print("Message:");
String message;
for (int i = 0; i < length; i++) {
message = message + (char) payload[i]; // convert *byte to string
}
Serial.print(message);
//決議json
DynamicJsonBuffer jsonBuffer;
JsonObject& root = jsonBuffer.parseObject(message);
String LED1State = root["LED1"];
String LED2State = root["LED2"];
String LED3State = root["LED3"];
if(LED1State=="true")
{
//讀取
int button1Sate = digitalRead(LED1);
if(button1Sate==1)//高電平置為低
{
digitalWrite(LED1,HIGH);
delay(200);
digitalWrite(LED1, LOW);
}else{//低電平置為高
digitalWrite(LED1,LOW);
delay(200);
digitalWrite(LED1,HIGH);
}
}
if(LED2State=="true")
{
//讀取
int button2Sate = digitalRead(LED2);
if(button2Sate==1)//高電平置為低
{
digitalWrite(LED2,HIGH);
delay(200);
digitalWrite(LED2, LOW);
}else{//低電平置為高
digitalWrite(LED2,LOW);
delay(200);
digitalWrite(LED2,HIGH);
}
}
if(LED3State=="true")
{
//讀取
int button3Sate = digitalRead(jidianqi);
if(button3Sate==1)//高電平置為低
{
digitalWrite(jidianqi,HIGH);
delay(200);
digitalWrite(jidianqi,LOW);
}else{//低電平置為高
digitalWrite(jidianqi,LOW);
delay(200);
digitalWrite(jidianqi,HIGH);
}
}
Serial.println();
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/294786.html
標籤:其他
