物联网( IoT ,Internet of things )即“万物相连的互联网”,是互联网基础上的延伸和扩展的网络,将各种信息传感设备与互联网结合起来而形成的一个巨大网络,实现在任何时间、任何地点,人、机、物的互联互通。把任何物品与互联网相连接,进行信息交换和通信,以实现对物品的智能化识别、定位、跟踪、监控和管理的一种网络。
随着多种技术的交互与融合,物联网的发展越来越迅速,物联网产品也变得越来越灵活多样。可以说,物联网是我们的生活产生了质的变化,特别是对于智能家居、智慧农业等,IoT技术的引入为环境的检测以及安全提供了巨大的帮助。
本文描述了一个基于TencentOS Tiny的智能环境检测系统,利用云平台与终端程序,使用户能够随时查看环境数据,并可以远程控制实现相关操作。
本项目实现了一个基于TencentOS Tiny的智能环境检测系统,以腾讯云IoT Explorer平台为中间媒介,连接用户和设备,使得用户能够接收设备上报的数据,设备能够接收用户下发的命令。
该系统主要包括三部分:
(1)主控制板
本次方案采用的是腾讯物联网操作系统TencentOS tiny团队联合南京厚德物联网有限公司设计的一款物联网评估版EVB_MX,该板使用STM32L431RCT6芯片,具有256K Flash和64KB SRAM,该开发板支持E53系列传感器扩展版和WiFi、LoRaWAN、NB-IoT、2G等通信方式。
本方案利用主控制板EVB_MX、E53_IA1传感器扩展板以及使用ESP8266模块进行WiFi通信。
(2)E53_IA1
E53_IA1扩展板采用了E53标准接口,包含了一个补光灯,一个BH1750光照强度传感器,一个小的电机,一个温湿度传感器SHT30,一个其中补光灯和贴片电机使用普通GPIO控制,BH1750和SHT30使用IIC接口通信。
(3)ESP8266
方案采用ESP8266实现设备与云平台之间通过WiFi进行通信,ESP8266 在较小尺寸封装中集成了业界领先的 Tensilica L106 超低功耗 32 位微型 MCU ,带有 16 位精简模式,主频支持 80 MHz 和160 MHz ,支持 RTOS ,集成 Wi Fi MAC/ BB/RF/PA/LNA ,板载天线。该模块支持标准的IEEE802.11 b/g/n 协议,完整的 TCP/IP 协议栈。用户可以使用该模块为现有的设备添加联网功能,也可以构建独立的网络控制器。
本文主要利用ESP8266使得主控制板芯片能够通过MQTT协议实现与云平台的通信。
(4)OLED显示屏
OLED液晶显示模块用来向用户显示系统状态、参数或者要输入系统的功能。本方案中,我们可以利用OLED显示屏来显示灯光和电机的状态,使得用户能够更清晰直接的获得其状态。此外,在某些时候,我们也可以利用OLED显示屏来显示相关信息,以方便对程序进行调试。
本方案利用E53_IA1传感器扩展版来实现对周围环境数据的监测和收集,E53_IA1包含一个补光灯、一个电机、一个光强传感器和一个温湿度传感器。
将其映射到实际应用中,我们可以利用光强传感器来收集环境中的光照强度,以此判断窗帘是否打开/关闭,或者当前是晴天还是阴天等等;利用温湿度传感器,我们可以收集环境中的温度和湿度数据,可以判断是否由意外事件发生(例如火灾时温度会骤变高,在水管破裂时湿度可能会变高等等),通过这些环境数据,用户可以采取进一步的操作命令;利用补光灯,我们可以在室内较暗、光强较低时,下发指令或使设备自动执行开灯操作;利用电机,我们可以将其当作一个电器(空调、电风扇等等),在室内温度较高或者其他状况时,下发指令或使设备自动执行打开/关闭电机操作。
借鉴官方提供的类似教程,我们可以很快速的实现上云和数据传输。下面是对TencentOS tiny源码进行修改以实现对传感器数据的收集和执行相关操作。
首先需要对传感器和相关变量值进行初始化,我们通过_init_data_template实现。
/*
_init_data_template主要用于初始化传感器数据。
根据上述功能描述,本方案包含5个数据属性:
电机开关motor_power_switch、电灯开关light_power_switch、光强luminance、温度temperature、湿度humidity
*/
static void _init_data_template(void)
{
Init_E53_IA1(); //初始化E53_IA1模块
E53_IA1_Read_Data(); //读取传感器数据
sg_ProductData.m_motor_power_switch = 0;
sg_DataTemplate[0].data_property.data = &sg_ProductData.m_motor_power_switch;
sg_DataTemplate[0].data_property.key = "motor_power_switch";
sg_DataTemplate[0].data_property.type = TYPE_TEMPLATE_BOOL;
sg_ProductData.m_light_power_switch = 0;
sg_DataTemplate[1].data_property.data = &sg_ProductData.m_light_power_switch;
sg_DataTemplate[1].data_property.key = "light_power_switch";
sg_DataTemplate[1].data_property.type = TYPE_TEMPLATE_BOOL;
sg_ProductData.m_luminance = (int)E53_IA1_Data.Lux;
sg_DataTemplate[2].data_property.data = &sg_ProductData.m_luminance;
sg_DataTemplate[2].data_property.key = "luminance";
sg_DataTemplate[2].data_property.type = TYPE_TEMPLATE_INT;
sg_ProductData.m_temperature = (int)E53_IA1_Data.Temperature;
sg_DataTemplate[3].data_property.data = &sg_ProductData.m_temperature;
sg_DataTemplate[3].data_property.key = "temperature";
sg_DataTemplate[3].data_property.type = TYPE_TEMPLATE_INT;
sg_ProductData.m_humidity = (int)E53_IA1_Data.Humidity;
sg_DataTemplate[4].data_property.data = &sg_ProductData.m_humidity;
sg_DataTemplate[4].data_property.key = "humidity";
sg_DataTemplate[4].data_property.type = TYPE_TEMPLATE_INT;
};
接下来是对电机和电灯的操作,这里我们只给出打开电机操作以及OLED显示,其余类似。
__weak void OLED_Clear(void) //清屏操作
{
printf("OLED Clear\n");
}
__weak void OLED_ShowString(int x, int y, uint8_t *str, int bold) //显示字符串
{
printf("OLED ShowString: %s\n", (char *)str);
}
static void motor_power_on(void) //打开电机操作
{
char *info = "motor on ";
//OLED_Clear();
OLED_ShowString(0, 0, (uint8_t *)info, 16); //OLED显示
HAL_GPIO_WritePin(IA1_Motor_GPIO_Port, IA1_Motor_Pin, GPIO_PIN_SET); //写入引脚,打开电机
}
本方案利用ESP8266模块,通过WiFi实现设备与云端通信,修改TencentOS tiny源码中的qcloud_iot_hub_sdk_explorer.c文件中的WiFi名称和密码。
#ifdef USE_ESP8266
extern int esp8266_sal_init(hal_uart_port_t uart_port);
extern int esp8266_join_ap(const char *ssid, const char *pwd);
esp8266_sal_init(HAL_UART_PORT_0);
esp8266_join_ap("wifi_name", "password");
#endif
与云端的通信是通过MQTT协议进行的,这里我们可以直接使用qcloud-iot-explorer-sdk中相关函数API来实现MQTT的初始化和数据传输,无需自己实现。
此外,我们还需要将在云平台获得到的产品和设备信息写入到程序中,以通过MQTT连接认证,代码在HAL_Device_tencentos_tiny.c中。
#ifdef DEBUG_DEV_INFO_USED
/* product Id */
static char sg_product_id[MAX_SIZE_OF_PRODUCT_ID + 1] = "PRODUCT_ID";
/* device name */
static char sg_device_name[MAX_SIZE_OF_DEVICE_NAME + 1] = "DEVICE_NAME";
#ifdef DEV_DYN_REG_ENABLED
/* product secret for device dynamic Registration */
static char sg_product_secret[MAX_SIZE_OF_PRODUCT_SECRET + 1] = "YOUR_PRODUCT_SECRET";
#endif
#ifdef AUTH_MODE_CERT
/* public cert file name of certificate device */
static char sg_device_cert_file_name[MAX_SIZE_OF_DEVICE_CERT_FILE_NAME + 1] = "YOUR_DEVICE_NAME_cert.crt";
/* private key file name of certificate device */
static char sg_device_privatekey_file_name[MAX_SIZE_OF_DEVICE_SECRET_FILE_NAME + 1] = "YOUR_DEVICE_NAME_private.key";
#else
/* device secret of PSK device */
static char sg_device_secret[MAX_SIZE_OF_DEVICE_SECRET + 1] = "DEVICE_SECRET";
#endif
本方案中设备需要向云平台上报的传感器数据包含上述5个属性:电机状态(开/关)、电灯状态、光强、温度和湿度。
// register data template properties
static int _register_data_template_property(void *pTemplate_client)
{
int i,rc;
for (i = 0; i < TOTAL_PROPERTY_COUNT; i++) {
rc = IOT_Template_Register_Property(pTemplate_client, &sg_DataTemplate[i].data_property, OnControlMsgCallback);
if (rc != QCLOUD_RET_SUCCESS) {
rc = IOT_Template_Destroy(pTemplate_client);
Log_e("register device data template property failed, err: %d", rc);
return rc;
} else {
Log_i("data template property=%s registered.", sg_DataTemplate[i].data_property.key);
}
}
return QCLOUD_RET_SUCCESS;
}
本方案中云平台(用户)能够向设备下发的指令包括开/关电机、开/关电灯。
//用户下发指令处理逻辑
void deal_down_stream_user_logic(void *client, ProductDataDefine * pData)
{
Log_d("someting about your own product logic wait to be done");
if (sg_ProductData.m_motor_power_switch == 1) {
motor_power_on();
} else {
motor_power_off();
}
if (sg_ProductData.m_light_power_switch == 1) {
light_power_on();
} else {
light_power_off();
}
}
//主处理函数
...{
...
/* handle control msg from server */
if (sg_control_msg_arrived) {
deal_down_stream_user_logic(client, &sg_ProductData);
/* control msg should reply, otherwise server treat device didn't receive and retain the msg which would be get by get status*/
memset((char *)&replyPara, 0, sizeof(sReplyPara));
replyPara.code = eDEAL_SUCCESS;
replyPara.timeout_ms = QCLOUD_IOT_MQTT_COMMAND_TIMEOUT;
replyPara.status_msg[0] = '\0'; //add extra info to replyPara.status_msg when error occured
rc = IOT_Template_ControlReply(client, sg_data_report_buffer, sg_data_report_buffersize, &replyPara);
if (rc == QCLOUD_RET_SUCCESS) {
Log_d("Contol msg reply success");
sg_control_msg_arrived = false;
} else {
Log_e("Contol msg reply failed, err: %d", rc);
}
} else{
Log_d("No control msg received...");
}
...
}
按照IoT Explorer平台相关指令,我们可以在平台上建立该项目,设置设备相关属性以及所涉及到的下发指令。
设置完产品参数,我们还需要创建设备,获得设备参数,并且对设备进行在线调试。
对于用户端,本方案实现了一个微信小程序来方便用户实时监控设备上传到云端的数据以及下发指令。
微信小程序的UI界面在pages/index/index.wxml中实现。根据方案功能,在小程序中,我们需要两大部分:设备信息(包括product ID和device name)和数据控制,在数据控制中应包含5个属性:2个控制属性(电机开关、电灯开关)和3个传感器数据(光强、温度、湿度)。最后微信小程序界面如下所示:
对于小程序与云平台的连接通信,我们需要在app.js中修改相关设备信息和认证参数,包括如下:
最后,很感谢腾讯云团队给予我的这次机会,以及在开发过程中提供的支持和帮助!!!希望自己之后能在此基础上更进一步,对IoT操作系统及其开发更熟悉!
作者:yyyyyyw
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。