前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【开发者成长激励计划-基于TencentOS Tiny 和腾讯云的环境监测系统】

【开发者成长激励计划-基于TencentOS Tiny 和腾讯云的环境监测系统】

原创
作者头像
用户7205256
修改2022-07-14 22:52:08
1.6K6
修改2022-07-14 22:52:08
举报
文章被收录于专栏:物联网篇物联网篇

1. 引言

本文设计了基于CH32V307和TencentOS Tiny的环境监测系统,通过DHT11传感器读取相关的数据,将温湿度数据显示在LCD上,并通过ESP8266实现下位机与腾讯云的连接,将该数据上传到腾讯云上,实现云端数据的监视。

2. 硬件介绍

整体架构

2.1 单片机

单片机采用CH32V307VCT6的芯片,CH32V307系列是基于32位RISC-V设计的互联型微控制器,配备了硬件堆栈区、快速中断入口,在标准RISC-V基础上大大提高了中断响应速度。加入单精度浮点指令集,扩充堆栈区,具有更高的运算性能。CH32V307是基于32位RISC-V设计的互联型微控制器,配备了硬件堆栈区、快速中断入口,在标准RISC-V基础上大大提高了中断响应速度。加入单精度浮点指令集,扩充堆栈区,具有更高的运算性能。扩展串口UART数量到8组,电机定时器到4组。提供USB2.0高速接口(480Mbps)并内置了PHY收发器,以太网MAC升级到千兆并集成了10M-PHY模块。

硬件使用的是 TencentOS Tiny CH32V_EVB RISC-V开发套件,板载Type-C接口WCH-LINK仿真器,板载esp8266 WiFi模组,支持腾讯云固件。

 TencentOS Tiny CH32V_EVB RISC-V开发套件
TencentOS Tiny CH32V_EVB RISC-V开发套件

2.2 温湿度传感器

DHT11是一款有已校准数字信号输出的温湿度传感器。 其精度湿度±5%RH, 温度±2℃,量程湿度5~95%RH, 温度-20~+60℃。

DHT11
DHT11

2.3 显示模块

LCD模块使用的是ST7789,一般是用于262K彩色TFT-LCD的单片控制器/驱动程序。它由960条源线和480条栅线驱动电路组成。ST7796S能够连接直接 Y为外部微处理器,接受8位/9位/16位/18位并行接口,spi和ST7796S也提供mipi接口。

这是官网提供的原理图。

2.4 通信模块

通信模块使用是ESP8266,可以直接烧录腾讯云的AT固件,连接腾讯云的物联网平台非常简单。ESP-12F是安信可用ESP8266EX芯片做的一款WiFi模组,这个模块已经把内部的电路设计好了。实际测试,ESP01和01s不如12f系列的稳定,经常出问题,要是长期使用还是建议使用12f系列。

2.5 效果图

3 程序设计

程序分为三个任务,分别为温湿度采集、数据显示、数据上传三个任务。

(1)创建任务

其中任务1为数据显示,任务2为温湿度采集,任务3为上传上传。

代码语言:javascript
复制
 tos_mail_q_create(&mail_q, mail_pool, MAIL_MAX, sizeof(mail_t));
    tos_task_create(&task1, "task1", task1_entry, NULL, 3, task1_stk, TASK1_STK_SIZE, 0); // Create task1
    tos_task_create(&task2, "task2", task2_entry, NULL, 3, task2_stk, TASK2_STK_SIZE, 0);// Create task2
    tos_task_create(&task3, "task3", task3_entry, NULL, 2, task3_stk, TASK3_STK_SIZE, 0);// Create task3

(2)温湿度采集数据

温湿度采用的是DHT11采集环境信息,由于DHT11对延时要求比较高,所以该设计采用的是定时器实现延时。采用的是定时器3.

初始化定时器3,实现定时器分频。

代码语言:javascript
复制
void TIM3_Init(void)
{
    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);  ///使能TIM3时钟
    TIM_TimeBaseInitStructure.TIM_Period    = 0xffff;  //自动重装载值
    TIM_TimeBaseInitStructure.TIM_Prescaler = 144-1;     //定时器分频
    TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式
    TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
    TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure);//初始化TIM3
}

延时函数

代码语言:javascript
复制
//微秒级延时
void TIM3_Delayus(u16 xus)
{
    TIM_Cmd(TIM3,ENABLE); //启动定时器
    while(TIM3->CNT < xus);
    TIM3->CNT = 0;
    TIM_Cmd(TIM3,DISABLE); //关闭定时器
}

任务函数

代码语言:javascript
复制
void task2_entry(void *arg)
{
    u8 temperature=0;
    u8 humidity=0;
    mail_t mail;
    while (1) {

        DHT11_Read_Data(&temperature,&humidity);  //读取温湿度值
        mail.temp = temperature;
        mail.humi = humidity;
        tos_mail_q_post_all(&mail_q, &mail, sizeof(mail_t));
        tos_task_delay(5000);
    }
}

(2)该系统移植的是系统中自带的LCD模块驱动代码,这里我添加的是实现汉字和英文混合显示的功能。其代码如下所示

代码语言:javascript
复制
void LCD_ShowStringCn(u16 x,u16 y,u8 *s,u16 fc,u16 bc,u8 sizey,u8 mode)
{
    while(*s!='\0')
    {
        if(*s<128){
            LCD_ShowChar(x,y,*s,fc,bc,sizey,mode);
            x+=sizey/2;
            s++;
        }
        else{
            if(sizey==12) LCD_ShowChinese12x12(x,y,s,fc,bc,sizey,mode);
            else if(sizey==16) LCD_ShowChinese16x16(x,y,s,fc,bc,sizey,mode);
            else if(sizey==24) LCD_ShowChinese24x24(x,y,s,fc,bc,sizey,mode);
            else if(sizey==32) LCD_ShowChinese32x32(x,y,s,fc,bc,sizey,mode);
            else return;
            s+=2;
            x+=sizey;
        }
    }
}

这里需要自己取字模,字模的格式如下

创建的显示任务代码

代码语言:javascript
复制
void task1_entry(void *arg)
{
    k_err_t err;
    mail_t mail;
    size_t mail_size;
    u8 s_temp[128];
    LCD_ShowString(0,0,"Welcome TencentOS",WHITE,BLACK,16,0);
    while (1) {

        err = tos_mail_q_pend(&mail_q, &mail, &mail_size, TOS_TIME_FOREVER);
        if (err == K_ERR_NONE) {
            TOS_ASSERT(mail_size == sizeof(mail_t));
            printf("温度: %d, 湿度:%d \n", mail.temp, mail.humi);
            sprintf(s_temp,"温度: %d, 湿度:%d   ",mail.temp, mail.humi);
            LCD_ShowStringCn(0,32,s_temp,GREEN,BLACK,16,0);
        }
    }
}

(3)创建上传任务代码

代码语言:javascript
复制
#define QOS0 0
void task3_entry(void *arg)
{
    k_err_t err;
    mail_t mail;
    size_t mail_size;
        char payload[256] = {0};
        u8 temperature=0;
        u8 humidity=0;
        mqtt_state_t state;

        char *product_id = "0G95XV3IEP";
        char *device_name = "isnt0";
        char *key = "C8CJeD69bCFvwsD13gnyBA==";

        device_info_t dev_info;
        memset(&dev_info, 0, sizeof(device_info_t));
        esp8266_tencent_firmware_sal_init(HAL_UART_PORT_2);
        esp8266_tencent_firmware_join_ap("TP-LINK_XXXX", "11112222");

        strncpy(dev_info.product_id, product_id, PRODUCT_ID_MAX_SIZE);
        strncpy(dev_info.device_name, device_name, DEVICE_NAME_MAX_SIZE);
        strncpy(dev_info.device_serc, key, DEVICE_SERC_MAX_SIZE);
        tos_tf_module_info_set(&dev_info, TLS_MODE_PSK);

        mqtt_param_t init_params = DEFAULT_MQTT_PARAMS;
        if (tos_tf_module_mqtt_conn(init_params) != 0) {
            printf("module mqtt conn fail\n");
        } else {
            printf("module mqtt conn success\n");
        }

        if (tos_tf_module_mqtt_state_get(&state) != -1) {
            printf("MQTT: %s\n", state == MQTT_STATE_CONNECTED ? "CONNECTED" : "DISCONNECTED");
        }

        static char topic_name[TOPIC_NAME_MAX_SIZE] = {0};
        static char topic_name_sub[TOPIC_NAME_MAX_SIZE] = {0};
        int size = snprintf(topic_name, TOPIC_NAME_MAX_SIZE, "$thing/up/property/%s/%s", product_id, device_name);

        if (size < 0 || size > sizeof(topic_name) - 1) {
            printf("topic content length not enough! content size:%d  buf size:%d", size, (int)sizeof(topic_name));
        }
        size = snprintf(topic_name_sub, TOPIC_NAME_MAX_SIZE, "$thing/down/property/%s/%s", product_id, device_name);
                if (size < 0 || size > sizeof(topic_name) - 1) {
                    printf("topic content length not enough! content size:%d  buf size:%d", size, (int)sizeof(topic_name));
                }
        if (tos_tf_module_mqtt_sub(topic_name_sub, QOS0, default_message_handler) != 0) {
            printf("module mqtt sub fail\n");
        } else {
            printf("module mqtt sub success\n");
        }
        while (1) {
            /* use AT+PUB AT command */
            memset(payload, 0, sizeof(payload));
            sprintf(payload, "{\\\"method\\\":\\\"report\\\"\\,\\\"clientToken\\\":\\\"123\\\"\\,\\\"params\\\":{\\\"temp\\\":%d\\,\\\"humi\\\":%d}}",temperature,humidity);
            printf("message publish: %s\n", payload);
            if (tos_tf_module_mqtt_pub(topic_name, QOS0, payload) != 0) {
                printf("module mqtt pub fail\n");
                break;
            } else {
                printf("module mqtt pub success\n");
            }
            err = tos_mail_q_pend(&mail_q, &mail, &mail_size, TOS_TIME_FOREVER);
            if (err == K_ERR_NONE) {
                TOS_ASSERT(mail_size == sizeof(mail_t));
                temperature = mail.temp ;
                humidity=  mail.humi ;
            }

        }

}

4 云平台设计

(1)物模型的搭建

(2)数据显示

这是完整的代码,在TencentOS-tiny-master\board\替换TencentOS_Tiny_CH32V307_EVB文件夹即可。 TencentOS_Tiny_CH32V307_EVB.rar

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
TencentOS Server
TencentOS Server 是腾讯云推出的 Linux 操作系统,它旨在为云上运行的应用程序提供稳定、安全和高性能的执行环境。它可以运行在腾讯云 CVM 全规格实例上,包括黑石物理服务器2.0。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档