简介
本文章使用NodeMCU(ESP8266)开发板和SHTC3温湿度传感器接入阿里云物联网(IoT)平台,并上传读取到的温湿度数据。每秒读取一次温湿度数据,每30秒上传一次30秒内的温湿度的平均值。可以自己修改一下程序使用其他温湿度传感器。本文程序使用Arduino IDE开发。
DHT11和DHT22温湿度传感器数据读取的程序:https://blog.zeruns.com/archives/527.html
ESP8266开发环境搭建教程:https://blog.zeruns.com/archives/526.html
SHTC3的SDA引脚接NodeMCU的D5引脚,SCL引脚接NodeMCU的D6引脚。
设置物联网平台
首先注册阿里云账号并开通物联网平台:https://www.aliyun.com/product/iot?source=5176.11533457&userCode=jdjc69nf&type=copy
然后打开物联网平台的控制台:https://iot.console.aliyun.com/product
接着按照图片提示创建产品
按照图片提示添加设备
程序源码
需先安装 PubSubClient
、ArduinoJson
、SparkFun SHTC3
这三个库。
然后按照下面的教程修改PubSubClient.h
按照代码中文字提示修改参数即可。
#include <ESP8266WiFi.h>
/* 依赖 PubSubClient 2.4.0 */
#include <PubSubClient.h>
/* 依赖 ArduinoJson 5.13.4 */
#include <ArduinoJson.h>
#include <SparkFun_SHTC3.h>
/* 连接您的WIFI SSID和密码 */
#define WIFI_SSID "路由器SSID"
#define WIFI_PASSWD "密码"
/* 设备的三元组信息*/
#define PRODUCT_KEY "设备PRODUCT_KEY"
#define DEVICE_NAME "替换DEVICE_NAME"
#define DEVICE_SECRET "替换DEVICE_SECRET"
#define REGION_ID "cn-shanghai"
/* 线上环境域名和端口号,不需要改 */
#define MQTT_SERVER PRODUCT_KEY ".iot-as-mqtt." REGION_ID ".aliyuncs.com"
#define MQTT_PORT 1883
#define MQTT_USRNAME DEVICE_NAME "&" PRODUCT_KEY
#define CLIENT_ID "ESP8266|securemode=3,timestamp=1234567890,signmethod=hmacsha1|"
// 算法工具: http://iot-face.oss-cn-shanghai.aliyuncs.com/tools.htm 进行加密生成password
// password教程 https://www.yuque.com/cloud-dev/iot-tech/mebm5g
#define MQTT_PASSWD "参考上面password教程,算法工具生成,如果上面的教程看不懂就看文章下面"
#define ALINK_BODY_FORMAT "{\"id\":\"ESP8266\",\"version\":\"1.0\",\"method\":\"thing.event.property.post\",\"params\":%s}"
#define ALINK_TOPIC_PROP_POST "/sys/" PRODUCT_KEY "/" DEVICE_NAME "/thing/event/property/post"
unsigned long lastMs = 0;
float RH,T,RH_sum,T_sum;
unsigned char count=0;
WiFiClient espClient;
PubSubClient client(espClient);
SHTC3 mySHTC3;
void callback(char *topic, byte *payload, unsigned int length)
{
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");
payload[length] = '\0';
Serial.println((char *)payload);
}
void wifiInit()
{
WiFi.mode(WIFI_STA);
WiFi.begin(WIFI_SSID, WIFI_PASSWD); //连接WiFi
while (WiFi.status() != WL_CONNECTED)
{
delay(1000);
Serial.println("WiFi not Connect");
}
Serial.println("Connected to AP");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
Serial.print("espClient [");
client.setServer(MQTT_SERVER, MQTT_PORT); /* 连接WiFi之后,连接MQTT服务器 */
client.setCallback(callback);
}
void mqttCheckConnect()
{
while (!client.connected())
{
Serial.println("Connecting to MQTT Server ...");
if (client.connect(CLIENT_ID, MQTT_USRNAME, MQTT_PASSWD))
{
Serial.println("MQTT Connected!");
}
else
{
Serial.print("MQTT Connect err:");
Serial.println(client.state());
delay(5000);
}
}
}
void mqttIntervalPost()
{
char param[32];
char jsonBuf[128];
sprintf(param, "{\"CurrentTemperature\":%f}",T_sum/count);
sprintf(jsonBuf, ALINK_BODY_FORMAT, param);
Serial.println(jsonBuf);
boolean d = client.publish(ALINK_TOPIC_PROP_POST, jsonBuf);
if(d){
Serial.println("publish Temperature success");
}else{
Serial.println("publish Temperature fail");
}
//https://blog.zeruns.com
sprintf(param, "{\"CurrentHumidity\":%f}",RH_sum/count);
sprintf(jsonBuf, ALINK_BODY_FORMAT, param);
Serial.println(jsonBuf);
d = client.publish(ALINK_TOPIC_PROP_POST, jsonBuf);
if(d){
Serial.println("publish Humidity success");
}else{
Serial.println("publish Humidity fail");
}
}
void errorDecoder(SHTC3_Status_TypeDef message) // The errorDecoder function prints "SHTC3_Status_TypeDef" resultsin a human-friendly way
{
switch(message)
{
case SHTC3_Status_Nominal : Serial.print("Nominal"); break;
case SHTC3_Status_Error : Serial.print("Error"); break;
case SHTC3_Status_CRC_Fail : Serial.print("CRC Fail"); break;
default : Serial.print("Unknown return code"); break;
}
}
//https://blog.zeruns.com
void setup()
{
/* initialize serial for debugging */
Serial.begin(115200);
Serial.println("Demo Start");
wifiInit();
Wire.begin(D5,D6); //初始化Wire(IIC)库
unsigned char i=0;
errorDecoder(mySHTC3.begin());
}
// the loop function runs over and over again forever
void loop()
{
delay(1000); //延时1000毫秒
SHTC3_Status_TypeDef result = mySHTC3.update();
if(mySHTC3.lastStatus == SHTC3_Status_Nominal) //判断SHTC3状态是否正常
{
RH = mySHTC3.toPercent(); //读取湿度数据
T = mySHTC3.toDegC(); //读取温度数据
RH_sum+=RH;
T_sum+=T;
count+=1;
}else{
Serial.print("Update failed, error: ");
errorDecoder(mySHTC3.lastStatus); //输出错误原因
Serial.println();
}
Serial.print("Humidity:"); //向串口打印 Humidity:
Serial.print(RH); //向串口打印湿度数据
Serial.print("%");
Serial.print(" Temperature:");
Serial.print(T); //向串口打印温度数据
Serial.println("C");
Serial.println("https://blog.zeruns.com");
if (millis() - lastMs >= 30000)
{
lastMs = millis();
mqttCheckConnect();
/* 上报 */
mqttIntervalPost();
count=0;
RH_sum=0;
T_sum=0;
}
client.loop();
}
修改PubSubClient.h
找到PubSubClient.h文件,将 #define MQTT_MAX_PACKET_SIZE
后的数字改为1024,将 #define MQTT_KEEPALIVE
后的数字改为60
password生成教程
password生成工具:http://iot-face.oss-cn-shanghai.aliyuncs.com/tools.htm
假设你的设备三元组数据如下
设备三元组
ProductKey = a14Xib5kdYd
DeviceName = ESP8266
DeviceSecret = oLyaKqVxtRvjH284LdhqVgVUx1UPy6zq
建立MQTT连接时参数,这个信息是代码中的CLIENT_ID,可以自己设置
clientId = ESP8266
timestamp = 1234567890
signmethod = hmacsha1
然后根据这些信息生成password的content
clientIdESP8266deviceNameESP8266productKeya15ptdU1zhPtimestamp1234567890
明文输入content,秘钥输入deviceSecret,点击hmac-sha1就可以生成password
效果图
推荐阅读:
- 高性价比和便宜的VPS/云服务器推荐:https://blog.zeruns.com/archives/383.html
- 搭建内网穿透服务器,带Web面板:https://blog.zeruns.com/archives/397.html
- 使用Cloudreve自建网盘:https://blog.zeruns.com/archives/515.html
- 怎样搭建个人博客:https://blog.zeruns.com/archives/218.html
- 学生优惠权益大全:https://blog.zeruns.com/archives/321.html
12 条评论
请问有具体的引脚图吗?
现在阿里平台有MQTT的链接参数可以查询了,大家可以根据平台给的参数,填入博主的代码中,err4的原因可能是MQTT参数没有配置正确
补两个图
请问大佬,一直err:4是什么缘故
阿里云设备怎么激活呀
换成了DHT11后 一直报这个错 MQTT Connect err:-2 是程序的问题还是网的问题
mqtt connect err:4
大佬我就变了dht11读取温度的。。。
你改了哪些部分
/ 依赖 PubSubClient 2.4.0 /
include <PubSubClient.h>/ 依赖 ArduinoJson 5.13.4 /
include <ArduinoJson.h>include <DHT.h>/ 连接您的WIFI SSID和密码 /
define WIFI_SSID "hantojiang"define WIFI_PASSWD "18858598108"/ 设备的三元组信息/
define PRODUCT_KEY "a1MZA197WJx"define DEVICE_NAME "esp8266"define DEVICE_SECRET "o2S1Sr7OphMWa9oZz39sBbdRdQ6WTksm"define REGION_ID "cn-shanghai"/ 线上环境域名和端口号,不需要改 /
define MQTT_SERVER PRODUCT_KEY ".iot-as-mqtt." REGION_ID ".aliyuncs.com"define MQTT_PORT 1883define MQTT_USRNAME DEVICE_NAME "&" PRODUCT_KEYdefine CLIENT_ID "esp8266|securemode=3,timestamp=1234567890,signmethod=hmacsha1|"// 算法工具: http://iot-face.oss-cn-shanghai.aliyuncs.com/tools.htm 进行加密生成password
define MQTT_PASSWD "fd8ca97350be983995cbd672e4c6f5442a8bfff9"define ALINK_BODY_FORMAT "{\"id\":\"123\",\"version\":\"1.0\",\"method\":\"thing.event.property.post\",\"params\":%s}"define ALINK_TOPIC_PROP_POST "/sys/" PRODUCT_KEY "/" DEVICE_NAME "/thing/event/property/post"// password教程 https://www.yuque.com/cloud-dev/iot-tech/mebm5g
unsigned long lastMs = 0;
WiFiClient espClient;
PubSubClient client(espClient);
DHT dht(D1,DHT11);
void callback(char topic, byte payload, unsigned int length)
WiFi.begin(WIFI_SSID, WIFI_PASSWD); Serial.print("Message arrived ["); Serial.print(topic); Serial.print("] "); payload[length] = '\0'; Serial.println((char *)payload);{
}
void wifiInit()
WiFi.mode(WIFI_STA); while (WiFi.status() != WL_CONNECTED) { delay(1000); Serial.println("WiFi not Connect"); } Serial.println("Connected to AP"); Serial.println("IP address: "); Serial.println(WiFi.localIP());{
Serial.print("espClient [");
client.setServer(MQTT_SERVER, MQTT_PORT); /* 连接WiFi之后,连接MQTT服务器 */ client.setCallback(callback);}
void mqttCheckConnect()
while (!client.connected()) { Serial.println("Connecting to MQTT Server ..."); if (client.connect(CLIENT_ID, MQTT_USRNAME, MQTT_PASSWD)) { Serial.println("MQTT Connected!"); } else { Serial.print("MQTT Connect err:"); Serial.println(client.state()); delay(5000); } }{
}
void mqttIntervalPost()
char param[32]; char jsonBuf[128]; sprintf(param, "{\"idle\":%d}", digitalRead(13)); sprintf(jsonBuf, ALINK_BODY_FORMAT, param); Serial.println(jsonBuf); boolean d = client.publish(ALINK_TOPIC_PROP_POST, jsonBuf); Serial.print("publish:0 失败;1成功"); Serial.println(d);{
}
void setup()
dht.begin(); /* initialize serial for debugging */ Serial.begin(115200); Serial.println("Demo Start"); wifiInit();{
}
// the loop function runs over and over again forever
if (millis() - lastMs >= 5000) { lastMs = millis(); mqttCheckConnect(); /* 上报 */ mqttIntervalPost(); } client.loop(); delay(1000); //延时1000毫秒void loop()
{
float RH = dht.readHumidity(); //读取湿度数据
float T = dht.readTemperature();//读取温度数据
Serial.print("Humidity:"); //向串口打印 Humidity:
Serial.print(RH); //向串口打印湿度数据
Serial.print("%");
Serial.print(" Temperature:");
Serial.print(T); //向串口打印温度数据
Serial.println("C");
}
大佬代码在这里
改得太多了很多地方都是错的,你就改一下我程序读取数据部分就行了啊
嗯 可以了 看来太高估自己了随意改你的代码 谢谢大佬 帮了我的大忙
这个是真的很厉害了 ::paopao:tieba_emotion_13::