1.【腾讯云物联网平台介绍】


底层数据传输基于MQTT或CoAP协议,可以有效减少网络带宽。同时也支持 MQTT CoAP http. websocket接入。
对于MQTT协议传输,支持QoS=0/QoS=1等消息特性。
安全方面引入网络安全传输协议(TLS、DLS),可以防范非法接入和数据窃取、篡改等风险。
支持:非对称加密(设备证书加密验证、适用高安全要求场景)
对称加密(秘钥加密验证、适用资源受限设备)
价格:<5122Bytes一条消息
<100万条/月--免费
100万<N≤1亿--每百万条=3元
免费消息包含:通过规则引擎转发到腾讯云内部组件的消息;
 CONNECT、 CONNACK、 PUBACK、 SUBSCRIBE SUBACK
 UNSUBSCRIBE、 UNSUBACK、 PINGREQ、 PINGRESP、 DISCONNECT报文

 

一个产品下的所有设备具备相同的主题类权限。为了实现设备数据安全隔离,目前,腾讯云限制设备只能发布和订阅自身主题。规则引擎:实现设备与其他实体的消息互通、处理主题中的数据并转发到腾讯云其它服务。
注目前数据格式必须是JSON才能使用规则引擎进行处理/转发(后续会支持二进制的数据格式)

 

参数说明

参数

说明

Profile Name

配置文件保存为的名称。

Broker Address

MQTT 服务器连接地址,广州域设备填入:PRODUCT_ID.iotcloud.tencentdevices.com,这里 PRODUCT_ID 为变量参数,用户需填入创建产品时自动生成的产品 ID,例如 9****ZW2EZ.iotcloud.tencentdevices.com

Broker Port

MQTT 服务器连接端口,证书认证型端口:8883;密钥认证型:1883

Client ID

MQTT 协议字段,按照物联网通信约束填入:产品 ID + 设备名,例如:"9****ZW2EZgate_dev01 ",9****ZW2EZ 是产品 ID,gate_dev01 是设备名。

Connection Timeout

连接超时时间秒。

Keep Alive Interval

心跳间隔时间秒。

Auto Reconnect

断网自动重连。

 

填写 User Credentials 信息。

  • User Name :MQTT 协议字段,按照物联网通信约束填入:产品 ID + 设备名 + SDKAppID + connid。(创建完产品即可在产品列表页和产品详情页查看 ProductID)如:"9****ZW2EZgate_dev01;12010126;12345",仅替换示例中的产品 ID + 设备名即可,后面的两个参数本身由物联网通信接入 SDK 自动生成,所以这里填写固定测试值。
  • Password :Password 必须填写。
    • 证书认证:由于 mqtt.fx 默认将密码标志位设为 true,所以需要填写一个任意的非空字符串作为密码,否则无法连接到物联云通信后台。而实际接入物联云后台时,鉴权是根据证书认证,此处随机填写的密码不会作为接入凭证。
    • 密钥认证:用户可进入 Hub 相应设备列表查看获取(具体页面见下方密钥认证步骤),也可以按照文档 手动生成Password

来自 <https://cloud.tencent.com/document/product/634/14630>

2.证书方式认证方式创建云端设备

2.1密钥认证

2.1.物联网通信

或按照下图点击点击

 2.2 产品列表→创建新产品

 2.3 设置产品名称→点击创建

 2.4 设备列表→添加新设备→保存

crt_esp8266 云端设备
crt_esp8266_mqtt mqqt客户端

 2.5 下载

2.6 再添加一个.添加设备

 2.7 点击下载

 

2.8.下载物联网证书(第三个证书),到文档中心

文档中心→物联网通信→快速入门→MQTT.fx接入指南

 

密码随便填

2.2.制作8266证书

 

1.打开乌班图(需要安装python2)将SDK包<tools>文件夹下的文件复制到Share文件夹

2:将【服务器证书】、【8266证书】、【8266私钥复制到共享文件夹</M/Share>中,将它们依次重命名为:【ca.crt】、【client.crt、【client.key】

3.进入Share文件夹

4:输入【./makefile.sh】,输出结果如下,表示客户端8266所需证书BN文件制作成功

yys@yys:~/桌面/Share$ ./makefile.sh 
ca.crt is found, generating esp_ca_cert.bin...
['TLS.ca_x509.cer']
esp_ca_cert.bin generated OK!
trust CA
client.crt && client.key are found, generating esp_cert_private_key.bin
writing RSA key
esp_ca_cert.bin && esp_cert_private_key.bin was generated under bin/ directory
 

生成4个文件夹

 

ESP8266认证服务端证书:
bool espconn_secure_ca_enable( uint8 level, uint32 flash_sector)
ESP8266作为SSL客户端,【参数1: level】=1
将《esp_ca_cert.bin》烧录到【参数2: flash_sector】所对应的扇区
服务端认证ESP8266的证书:
 bool espconn_secure_cert_req_enable(uint8 8 level,uint32 2 flash_sector
ESP8266作为SSL客户端,【参数1: level】=1
将《esp_certt_private_key.bin》烧录到【参数2: flashsector】所对应的扇区

2.3.设备接入腾讯云

4.1.添加topic

进入产品列表

产品列表→<名字>如iot_8266→权限列表→添加Topic权限

名字:SW_LED

权限:订阅和发布

这一步作为主题订阅和发布

4.2 添加规则引擎

规则引擎→新建规则→名字随便→确定

点击名字进入→字段*表示不筛选→topic(选刚才建立的mqtt)→条件为空(任意)→确定

 

这个为mqtt客户端

4.2.1添加行为操作

最好点击保存

这个为云端

基本信息

编辑

规则名称

AAA

规则状态

已启用

规则描述

筛选数据

编辑

字段

*

Topic

8ZHBV8CPQ6/crt_esp8266_mqtt/SW_LED

条件

当前SQL

SELECT * FROM '8ZHBV8CPQ6/crt_esp8266_mqtt/SW_LED'

行为操作

数据转发到另一个Topic ( Republish )

编辑删除

Topic

8ZHBV8CPQ6/crt_esp8266/SW_LED

4.3 最后回到规则引擎点击启用

 

 

999.我的设置

具体配置如下:

设备] crt_esp8266

[MQTT_Host]8ZHBV8CPQ6.iotcloud.tencentdevices.com:8883

[ClientID]    8ZHBV8CPQ6crt_esp8266

[Username]8ZHBV8CPQ6crt_esp8266;12010126;12345

[Password]yys534640040

 

[设备] crt_esp8266_mqtt

[MQTT_Host]]8ZHBV8CPQ6.iotcloud.tencentdevices.com:8883

[ClientID] 8ZHBV8CPQ6crt_esp8266_mqtt

[Username]8ZHBV8CPQ6crt_esp8266_mqtt;12010126;12345

[Password]yys534640040

[主题]:

[esp8266]订阅:8ZHBV8CPQ6/crt_esp8266/SW_LED

[mqtt.fx] 发布: 8ZHBV8CPQ6/crt_esp8266_mqtt/SW_LED

 

mqttx软件测试

 成功后crt_esp8266_mqtt会在线

 

文件31_MQTT_TLS_JX

进入"D:\esp8266\doc\31_MQTT_TLS_JX\esp_mqtt_proj\include\mqtt_config.h"

设置服务端的几个参数,持有人标识符随便改,不然不会更新

#define CFG_HOLDER    		0x66666534	// 持有人标识(只有更新此数值,系统参数才会更新)		/* Change this value to load default configurations */

/*DEFAULT CONFIGURATIONS*/
// 注:【MQTT协议规定:连接服务端的每个客户端都必须有唯一的客户端标识符(ClientId)】。如果两相同ID的客户端不断重连,就会进入互踢死循环
//--------------------------------------------------------------------------------------------------------------------------------------
#define MQTT_HOST			"8ZHBV8CPQ6.iotcloud.tencentdevices.com" 			// MQTT服务端域名/IP地址	// the IP address or domain name of your MQTT server or MQTT broker ,such as "mqtt.yourdomain.com"
#define MQTT_PORT       	8883    										// 网络连接端口号			// the listening port of your MQTT server or MQTT broker
#define MQTT_CLIENT_ID   	"8ZHBV8CPQ6crt_esp8266"	// 官方例程中是"Device_ID"		// 客户端标识符				// the ID of yourself, any string is OK,client would use this ID register itself to MQTT server
#define MQTT_USER        	"8ZHBV8CPQ6crt_esp8266;12010126;12345" 			// MQTT用户名				// your MQTT login name, if MQTT server allow anonymous login,any string is OK, otherwise, please input valid login name which you had registered
#define MQTT_PASS        	"yys534640040" 			// MQTT密码					// you MQTT login password, same as above

#define STA_SSID 			"yang1234"    	// WIFI名称					// your AP/router SSID to config your device networking
#define STA_PASS 			"y123456789" 	// WIFI密码					// your AP/router password
#define STA_TYPE			AUTH_WPA2_PSK

#define DEFAULT_SECURITY	TWO_WAY_ANTHENTICATION		// 加密传输类型【双向认证】		// very important: you must config DEFAULT_SECURITY for SSL/TLS

#define CA_CERT_FLASH_ADDRESS 		0x77   		// 【CA证书BIN】烧录地址(扇区)			// CA certificate address in flash to read, 0x77 means address 0x77000
#define CLIENT_CERT_FLASH_ADDRESS 	0x78 		// 【8266证书BIN】烧录地址(扇区)		// client certificate and private key address in flash to read, 0x78 means address 0x78000

2.修改8266订阅主题

"D:\esp8266\doc\31_MQTT_TLS_JX\esp_mqtt_proj\user\user_main.c"

MQTT_Subscribe(client, "8ZHBV8CPQ6/crt_esp8266/SW_LED", 0);	// 订阅主题"SW_LED",QoS=0
 // 根据接收到的主题名/有效载荷,控制LED的亮/灭
    //-----------------------------------------------------------------------------------
    if( os_strcmp(topicBuf,"8ZHBV8CPQ6/crt_esp8266/SW_LED") == 0 )	// 主题 == "SW_LED"
    {
    	if( os_strcmp(dataBuf,"{\"SW_LED\":\"LED_ON\"}") == 0 )			// 有效载荷 == "LED_ON"
    	{
    		GPIO_OUTPUT_SET(GPIO_ID_PIN(4),0);	// LED亮
    	}

    	else if( os_strcmp(dataBuf,"{\"SW_LED\":\"LED_OFF\"}") == 0 )	// 有效载荷 == "LED_OFF"
    	{
    		GPIO_OUTPUT_SET(GPIO_ID_PIN(4),1);	// LED灭
    	}
    }

编译上传加上证书上传

成功后crt_esp8266会在线

串口调试

STATION_IDLE

connected with yang1234, channel 6
dhcp client start...
STATION_IDLE
STATION_IDLE
STATION_IDLE
STATION_IDLE
STATION_IDLE
ip:192.168.31.131,mask:255.255.255.0,gw:192.168.31.1
current time : Sat Jan 16 11:07:11 2021

your ESP SSL/TLS configuration is 3.[0:NO_TLS    1:TLS_WITHOUT_AUTHENTICATION    2ONE_WAY_ANTHENTICATION    3TWO_WAY_ANTHENTICATION]
TCP: Connect to domain 8ZHBV8CPQ6.iotcloud.tencentdevices.com:8883
DNS: found ip 49.233.106.190
TCP: connecting...

------------- MQTT_Task -------------
client handshake start.
espconn_mbedtls.c 661, type[certificate],length[855]
espconn_mbedtls.c 661, type[certificate],length[855]
espconn_mbedtls.c 661, type[private_key],length[1192]
espconn_mbedtls.c 661, type[TLS.ca_x509.cer],length[969]
client handshake ok!
MQTT: Connected to broker 8ZHBV8CPQ6.iotcloud.tencentdevices.com:8883
MQTT: Sending, type: 1, id: 0000

------------- MQTT_Task -------------
TCP: Sent

------------- MQTT_Task -------------
TCP: data received 4 bytes
TCP: data received 32,2,0,0 
MQTT: Connected to 8ZHBV8CPQ6.iotcloud.tencentdevices.com:8883
MQTT: Connected
MQTT: queue subscribe, topic"8ZHBV8CPQ6/crt_esp8266/SW_LED", id: 1

------------- MQTT_Task -------------
MQTT: Sending, type: 8, id: 0001
TCP: Sent

------------- MQTT_Task -------------
TCP: data received 5 bytes
TCP: data received 144,3,0,1 
MQTT: Subscribe successful

------------- MQTT_Task -------------
pm open,type:2 0
TCP: data received 53 bytes
TCP: data received 48,51,0,29 
Receive topic: 8ZHBV8CPQ6/crt_esp8266/SW_LED, data: {"SW_LED":"LED_ON"}
 

在mqtt.fc软件

在publish输入8ZHBV8CPQ6/crt_esp8266_mqtt/SW_LED订阅

输入{"SW_LED":"LED_ON"}灯亮,不要有空格

{"SW_LED":"LED_ON"}

在mqtt.fc软件输入{"SW_LED":"LED_OFF"}灯灭

{"SW_LED":"LED_OFF"}

 

3.密钥方式认证方式创建云端设备

对于认证方式, 指定了设备通过何种方式和云端进行双向认证. 默认的证书方式相对于密钥认证安全性高一点, 但是问题在于证书方式需要在嵌入式设备端存储证书同时实现证书的相关处理, 对设备的RAM和ROM要求较高, 相对而言, 密钥认证的方式资源占用量就小点, 由于我们主要支持的设备都是小型嵌入式设备, 因此选用密钥认证。

数据格式指的是设备和云端进行数据交互时候使用的格式, json格式为文本字符串, 可读性高, 并且便于解析, 对于功能复杂的设备交互而已比较理想, 但是对于小型设备或是定制设备, 数据单一, 或是有自定义的格式(二进制或是文本), 这种时候, 用自定义的数据格式, 一方面节约流量, 另一方面比较灵活.。

 

dev 云端设备
dev_mqtt mqqt客户端

只需要填写User creadential就可以了,不用ssl证书

以下和证书认证一样,点击查看

[设备] dev

[MQTT_Host]4I7KLY9ORJdev.iotcloud.tencentdevices.com:1883

[ClientID]4I7KLY9ORJdev

[Username]4I7KLY9ORJdev;12010126;VK4PW;1646780037

[Password]1cd9476b248ad2ba0c3098535744e0a24a9dd3a46a60be2803a19ad2c7fdc5a1;hmacsha256

 

[设备] dev_mqtt

[MQTT_Host]4I7KLY9ORJdev.iotcloud.tencentdevices.com:1883

[ClientID]4I7KLY9ORJdev_mqtt

[Username]4I7KLY9ORJdev_mqtt;12010126;VZ33F;1646779997

[Password]2f0c91ec0559cc42bb576eb6e7bf8522d90ec6d7f2bd3a8aba78b230207a09d6;hmacsha256


[主题]:

[esp8266]订阅:4I7KLY9ORJ/dev/LED

[mqtt.fx] 发布:4I7KLY9ORJ/dev_mqtt/LED
 

4.arduino ide 的esp8266连接腾讯云

4.1 发布主题

代码来源

dev 云端设备
dev_mqtt mqqt客户端

使用密码方式

用户名密码都是mqtt客户端

 String topicStringmqtt客户端

配置开发板连接Mysql需要的库文件:MySQL_Connector_Arduino
这些库文件可以在gitHab上找到,下面是网址:
https://github.com/adafruit/DHT-sensor-library
https://github.com/ChuckBell/MySQL_Connector_Arduino
https://github.com/esp8266/Arduino/tree/master/libraries/ESP8266WiFi

三秒发布一次 

#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <Ticker.h>
 
// 设置wifi接入信息(请根据您的WiFi信息进行修改)
const char* ssid = "yang1234";
const char* password = "y123456789";
const char* mqttServer = "4I7KLY9ORJdev.iotcloud.tencentdevices.com";

 // MQTT服务端连接用户名密码
const char* mqttUserName = "4I7KLY9ORJdev_mqtt;12010126;VZ33F;1646779997";
const char* mqttPassword = "2f0c91ec0559cc42bb576eb6e7bf8522d90ec6d7f2bd3a8aba78b230207a09d6;hmacsha256";
 
// 如以上MQTT服务器无法正常连接,请前往以下页面寻找解决方案
// http://www.taichi-maker.com/public-mqtt-broker/
 
Ticker ticker;
WiFiClient wifiClient;
PubSubClient mqttClient(wifiClient);
 
int count;    // Ticker计数用变量
 
void setup() {
  Serial.begin(9600);
  
  //设置ESP8266工作模式为无线终端模式
  WiFi.mode(WIFI_STA);
  
  // 连接WiFi
  connectWifi();
  
  // 设置MQTT服务器和端口号
  mqttClient.setServer(mqttServer, 1883);
 
  // 连接MQTT服务器
  connectMQTTServer();
 
  // Ticker定时对象
  ticker.attach(1, tickerCount);  
}
 
void loop() { 
  if (mqttClient.connected()) { // 如果开发板成功连接服务器
    // 每隔3秒钟发布一次信息
    if (count >= 3){
      pubMQTTmsg();
      count = 0;
    }    
    // 保持心跳
    mqttClient.loop();
  } else {                  // 如果开发板未能成功连接服务器
    connectMQTTServer();    // 则尝试连接服务器
  }
}
 
void tickerCount(){
  count++;
}
 
void connectMQTTServer(){
  // 根据ESP8266的MAC地址生成客户端ID(避免与其它ESP8266的客户端ID重名)
  String clientId = "4I7KLY9ORJdev_mqtt";
 
  // 连接MQTT服务器
  if (mqttClient.connect(clientId.c_str(), mqttUserName, mqttPassword)) { 
    Serial.println("MQTT Server Connected.");
    Serial.println("Server Address: ");
    Serial.println(mqttServer);
    Serial.println("ClientId:");
    Serial.println(clientId);
  } else {
    Serial.print("MQTT Server Connect Failed. Client State:");
    Serial.println(mqttClient.state());
    delay(3000);
  }   
}
 
// 发布信息
void pubMQTTmsg(){
  static int value; // 客户端发布信息用数字
 
  // 建立发布主题。主题名称以Taichi-Maker-为前缀,后面添加设备的MAC地址。
  // 这么做是为确保不同用户进行MQTT信息发布时,ESP8266客户端名称各不相同,
  String topicString = "4I7KLY9ORJ/dev_mqtt/LED";
  char publishTopic[topicString.length() + 1];  
  strcpy(publishTopic, topicString.c_str());
 
  // 建立发布信息。信息内容以Hello World为起始,后面添加发布次数。
  String messageString = "Hello World " + String(value++); 
  char publishMsg[messageString.length() + 1];   
  strcpy(publishMsg, messageString.c_str());
  
  // 实现ESP8266向主题发布信息
  if(mqttClient.publish(publishTopic, publishMsg)){
    Serial.println("Publish Topic:");Serial.println(publishTopic);
    Serial.println("Publish message:");Serial.println(publishMsg);    
  } else {
    Serial.println("Message Publish Failed."); 
  }
}
 
// ESP8266连接wifi
void connectWifi(){
 
  WiFi.begin(ssid, password);
 
  //等待WiFi连接,成功连接后输出成功信息
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi Connected!");  
  Serial.println(""); 
}

 

带mysql的发布主题

#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <MySQL_Connection.h>    // Arduino连接Mysql的库
#include <MySQL_Cursor.h>

// 设置wifi接入信息(请根据您的WiFi信息进行修改)
const char* ssid = "yang1234";
const char* password = "y123456789";
const char* mqttServer = "4I7KLY9ORJ.iotcloud.tencentdevices.com";
// 如以上MQTT服务器无法正常连接,请前往以下页面寻找解决方案
// http://www.taichi-maker.com/public-mqtt-broker/
 // 云端连接用户名密码
const char* mqttUserName = "4I7KLY9ORJdev;12010126;NB6RR;1646777246";
const char* mqttPassword = "bba47318ac52335da17a34d195097ffe0b776cbb831945d8575324eda24682ed;hmacsha256";
WiFiClient wifiClient;
PubSubClient mqttClient(wifiClient);

IPAddress server_addr(192,168,31,84);// 安装Mysql的电脑的IP地址
// Mysql中添加一条数据的命令
char mysqluser[] = "root";
char mysqlpwd[] = "123456";
char INSERT_SQL[] = "INSERT INTO log.d20210125(content,time) VALUES ('%s','%s')";
WiFiClient client;      // 声明一个Mysql客户端,在lianjieMysql中使用
MySQL_Connection conn(&client);
MySQL_Cursor* cursor;    // 

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);     // 设置板上LED引脚为输出模式
  digitalWrite(LED_BUILTIN, HIGH);  // 启动后关闭板上LED
  Serial.begin(9600);               // 启动串口通讯
  
  //设置ESP8266工作模式为无线终端模式
  WiFi.mode(WIFI_STA);
  
  // 连接WiFi
  connectWifi();
  
  // 设置MQTT服务器和端口号
  mqttClient.setServer(mqttServer, 1883);
  // 设置MQTT订阅回调函数
  mqttClient.setCallback(receiveCallback);
 
  // 连接MQTT服务器
  connectMQTTserver();
  
  if (conn.connect(server_addr, 3306, mysqluser, mysqlpwd))         // 连接数据库
    Serial.println("OK.");   
  else
    Serial.println("FAILED.");
  cursor = new MySQL_Cursor(&conn);    // 创建一个数据库游标实例
  
}
 
void loop() {
  if (mqttClient.connected()) { // 如果开发板成功连接服务器
    mqttClient.loop();          // 处理信息以及心跳
  } else {                      // 如果开发板未能成功连接服务器
    connectMQTTserver();        // 则尝试连接服务器
  }
}
 
// 连接MQTT服务器并订阅信息
void connectMQTTserver(){
  // 根据ESP8266的MAC地址生成客户端ID(避免与其它ESP8266的客户端ID重名)
  String clientId = "4I7KLY9ORJdev";
 
  // 连接MQTT服务器
  if (mqttClient.connect(clientId.c_str(), mqttUserName, mqttPassword)) { 
    Serial.println("MQTT Server Connected.");
    Serial.println("Server Address:");
    Serial.println(mqttServer);
    Serial.println("ClientId: ");
    Serial.println(clientId);
    subscribeTopic(); // 订阅指定主题
  } else {
    Serial.print("MQTT Server Connect Failed. Client State:");
    Serial.println(mqttClient.state());
    delay(5000);
  }   
}
 
// 收到信息后的回调函数
void receiveCallback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message Received [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println("");
  Serial.print("Message Length(Bytes) ");
  Serial.println(length);
 
  if ((char)payload[0] == '1') {     // 如果收到的信息以“1”为开始
    digitalWrite(BUILTIN_LED, LOW);  // 则点亮LED。
    Serial.println("LED ON");
    
    char buff[128];   // 定义数据的数组
    sprintf(buff,INSERT_SQL,"1", "22:20"); // 讲tem和hem中数据放入SQL中
    MySQL_Cursor *cur_mem = new MySQL_Cursor(&conn);  // 创建一个Mysql实例
    cur_mem->execute(buff);// 将值插入数据库中
    delete cur_mem;   // 删除mysql实例为下次采集作准备
    
  } else {                           
    digitalWrite(BUILTIN_LED, HIGH); // 否则熄灭LED。
    Serial.println("LED OFF");
  }
}
 
// 订阅指定主题
void subscribeTopic(){
 
  // 建立订阅主题。主题名称以Taichi-Maker-Sub为前缀,后面添加设备的MAC地址。
  // 这么做是为确保不同设备使用同一个MQTT服务器测试消息订阅时,所订阅的主题名称不同
  String topicString = "4I7KLY9ORJ/dev/LED";
  char subTopic[topicString.length() + 1];  
  strcpy(subTopic, topicString.c_str());
  
  // 通过串口监视器输出是否成功订阅主题以及订阅的主题名称
  if(mqttClient.subscribe(subTopic)){
    Serial.println("Subscrib Topic:");
    Serial.println(subTopic);
  } else {
    Serial.print("Subscribe Fail...");
  }  
}
 
// ESP8266连接wifi
void connectWifi(){
 
  WiFi.begin(ssid, password);
 
  //等待WiFi连接,成功连接后输出成功信息
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi Connected!");  
  Serial.println(""); 
}

 mysql定义

#include <MySQL_Connection.h>    // Arduino连接Mysql的库
#include <MySQL_Cursor.h>
IPAddress server_addr(192,168,31,84);// 安装Mysql的电脑的IP地址
// Mysql中添加一条数据的命令
char mysqluser[] = "root";
char mysqlpwd[] = "123456";
char INSERT_SQL[] = "INSERT INTO log.d20210125(content,time) VALUES ('%s','%s')";
WiFiClient client;      // 声明一个Mysql客户端,在lianjieMysql中使用
MySQL_Connection conn(&client);
MySQL_Cursor* cursor;    // 

void setup() {
  
  Serial.begin(9600);               // 启动串口通讯
  
  if (conn.connect(server_addr, 3306, mysqluser, mysqlpwd))         // 连接数据库
    Serial.println("OK.");   
  else
    Serial.println("FAILED.");
  cursor = new MySQL_Cursor(&conn);    // 创建一个数据库游标实例
  
}
//写入mysql
char buff[128];   // 定义数据的数组
sprintf(buff,INSERT_SQL,"1", "22:20"); // 讲tem和hem中数据放入SQL中
MySQL_Cursor *cur_mem = new MySQL_Cursor(&conn);  // 创建一个Mysql实例
cur_mem->execute(buff);// 将值插入数据库中
delete cur_mem;   // 删除mysql实例为下次采集作准备

 

 

 

开发板上传连接服务器后发现云端在线了

然后连接云端,注意账号密码为云端的不然被挤下线

4.1.1 mqtt.fx客户端订阅消息

subscribe为客户端4I7KLY9ORJ/dev/LED,会接收到不少mqtt客户端发来的消息

 

Publish Topic:
4I7KLY9ORJ/dev_mqtt/LED
Publish message:
Hello World 176
Publish Topic:
4I7KLY9ORJ/dev_mqtt/LED
Publish message:
Hello World 177
Publish Topic:
4I7KLY9ORJ/dev_mqtt/LED
Publish message:
Hello World 178

4.1.2.python订阅消息

需要先安装paho-mqtt

pip install paho-mqtt

方法一:正确率高

from django.test import TestCase

# Create your tests here.

import paho.mqtt.client as mqtt
import time
strBroker = "4I7KLY9ORJ.iotcloud.tencentdevices.com"
# 通信端口
port = 1883
# 用户名
username = '4I7KLY9ORJdev_mqtt;12010126;SMXAL;1647572493'
# 密码
password = 'ed304dd3f89c1342b0bf4d984b58b81fa87d04fe68aacdd8401212c2d8a1561e;hmacsha256'

TASK_TOPIC = '4I7KLY9ORJ/dev_mqtt/LED'  # 客户端发布消息主题

client_id = time.strftime('%Y%m%d%H%M%S', time.localtime(time.time()))
client = mqtt.Client(client_id=client_id)
client.username_pw_set(username, password)
client.connect(strBroker, port, keepalive=600)
# client_id='2'#要求client_id的值都是唯一的
time.sleep(0.4)
client.publish(TASK_TOPIC, "1", qos=1)




方法二:容易连接拒绝

import json
import sys
import os
import time
import paho.mqtt.client as mqtt

# 服务器地址
strBroker = "4I7KLY9ORJdev.iotcloud.tencentdevices.com"
# 通信端口

# 用户名
username = '4I7KLY9ORJdev;12010126;DJFEX;1647576389'
# 密码
password = '828bbecdc52114a939a290633bd0f26c759275adc3c81746406a816e9d5f1947;hmacsha256'
# 订阅主题名
topic = '4I7KLY9ORJ/dev/LED'
MQTTPORT = 1883

mqttClient = mqtt.Client()



sys.path.append(os.path.abspath(os.path.dirname(__file__) + '/' + '..'))
sys.path.append("..")

REPORT_TOPIC = topic  # 主题


def on_connect(client, userdata, flags, rc):
    print('connected to mqtt with resurt code ', rc)
    client.subscribe(REPORT_TOPIC)  # 订阅主题


def on_message(client, userdata, msg):
    """
    接收客户端发送的消息
    :param client: 连接信息
    :param userdata:
    :param msg: 客户端返回的消息
    :return:
    """
    print("Start server!")
    print(f"{msg.topic}: {msg.payload.decode()}")
    # payload = json.loads(msg.payload.decode('utf-8'))
    # print(payload)


def server_conenet(client):
    client.on_connect = on_connect  # 启用订阅模式
    client.on_message = on_message  # 接收消息
    client.username_pw_set(username, password=password)

    client.connect(strBroker, 1883, 60)  # 链接
    # client.loop_start()   # 以start方式运行,需要启动一个守护线程,让服务端运行,否则会随主线程死亡
    client.loop_forever()  # 以forever方式阻塞运行。


def server_stop(client):
    client.loop_stop()  # 停止服务端
    sys.exit(0)


def server_main():
    client_id = time.strftime('%Y%m%d%H%M%S', time.localtime(time.time()))
    client = mqtt.Client(client_id, transport='tcp')
    server_conenet(client)


if __name__ == '__main__':
    # 启动监听
    server_main()

 

4.2 订阅主题

代码来源

dev 云端设备
dev_mqtt mqqt客户端

使用密码方式

用户名密码都是云端

 String topicString也为云端

 

#include <ESP8266WiFi.h>
#include <PubSubClient.h>
 
// 设置wifi接入信息(请根据您的WiFi信息进行修改)
const char* ssid = "yang1234";
const char* password = "y123456789";
const char* mqttServer = "4I7KLY9ORJ.iotcloud.tencentdevices.com";
// 如以上MQTT服务器无法正常连接,请前往以下页面寻找解决方案
// http://www.taichi-maker.com/public-mqtt-broker/
 // 云端连接用户名密码
const char* mqttUserName = "4I7KLY9ORJdev;12010126;NB6RR;1646777246";
const char* mqttPassword = "bba47318ac52335da17a34d195097ffe0b776cbb831945d8575324eda24682ed;hmacsha256";
WiFiClient wifiClient;
PubSubClient mqttClient(wifiClient);
 
void setup() {
  pinMode(LED_BUILTIN, OUTPUT);     // 设置板上LED引脚为输出模式
  digitalWrite(LED_BUILTIN, HIGH);  // 启动后关闭板上LED
  Serial.begin(9600);               // 启动串口通讯
  
  //设置ESP8266工作模式为无线终端模式
  WiFi.mode(WIFI_STA);
  
  // 连接WiFi
  connectWifi();
  
  // 设置MQTT服务器和端口号
  mqttClient.setServer(mqttServer, 1883);
  // 设置MQTT订阅回调函数
  mqttClient.setCallback(receiveCallback);
 
  // 连接MQTT服务器
  connectMQTTserver();
}
 
void loop() {
  if (mqttClient.connected()) { // 如果开发板成功连接服务器
    mqttClient.loop();          // 处理信息以及心跳
  } else {                      // 如果开发板未能成功连接服务器
    connectMQTTserver();        // 则尝试连接服务器
  }
}
 
// 连接MQTT服务器并订阅信息
void connectMQTTserver(){
  // 根据ESP8266的MAC地址生成客户端ID(避免与其它ESP8266的客户端ID重名)
  String clientId = "4I7KLY9ORJdev";
 
  // 连接MQTT服务器
  if (mqttClient.connect(clientId.c_str(), mqttUserName, mqttPassword)) { 
    Serial.println("MQTT Server Connected.");
    Serial.println("Server Address:");
    Serial.println(mqttServer);
    Serial.println("ClientId: ");
    Serial.println(clientId);
    subscribeTopic(); // 订阅指定主题
  } else {
    Serial.print("MQTT Server Connect Failed. Client State:");
    Serial.println(mqttClient.state());
    delay(5000);
  }   
}
 
// 收到信息后的回调函数
void receiveCallback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message Received [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println("");
  Serial.print("Message Length(Bytes) ");
  Serial.println(length);
 
  if ((char)payload[0] == '1') {     // 如果收到的信息以“1”为开始
    digitalWrite(BUILTIN_LED, LOW);  // 则点亮LED。
    Serial.println("LED ON");
  } else {                           
    digitalWrite(BUILTIN_LED, HIGH); // 否则熄灭LED。
    Serial.println("LED OFF");
  }
}
 
// 订阅指定主题
void subscribeTopic(){
 
  // 建立订阅主题。主题名称以Taichi-Maker-Sub为前缀,后面添加设备的MAC地址。
  // 这么做是为确保不同设备使用同一个MQTT服务器测试消息订阅时,所订阅的主题名称不同
  String topicString = "4I7KLY9ORJ/dev/LED";
  char subTopic[topicString.length() + 1];  
  strcpy(subTopic, topicString.c_str());
  
  // 通过串口监视器输出是否成功订阅主题以及订阅的主题名称
  if(mqttClient.subscribe(subTopic)){
    Serial.println("Subscrib Topic:");
    Serial.println(subTopic);
  } else {
    Serial.print("Subscribe Fail...");
  }  
}
 
// ESP8266连接wifi
void connectWifi(){
 
  WiFi.begin(ssid, password);
 
  //等待WiFi连接,成功连接后输出成功信息
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi Connected!");  
  Serial.println(""); 
}

开发板上传连接服务器后发现云端在线了

4.2.1 mqtt.fx客户端发布消息

然后连接mqtt客户端,注意账号密码为mqtt客户端的,不然被挤下线

 

publish为客户端4I7KLY9ORJ/dev_mqtt/LED

串口监视器显示1时为灯亮,0为灯灭


MQTT Server Connected.
Server Address:
4I7KLY9ORJ.iotcloud.tencentdevices.com
ClientId: 
4I7KLY9ORJdev
Subscrib Topic:
4I7KLY9ORJ/dev/LED
Message Received [4I7KLY9ORJ/dev/LED] 1
Message Length(Bytes) 1
LED ON
Message Received [4I7KLY9ORJ/dev/LED] 0
Message Length(Bytes) 1
LED OFF
Message Received [4I7KLY9ORJ/dev/LED] 111
Message Length(Bytes) 3
LED ON

4.2.2 python实现发布消息 

 

import paho.mqtt.publish as publish
strBroker = "4I7KLY9ORJ.iotcloud.tencentdevices.com"
# 通信端口
port = 1883
# 用户名
username = '4I7KLY9ORJdev_mqtt;12010126;SMXAL;1647572493'
# 密码
password = 'ed304dd3f89c1342b0bf4d984b58b81fa87d04fe68aacdd8401212c2d8a1561e;hmacsha256'

TASK_TOPIC = '4I7KLY9ORJ/dev_mqtt/LED'  # 客户端发布消息主题
client_id = '4I7KLY9ORJ'

'''
发送消息
'''


def transmitMQTT(strMsg):
    auth = {'username': username, 'password': password}
    publish.single(TASK_TOPIC, strMsg, hostname=strBroker, auth=auth)


if __name__ == '__main__':
    msg = "1"
    transmitMQTT(msg)
    print("Send msg = [", msg, "] ok.")