阿里云(MQTT)传感数据上云例程
1. 概述
本文介绍如何使用YoC的IoT框架,实现上传数据到阿里云。
2. 适用的硬件
本例程可以运行在CB2201开发板上。
3. 应用开发
本章节介绍了数据上云例程的开发流程,包括应用初始化、网络初始化、模拟传感器、上云通道初始化及其相关事件的处理。
3.1 应用初始化
应用入口函数为app_main,主要实现了网络驱动初始化、传感驱动初始化、上云通道初始化、系统事件和通道事件的订阅等。
void main()
{
/* 板级初始化 */
board_yoc_init();
/* 模拟传感器驱动注册 */
sensor_simulate_register(NULL, 0);
/* LED驱动注册 */
led_rgb_register(&led_config, 1);
led_set_status(LED_ON);
/* 订阅网络事件 */
event_subscribe(EVENT_NETMGR_GOT_IP, network_event, NULL);
event_subscribe(EVENT_NETMGR_NET_DISCON, network_event, NULL);
/* 订阅应用自定义事件 */
event_subscribe(EVENT_DATA_REPORT, user_local_event_cb, NULL);
event_subscribe(EVENT_CHANNEL_CHECK, user_local_event_cb, NULL);
event_subscribe(EVENT_CHANNEL_CLOSE, user_local_event_cb, NULL);
/* 订阅上云通道事件 */
event_subscribe(EVENT_IOT_CONNECT_SUCCESS, iot_event, NULL);
event_subscribe(EVENT_IOT_CONNECT_FAILED, iot_event, NULL);
event_subscribe(EVENT_IOT_DISCONNECTED, iot_event, NULL);
event_subscribe(EVENT_IOT_PUSH_SUCCESS, iot_event, NULL);
event_subscribe(EVENT_IOT_PUSH_FAILED, iot_event, NULL);
/* 启动定时上云定时器 */
event_publish_delay(EVENT_DATA_REPORT, NULL, DATA_PUSH_INTERVAL);
/* 阿里云MQTT通道初始化 */
iot_alimqtt_config_t cfg = {.server_url_suffix =
"iot-as-mqtt.cn-shanghai.aliyuncs.com:1883"};
iot_handle = iot_new_alimqtt(&cfg);
}
3.2 板级初始化
板级初始化的入口为board_yoc_init,主要完成硬件初始化以及OS组件的初始化,由app_main函数调用。
void board_yoc_init(void)
{
/* 初始化console驱动 */
#ifdef CONSOLE_ID
console_init(CONSOLE_ID, 115200, 128);
#else
console_init(0, 115200, 128);
#endif
/* 初始化出厂配置Flash分区 */
nvram_init("factory");
/* 创建CLI任务 */
utask_t *task = utask_new("at&cli", 2 * 1024, QUEUE_MSG_COUNT, AOS_DEFAULT_APP_PRI);
#if defined(CONFIG_AT) && CONFIG_AT
at_server_init(task);
#endif
/* CLI初始化及系统命令注册 */
board_cli_init(task);
/* 网络驱动初始化 */
network_init();
}
3.3 网络驱动初始化
网络初始化的入口为network_init,主要完成网络设备和网络管理模块的初始化,由board_yoc_init函数调用。
static void network_init(void)
{
esp_wifi_param_t esp_param;
/* 与ESP8266模组通讯的串口参数配置 */
esp_param.device_name = "uart2";
esp_param.baud = 115200;
esp_param.buf_size = 4096;
esp_param.enable_flowctl = 0;
/* 复位引脚配置 */
esp_param.reset_pin = WIFI_ESP8266_RESET;
esp_param.smartcfg_pin = WIFI_ESP8266_SMARTCFG;
/* 注册esp8266驱动 */
wifi_esp8266_register(NULL, &esp_param);
/* 初始化网络管理模块 */
app_netmgr_hdl = netmgr_dev_wifi_init();
if (app_netmgr_hdl) {
netmgr_service_init(NULL);
netmgr_start(app_netmgr_hdl);
}
}
3.4 获取传感数据
注册传感器驱动后,应用可以调用传感器API来获取数据。以下是读取传感器的代码,实现在sensor_data.c中。
static void get_sensor_value(char *name)
{
dev_t *sensor_dev;
sensor_dht11_t sval;
int ret, i;
g_humi_value = -1000;
g_temp_value = -1000;
/* 打开传感器设备 */
sensor_dev = sensor_open(name);
if (sensor_dev == NULL) {
LOGE(TAG, "no %s driver", name);
return;
}
/* 采集数据 */
sensor_fetch(sensor_dev);
/* 读取传感器数据 */
if (sensor_getvalue(sensor_dev, (void *)&sval, sizeof(sensor_dht11_t)) < 0) {
sensor_close(sensor_dev);
return;
}
/* 关闭设备 */
sensor_close(sensor_dev);
g_temp_value = sval.degree / 10;
g_humi_value = sval.rh / 10;
}
3.6 数据上云
3.6.1 上云流程介绍
uDATA 存储传感器采集的各种数据,接收云端下发的数据,采用的键值形式来保存数据对
IoT框架 整合各个平台的SDK,定义了数据处理及上云接口,规范不同的云平台,抽象为统一的操作流程,采用一致的编程习惯,降低用户使用不同平台的学习成本
- 主要流程包含如下步骤:初始化上云通道、网络事件处理、初始化uDATA,启动上云通道、数据处理、关闭IoT
3.6.2 初始化上云通道
上云通道创建及事件订阅的具体示例代码参见“应用初始化”章节。
3.6.3 处理网络、云通道事件
static void iot_event(uint32_t event_id, const void *param, void *context)
{
switch (event_id) {
case EVENT_IOT_CONNECT_SUCCESS:
/* 通道连接成功 */
LOGD(TAG, "CONNNECT SUCCESS");
g_iot_connected = 1;
break;
case EVENT_IOT_CONNECT_FAILED:
case EVENT_IOT_DISCONNECTED:
/* 连接失败或者断开连接需要关闭通道*/
channel_close();
break;
case EVENT_IOT_PUSH_SUCCESS:
/* 数据上传成功 */
LOGD(TAG, "PUSH_SUCCESS");
break;
case EVENT_IOT_PUSH_FAILED:
/* 数据上传失败 */
LOGD(TAG, "PUSH_FAILED");
break;
default:;
}
}
static void network_event(uint32_t event_id, const void *param, void *context)
{
switch(event_id) {
case EVENT_NETMGR_GOT_IP:
/* 网络连接成功,启动上云通道 */
LOGD(TAG, "EVENT_NETMGR_GOT_IP");
if (g_iot_connected == 0) {
channel_open();
}
break;
case EVENT_NETMGR_NET_DISCON:
/* 网络断开,关闭上云通道 */
channel_close();
g_iot_connected = 0;
break;
}
}
3.6.4 初始化uDATA,启动上云通道
static void init_channel_udata(uData *udata)
{
/* 温度节点初始化 */
yoc_udata_set(udata, value_s("temp"), value_i(0), 1);
/* 湿度节点初始化 */
yoc_udata_set(udata, value_s("humi"), value_i(0), 1);
yoc_udata_set(udata, value_s("deviceName"), value_s(aos_get_device_name()), 1);
}
static int channel_open(void)
{
/* 打开云通道 */
iot_ch_post = iot_channel_open(iot_handle, "thing/event/property/post,thing/service/property/set");
if (iot_ch_post == NULL) {
LOGE(TAG, "iot ch open");
return -1;
}
/* 配置通道发送和接收是的回调处理 */
iot_channel_config(iot_ch_post, channel_set, channel_get, NULL);
/* 初始化节点数据 */
init_channel_udata(iot_ch_post->uData);
/* 启动云通道 */
iot_channel_start(iot_ch_post);
return 0;
}
3.6.5 接收到云端数据
static void channel_set(uData *udata, void *arg)
{
uData *node;
/* 遍历所有数据节点,使用node->value.updated判断更新的数据 */
slist_for_each_entry(&udata->head, node, uData, head)
{
if (node->value.updated) {
if (node->value.type == TYPE_STR) {
LOGI(TAG, "ch set s (%s,%s)", node->key.v_str, node->value.v_str);
} else {
LOGI(TAG, "ch set i (%s,%d)", node->key.v_str, node->value.v_int);
}
}
}
}
3.6.6 发送数据
static void channel_get(uData *udata, void *arg)
{
int temp = 0, humi = 0;
/* 获取传感器数据 */
temperature_capture(SENSOR_NAME, &temp, 0);
humidity_capture(SENSOR_NAME, &humi, 0);
/* 同步数据到uData节点 */
yoc_udata_set(udata, value_s("temp"), value_i(temp), 1);
yoc_udata_set(udata, value_s("humi"), value_i(humi), 1);
yoc_udata_set(udata, value_s("led"), value_i(g_led_status), 1);
yoc_udata_set(udata, value_s("deviceName"), value_s(aos_get_device_name()), 1);
}
static void push_action(void)
{
/* 发送数据 */
if (iot_channel_push(iot_ch_post, 1) != 0) {
LOGE(TAG, "push err");
}
}
static void user_local_event_cb(uint32_t event_id, const void *param, void *context)
{
/* 使用自定义消息的延时处理,实现定时发送功能 */
if (event_id == EVENT_DATA_REPORT){
/* 发送数据 */
push_action();
/* 延时事件,准备下一次的数据上传 */
event_publish_delay(EVENT_DATA_REPORT, NULL, DATA_PUSH_INTERVAL);
}
}
4. 例程运行
例程运行前需要进行云端配置、获取许可证和上云参数并配置到设备端。 若开发板已经预置好参数,编译烧写完成后,直接转到4.2.4章节。
4.1 阿里云物联网配置
4.1.1 登录(注册)
4.1.2 创建产品
使用物联网平台的第一步是在云端创建产品和对应设备,获取设备证书(ProductKey、DeviceName和DeviceSecret)
在实例概览页,找到已创建的公共实例或企业版实例,单击实例名称。
在左侧导航栏,选择设备管理 > 产品,单击创建产品。 具体产品参数可参考创建产品和设备
4.1.3 上云配置
获取三要素
在设备详情中可以查看、复制设备证书信息。设备证书由设备的ProductKey、DeviceName和DeviceSecret组成,是设备与物联网平台进行通信的重要身份认证,建议您妥善保管,在接下来的设备配置中需要用到。
参数 | 说明 |
---|---|
ProductKey | 设备所隶属产品的Key,即物联网平台为产品颁发的全局唯一标识符。 |
DeviceName | 设备在产品内的唯一标识符。DeviceName与设备所属产品的ProductKey组合,作为设备标识,用来与物联网平台进行连接认证和通信。 |
DeviceSecret | 物联网平台为设备颁发的设备密钥,用于认证加密。需与DeviceName成对使用。 |
- 获取许可证
我的产品->编辑->许可证,点击
下载
后即可产生下载压缩包到本地
4.2 设备端配置
4.2.1 烧录许可证
解压后文件中,pieces/*.hex文件是用于烧录的许可证文件。
右键点击工程名->Open Flash Programmer->YoC-CB2201-KP打开FlashProgrammer
,点击Browse按钮选择下载到的许可证文件,点击Start开始烧录。烧录完成,按开发板复位键。
4.2.2 编译烧录例程
烧录完成后,按复位键重启
4.2.3 配置上云三要素
将4.1.3中获取到的三要素,使用factory setali
命令通过串口调试终端设置到设备,返回setali success
完成上云三要素的配置, 在串口中输入信息为:
factory setali PRODUCTKEY DEVICENAME DEVICESECRET
注:需要将PRODUCTKEY DEVICENAME DEVICESECRET更换为具体的内容
4.2.4 配置网络
如ssid名称为Test01
,password名称为test1234
,在串口中输入信息为:
kv set wifi_ssid Test01
kv set wifi_psk test1234
设置完成之后需要按复位按钮重启开发板使得新网络配置生效。 待调试终端打印[I][netmgr ]IP: XXX.XXX.XXX.XXX
的信息表示网络已经连接成功。
4.2.5 设备调试串口输出
网络配置成功后,程序会自动启动数据上云
串口调试终端输出如下结果,表示模拟传感器数据上云成功
4.3 云端数据展示
在左侧导航栏,单击监控运维 > 日志服务,进入云端运行日志页签,展示如下,点击查看更多日志功能