当前位置:   article > 正文

esp8266+SDK开发 上报设备采集的数据至阿里云平台_数据采集上报 sdk

数据采集上报 sdk

本文介绍如何使用esp8266+MQTT协议,从硬件的角度如何上云,并将数据采集-发送到阿里云后台。

 

相关

完整项目介绍:https://blog.csdn.net/feit2417/article/details/86671932

码云(获取源码):https://gitee.com/hinzer/temp_hum_system

 

 

准备

乐鑫提供 ESP8266 SDK

阿里Link 设备端SDK iotkit-embedded-2.3.0

 

我们使用基于TCP的MQTT协议来连接阿里云Link平台,需要遵循Alink协议规范,对阿里C-SDK进行移植到ESP8266

下面来介绍一下移植过程。

 

项目模板

1.使用ESP8266-sdk目录下examples/mqtt_demo,以此为模板。放置在根目录下。
2.修改项目目录下的·gen_misc.sh·和·Makefile·文件,

  1. export SDK_PATH=$/mnt/hgfs/sharefolder-esp8266/ESP8266_RTOS_SDK-2.0.0        //SDK根目录
  2. export BIN_PATH=$/mnt/hgfs/sharefolder-esp8266/ESP8266_RTOS_SDK-2.0.0/bin     //输出bin文件目录
  1. parent_dir:=$(abspath $(shell pwd)/$(lastword $(MAKEFILE_LIST)))
  2. parent_dir:=$(shell dirname $(parent_dir))
  3. parent_dir:=$(shell dirname $(parent_dir))
  4. SDK_PATH= $(parent_dir)
  5. BIN_PATH=$(SDK_PATH)/bin


3.编译项目,没有问题

 

 

移植相关文件

使用MQTT-TCP连接Link平台,需要mqttClientId、mqttUsername、mqttPassword这三个参数认证。但是这些参数并不是直接提供给我们的,需要使用加密机制来对三元组数据生成。

1.找到Link-SDK中的utils\digest目录,复制.c和.h文件到工程目录下

  • .c文件复制到user目录下
  • .h文件复制到include目录下
  • 复制iot_export_errno.h到include目录下

2.清除不必要的头文件包含,去除log_err函数(如果有的话)

3.每个.h文件中,包涵 

  1. #include "esp_common.h"
  2. #include "iot_export_errno.h"

4.编译,直到无错误
OK,基本移植完成了。

 

 

开始修改代码

实现设备连接到云平台
参考官方文档:https://help.aliyun.com/document_detail/73742.html?spm=a2c4g.11186623.6.644.44a53f86Ed7mht
1.在`user_config.h`中修改wifi信息,和MQTT代理服务器地址

  1. #define SSID         "espressif"        /* Wi-Fi SSID */
  2. #define PASSWORD     "1234567890"     /* Wi-Fi Password */
  3. #define MQTT_BROKER  "a1u8k40ci7d.iot-as-mqtt.cn-shanghai.aliyuncs.com"  /* 代理服务地址,参考官方文档*/
  4. #define MQTT_PORT    1883             /* MQTT Port*/


2.`MQTTEcho.c`中修改配置

  1. //设备信息
  2. char *clientId  = "你的设备id";
  3. char *timestamp = "789";
  4. char *deviceName = "你的设备名";
  5. char *productKey = "产品key值";
  6. char *devicesecret = "设备secret值";
  7. //mqtt连接信息
  8. char mqttClientId[100];
  9. char mqttUsername[100];
  10. char mqttPassword[100];
  11. char hmac_source[512];


3.获取mqttClientId、mqttUsername、mqttPassword这三个参数认证

  1. void GetmqttClientId(void)
  2. {//获取mqttClientId
  3.     sprintf(mqttClientId,"%s|securemode=3,signmethod=hmacsha1,timestamp=%s|",clientId,timestamp);
  4.     printf("%s\r\n",mqttClientId);
  5. }
  6. void GetmqttUsername(void)
  7. {//获取mqttUsername
  8.     sprintf(mqttUsername,"%s&%s",deviceName,productKey);
  9.     printf("%s\r\n",mqttUsername);
  10. }
  11. void GetmqttPassword(void)
  12. {//获取mqttPassword
  13.     sprintf(hmac_source,
  14.         "clientId%s" "deviceName%s" "productKey%s" "timestamp%s",
  15.         clientId,deviceName,productKey,timestamp);
  16.     utils_hmac_sha1(hmac_source,strlen(hmac_source),
  17.         mqttPassword,devicesecret,strlen(devicesecret));
  18.     printf("%s\r\n",mqttPassword);
  19. }


4.在线程`mqtt_client_thread`中,进行参数获取,并进行认证

  1.     GetmqttClientId();
  2.     GetmqttUsername();
  3.     GetmqttPassword();
  4.     //GetMqttTopicPropertyPost();
  5.     //GetMqttTopicPropertyPostReply();
  6.     connectData.clientID.cstring = mqttClientId;
  7.     connectData.username.cstring = mqttUsername;
  8.     connectData.password.cstring = mqttPassword;
  9.     connectData.MQTTVersion = 4;    //mqtt v3.1
  10.     if ((rc = MQTTConnect(&client, &connectData)) != 0) {
  11.         printf("Return code from MQTT connect is %d\n", rc);
  12.     } else {
  13.         printf("MQTT Connected\n");
  14.     }
  15.     vTaskDelete(NULL);
  16.     return;

 ps:需要修改sendbuf和readbuf的缓冲大小为300

 

 5.再修改工程目录下Makefile文件。

  1.  #CONFIGURATION_DEFINES =        -DICACHE_FLASH -DMQTT_TASK
  2. CONFIGURATION_DEFINES = -DICACHE_FLASH 

 

6.编译程序,直至成功

 

现在设备可以连接到阿里云了

 

 

采集温湿度数据并上报至云端

设备通过MQTT协议,发布订阅的方式与平台进行交互。Alink协议采用json格式,需要cJSON库对采集到的数据进行封装。数据采集部分使用dht11完成温度、湿度的采集,这里使用现成的函数库。
1.从ESP8266 SDK 目录中`driver_lib/`,添加库文件到工程目录

  • 将include/*.h文件copy到工程目录include/
  • 将driver文件copy到工程目录
  • 添加第三方库文件(third_party/)cJSON.c、cJSON.h到工程目录
  • 添加第三方库文件cJSON.c、cJSON.h到工程目录

2.修改Makefile

  • 添加子目录 driver/
  • 生成静态库 libdriver.a
  1. SUBDIRS=    \
  2.     user    \
  3.     driver
  4. COMPONENTS_eagle.app.v6 = \
  5.     user/libuser.a        \
  6.     driver/libdriver.a

3.修改工程
封装信息

  1. //封装发布主题(上报数据)和订阅主题(订阅发布响应)
  2. #define TOPIC_PROPERTY_POST                 "/sys/%s/%s/thing/event/property/post"
  3. #define TOPIC_PROPERTY_POST_REPLY        "/sys/%s/%s/thing/event/property/post_reply"
  4. //对数据的jison格式进行封装
  5. #define DATAPAYLOAD                        "{\r\n\"id\" : \"1123\",\r\n\"version\":\"1.0\",\r\n\"params\" : {\r\n\"tempture\": %d,\r\n\"humidity\": %d,\r\n},\r\n\"method\":\"thing.event.property.post\"\r\n}"

mqtt_client线程中进行每10s一次主题上报

  1. static void mqtt_client_thread(void* pvParameters)
  2. {
  3.     printf("mqtt client thread starts\n");
  4.     MQTTClient client;
  5.     Network network;
  6.     unsigned char sendbuf[300], readbuf[300] = {0};
  7.     int rc = 0, count = 0;
  8.     MQTTPacket_connectData connectData = MQTTPacket_connectData_initializer;
  9.     pvParameters = 0;
  10.     NetworkInit(&network);
  11.     MQTTClientInit(&client, &network, 30000, sendbuf, sizeof(sendbuf), readbuf, sizeof(readbuf));
  12.     char* address = MQTT_BROKER;
  13.     printf("address = %s\r\n",address);
  14.     
  15.     if ((rc = NetworkConnect(&network, address, MQTT_PORT)) != 0) {
  16.         printf("Return code from network connect is %d\n", rc);
  17.     }
  18. #if defined(MQTT_TASK)
  19.     if ((rc = MQTTStartTask(&client)) != pdPASS) {
  20.         printf("Return code from start tasks is %d\n", rc);
  21.     } else {
  22.         printf("Use MQTTStartTask\n");
  23.     }
  24. #endif
  25.     GetmqttClientId();
  26.     GetmqttUsername();
  27.     GetmqttPassword();
  28.     GetMqttTopicPropertyPost();
  29.     GetMqttTopicPropertyPostReply();
  30.     connectData.clientID.cstring = mqttClientId;
  31.     connectData.username.cstring = mqttUsername;
  32.     connectData.password.cstring = mqttPassword;
  33.     connectData.MQTTVersion = 4;    //mqtt v3.1
  34.     printf("connectData.struct_id = %s\r\n",connectData.struct_id);
  35.     printf("connectData.struct_version = %d\r\n",connectData.struct_version);
  36.     printf("connectData.MQTTVersion = %d\r\n",connectData.MQTTVersion);
  37.     printf("connectData.clientID = %s\r\n",connectData.clientID.cstring);
  38.     printf("connectData.keepAliveInterval = %d\r\n",connectData.keepAliveInterval);
  39.     printf("connectData.cleansession = %d\r\n",connectData.cleansession);
  40.     printf("connectData.willFlag = %d\r\n",connectData.willFlag);
  41.     printf("connectData.username = %s\r\n",connectData.username.cstring);
  42.     printf("connectData.password = %s\r\n",connectData.password.cstring);
  43.     if ((rc = MQTTConnect(&client, &connectData)) != 0) {
  44.         printf("Return code from MQTT connect is %d\n", rc);
  45.     } else {
  46.         printf("MQTT Connected\n");
  47.     }
  48.     //订阅主题响应...
  49.     if ((rc = MQTTSubscribe(&client, MqttTopicPropertyPostReply, 2, messageArrived)) != 0) {
  50.         printf("Return code from MQTT subscribe is %d\n", rc);
  51.     } else {
  52.         printf("MQTT subscribe to topic %s\n",MqttTopicPropertyPostReply);
  53.     }
  54.     while (++count) {
  55.         GetJsonData();        //获取jison对象
  56.         MQTTMessage message;
  57.         message.qos = QOS0;
  58.         message.retained = 0;
  59.         message.payload = JsonDataPayLoad;
  60.         printf("JSON is %s\r\n",message.payload);
  61.         message.payloadlen = strlen(JsonDataPayLoad);
  62.         //发布数据主题
  63.         if ((rc = MQTTPublish(&client, MqttTopicPropertyPost, &message)) != 0) {
  64.             printf("Return code from MQTT publish is %d\n", rc);
  65.         } else {
  66.             printf("MQTT publish topic %s, message  is %s\n",MqttTopicPropertyPost,message.payload);
  67.         }
  68.         //等待应答主题
  69.         MQTTYield(&client,200);
  70.         //定时10s发送
  71.         vTaskDelay(10000 / portTICK_RATE_MS);  //send every 10 seconds
  72.     }
  73.     printf("mqtt_client_thread going to be deleted\n");
  74.     vTaskDelete(NULL);
  75.     return;
  76. }


编译后的bin文件烧写到设备,运行


本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
  

闽ICP备14008679号