前言
由于工作关系,我接触到相关嵌入式开发。来公司3年,天天耳濡目染,我觉得自己至少也得写点嵌入式相关
目标
实现一个家庭温湿度计的小工具。 直接上理想的结果
配件
esp8266开发板
温湿度传感器
杜邦线
usb线

淘宝搜一下.
接线
如果你和我的同款,则接线应该相同。
传感器的GND 接 esp8266的GND
传感器的DATA接 esp8266的 D4
传感器的VCC 接 esp8266的 3V


平台配置
创建产品
记得选中 密钥认证


定义数据模型

面板设置

添加设备

用腾讯连连小程序扫描即可。
编码
编码的逻辑
1、先连接wifi
2、再连接mqtt,连接后订阅消息,接收控制指令。
3、不断检查时间间隔,时间到了则读取温度、湿度。提交数据
/**
连接wifi
连接mqtt
读取温湿度
DHT11的湿度测量分辨率是1%,温度测量分辨率是1摄氏度。
*/
#include <SimpleDHT.h>
#include <Arduino_JSON.h>
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <NTPClient.h>
#include <WiFiUdp.h>
#include <PubSubClient.h>
#ifndef STASSID
#define STASSID "wifi名称"
#define STAPSK "wifi密码"
#endif
const char* ssid = STASSID;
const char* password = STAPSK;
/* 产品的三元组信息,*/
#define PRODUCT_KEY "产品id"
#define DEVICE_NAME "设备id"
#define DEVICE_SECRET "设备密钥"
/**
mqtt 服务器信息
*/
#define MQTT_SERVER PRODUCT_KEY".iotcloud.tencentdevices.com"
#define MQTT_PORT 1883
/**
过期时间
2021-11-11 11:09:16
${productid}${devicename};${sdkappid};${connid};${expiry}
11:16:52.842 -> S6UF3TTS5Resp8266living;12010126;fthome;1636600156
*/
#define MQTT_USRNAME PRODUCT_KEY DEVICE_NAME";12010126;fthome;1636600156"
#define MQTT_CLIENT_ID PRODUCT_KEY DEVICE_NAME
/**
密码规则
row_key = base64(key)
token = hmacsh1(username,row_key)
4c60988b98fe88af7211ef4baad57efc75d679c1f012100335c798ef566bedda
${token};hmac 签名方法
*/
#define MQTT_PASSWD "4c60988b98fe88af7211ef4baad57efc75d679c1f012100335c798ef566bedda;hmacsha256"
#define POST_TOPIC "$thing/up/property/" PRODUCT_KEY "/" DEVICE_NAME
#define BODY_FORMAT "{\"method\":\"report\",\"clientToken\":\"msg-id-%d\",\"params\":{\"temperature\":%s,\"humidity\":%s,\"upmin\":%d}}"
#define DOWN_TOPIC "$thing/down/property/" PRODUCT_KEY "/" DEVICE_NAME
/**
设备对服务器下发消息的回应
*/
#define REPLY_FORMAT "{\"method\":\"control_reply\",\"clientToken\":\"%s\",\"code\":0,\"status\":\"success\"}"
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP);
ESP8266WiFiMulti WiFiMulti;
WiFiClient espClient;
PubSubClient client(espClient);
int pinDHT11 = 2;
/**
默认的上报时间
*/
int upmin = 1;
unsigned long lastMs = 0;
SimpleDHT11 dht11(pinDHT11);
void callback(char *topic, byte *payload, unsigned int length)
{
char input[length];
for (int i = 0; i < length; i++) {
//Serial.print((char)payload[i]);
input[i] = (char)payload[i];
}
if (strstr(topic, DOWN_TOPIC))
{
JSONVar myObject = JSON.parse(input);
if (JSON.typeof(myObject) == "undefined")
{
return ;
}
//消息类型
if (myObject.hasOwnProperty("method")) {
Serial.print("myObject[\"method\"] = ");
Serial.println(myObject["method"]);
//是否控制下发指令
if (strstr(myObject["method"], "control")) {
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");
Serial.println(input);
/**
{
"method": "control",
"clientToken": "clientToken-0a9dc8ef-1b3b-45f0-af55-a10988431f00",
"params": {
"upmin": 1
}
}
*/
//先应答
char jsonBuf[128];
sprintf(jsonBuf, REPLY_FORMAT, (const char*)myObject["clientToken"]);
Serial.println(jsonBuf);
boolean d = client.publish(POST_TOPIC, jsonBuf);
if (d) {
Serial.println("reply control msg ok ");
} else {
Serial.println("reply control error ");
}
if (myObject.hasOwnProperty("params")) {
Serial.println(myObject["params"]["upmin"]);
Serial.println(JSON.typeof(myObject["params"]["upmin"]));
if (JSON.typeof(myObject["params"]["upmin"]) == "number") {
upmin = myObject["params"]["upmin"];
}
}
}
}
}
}
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
// Attempt to connect
if (client.connect(MQTT_CLIENT_ID, MQTT_USRNAME, MQTT_PASSWD)) {
Serial.println("connected");
// 订阅消息
client.subscribe(DOWN_TOPIC);
Serial.println("subscribe done");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
}
}
}
void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_STA);
WiFiMulti.addAP(ssid, password);
Serial.println();
Serial.println();
Serial.print("Wait for WiFi... ");
while (WiFiMulti.run() != WL_CONNECTED) {
Serial.print(".");
delay(500);
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
delay(500);
timeClient.begin();
/**
连接服务器
*/
client.setServer(MQTT_SERVER, MQTT_PORT);
client.setCallback(callback);
}
void loop() {
if (!client.connected()) {
reconnect();
}
//符合间隔数据,上报一次
if (millis() - lastMs >= upmin * 1000 ) {
lastMs = millis();
Serial.println("start up msg ");
//上报1次。
float temperature = 0.0;
float humidity = 0.0;
int err = SimpleDHTErrSuccess;
if ((err = dht11.read2(&temperature, &humidity, NULL)) != SimpleDHTErrSuccess) {
return;
}
char jsonBuf[128];
int timestamp = millis();
char ts[6] = "";
char hs[6] = "";
dtostrf(temperature, 2, 2, ts);
dtostrf(humidity, 2, 2, hs);
sprintf(jsonBuf, BODY_FORMAT, timestamp, ts, hs,upmin);
boolean d = client.publish(POST_TOPIC, jsonBuf);
if (d) {
Serial.print("up msg ok ");
} else {
Serial.print("up msg error ");
}
}
client.loop();
delay(5000);
}
代码中的参数的获取位置

注意事项
-
读取的温度和湿度没有小数
虽然我代码写的是 浮点数,但是实际读取结果只能整数。这是因为我买的传感器只支持整数。精度不够。 -
腾讯mqtt的文档地址
https://github.com/tencentyun/qcloud-iot-esp-wifi
其他地方完全看不懂。尤其其中topic
- Mqtt参数的密码问题
密码我不会代码生成,所以选中在线计算。
这里要注意,记得勾选 我图中的base64格式密钥。

-
最后的结果
image.png

- 后续
网友评论