1.使用RTThread和TouchGFX实现DIY数字仪表(一)——使用STM32CUBMX5.6移植touchGFX4.13 硬件: 野火挑战者STM32F767 V1开发版和ESP8266模块 1.准备一套 野火挑战者STM32F767 开发版或其他核心板 代码持续更新中:github代码下载地址https://gitee.com/Aladdin-Wang/hellotouchGFX.git 加微信备注touchgfx,拉入touchgfx-rtthread技术交流群共同学习 由于我们获取天气信息是通过访问心知天气的网络API,所以我们需要开启本地Web客户端。 查看心知天气的API返回数据可知,所使用的数据格式是JSON,所以需要开启CJSON软件包用于解析数据。 weather_httpclient.c weather_httpclient.h 因中文地名需要URL转码 url_code.h
目录:
2.使用RTThread和TouchGFX实现DIY数字仪表(二)——把TouchGFX移植到RTThread系统
3.使用RTThread和TouchGFX实现DIY数字仪表(三)——获取温湿度传感器数据
4.使用RTThread和TouchGFX实现DIY数字仪表(四)——同步网络时间
5.使用RTThread和TouchGFX实现DIY数字仪表(五)——同步天气信息
6.使用RTThread和TouchGFX实现DIY数字仪表(六)——链接阿里云物联网平台
7.使用RTThread和TouchGFX实现DIY数字仪表(七)——使用MQTT.fx模拟手机设备进行M2M设备间通信
8.使用RTThread和TouchGFX实现DIY数字仪表(八)——开发微信小程序
9.使用RTThread和TouchGFX实现DIY数字仪表(九)——TouchGFX控件使用教程实验平台:
软件: TouchGFXDesigner v4.13和 STM32CubeMX v5.6.0,MDK v5.29,RT-Thread env 工具实验前准备工作:
2.安装 TouchGFXDesigner v4.13
3.安装STM32CubeMX v5.6.0和X_CUBE_TOUCHGFX软件包
4.安装 MDK v5.27以上版本
5.下载 RTThread源码包https://gitee.com/rtthread/rt-thread
6.注册心知天气下载:
联系作者:
1.注册心知天气获取私钥
2.添加WebClient软件包
3.添加CJSON软件包
4.添加使用代码
#include <rtthread.h> #include <webclient.h> #include <url_code.h> #include <string.h> #include "cJSON_util.h" #include <board.h> #include <arpa/inet.h> #include <netdev.h> #include <ntp.h> #include <weather_httpclient.h> #define LOG_TAG "weather" #define LOG_LVL LOG_LVL_INFO #include <ulog.h> #define THREAD_PRIORITY 12 #define THREAD_STACK_SIZE 1024 #define THREAD_TIMESLICE 5 static rt_thread_t tid1 = RT_NULL; static struct rt_mailbox weather_mb; static char mb_pool[16]; char *gfxvalue; #define GET_HEADER_BUFSZ 2048 #define GET_RESP_BUFSZ 2048 #define GET_RESP_CONTENTSZ 4096 #define URL_LEN_MAX 2048 #define GET_LOCAL_URI "https://api.seniverse.com/v3/weather/daily.json?key=S97hL3kj6EbnjEmyC&location=%s&language=zh-Hans&unit=c&start=0&days=5" #define LOCAL_CITY "beijing" static weather_t gfx_weather[3]; static void weather_data_parse(char* data) { cJSON *root = RT_NULL, *arrayItem = RT_NULL,*object = RT_NULL, *object2 = RT_NULL,*list = RT_NULL, *item = RT_NULL, *weatheritem = RT_NULL; int index, list_size = 0; root = cJSON_Parse((const char *)data); if (!root) { rt_kprintf("No memory for cJSON root!n"); return; } arrayItem = cJSON_GetObjectItem(root, "results"); if (arrayItem == RT_NULL) { rt_kprintf("cJSON get results failed."); goto __EXIT; } object = cJSON_GetArrayItem(arrayItem, 0); if (object == RT_NULL) { rt_kprintf("cJSON get object failed."); goto __EXIT; } item = cJSON_GetObjectItem(object, "location"); /* 匹配子对象1 */ if (item == RT_NULL) { rt_kprintf("cJSON get location failed."); goto __EXIT; } if((list = cJSON_GetObjectItem(item,"name")) != NULL) { rt_kprintf("city: %srn",list->valuestring); } object2 = cJSON_GetObjectItem(object, "daily"); /* 匹配子对象2 */ if (object2 == RT_NULL) { rt_kprintf("cJSON get object2 failed."); goto __EXIT; } int size = cJSON_GetArraySize(object2); //获取数组中对象个数 rt_kprintf("n"); for(int i = 0 ;i<size;i++ ) { item = cJSON_GetArrayItem(object2, i); if (item == RT_NULL) { rt_kprintf("cJSON get daily failed."); goto __EXIT; } if((list = cJSON_GetObjectItem(item,"date")) != NULL) { rt_kprintf("date: %srn",list->valuestring); strncpy(gfx_weather[i].date, list->valuestring,strlen(list->valuestring)); } if((list = cJSON_GetObjectItem(item,"text_day")) != NULL) { rt_kprintf("text_day: %srn",list->valuestring); strncpy(gfx_weather[i].text_day, list->valuestring,strlen(list->valuestring)); } if((list = cJSON_GetObjectItem(item,"code_day")) != NULL) { rt_kprintf("code_day: %srn",list->valuestring); strncpy(gfx_weather[i].code_day, list->valuestring,strlen(list->valuestring)); } if((list = cJSON_GetObjectItem(item,"text_night")) != NULL) { rt_kprintf("text_night: %srn",list->valuestring); strncpy(gfx_weather[i].text_night, list->valuestring,strlen(list->valuestring)); } if((list = cJSON_GetObjectItem(item,"high")) != NULL) { rt_kprintf("high: %srn",list->valuestring); strncpy(gfx_weather[i].high, list->valuestring,strlen(list->valuestring)); } if((list = cJSON_GetObjectItem(item,"low")) != NULL) { rt_kprintf("low: %srn",list->valuestring); strncpy(gfx_weather[i].low, list->valuestring,strlen(list->valuestring)); } if((list = cJSON_GetObjectItem(item,"wind_direction")) != NULL) { rt_kprintf("wind_direction: %srn",list->valuestring); strncpy(gfx_weather[i].wind_direction, list->valuestring,strlen(list->valuestring)); } if((list = cJSON_GetObjectItem(item,"wind_speed")) != NULL) { rt_kprintf("wind_speed: %srn",list->valuestring); strncpy(gfx_weather[i].wind_speed, list->valuestring,strlen(list->valuestring)); } if((list = cJSON_GetObjectItem(item,"rainfall")) != NULL) { rt_kprintf("rainfall: %srn",list->valuestring); strncpy(gfx_weather[i].rainfall, list->valuestring,strlen(list->valuestring)); } if((list = cJSON_GetObjectItem(item,"humidity")) != NULL) { rt_kprintf("humidity: %srn",list->valuestring); strncpy(gfx_weather[i].humidity, list->valuestring,strlen(list->valuestring)); } rt_kprintf("n"); } __EXIT: if (root != RT_NULL) cJSON_Delete(root); } int get_weather(int argc, char **argv) { struct webclient_session* session = RT_NULL; unsigned char *buffer = RT_NULL; char *URI = RT_NULL; int index, ret = 0; int bytes_read, resp_status; int content_length = -1; char *city_name = rt_calloc(1,255); if(argc == 1) { strcpy(city_name, LOCAL_CITY); } else if (argc == 2) { strcpy(city_name, argv[1]); urlencode(city_name);//对中文编码 } else if(argc > 2) { rt_kprintf("wt [CityName] - webclient GET request test.n"); return -1; } URI = rt_calloc(1, URL_LEN_MAX); rt_snprintf(URI, URL_LEN_MAX, GET_LOCAL_URI, city_name); buffer = (unsigned char *) web_malloc(GET_RESP_CONTENTSZ); if (buffer == RT_NULL) { rt_kprintf("no memory for receive buffer.n"); ret = -RT_ENOMEM; goto __exit; } /* create webclient session and set header response size */ session = webclient_session_create(GET_HEADER_BUFSZ); if (session == RT_NULL) { ret = -RT_ENOMEM; goto __exit; } /* send GET request by default header */ rt_kprintf("send GET request to %sn", URI); if ((resp_status = webclient_get(session, URI)) != 200) { rt_kprintf("webclient GET request failed, response(%d) error.n", resp_status); ret = -RT_ERROR; goto __exit; } content_length = webclient_content_length_get(session); if (content_length < 0) { rt_kprintf("webclient GET request type is chunked.n"); do { bytes_read = webclient_read(session, buffer, GET_RESP_BUFSZ); if (bytes_read <= 0) { break; } for (index = 0; index < bytes_read; index++) { rt_kprintf("%c", buffer[index]); } } while (1); rt_kprintf("n"); } else { int content_pos = 0; do { bytes_read = webclient_read(session, buffer+content_pos, GET_RESP_BUFSZ); if (bytes_read <= 0) { break; } content_pos += bytes_read; } while (content_pos < content_length); weather_data_parse((char*)buffer); } __exit: if (session) { webclient_close(session); } if (buffer) { web_free(buffer); } if (URI) { web_free(URI); } return ret; } weather_t *gfxget_weather_date(void) { if (rt_mb_recv(&weather_mb, (rt_ubase_t *)&gfx_weather, RT_WAITING_NO) == RT_EOK) { return gfx_weather; } else { return RT_NULL; } } /* 入口函数 */ static void weather_collect_thread_entry(void *parameter) { //获取网卡对象 struct netdev* net = netdev_get_by_name("esp0"); //阻塞判断当前网络是否正常连接 while(netdev_is_internet_up(net) != 1) { rt_thread_mdelay(200); } if(0== get_weather(1,0)) { rt_mb_send(&weather_mb, (rt_uint32_t)gfx_weather); } while(1) { rt_thread_mdelay(5000); rt_mb_send(&weather_mb, (rt_uint32_t)gfx_weather); } } /* 创建线程 */ int weather_collect(void) { rt_err_t result = RT_EOK; /* 初始化mailbox */ result = rt_mb_init(&weather_mb, "weather_mbt", /* 名称是 sht30_mbt */ &mb_pool[0], /* 邮箱用到的内存池是 mb_pool */ sizeof(mb_pool) / 4, /* 邮箱中的邮件数目,因为一封邮件占 4 字节 */ RT_IPC_FLAG_FIFO); /* 采用 FIFO 方式进行线程等待 */ if (result != RT_EOK) { LOG_D("init mailbox failed.n"); return -1; } /* 创建线程*/ tid1 = rt_thread_create("weather", weather_collect_thread_entry, RT_NULL, THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE); /* 如果获得线程控制块,启动这个线程 */ if (tid1 != RT_NULL) rt_thread_startup(tid1); return 0; } INIT_APP_EXPORT(weather_collect); #ifdef FINSH_USING_MSH #include <finsh.h> MSH_CMD_EXPORT_ALIAS(get_weather, wt, wt [CityName] webclient GET request test); #endif /* FINSH_USING_MSH */
#ifndef __WEATHER_H_ #define __WEATHER_H_ #include <rtthread.h> typedef struct weather { char date[8]; char text_day[8]; char code_day[8]; char text_night[8]; char high[8]; char low[8]; char wind_direction[8]; char wind_speed[8]; char rainfall[8]; char humidity[8]; } weather_t; #endif
5. 添加URL转码文件
url_code.c#include <url_code.h> //#include <stdio.h> #include <string.h> #include <rtthread.h> #define BURSIZE 1024 static int hex2dec(char c) { if ('0' <= c && c <= '9') { return c - '0'; } else if ('a' <= c && c <= 'f') { return c - 'a' + 10; } else if ('A' <= c && c <= 'F') { return c - 'A' + 10; } else { return -1; } } static char dec2hex(short int c) { if (0 <= c && c <= 9) { return c + '0'; } else if (10 <= c && c <= 15) { return c + 'A' - 10; } else { return (char)-1; } } /* * 编码一个url */ void urlencode(char *url) { int i = 0; int len = strlen(url); int res_len = 0; char *res = rt_calloc(1, BURSIZE); for (i = 0; i < len; ++i) { char c = url[i]; if (('0' <= c && c <= '9') || ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || c == '/' || c == '.') { res[res_len++] = c; } else { int j = (short int)c; if (j < 0) j += 256; int i1, i0; i1 = j / 16; i0 = j - i1 * 16; res[res_len++] = '%'; res[res_len++] = dec2hex(i1); res[res_len++] = dec2hex(i0); } } res[res_len] = ' '; strcpy(url, res); rt_free(res); } /* * 解码url */ void urldecode(char *url) { int i = 0; int len = strlen(url); int res_len = 0; char *res = rt_calloc(1, BURSIZE); for (i = 0; i < len; ++i) { char c = url[i]; if (c != '%') { res[res_len++] = c; } else { char c1 = url[++i]; char c0 = url[++i]; int num = 0; num = hex2dec(c1) * 16 + hex2dec(c0); res[res_len++] = num; } } res[res_len] = ' '; strcpy(url, res); rt_free(res); }
#ifndef __URL_CODE_H__ #define __URL_CODE_H__ void urlencode(char *url); void urldecode(char *url); #endif
6. 实验
本网页所有视频内容由 imoviebox边看边下-网页视频下载, iurlBox网页地址收藏管理器 下载并得到。
ImovieBox网页视频下载器 下载地址: ImovieBox网页视频下载器-最新版本下载
本文章由: imapbox邮箱云存储,邮箱网盘,ImageBox 图片批量下载器,网页图片批量下载专家,网页图片批量下载器,获取到文章图片,imoviebox网页视频批量下载器,下载视频内容,为您提供.
阅读和此文章类似的: 全球云计算