【IoT迷你赛】五分钟简明魔法系列1 - 5分钟让你的温度计上云~

2019-08-27 10:43:02 浏览数 (1)

本文目标

5分钟让零基础的同学体验使用TencentOS tiny让IoT设备极速上云

如何使用

  • 坚持阅读5分钟
  • 动手实验
  • 发挥你的想象力~

硬件清单

  • EVB_MX实验板
  • DHT11 湿温传感器
  • 发光二极管 WechatIMG51.jpegWechatIMG51.jpeg

硬件连接

硬件连接.png硬件连接.png
实物连接.jpeg实物连接.jpeg

5分钟show time

TencentOS tiny已经内部集成主流物联网协议栈(如 CoAP/MQTT/TLS/DTLS/LoRaWAN/NB-IoT 等),并有现成的连接腾讯云例程提供,只要稍作改动,就可以完成我们今天的小目标~

腾讯云配置

  1. 登录https://console.cloud.tencent.com/iotexplorer
  2. 新建项目 - 新建产品 新建项目.png新建项目.png 新建产品.png新建产品.png
  3. 设置数据模版
  4. 删除标准功能的“模式”“摆风”
  5. 在“自定义功能”里面“新建功能” 新增相对湿度.png新增相对湿度.png
  6. 点击右上角“查看JSON”查看数据模版,主要关注properties.id部分
代码语言:txt复制
{
  "version": "1.0",
  "profile": {
    "ProductId": "R9YTOMNG9Q",
    "CategoryId": "124"
  },
  "properties": [
    {
      "id": "power_switch",
      "name": "空调开关",
      "desc": "控制开关",
      "required": true,
      "mode": "rw",
      "define": {
        "type": "bool",
        "mapping": {
          "0": "关",
          "1": "开"
        }
      }
    },
    {
      "id": "Temperature",
      "name": "温度",
      "desc": "温度",
      "mode": "rw",
      "required": false,
      "define": {
        "type": "float",
        "unit": "oC",
        "unitDesc": "摄氏度",
        "step": "1",
        "min": "16.0",
        "max": "36.0",
        "start": "16"
      }
    },
    {
      "id": "hum",
      "name": "相对湿度",
      "desc": "",
      "mode": "rw",
      "define": {
        "type": "float",
        "min": "0",
        "max": "100",
        "start": "0",
        "step": "1",
        "unit": "%"
      },
      "required": false
    }
  ],
  "events": []
}
  • 点击设备调试-新增设备,成功后点击“查看”,记录“设备名称”、“设备密钥”、“产品ID”

下位机程序编写

打开demo

TencentOS tiny 项目工程中包含了 explorer 的 demo 工程:

进入 TencentOS-tinyboardTencentOS_tiny_EVB_MX

KEIL tencent_cloud_sdk_data_template 目录,双击 TencentOS_tiny.uvprojx,用 mdk 打开。

配置产品信息

修改 tos_hal_os.c 文件

  • 产品 ID: 将控制台的产品 ID ,复制 sg_product_id 中。
  • 设备名称: 将控制台的设备名称,复制到 sg_device_name 中。
  • 设备密钥:将控制台的设备密钥,复制到sg_device_secret 中。

配置wifi连接信息

修改tencent_cloud_sdk_explorer.c

  • 修改esp8266_join_ap调用参数,分别为wifi账号,密码

初始化gpio,控制发光二极管

修改tencent_cloud_sdk_explorer.c

代码语言:txt复制
......
void init_gpio5(void)
{
  GPIO_InitTypeDef GPIO_InitStruct;

  GPIO_InitStruct.Pin = GPIO_PIN_9;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
}

void application_entry(void *arg)
{
#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("ladygg", "19871227");
#endif
    
#ifdef USE_NB_BC35
    extern int bc35_28_95_sal_init(hal_uart_port_t uart_port);
    bc35_28_95_sal_init(HAL_UART_PORT_0);
#endif
	init_gpio5();
......

修改demo数据模版

修改light_data_template_sample.c,需要修改的地方为

  1. TOTAL_PROPERTY_COUNT 字段数量
  2. ProductDataDefine 通信数据结构定义
代码语言:txt复制
typedef struct _ProductDataDefine {
    TYPE_DEF_TEMPLATE_BOOL      m_light_switch;
    TYPE_DEF_TEMPLATE_FLOAT     m_temperature;
	TYPE_DEF_TEMPLATE_FLOAT     m_hum;
} ProductDataDefine;
  1. _init_data_template 通信数据模版初始化
代码语言:txt复制
static void _init_data_template(void)
{
    memset((void *)&sg_ProductData, 0, sizeof(ProductDataDefine));

    sg_ProductData.m_light_switch = 0;
    sg_DataTemplate[0].data_property.key  = "power_switch";
    sg_DataTemplate[0].data_property.data = &sg_ProductData.m_light_switch;
    sg_DataTemplate[0].data_property.type = TYPE_TEMPLATE_BOOL;

    sg_ProductData.m_temperature = 0;
    sg_DataTemplate[1].data_property.key  = "Temperature";
    sg_DataTemplate[1].data_property.data = &sg_ProductData.m_temperature;
    sg_DataTemplate[1].data_property.type = TYPE_TEMPLATE_FLOAT;

    sg_ProductData.m_hum = 0;
    sg_DataTemplate[2].data_property.key  = "hum";
    sg_DataTemplate[2].data_property.data = &sg_ProductData.m_hum;
    sg_DataTemplate[2].data_property.type = TYPE_TEMPLATE_FLOAT;

};
  1. update_self_define_value 对json数据进行解释
代码语言:txt复制
static int update_self_define_value(const char *jsondoc, DeviceProperty *property) 
{
    TYPE_DEF_TEMPLATE_BOOL light_switch; 
    
    TYPE_DEF_TEMPLATE_FLOAT tmp;
	TYPE_DEF_TEMPLATE_FLOAT hum;
    
	.......

    if (!property_data) {
        Log_d("Property:%s no matched", property->key);	
        HAL_Free(json_doc);
        return QCLOUD_ERR_FAILURE;
    }

    switch (property->type) {
        case TYPE_TEMPLATE_BOOL: // power switch
            light_switch = *(TYPE_DEF_TEMPLATE_BOOL *)property->data;
            sg_ProductData.m_light_switch = light_switch;
            break;


        case TYPE_TEMPLATE_FLOAT:
						if (0 == strcmp("hum", property->key)) {
							hum = *(TYPE_DEF_TEMPLATE_FLOAT *)property->data;
            sg_ProductData.m_hum = hum;
            
						} else {
							tmp = *(TYPE_DEF_TEMPLATE_FLOAT *)property->data;
            sg_ProductData.m_temperature = tmp;
						
						}
            break;
    }

    HAL_Free(property_data);
    .......
}
  1. deal_down_stream_user_logic 发光二极管控制
代码语言:txt复制
static void deal_down_stream_user_logic(ProductDataDefine *light)
{		
		if(light->m_light_switch){
			HAL_GPIO_WritePin(GPIOC,GPIO_PIN_9,GPIO_PIN_SET);
		}else{
			HAL_GPIO_WritePin(GPIOC,GPIO_PIN_9,GPIO_PIN_RESET);
		}
}
  1. cycle_report 5s定时上报温度和相对湿度,同时显示在oled上
代码语言:txt复制
int cycle_report(DeviceProperty *pReportDataList[], Timer *reportTimer)
{
    int i;
	DHT11_Data_TypeDef getdata = {0};
	uint8_t get_ok;
				get_ok=DHT11_Read_TempAndHumidity(&getdata);
				if(get_ok==SUCCESS){
					sg_ProductData.m_temperature=getdata.temperature;
					sg_ProductData.m_hum=getdata.humidity;
					sg_DataTemplate[1].state=eCHANGED;
					sg_DataTemplate[2].state=eCHANGED;
					
					char str[255];

					sprintf(str, "temperature %.2f humidity %.2f",getdata.temperature,getdata.humidity);
					OLED_Clear();
					OLED_ShowString(0, 0, (uint8_t *)str, 16);
				}

    if (expired(reportTimer)){
        for (i = 0; i < TOTAL_PROPERTY_COUNT; i  ) {
            pReportDataList[i] = &(sg_DataTemplate[i].data_property);
            countdown_ms(reportTimer, 5000);
        }
        return QCLOUD_ERR_SUCCESS;
    } else {
        return QCLOUD_ERR_INVAL;
    }
}
  1. 最后,编译,烧写

试试咒语

运行1.jpeg运行1.jpeg
数据显示.png数据显示.png
落魄程序员在线点灯.png落魄程序员在线点灯.png
运行2.jpeg运行2.jpeg

课后习题

  1. 看到硬件清单里的红外编解码模块么?想不想做点什么?
  2. wifi账号密码写死在代码里,怎么产品化呀,快来用AirKiss配网吧~

0 人点赞