https://github.com/knolleary/pubsubclient
http://www.itdecent.cn/p/590f249ecd05
https://github.com/plapointe6/EspMQTTClient
https://github.com/Imroy/pubsubclient
esp32是樂鑫物聯(lián)網(wǎng)芯片,帶wifi。
使用arduino進(jìn)行編程。MQTT的服務(wù)器代碼用NODEJS完成。mqserver.js
arduino的代碼如下:
/*
Basic ESP8266 MQTT example
This sketch demonstrates the capabilities of the pubsub library in combination
with the ESP8266 board/library.
It connects to an MQTT server then:
? - publishes "hello world" to the topic "outTopic" every two seconds
? - subscribes to the topic "inTopic", printing out any messages
? ? it receives. NB - it assumes the received payloads are strings not binary
? - If the first character of the topic "inTopic" is an 1, switch ON the ESP Led,
? ? else switch it off
It will reconnect to the server if the connection is lost using a blocking
reconnect function. See the 'mqtt_reconnect_nonblocking' example for how to
achieve the same result without blocking the main loop.
To install the ESP8266 board, (using Arduino 1.6.4+):
? - Add the following 3rd party board manager under "File -> Preferences -> Additional Boards Manager URLs":
? ? ? http://arduino.esp8266.com/stable/package_esp8266com_index.json
? - Open the "Tools -> Board -> Board Manager" and click install for the ESP8266"
? - Select your ESP8266 in "Tools -> Board"
*/
#include <WiFi.h>
#include <PubSubClient.h>
// Update these with values suitable for your network.
const char* ssid = "xxx";
const char* password = "xx123456";
const char* mqtt_server = "xx.xx.xx.xx";
WiFiClient espClient;
PubSubClient client(espClient);
long lastMsg = 0;
char msg[50];
int value = 0;
int dhtpin=12;
int ledpin=11;
int temp;//溫度
int humi;//濕度
void setup() {
? pinMode(ledpin,OUTPUT);
? Serial.begin(115200);
? setup_wifi();
? client.setServer(mqtt_server, 1883);
? client.setCallback(callback);
}
void setup_wifi() {? ? //連接wifi
? delay(10);
? // We start by connecting to a WiFi network
? 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.println("WiFi connected");
? Serial.println("IP address: ");
? Serial.println(WiFi.localIP());
}
void callback(char* topic, byte* payload, unsigned int length) {? ? //回調(diào)函數(shù)
? Serial.print("Message arrived [");
? Serial.print(topic);
? Serial.print("] ");
? for (int i = 0; i < length; i++) {
? ? Serial.print((char)payload[i]);
? }
? Serial.println();
? // Switch on the LED if an 1 was received as first character
? if (length>2){
? ? if ((char)payload[length-2] == '1') {
? ? ? digitalWrite(ledpin, LOW);? // Turn the LED on (Note that LOW is the voltage level
? ? ? // but actually the LED is on; this is because
? ? ? // it is acive low on the ESP-01)
? ? } else {
? ? ? digitalWrite(ledpin, HIGH);? // Turn the LED off by making the voltage HIGH
? ? }
? }
}
void reconnect() {????????//每次發(fā)布mqtt信息時,需檢查連接
? // Loop until we're reconnected
? while (!client.connected()) {
? ? Serial.print("Attempting MQTT connection...");
? ? // Attempt to connect
? ? if (client.connect("ID_ESP32Client")) {
? ? ? Serial.println("connected");
? ? ? // Once connected, publish an announcement...
? ? ? client.publish("hmdata", "{\"datetime\":\"2018-7-1 19:30\",\"temp\":25,\"humi\":100}");? //發(fā)布json格式
? ? ? // ... and resubscribe
? ? ? client.subscribe("hmdata");????????//訂閱
? ? } else {
? ? ? Serial.print("failed, rc=");
? ? ? Serial.print(client.state());
? ? ? Serial.println(" try again in 5 seconds");
? ? ? // Wait 5 seconds before retrying
? ? ? delay(5000);
? ? }
? }
}
void loop() {
? if (!client.connected()) {
? ? reconnect();
? }
? client.loop();? ? //檢查調(diào)用回調(diào)函數(shù)
? long now = millis();
? if (now - lastMsg > 2000) {
? ? lastMsg = now;
? ? ++value;
? ? wenshidu();? //讀取溫度
? ? temp=temp+random(1,5);
? ? humi=humi+random(1,10);
? ? snprintf (msg, 75, "{\"datetime\":\"2018-7-2 20:30\",\"temp\":%ld,\"humi\":%ld}", temp,humi);
? ? Serial.print("Publish message: ");
? ? Serial.println(msg);
? ? client.publish("hmdata", msg);
? }
}
void wenshidu()? //獲取溫濕度。
{
int pin=12;
int tol;//校對碼
int j;
unsigned int loopCnt;
int chr[40] = {0};//創(chuàng)建數(shù)字?jǐn)?shù)組,用來存放40個bit
unsigned long time1;
? bgn:
? delay(2000);
//設(shè)置2號接口模式為:輸出
//輸出低電平20ms(>18ms)
//輸出高電平40μs
? pinMode(pin,OUTPUT);
? digitalWrite(pin,LOW);
? delay(20);
? digitalWrite(pin,HIGH);
? delayMicroseconds(40);
? digitalWrite(pin,LOW);
//設(shè)置2號接口模式:輸入
? pinMode(pin,INPUT);
? //高電平響應(yīng)信號
? loopCnt=10000;
? while(digitalRead(pin) != HIGH)
? {
? ? if(loopCnt-- == 0)
? ? {
//如果長時間不返回高電平,輸出個提示,重頭開始。
? ? ? Serial.println("HIGH");
? ? ? goto bgn;
? ? }
? }
? //低電平響應(yīng)信號
? loopCnt=30000;
? while(digitalRead(pin) != LOW)
? {
? ? if(loopCnt-- == 0)
? ? {
//如果長時間不返回低電平,輸出個提示,重頭開始。
? ? ? Serial.println("LOW");
? ? ? goto bgn;
? ? }
? }
//開始讀取bit1-40的數(shù)值?
? ? for(int i=0;i<40;i++)
? {
? ? while(digitalRead(pin) == LOW)
? ? {}
//當(dāng)出現(xiàn)高電平時,記下時間“time”
? ? time1 = micros();
? ? while(digitalRead(pin) == HIGH)
? ? {}
//當(dāng)出現(xiàn)低電平,記下時間,再減去剛才儲存的time
//得出的值若大于50μs,則為‘1’,否則為‘0’
//并儲存到數(shù)組里去
? ? if (micros() - time1? >50)
? ? {
? ? ? chr[i]=1;
? ? }else{
? ? ? chr[i]=0;
? ? }
? }
//濕度,8位的bit,轉(zhuǎn)換為數(shù)值
humi=chr[0]*128+chr[1]*64+chr[2]*32+chr[3]*16+chr[4]*8+chr[5]*4+chr[6]*2+chr[7];
//溫度,8位的bit,轉(zhuǎn)換為數(shù)值
temp=chr[16]*128+chr[17]*64+chr[18]*32+chr[19]*16+chr[20]*8+chr[21]*4+chr[22]*2+chr[23];
? //校對碼,8位的bit,轉(zhuǎn)換為數(shù)值
//tol=chr[32]*128+chr[33]*64+chr[34]*32+chr[35]*16+chr[36]*8+chr[37]*4+chr[38]*2+chr[39];
//輸出:溫度、濕度、校對碼
? Serial.print("temp:");
? Serial.println(temp);
? Serial.print("humi:");
? Serial.println(humi);
}
需要說明的是:
ESP32的電壓是3.3v,導(dǎo)致帶DHT11傳感器時,用dht11庫會出現(xiàn)校驗錯誤。因此,采用自寫代碼形式,完成溫濕度采集。還沒有仔細(xì)分析二者代碼有什么不同。
實際使用時,發(fā)現(xiàn)一個問題:發(fā)布的消息和收到的消息會不同步,發(fā)布消息后,要3個周期才能收到自己發(fā)布的消息。很奇怪。
---------------------
作者:wengduke
來源:CSDN
原文:https://blog.csdn.net/wengduke/article/details/80889364
版權(quán)聲明:本文為博主原創(chuàng)文章,轉(zhuǎn)載請附上博文鏈接!