0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

使用RT-Thread Studio来实现疫情监控平台

RTThread物联网操作系统 来源:RTThread物联网操作系统 2020-09-04 14:49 次阅读

上周末加班,这周末休息,有时间整理一篇之前做的基于RT-Thread的疫情监控平台。上一篇文章我们使用STM32F103 MCU裸机开发的方式实现了疫情监控平台。这次我们玩点高端的,使用RT-Thread Studio来实现同样的功能,一起来看看吧!

文章目录

使用到的软件包

0.RT-Thread Studio的下载和安装

1.硬件准备

2.新建工程

3.添加LED闪烁功能

4.添加ESP8266软件包

5.疫情数据的获取

6.疫情数据的解析

7.疫情数据的显示

开源地址

最终的显示效果:

显示效果

有效文件就这9个,其他的就全是图形化配置:

有效文件

整个流程下来,如果顺利的话,可以在2个小时内完成。

使用到的软件包

at device:用于ESP8266配网

webclient:用于发送HTTPS请求

mbdetls:用于HTTPS加密

cJSON:用于JSON数据解析

0.RT-Thread Studio的下载和安装

一站式的 RT-Thread 开发工具,通过简单易用的图形化配置系统以及丰富的软件包和组件资源,让物联网开发变得简单和高效。

RT-Thread Studio

支持多种芯片,STM32全系列

支持创建裸机工程、RT-Thread Nano和Master工程

强大的代码编辑功能,基于Eclipse框架

免费无版权限制,基于开源Eclipse和ARM-GCC编译器。

支持多种仿真器,J-Link,ST-link等,支持在线调试,变量观察。

SDK管理器,图形化配置RT-Thread软件包,同步RT-Thread最新版本。

集成Putty串口终端工具

更多的使用教程

https://www.rt-thread.org/page/studio.html

目前最新版本为1.1.3版本,支持3种下载方式,我们选择最后一个下载方式,从RT-Thread 官网服务器上下载。

下载地址:

http://117.143.63.254:9012/www/studio/download/RT-Thread%20Studio-v1.1.3-setup-x86_64_20200731-2100.exe

下载链接

安装过程和常用的软件安装方法一样,选择安装路径,然后Next就行了。

1.硬件准备

开发板用的是我在大四时自己设计的STM32开发板——NiceDay,基于STM32F103RET主控。这是我设计的第二块板子(第一块是毕业设计两轮平衡车主板),是在大四快毕业时,毕设实物和论文完成之后还有点时间,就设计了这款板子,最开始是准备做桌面天气时钟的。

开发板

2.新建工程

RT-Thread Studio支持创建裸机工程、包含RT-Thread Nano版本的工程和包含Master版本的工程。这里,我们选择创建RT-Thread 项目,即包含完整版RT-Thread的工程。

新建项目

工程支持基于芯片创建工程,或者基于已有的BSP创建,这里使用的是我自己设计的开发板,所以选择基于芯片,选择芯片型号:STM32F103RE,调试串口选择串口1,调试器选择J-Link,SWD接口

新建项目

创建完成之后,直接按Ctrl+B编译整个工程,第一次编译时间会长一点,如果修改很少,下次再进行编译就会很快了,可以看到无警告无错误。

编译结果

使用SWD接口连接JLink调试器和开发板,开发板上电,直接点击下载按钮,也可以使用快捷键Ctrl+Alt+D下载

下载程序

底部可以看到下载信息,从LOG来看,下载的程序文件是Bin文件,比较,擦除,编程,验证,复位整个流程耗时13s左右。

下载LOG

RT-Thread Studio是自带Putty串口终端的,点击终端图标:

终端按钮

选择串口号、波特率、文字编码方式等。

配置终端

底部切换到终端窗口,可以看到串口终端输出信息:

串口终端

这样,不到5分钟,一个基于STM32F103RET6的工程模板就创建好了,包含RT-Thread完整版操作系统,整个过程不需要写一行代码,完全图形化配置。

3.添加LED闪烁功能

作为单片机点灯小能手,RT-Thread下如何点灯是必须掌握的。打开RT-Thread组件图形化配置界面,可以看到默认开启了PIN和串口设备驱动的。

图形化配置界面

在main.c文件中添加LED闪烁功能。包含头文件和添加宏定义

#include #include #defineLED_RED_PINGET_PIN(A,7) #defineLED_BLUE_PINGET_PIN(A,6) intmain(void) { intcount=1; rt_pin_mode(LED_RED_PIN,PIN_MODE_OUTPUT); rt_pin_mode(LED_BLUE_PIN,PIN_MODE_OUTPUT); while(count++) { rt_pin_write(LED_BLUE_PIN,PIN_LOW); rt_pin_write(LED_RED_PIN,PIN_LOW); rt_thread_mdelay(100); rt_pin_write(LED_BLUE_PIN,PIN_HIGH); rt_pin_write(LED_RED_PIN,PIN_HIGH); rt_thread_mdelay(100); } returnRT_EOK; }

重新编译,下载。可以看到LED闪烁起来了。工程默认是使用内部RC作为输入时钟,所以无论你的板子是8M还是12M,都可以正常闪烁。我的开发板是8M晶体,这里我们配置使用外部HSE作为输入时钟。

打开drivers->stm32f1xx_hal_conf.h文件,修改HSE_VALUE宏定义为8M。

晶体频率修改

打开drivers->drv_clk.c文件:

时钟源修改

配置PLL时钟源为HSE,并设置倍频系数为9。

时钟源修改

倍频系数

这里根据实际板子晶体频率来设置,如果是12M晶体,倍频系数应该设置为6,如果是16M,需要参考时钟树,先2倍分频,然后9倍倍频。

#include voidsystem_clock_config(inttarget_freq_Mhz) { RCC_OscInitTypeDefRCC_OscInitStruct={0}; /**InitializestheCPU,AHBandAPBbussesclocks */ RCC_OscInitStruct.OscillatorType=RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState=RCC_HSE_ON; RCC_OscInitStruct.PLL.PLLSource=RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLState=RCC_PLL_ON; ........ //9倍频 RCC_OscInitStruct.PLL.PLLMUL=RCC_PLL_MUL9;//8*9=72M ........ }

这样就修改为外部8M晶体作为PLL时钟源,再次编译下载,和之前的现象是一样的。

4.添加ESP8266软件包

联网设备,我们选择的是ESP8266-01S,如果看过上一篇疫情监控三部曲——在STM32F103 MCU上实现(裸机版),里面介绍了如何配置ESP8266 GET HTTPS请求, 配置工作模式 > 连接WiFi > 与服务器建立SSL连接 > 发送GET请求获取数据等等,整个流程固定而繁琐,那么能不能封装成一个模块,直接拿来使用呢?

esp8266

这里就要介绍RT-Thread的AT Device软件包了,

AT device 软件包是由 RT-Thread AT 组件针对不同 AT 设备的移植文件和示例代码组成,目前支持的 AT 设备有:ESP8266、ESP32、M26、MC20、RW007、MW31、SIM800C、W60X 、SIM76XX、A9/A9G、BC26 、AIR720、ME3616、M6315、BC28、EC200X、M5311系列设备等,目前上述设备都完成对 AT socket 功能的移植,及设备通过 AT 命令实现标准 socket 编程接口,完成 socket 通讯的功能,具体功能介绍可参考 《RT-Thread 编程指南》AT 命令章节 。
https://www.rt-thread.org/document/site/programming-manual/at/at/

简单的说,就是我只需要调用这个软件包,然后修改WiFi账号和密码,就可以直接配置ESP8266联网了。

由于AT Device依赖于libc组件,所以在添加AT Device软件包之前,先开启libc。

在RT-Thread Settings中点击libc灰色图标,变成彩色说明已经开启。

组件配置

添加AT Device软件包,点击立即添加

软件包

在弹出的软件包中心,搜索at_device,然后点击添加,添加到当前工程。

软件包

在at_device软件包上右键,选择详细配置:

软件包

在弹出的页面,选择我们使用的WiFi模块类型,乐鑫的ESP8266系列,并配置WiFi账号和密码,WiFi模块所连接的串口号。

WiFi配置

点击保存之后,工程会重新进行配置,添加相应的软件包文件到当前工程,重新生成Makefile文件,rtconfig文件等等。

虽然我们在at_device配置中选择了uart2作为at_device设备连接的串口。但此时串口2并没有开启,还需要我们手动使能。

打开drivers->board.h文件,通过宏定义的方式使能串口2。

#defineBSP_USING_UART2 #defineBSP_UART2_TX_PIN"PA2" #defineBSP_UART2_RX_PIN"PA3"

这样就开启了UART2的片上外设,Ctrl + B重新进行编译,时间会有些长,编译完成之后,可以看到flash文件大小明显比之前大了。

编译结果

Ctrl + Alt + D重新下载运行,打开串口终端:

终端

可以看到,UART2初始化成功,WiFi连接成功。说明我们的串口模块已经可以正常工作了。提示[E/at.clnt] execute command (AT+CIPDNS_CUR?) failed!失败信息,是因为当前ESP8266的固件版本不支持AT+CIPDNS_CUR?这条命令,把固件升级到最新版本就好了。这个不影响后面的操作,所以就不用在意这个了。

测试一下ifconfig和ping命令,都是正常的。

终端

在RT-Thread Studio中配置ESP8266模块联网,整个流程只写了3行代码,可以说是非常的快速方便。

5.疫情数据的获取

WiFi模块连接上互联网之后,就可以连接GET疫情数据的API接口https://lab.isaaclin.cn/nCoV/api/overall,然后读取返回的疫情数据。在上一篇的裸机工程中,是通过先和服务器建立SSL连接,然后发送GET HTTPS请求,获取到的返回数据,那RT-Thread有没有这样功能的软件包呢?这里就需要添加另一个软件包webclient。

WebClient 软件包是 RT-Thread 自主研发的,基于 HTTP 协议的客户端的实现,它提供设备与 HTTP Server 的通讯的基本功能。
WebClient 软件包功能特点如下:

支持 IPV4/IPV6 地址;

支持 GET/POST 请求方法;

支持文件的上传和下载功能;

支持 HTTPS 加密传输;

完善的头部数据添加和处理方式。

和添加at_device一样,在软件包中心中搜索webclient,

软件包

然后添加到当前工程,右键进行配置,由于我们的https://lab.isaaclin.cn/nCoV/api/overall这个疫情数据接口是HTTPS类型的,根据软件包使用手册,我们需要选择TLS模式中的 MbedTLS。勾选添加GET和POST示例。

软件包配置

保存配置,看一下当前已经添加了哪些功能,可以看到有一些组件我们并没有去打开,但是已经被开启了,这是因为有些软件包是会依赖一些组件的,当使能软件包时,一些依赖的组件也被同时使能。

软件包

Ctrl + B编译,Ctrl + Alt + D下载运行。在终端输入web_get_test测试GET请求功能。

GET示例

可以看到,执行get命令之后,会返回一个字符串,那么GET的是哪个地址呢?打开packages->webclient-v2.1.2->samples->webclient_get_sample.c文件,

示例代码

可以看到GET的是这个地址:http://www.rt-thread.com/service/rt-thread.txt,我们用电脑上的浏览器访问一下:

浏览器访问

经过实际测试发现,GET HTTPS请求,还需要使能软件模拟RTC这个组件,否则会报assertion failed at function:gettimeofday, line number:19错误。

使能RTC

我们重新写一个获取疫情数据的函数,并导出到MSH。

usr_ncov.c文件内容

//usr_ncov.c #include"usr_ncov.h" intget_NCOV_Data(void) { char*uri=RT_NULL; structwebclient_session*session=RT_NULL; uint8_t*buffer=RT_NULL; intindex,ret=0; intbytes_read,resp_status; intcontent_length=-1; intbuffer_size=1600; uri=web_strdup(API_NCOV); rt_kprintf("startgetapi:%s ",API_NCOV); if(uri!=RT_NULL) { buffer=(unsignedchar*)web_malloc(buffer_size); if(buffer==RT_NULL) { rt_kprintf("nomemoryforreceivebuffer. "); ret=-RT_ENOMEM; goto__exit; } /*createwebclientsessionandsetheaderresponsesize*/ session=webclient_session_create(buffer_size); if(session==RT_NULL) { ret=-RT_ENOMEM; goto__exit; } /*sendGETrequestbydefaultheader*/ if((resp_status=webclient_get(session,uri))!=200) { rt_kprintf("webclientGETrequestfailed,response(%d)error. ",resp_status); ret=-RT_ERROR; goto__exit; } rt_kprintf("webclientgetresponsedata: "); content_length=webclient_content_length_get(session); if(content_length< 0)         {             rt_kprintf("webclient GET request type is chunked. ");             do             {                 bytes_read = webclient_read(session, buffer, buffer_size);                 if (bytes_read <= 0)                     break;                 for (index = 0; index < bytes_read; index++)                 {                     rt_kprintf("%c", buffer[index]);                 }             } while (1);             rt_kprintf(" ");         }         else         {             /* 读取服务器响应的数据 */             bytes_read = webclient_read(session, buffer, content_length);             rt_kprintf("data length:%d ", bytes_read);             buffer[bytes_read] = '';             rt_kprintf("  %s  ", buffer); //            rt_kprintf("parse data ");             // parseData(buffer);        //解析函数             rt_kprintf(" ");         }         __exit:         if (session)             webclient_close(session);         if (buffer)             web_free(buffer);     }     else         rt_kprintf("api error: %s ", API_NCOV);     return ret; } MSH_CMD_EXPORT(get_NCOV_Data, get api ncov);

usr_ncov.h文件内容

#ifndefAPPLICATIONS_USR_NCOV_H_ #defineAPPLICATIONS_USR_NCOV_H_ #include #include #include #defineAPI_NCOV"https://lab.isaaclin.cn/nCoV/api/overall" intget_NCOV_Data(void); #endif/*APPLICATIONS_USR_NCOV_H_

重新编译,下载,运行。在终端运行这个命令:

命令获取疫情数据

可以看到获取到了返回的数据,长度1366个字节。下一步就是对这个JSON数据进行解析,获取到我们想要的疫情数据。

6.疫情数据的解析

API返回的数据是JSON格式的,关于JSON的介绍和解析,可以查看使用cJSON库解析和构建JSON字符串。数据的解析使用的开源小巧的cJSON解析库,我们可以在软件包管理中心直接添加:

添加cJSON

在进行解析之前,先来分析一下JSON原始数据的格式:results键的值是一个数组,数组只有一个JSON对象,获取这个对象对应键的值可以获取到国内现存和新增确诊人数、累计和新增死亡人数,累计和新增治愈人数等数据。

全球疫情数据保存在globalStatistics键里,它的值是一个JSON对象,对象仅包含简单的键值对,这些键的值,就是全球疫情数据,其中updateTime键的值是更新时间,这是毫秒级UNIX时间戳,可以转换为标准北京时间。

{ "results":[{ "currentConfirmedCount":509, "currentConfirmedIncr":16, "confirmedCount":85172, "confirmedIncr":24, "suspectedCount":1899, "suspectedIncr":4, "curedCount":80015, "curedIncr":8, "deadCount":4648, "deadIncr":0, "seriousCount":106, "seriousIncr":9, "globalStatistics":{ "currentConfirmedCount":4589839, "confirmedCount":9746927, "curedCount":4663778, "deadCount":493310, "currentConfirmedIncr":281, "confirmedIncr":711, "curedIncr":424, "deadIncr":6 }, "updateTime":1593227489355 }], "success":true }

先定义了结构体NCOV_DATA,用于存储国内和全球疫情数据:

structNCOV_DATA{ intcurrentConfirmedCount; intcurrentConfirmedIncr; intconfirmedCount; intconfirmedIncr; intcuredCount; intcuredIncr; intdeadCount; intdeadIncr; intseriousCount; intseriousIncr; charupdateTime[20]; };

对应的解析函数:

#include structNCOV_DATAdataChina={0,0,0,0,0,0,0,0,0,0,"06-1316:22"};; structNCOV_DATAdataGlobal={0,0,0,0,0,0,0,0,0,0,NULL}; intparseData(uint8_t*str) { intret=0; cJSON*root,*result_arr; cJSON*result,*global; time_tupdateTime; structtm*time; root=cJSON_Parse((constchar*)str);//创建JSON解析对象,返回JSON格式是否正确 if(root!=0) { rt_kprintf("JSONformatok,startparse!!! "); result_arr=cJSON_GetObjectItem(root,"results"); if(result_arr->type==cJSON_Array) { //rt_kprintf("resultisarray "); result=cJSON_GetArrayItem(result_arr,0); if(result->type==cJSON_Object) { //rt_kprintf("result_arr[0]isobject "); /*chinadataparse*/ dataChina.currentConfirmedCount=cJSON_GetObjectItem(result,"currentConfirmedCount")->valueint; dataChina.currentConfirmedIncr=cJSON_GetObjectItem(result,"currentConfirmedIncr")->valueint; dataChina.confirmedCount=cJSON_GetObjectItem(result,"confirmedCount")->valueint; dataChina.confirmedIncr=cJSON_GetObjectItem(result,"confirmedIncr")->valueint; dataChina.curedCount=cJSON_GetObjectItem(result,"curedCount")->valueint; dataChina.curedIncr=cJSON_GetObjectItem(result,"curedIncr")->valueint; dataChina.deadCount=cJSON_GetObjectItem(result,"deadCount")->valueint; dataChina.deadIncr=cJSON_GetObjectItem(result,"deadIncr")->valueint; rt_kprintf("**********chinancovdata********** "); rt_kprintf("%-23s:%8d,%-23s:%8d ","currentConfirmedCount",dataChina.currentConfirmedCount,"currentConfirmedIncr",dataChina.currentConfirmedIncr); rt_kprintf("%-23s:%8d,%-23s:%8d ","confirmedCount",dataChina.confirmedCount,"confirmedIncr",dataChina.confirmedIncr); rt_kprintf("%-23s:%8d,%-23s:%8d ","curedCount",dataChina.curedCount,"curedIncr",dataChina.curedIncr); rt_kprintf("%-23s:%8d,%-23s:%8d ","deadCount",dataChina.deadCount,"deadIncr",dataChina.deadIncr); /*globaldataparse*/ global=cJSON_GetObjectItem(result,"globalStatistics"); if(global->type==cJSON_Object) { dataGlobal.currentConfirmedCount=cJSON_GetObjectItem(global,"currentConfirmedCount")->valueint; dataGlobal.currentConfirmedIncr=cJSON_GetObjectItem(global,"currentConfirmedIncr")->valueint; dataGlobal.confirmedCount=cJSON_GetObjectItem(global,"confirmedCount")->valueint; dataGlobal.confirmedIncr=cJSON_GetObjectItem(global,"confirmedIncr")->valueint; dataGlobal.curedCount=cJSON_GetObjectItem(global,"curedCount")->valueint; dataGlobal.curedIncr=cJSON_GetObjectItem(global,"curedIncr")->valueint; dataGlobal.deadCount=cJSON_GetObjectItem(global,"deadCount")->valueint; dataGlobal.deadIncr=cJSON_GetObjectItem(global,"deadIncr")->valueint; rt_kprintf(" **********globalncovdata********** "); rt_kprintf("%-23s:%8d,%-23s:%8d ","currentConfirmedCount",dataGlobal.currentConfirmedCount,"currentConfirmedIncr",dataGlobal.currentConfirmedIncr); rt_kprintf("%-23s:%8d,%-23s:%8d ","confirmedCount",dataGlobal.confirmedCount,"confirmedIncr",dataGlobal.confirmedIncr); rt_kprintf("%-23s:%8d,%-23s:%8d ","curedCount",dataGlobal.curedCount,"curedIncr",dataGlobal.curedIncr); rt_kprintf("%-23s:%8d,%-23s:%8d ","deadCount",dataGlobal.deadCount,"deadIncr",dataGlobal.deadIncr); }elsereturn1; /*毫秒级时间戳转字符串*/ updateTime=(time_t)(cJSON_GetObjectItem(result,"updateTime")->valuedouble/1000); updateTime+=8*60*60;/*UTC8校正*/ time=localtime(&updateTime); /*格式化时间*/ strftime(dataChina.updateTime,20,"%m-%d%H:%M",time); rt_kprintf("update:%s ",dataChina.updateTime);/*06-2411:21*/ //数据在LCD显示 //gui_show_ncov_data(dataChina,dataGlobal); }elsereturn1; }elsereturn1; rt_kprintf(" parsecomplete "); } else { rt_kprintf("JSONformaterror:%s ",cJSON_GetErrorPtr());//输出json格式错误信息 return1; } cJSON_Delete(root); returnret; }

在数据接收完成之后,对JSON数据进行解析。

解析结果

7.疫情数据的显示

数据解析出来之后,剩下的就简单了,把上一篇文章中9341的驱动文件移植过来就好了。

液晶屏使用的是3.2寸 LCD,IL9341驱动芯片,320*240分辨率,16位并口。由于屏幕分辨率比较低,可显示的内容有限,所以只是显示了最基本的几个疫情数据。为了减小程序大小,GUI只实现了基本的画点,画线函数,字符的显示,采用的是部分字符取模,只对程序中用到的汉字和字符进行取模。为了增强可移植性,程序中并没有使用外置SPI Flash存储整个字库。

由于RT-Thread Studio使用的HAL库,所以LCD的GPIO初始化函数需要修改一下:

voidlcd_gpio_init(void) { GPIO_InitTypeDefGPIO_InitStructure; __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); __HAL_RCC_AFIO_CLK_ENABLE(); __HAL_AFIO_REMAP_SWJ_NOJTAG(); GPIO_InitStructure.Mode=GPIO_MODE_OUTPUT_PP; GPIO_InitStructure.Pull=GPIO_PULLUP; GPIO_InitStructure.Speed=GPIO_SPEED_FREQ_HIGH; GPIO_InitStructure.Pin=GPIO_PIN_9|GPIO_PIN_8|GPIO_PIN_7|GPIO_PIN_6; HAL_GPIO_Init(GPIOC,&GPIO_InitStructure);//GPIOC GPIO_InitStructure.Pin=GPIO_PIN_8;//背光引脚PA8 HAL_GPIO_Init(GPIOA,&GPIO_InitStructure);//GPIOC GPIO_InitStructure.Pin=GPIO_PIN_All; HAL_GPIO_Init(GPIOB,&GPIO_InitStructure); HAL_GPIO_WritePin(GPIOC,GPIO_PIN_9|GPIO_PIN_8|GPIO_PIN_7|GPIO_PIN_6,GPIO_PIN_SET); HAL_GPIO_WritePin(GPIOA,GPIO_PIN_8,GPIO_PIN_SET); HAL_GPIO_WritePin(GPIOB,GPIO_PIN_All,GPIO_PIN_SET); }

延时函数换成:

rt_thread_mdelay(nms);

还有一点,在Keil中,文字编码选择GBK编码,1个汉字占用2个字节,而RT-Thread Studio为UTF-8编码,1个汉字占用3个字节,汉字显示函数需要调整:

voidgui_show_chn(uint16_tx0,uint16_ty0,char*chn) { uint8_tidx=0; uint8_t*code[3];//UTF-8:国=E59BBD uint8_tsize=sizeof(FONT_16X16_TABLE)/sizeof(FONT_16X16_TABLE[0]); /*遍历汉字,获取索引*/ for(idx=0;idx< size; idx++)     {         code[0] = FONT_16X16_TABLE[idx].chn;         code[1] = FONT_16X16_TABLE[idx].chn + 1;         code[2] = FONT_16X16_TABLE[idx].chn + 2;         //汉字内码一致         if(!(strcmp(code[0], chn) || strcmp(code[1], chn+1) || strcmp(code[2], chn+2)))         {             gui_show_F16X16_Char(x0, y0, idx, WHITE);             return; //            break;         }     } }

疫情数据显示函数:

voidgui_show_ncov_data(structNCOV_DATAchina,structNCOV_DATAglobal) { uint8_ty0=20; lcd_clear(BLACK); gui_show_bar(); gui_drawLine(0,18,320,DIR_X,WHITE); gui_drawLine(0,38,320,DIR_X,WHITE); gui_drawLine(0,138,320,DIR_X,WHITE); gui_drawLine(0,158,320,DIR_X,WHITE); gui_drawLine(0,220,320,DIR_X,WHITE); /*"国内疫情"*/ gui_show_chn_string(128,y0,"国内疫情"); gui_show_line_data(40,"现存确诊:",china.currentConfirmedCount,"较昨日:",china.currentConfirmedIncr); gui_show_line_data(60,"累计确诊:",china.confirmedCount,"较昨日:",china.confirmedIncr); gui_show_line_data(80,"累计治愈:",china.curedCount,"较昨日:",china.curedIncr); gui_show_line_data(100,"现存重症:",china.seriousCount,"较昨日:",china.seriousIncr); gui_show_line_data(120,"累计死亡:",china.deadCount,"较昨日:",china.deadIncr); /*全球疫情*/ gui_show_chn_string(128,140,"全球疫情"); gui_show_line_data(160,"现存确诊:",global.currentConfirmedCount,"较昨日:",global.currentConfirmedIncr); gui_show_line_data(180,"累计治愈:",global.curedCount,"较昨日:",global.curedIncr); gui_show_line_data(200,"累计死亡:",global.deadCount,"较昨日:",global.deadIncr); gui_show_chn_string(160,222,"更新于:"); gui_show_F8X16_String(230,222,china.updateTime,GREEN); }

最终显示效果

最终效果

开源地址

代码已经开源,地址在文末,欢迎大家参与,丰富这个小项目的功能!

基于STM32+RT-Thread的疫情监控平台
https://github.com/whik/rtt_2019_ncov

基于STM32F103的疫情监控平台(裸机版)
https://github.com/whik/stm32_2019_ncov

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 物联网
    +关注

    关注

    2909

    文章

    44534

    浏览量

    372693
  • 软件包
    +关注

    关注

    0

    文章

    104

    浏览量

    11590
  • RT-Thread
    +关注

    关注

    31

    文章

    1285

    浏览量

    40069

原文标题:基于STM32+RT-Thread的新冠肺炎疫情监控平台

文章出处:【微信号:RTThread,微信公众号:RTThread物联网操作系统】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    rt-thread studio导入bsp失败的原因?

    rt-thread studio导入bsp失败,bsp:gd32470z-lckfb
    发表于 09-27 09:54

    rt-thread studio导入bsp失败的原因?

    rt-thread studio导入bsp失败,bsp:gd32470z-lckfb
    发表于 09-13 07:49

    rt-thread studio手动导入bsp失败的原因?怎么处理?

    rt-thread studio 手动导入bsp 失败。 版本: 2.2.8 构建ID: 202405200930 导入的bsp 是直接从rt-thread 代码仓库下载的
    发表于 09-13 06:45

    如何在RT-thread studio的裸机例程上移植freertos?

    如何在RT-thread studio的裸机例程上移植freertos
    发表于 09-13 06:32

    RT-Thread Studio导入keil MDK工程失败的原因?怎么解决?

    RT-Thread Studio导入keil MDK工程失败
    发表于 07-15 06:56

    【ch32v307_RTT】1、使用RT-Thread studio新建工程

    【前言】 ch32v307有成熟的RT-Thread 支持,使用RT-Thread studio可以快速的建立工程,我将分享系列文章,这一篇是如何快速建立工程。 【前题】 安装好RT-Thre
    发表于 06-29 18:25

    6月6日杭州站RT-Thread线下workshop,探索RT-Thread混合部署新模式!

    6月6日下午我们将在杭州举办RT-Thread混合部署线下workshop,在瑞芯微RK3568平台实现同时运行RT-Thread和linux,本次workshop邀请到
    的头像 发表于 05-28 08:35 437次阅读
    6月6日杭州站<b class='flag-5'>RT-Thread</b>线下workshop,探索<b class='flag-5'>RT-Thread</b>混合部署新模式!

    5月16日南京站RT-Thread线下workshop,探索RT-Thread混合部署新模式!

    5月16日下午我们将在南京举办RT-Thread混合部署线下workshop,在瑞芯微RK3568平台实现同时运行RT-Thread和linux,本次workshop邀请到
    的头像 发表于 05-01 08:35 355次阅读
    5月16日南京站<b class='flag-5'>RT-Thread</b>线下workshop,探索<b class='flag-5'>RT-Thread</b>混合部署新模式!

    RT-Thread混合部署Workshop北京站来啦!

    4月25日,下午我们将在北京举办RT-Thread混合部署线下workshop,在瑞芯微RK3568平台实现同时运行RT-Thread和linux,本次workshop邀请到
    的头像 发表于 04-19 08:34 435次阅读
    <b class='flag-5'>RT-Thread</b>混合部署Workshop北京站来啦!

    4月25日北京站RT-Thread线下workshop,探索RT-Thread混合部署新模式

    4月25日,下午我们将在北京举办RT-Thread混合部署线下workshop,在瑞芯微RK3568平台实现同时运行RT-Thread和linux,本次workshop邀请到
    的头像 发表于 04-16 08:35 414次阅读
    4月25日北京站<b class='flag-5'>RT-Thread</b>线下workshop,探索<b class='flag-5'>RT-Thread</b>混合部署新模式

    4月10日深圳场RT-Thread线下workshop,探索RT-Thread混合部署新模式!

    4月10日我们将在深圳福田举办RT-Thread混合部署线下workshop,在瑞芯微RK3568平台实现同时运行RT-Thread和linux,本次workshop邀请到
    的头像 发表于 03-27 11:36 813次阅读
    4月10日深圳场<b class='flag-5'>RT-Thread</b>线下workshop,探索<b class='flag-5'>RT-Thread</b>混合部署新模式!

    4月10日深圳场RT-Thread线下workshop,探索RT-Thread混合部署新模式!

    4月10日我们将在深圳福田举办RT-Thread混合部署线下workshop,在瑞芯微RK3568平台实现同时运行RT-Thread和linux,本次workshop邀请到
    的头像 发表于 03-27 08:34 524次阅读
    4月10日深圳场<b class='flag-5'>RT-Thread</b>线下workshop,探索<b class='flag-5'>RT-Thread</b>混合部署新模式!

    RT-Thread Studio添加软件包报错怎么解决?

    RT-Thread Studio添加软件包报错ImportError: No module named psutil
    发表于 03-01 08:41

    使用RT-Thread Studio下载代码不能运行是为什么?

    直接使用源码包里面的keil工程下载代码正常执行,但是使用RT-Thread Studio下载就不行了 使用的是TM4C123H6PM的例程,但是我的芯片是TM4C123H6PZ的,keil上是可以直接下载并正常工作的,但是RT-Thr
    发表于 03-01 08:22

    rt-thread studio地址偏移怎么配置?

    rt-thread studio地址偏移配置,这个再哪配置?
    发表于 02-23 06:24