桌面天气时钟【心知天气API、可获取实时时间、合成解码cJSON】 您所在的位置:网站首页 桌面时钟不对 桌面天气时钟【心知天气API、可获取实时时间、合成解码cJSON】

桌面天气时钟【心知天气API、可获取实时时间、合成解码cJSON】

2024-07-18 02:58| 来源: 网络整理| 查看: 265

全套代码已经开源,可以通过CSDN资源链接获取 文中有基本代码讲解

文章目录 一、需要的模块1.C8T62.esp323. 1.44寸TFT彩色屏幕4. 分光棱镜 二、准备工作1.注册心知天气获取自己的API2.了解合成cJSON数据包【让心知天气拥有时间数据】3.使用stm32解析数据包4.屏幕显示,由于分光棱镜的原理,需要反转屏幕。 三、代码编写总结

一、需要的模块 1.C8T6

采用c8t6作为主控,搭载各种功能以及屏幕。 问题在于由于最小系统板内存小,后期添加功能不方便(内存小已经阉割了很多功能了,只有小部分字库和基础图片)请添加图片描述

2.esp32

在这里esp32主要用来联网获取实时天气,时间,地点等。天气获取主要通过心知天气,时间日期通过阿里云数据。请添加图片描述

3. 1.44寸TFT彩色屏幕

主要显示界面,显示天气时间等信息。请添加图片描述

4. 分光棱镜

可以模拟出全息投影的感觉,帅到爆! ! ! 请添加图片描述请添加图片描述

二、准备工作 1.注册心知天气获取自己的API

心知天气官网链接:https://www.seniverse.com/

注册自己的控制台,并取得私钥,用来获取数据包。

点击【我的产品】

请添加图片描述

如图为【私钥】需要在Arduino的代码中修改。

请添加图片描述

2.了解合成cJSON数据包【让心知天气拥有时间数据】

- 获取天气数据

运行后esp32串口会下发一个心知天气的数据包:

{"results":[{"location":{"id":"私钥","name":"地点","country":"CN","path":"---","timezone":"Asia/Shanghai","timezone_offset":"+08:00"},"now":{"text":"Overcast","code":"9","temperature":"19"},"last_update":"2022-07-18T10:40:06+08:00"}]}

该处使用CSDN的cJSON工具解析数据。

代码如下(示例):

{ "results": [ { "location": { "id": "私钥", "name": "地点", "country": "CN", "path": "---", "timezone": "Asia/Shanghai", "timezone_offset": "+08:00" }, "now": { "text": "Sunny", "code": "0", "temperature": "29" }, "last_update": "2022-08-01T16:40:06+08:00" } ] } 如上图就是一个完整的数据包结构了,我们会在32中对数据进行解析保存,达到分级、分块调用的目的。

由于心知天气免费版只提供了基础的天气数据,没有时间日期等信息,所以我又使用了阿里云的数据,并把两个数据进行整合,合成新的数据包。

- 获取时间数据【合成数据包】

阿里云下发的数据不满足HTTP数据包的形式,所以曲线救国,我在代码中合成了新的数据包, 并把所以时间日期数据单独放在字符串中。 int Year,Mon,Day,Hour,Min,Wday; struct tm timeInfo; //声明一个结构体 DynamicJsonDocument dat(1024);//建立一个新的数据包 //将时间数据对应在字符串中,方便合成新的cJSON数据包 const String MONTH_NAMES[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; //月份 const String DAY_NAMES[] = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30","31"}; //日 const String HOUR_NAMES[] = {"00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24"};//时 const String MIN_NAMES[] = {"00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12", "13","14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "50", "51", "52", "53", "54", "55", "56", "57", "58", "59", "60"}; //分 const String WDAY_NAMES[] = {"Sun.", "Mon.", "Tues.", "Wed.", "Thur.", "Fri.", "Sat."}; //星期 //location 心知天气的【location】数据 dat["results"][0]["location"]["id"] = doc["results"][0]["location"]["id"].as(); dat["results"][0]["location"]["name"] = doc["results"][0]["location"]["name"].as(); dat["results"][0]["location"]["country"] = doc["results"][0]["location"]["country"].as(); dat["results"][0]["location"]["path"] = doc["results"][0]["location"]["path"].as(); dat["results"][0]["location"]["timezone"] = doc["results"][0]["location"]["timezone"].as(); dat["results"][0]["location"]["timezone_offset"] = doc["results"][0]["location"]["timezone_offset"].as(); //now 心知天气【now】数据和时间结合 放在新的【now】结构体中 dat["results"][0]["now"]["text"] = doc["results"][0]["now"]["text"].as(); dat["results"][0]["now"]["code"] = doc["results"][0]["now"]["code"].as(); dat["results"][0]["now"]["temperature"] = doc["results"][0]["now"]["temperature"].as(); dat["results"][0]["now"]["mon"]=MONTH_NAMES[timeInfo.tm_mon ].c_str(); dat["results"][0]["now"]["day"]=DAY_NAMES[timeInfo.tm_mday].c_str(); dat["results"][0]["now"]["hour"]=HOUR_NAMES[timeInfo.tm_hour].c_str(); dat["results"][0]["now"]["min"]=MIN_NAMES[timeInfo.tm_min].c_str(); dat["results"][0]["now"]["wday"]=WDAY_NAMES[timeInfo.tm_wday].c_str(); dat["results"][0]["last_update"]= doc["results"][0]["last_update"].as(); char json_string[1024]; serializeJson(dat,json_string);//把所有数据放在新的【dat】中 Serial.println(json_string);//输出

于是我们得到了新的数据包,包含了实时时间和日期信息

{"results":[{ "location":{"id":"私钥","name":"地点","country":"CN","path":"---", "timezone":"Asia/Shanghai","timezone_offset":"+08:00"}, "now":{"text":"Sunny","code":"0","temperature":"27","mon":"Aug","day":"2","hour":"18","min":"47","wday":"Tues."},"last_update":"2022-08-02T18:40:06+08:00"}]}

再次使用CSDN的cJSON工具解析数据。

代码如下(示例):

{ "results": [ { "location": { "id": "私钥", "name": "地点", "country": "CN", "path": "---", "timezone": "Asia/Shanghai", "timezone_offset": "+08:00" }, "now": { "text": "Sunny", "code": "0", "temperature": "27", "mon": "Aug", "day": "2", "hour": "18", "min": "47", "wday": "Tues." }, "last_update": "2022-08-02T18:40:06+08:00" } ] }

可以看到现在的数据包要远远大于之前,拥有了时间和日期数据。

3.使用stm32解析数据包

- 解析cJSON数据

#include "cJSON.h" //对应子对象1结构体--Location typedef struct { char id[32]; char name[32]; char country[32]; char path[64]; char timezone[32]; char timezone_offset[32]; }Location; //对应子对象2结构体--Now typedef struct { char text[32]; char code[32]; char temperature[32]; char mon[32]; char day[32]; char hour[32]; char min[32]; char wday[32]; }Now; //用于保存服务器返回的天气数据 typedef struct { Location location; //子对象1 Now now; //子对象2 char last_update[64]; //子对象3 }Results; /********************************************************************************* * Function Name : cJSON_WeatherParse,解析天气数据 * Parameter : JSON:天气数据包 results:保存解析后得到的有用的数据 * Return Value : 0:成功 其他:错误 * Function Explain : * Create Date : 2017.12.6 by lzn **********************************************************************************/ int cJSON_WeatherParse(char *JSON, Results *results) { cJSON *json,*arrayItem,*object,*subobject,*item; json = cJSON_Parse(JSON); //解析JSON数据包 if(json == NULL) //检测JSON数据包是否存在语法上的错误,返回NULL表示数据包无效 { return 1; } else { if((arrayItem = cJSON_GetObjectItem(json,"results")) != NULL); //匹配字符串"results",获取数组内容 { int size = cJSON_GetArraySize(arrayItem); //获取数组中对象个数 //printf("cJSON_GetArraySize: size=%d \r\n",size); if((object = cJSON_GetArrayItem(arrayItem,0)) != NULL)//获取父对象内容 { /* 匹配子对象1 */ if((subobject = cJSON_GetObjectItem(object,"location")) != NULL) { //printf("---------------------------------subobject1-------------------------------\r\n"); if((item = cJSON_GetObjectItem(subobject,"id")) != NULL) //匹配子对象1成员"id" { memcpy(results[0].location.id,item->valuestring,strlen(item->valuestring)); } if((item = cJSON_GetObjectItem(subobject,"name")) != NULL) //匹配子对象1成员"name" { memcpy(results[0].location.name,item->valuestring,strlen(item->valuestring)); } if((item = cJSON_GetObjectItem(subobject,"country")) != NULL) //匹配子对象1成员"country" { memcpy(results[0].location.country,item->valuestring, strlen(item->valuestring)); } if((item = cJSON_GetObjectItem(subobject,"path")) != NULL) //匹配子对象1成员"path" { memcpy(results[0].location.path,item->valuestring, strlen(item->valuestring)); } if((item = cJSON_GetObjectItem(subobject,"timezone")) != NULL) //匹配子对象1成员"timezone" { memcpy(results[0].location.timezone,item->valuestring, strlen(item->valuestring)); } if((item = cJSON_GetObjectItem(subobject,"timezone_offset")) != NULL) //匹配子对象1成员"timezone_offset" { memcpy(results[0].location.timezone_offset,item->valuestring, strlen(item->valuestring)); } } /* 匹配子对象2 */ if((subobject = cJSON_GetObjectItem(object,"now")) != NULL) { //printf("---------------------------------subobject2-------------------------------\r\n"); if((item = cJSON_GetObjectItem(subobject,"text")) != NULL) //匹配子对象2成员"text" { memcpy(results[0].now.text,item->valuestring,strlen(item->valuestring)); } if((item = cJSON_GetObjectItem(subobject,"code")) != NULL) //匹配子对象2成员"code" { memcpy(results[0].now.code,item->valuestring,strlen(item->valuestring)); } if((item = cJSON_GetObjectItem(subobject,"temperature")) != NULL) //匹配子对象2成员"temperature" { memcpy(results[0].now.temperature,item->valuestring, strlen(item->valuestring)); } if((item = cJSON_GetObjectItem(subobject,"mon")) != NULL) //匹配子对象2成员"mon" { memcpy(results[0].now.mon,item->valuestring,strlen(item->valuestring)); } if((item = cJSON_GetObjectItem(subobject,"day")) != NULL) //匹配子对象2成员"day" { memcpy(results[0].now.day,item->valuestring,strlen(item->valuestring)); } if((item = cJSON_GetObjectItem(subobject,"hour")) != NULL) //匹配子对象2成员"hour" { memcpy(results[0].now.hour,item->valuestring,strlen(item->valuestring)); } if((item = cJSON_GetObjectItem(subobject,"min")) != NULL) //匹配子对象2成员"min" { memcpy(results[0].now.min,item->valuestring,strlen(item->valuestring)); } if((item = cJSON_GetObjectItem(subobject,"wday")) != NULL) //匹配子对象2成员"wday" { memcpy(results[0].now.wday,item->valuestring,strlen(item->valuestring)); } } /* 匹配子对象3 */ if((subobject = cJSON_GetObjectItem(object,"last_update")) != NULL) { //printf("---------------------------------subobject3-------------------------------\r\n"); memcpy(results[0].last_update,item->valuestring,strlen(subobject->valuestring)); } } } } cJSON_Delete(json); //释放cJSON_Parse()分配出来的内存空间 return 0; }

如上我们已经对数据包进行了解析。 然后进行分布调用。

//调用温度数据,结构基本不变 //只需要更改获取的数据结构体位置 memset(dtOLEDBuf, 0, sizeof(dtOLEDBuf)); sprintf((char *)dtOLEDBuf,"%s^C",results[0].now.temperature);//更改这行代码获取其他数据。 LCD_ShowString(73,66,(u8 *)dtOLEDBuf,GRAYBLUE,BLACK,16,0); USART_RX_STA=0; memset(USART_RX_BUF, 0, sizeof(USART_RX_BUF));

例如: 获取地点数据,只需要找不同,根据上面的代码,更改下面的

//地点 memset(dtOLEDBuf, 0, sizeof(dtOLEDBuf)); sprintf((char *)dtOLEDBuf,"%s",results[0].location.name);//更改了这行的 LCD_ShowString(60,100,(u8 *)dtOLEDBuf,CYAN,BLACK,16,0); USART_RX_STA=0; memset(USART_RX_BUF, 0, sizeof(USART_RX_BUF)); 4.屏幕显示,由于分光棱镜的原理,需要反转屏幕。

根据原子哥的视频和芯片手册

在这里插入图片描述 请添加图片描述

我们只需要改变这行代码,就可以实现屏幕反转。使分光棱镜中的显示正向。

在这里插入图片描述

在初始化屏幕的初始化文件中改为 请添加图片描述

具体可以参考CSDN博主https://blog.csdn.net/qq1113512618/article/details/111937148的文章。

三、代码编写

32 main函数编写。

include "stm32f10x.h" #include "delay.h" #include "sys.h" #include "usart.h" #include "oled.h" #include "led.h" #include "lcd_init.h" #include "lcd.h" #include "pic.h" #include "cJSON.h" //子对象1结构体--Location typedef struct { char id[32]; char name[32]; char country[32]; char path[64]; char timezone[32]; char timezone_offset[32]; }Location; //子对象2结构体--Now typedef struct { char text[32]; char code[32]; char temperature[32]; char mon[32]; char day[32]; char hour[32]; char min[32]; char wday[32]; }Now; //用于保存服务器返回的天气数据 typedef struct { Location location; //子对象1 Now now; //子对象2 char last_update[64]; //子对象3 }Results; /********************************************************************************* * Function Name : cJSON_WeatherParse,解析天气数据 * Parameter : JSON:天气数据包 results:保存解析后得到的有用的数据 * Return Value : 0:成功 其他:错误 * Function Explain : * Create Date : 2017.12.6 by lzn **********************************************************************************/ int cJSON_WeatherParse(char *JSON, Results *results) { cJSON *json,*arrayItem,*object,*subobject,*item; json = cJSON_Parse(JSON); //解析JSON数据包 if(json == NULL) //检测JSON数据包是否存在语法上的错误,返回NULL表示数据包无效 { //printf("Error before: [%s] \r\n",cJSON_GetErrorPtr()); //打印数据包语法错误的位置 return 1; } else { if((arrayItem = cJSON_GetObjectItem(json,"results")) != NULL); //匹配字符串"results",获取数组内容 { int size = cJSON_GetArraySize(arrayItem); //获取数组中对象个数 //printf("cJSON_GetArraySize: size=%d \r\n",size); if((object = cJSON_GetArrayItem(arrayItem,0)) != NULL)//获取父对象内容 { /* 匹配子对象1 */ if((subobject = cJSON_GetObjectItem(object,"location")) != NULL) { //printf("---------------------------------subobject1-------------------------------\r\n"); if((item = cJSON_GetObjectItem(subobject,"id")) != NULL) //匹配子对象1成员"id" { //printf("cJSON_GetObjectItem: type=%d, string is %s,valuestring=%s \r\n",item->type,item->string,item->valuestring); memcpy(results[0].location.id,item->valuestring,strlen(item->valuestring)); } if((item = cJSON_GetObjectItem(subobject,"name")) != NULL) //匹配子对象1成员"name" { //printf("cJSON_GetObjectItem: type=%d, string is %s,valuestring=%s \r\n",item->type,item->string,item->valuestring); memcpy(results[0].location.name,item->valuestring,strlen(item->valuestring)); } if((item = cJSON_GetObjectItem(subobject,"country")) != NULL)//匹配子对象1成员"country" { //printf("cJSON_GetObjectItem: type=%d, string is %s,valuestring=%s \r\n",item->type,item->string,item->valuestring); memcpy(results[0].location.country,item->valuestring,strlen(item->valuestring)); } if((item = cJSON_GetObjectItem(subobject,"path")) != NULL) //匹配子对象1成员"path" { //printf("cJSON_GetObjectItem: type=%d, string is %s,valuestring=%s \r\n",item->type,item->string,item->valuestring); memcpy(results[0].location.path,item->valuestring,strlen(item->valuestring)); } if((item = cJSON_GetObjectItem(subobject,"timezone")) != NULL)//匹配子对象1成员"timezone" { //printf("cJSON_GetObjectItem: type=%d, string is %s,valuestring=%s \r\n",item->type,item->string,item->valuestring); memcpy(results[0].location.timezone,item->valuestring,strlen(item->valuestring)); } if((item = cJSON_GetObjectItem(subobject,"timezone_offset")) != NULL)//匹配子对象1成员"timezone_offset" { //printf("cJSON_GetObjectItem: type=%d, string is %s,valuestring=%s \r\n",item->type,item->string,item->valuestring); memcpy(results[0].location.timezone_offset,item->valuestring,strlen(item->valuestring)); } } /* 匹配子对象2 */ if((subobject = cJSON_GetObjectItem(object,"now")) != NULL) { //printf("---------------------------------subobject2-------------------------------\r\n"); if((item = cJSON_GetObjectItem(subobject,"text")) != NULL)//匹配子对象2成员"text" { //printf("cJSON_GetObjectItem: type=%d, string is %s,valuestring=%s \r\n",item->type,item->string,item->valuestring); memcpy(results[0].now.text,item->valuestring,strlen(item->valuestring)); } if((item = cJSON_GetObjectItem(subobject,"code")) != NULL)//匹配子对象2成员"code" { //printf("cJSON_GetObjectItem: type=%d, string is %s,valuestring=%s \r\n",item->type,item->string,item->valuestring); memcpy(results[0].now.code,item->valuestring,strlen(item->valuestring)); } if((item = cJSON_GetObjectItem(subobject,"temperature")) != NULL) //匹配子对象2成员"temperature" { //printf("cJSON_GetObjectItem: type=%d, string is %s,valuestring=%s \r\n",item->type,item->string,item->valuestring); memcpy(results[0].now.temperature,item->valuestring,strlen(item->valuestring)); } if((item = cJSON_GetObjectItem(subobject,"mon")) != NULL) //匹配子对象2成员"mon" { //printf("cJSON_GetObjectItem: type=%d, string is %s,valuestring=%s \r\n",item->type,item->string,item->valuestring); memcpy(results[0].now.mon,item->valuestring,strlen(item->valuestring)); } if((item = cJSON_GetObjectItem(subobject,"day")) != NULL) //匹配子对象2成员"day" { //printf("cJSON_GetObjectItem: type=%d, string is %s,valuestring=%s \r\n",item->type,item->string,item->valuestring); memcpy(results[0].now.day,item->valuestring,strlen(item->valuestring)); } if((item = cJSON_GetObjectItem(subobject,"hour")) != NULL) //匹配子对象2成员"hour" { //printf("cJSON_GetObjectItem: type=%d, string is %s,valuestring=%s \r\n",item->type,item->string,item->valuestring); memcpy(results[0].now.hour,item->valuestring,strlen(item->valuestring)); } if((item = cJSON_GetObjectItem(subobject,"min")) != NULL) //匹配子对象2成员"min" { //printf("cJSON_GetObjectItem: type=%d, string is %s,valuestring=%s \r\n",item->type,item->string,item->valuestring); memcpy(results[0].now.min,item->valuestring,strlen(item->valuestring)); } if((item = cJSON_GetObjectItem(subobject,"wday")) != NULL) //匹配子对象2成员"wday" { //printf("cJSON_GetObjectItem: type=%d, string is %s,valuestring=%s \r\n",item->type,item->string,item->valuestring); memcpy(results[0].now.wday,item->valuestring,strlen(item->valuestring)); } } /* 匹配子对象3 */ if((subobject = cJSON_GetObjectItem(object,"last_update")) != NULL) { //printf("---------------------------------subobject3-------------------------------\r\n"); //printf("cJSON_GetObjectItem: type=%d, string is %s,valuestring=%s \r\n",subobject->type,subobject->string,subobject->valuestring); memcpy(results[0].last_update,item->valuestring,strlen(subobject->valuestring)); } } } } cJSON_Delete(json); //释放cJSON_Parse()分配出来的内存空间 return 0; } int simple_atoi(char *source) //字符串转整形 { int length = strlen(source); //计算长度 int sum = 0,i=0; //for(int i=0;source[i]!='';i++) printf("source[%d]: %c",i,source[i]); //输出每个数字字符 if(length!=1) { for(int i=0;i sum=source[0]-'0'; return sum; } } int main(void) { u16 uart1Len; Results results[] = {{0}}; u8 dtOLEDBuf[16]; //OLED缓存器 int weather=0; int day,x=0; char a; char Cooper[]={"Cooper"}; //初始化 //延时函数初始化 delay_init(); NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级 uart_init(115200); //串口初始化为115200 LED_Init();//LED初始化 LCD_Init();//LCD初始化 LCD_Fill(0,0,LCD_W,LCD_H,BLACK); while(1) { Results results[] = {{0}}; //串口1收到的信息 if(USART_RX_STA&0x8000) { uart1Len=USART_RX_STA&0x3f; //得到此次接收到的数据长度 day=cJSON_WeatherParse(USART_RX_BUF, results); //解析天气数据 打印结构体内内容 // ·("打印结构体内内容如下: \r\n"); // printf("%s \r\n",results[0].now.text); // printf("%s \r\n",results[0].now.code); // printf("%s \r\n",results[0].last_update); //清屏,重新显示屏幕内容 LCD_Fill(0,0,LCD_W,LCD_H,BLACK); //天气 memset(dtOLEDBuf, 0, sizeof(dtOLEDBuf)); sprintf((char *)dtOLEDBuf,"%s",results[0].now.code); // printf("%s",results[0].now.code); weather=simple_atoi((char *)results[0].now.code); switch(weather) { //晴天 case 0: case 1: case 2: case 3: { LCD_ShowPicture(8,76,40,40,gImage_0); memset(dtOLEDBuf, 0, sizeof(dtOLEDBuf)); sprintf((char *)dtOLEDBuf,"%s",results[0].now.text); LCD_ShowString(70,82,(u8 *)dtOLEDBuf,LIGHTBLUE,BLACK,16,0); }break; //多云,阴天 case 5: case 6: case 7: case 8: case 9: { LCD_ShowPicture(8,76,40,40,gImage_4); memset(dtOLEDBuf, 0, sizeof(dtOLEDBuf)); sprintf((char *)dtOLEDBuf,"%s",results[0].now.text); LCD_ShowString(70,82,(u8 *)dtOLEDBuf,LIGHTBLUE,BLACK,16,0); }break; //雨天 case 10: case 11: case 12: case 13: case 14: case 15: case 16: case 17: case 18: { LCD_ShowPicture(8,76,40,40,gImage_14); memset(dtOLEDBuf, 0, sizeof(dtOLEDBuf)); sprintf((char *)dtOLEDBuf,"%s",results[0].now.text); LCD_ShowString(70,82,(u8 *)dtOLEDBuf,LIGHTBLUE,BLACK,16,0); }break; //雪天 case 19: case 20: case 21: case 22: case 23: case 24: case 25: { LCD_ShowPicture(8,76,40,40,gImage_23); memset(dtOLEDBuf, 0, sizeof(dtOLEDBuf)); sprintf((char *)dtOLEDBuf,"%s",results[0].now.text); LCD_ShowString(70,82,(u8 *)dtOLEDBuf,LIGHTBLUE,BLACK,16,0); }break; //其他 default: { LCD_ShowPicture(8,76,40,40,gImage_4); memset(dtOLEDBuf, 0, sizeof(dtOLEDBuf)); sprintf((char *)dtOLEDBuf,"%s",results[0].now.text); LCD_ShowString(70,82,(u8 *)dtOLEDBuf,LIGHTBLUE,BLACK,16,0); }break; } //温度 (x,y) x大→小 y 上小 下大 memset(dtOLEDBuf, 0, sizeof(dtOLEDBuf)); sprintf((char *)dtOLEDBuf,"%s^C",results[0].now.temperature); LCD_ShowString(73,66,(u8 *)dtOLEDBuf,GRAYBLUE,BLACK,16,0); USART_RX_STA=0; memset(USART_RX_BUF, 0, sizeof(USART_RX_BUF)); //地点 memset(dtOLEDBuf, 0, sizeof(dtOLEDBuf)); sprintf((char *)dtOLEDBuf,"%s",results[0].location.name); LCD_ShowString(60,100,(u8 *)dtOLEDBuf,CYAN,BLACK,16,0); USART_RX_STA=0; memset(USART_RX_BUF, 0, sizeof(USART_RX_BUF)); //日期 //月 memset(dtOLEDBuf, 0, sizeof(dtOLEDBuf)); sprintf((char *)dtOLEDBuf,"%s.",results[0].now.mon); LCD_ShowString(44,43,(u8 *)dtOLEDBuf,GRAYBLUE,BLACK,16,0); USART_RX_STA=0; memset(USART_RX_BUF, 0, sizeof(USART_RX_BUF)); //日 memset(dtOLEDBuf, 0, sizeof(dtOLEDBuf)); sprintf((char *)dtOLEDBuf,"%sth.",results[0].now.day); LCD_ShowString(4,43,(u8 *)dtOLEDBuf,GRAYBLUE,BLACK,16,0); USART_RX_STA=0; memset(USART_RX_BUF, 0, sizeof(USART_RX_BUF)); //周 memset(dtOLEDBuf, 0, sizeof(dtOLEDBuf)); sprintf((char *)dtOLEDBuf,"%s",results[0].now.wday); LCD_ShowString(84,15,(u8 *)dtOLEDBuf,CYAN,BLACK,16,0); USART_RX_STA=0; memset(USART_RX_BUF, 0, sizeof(USART_RX_BUF)); //时 memset(dtOLEDBuf, 0, sizeof(dtOLEDBuf)); sprintf((char *)dtOLEDBuf,"%s:",results[0].now.hour); LCD_ShowString(2,10,(u8 *)dtOLEDBuf,WHITE,BLACK,32,0); USART_RX_STA=0; memset(USART_RX_BUF, 0, sizeof(USART_RX_BUF)); //分 memset(dtOLEDBuf, 0, sizeof(dtOLEDBuf)); sprintf((char *)dtOLEDBuf,"%s",results[0].now.min); LCD_ShowString(50,10,(u8 *)dtOLEDBuf,WHITE,BLACK,32,0); USART_RX_STA=0; memset(USART_RX_BUF, 0, sizeof(USART_RX_BUF)); //分号(时分之间) LCD_ShowChar(33,8,':',YELLOW,BLACK,32,0); //划线 LCD_DrawLine(0,62,128,62,YELLOW); //画圆圈 x++; if(x==10) { x=0; LCD_ShowString(80,43,Cooper,YELLOW,BLACK,16,0); } Draw_Circle(103,44,x,LIGHTGREEN); } delay_ms(5); } }

esp32代码编写

#include #include #include #include #define NTP1 "ntp1.aliyun.com" #define NTP2 "ntp2.aliyun.com" #define NTP3 "ntp3.aliyun.com" //填写WIFI入网信息 const char * ID = "自己WIFI名称"; const char * PASSWORD = "WIFI密码"; const String MONTH_NAMES[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; //月份 const String DAY_NAMES[] = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30","31"}; //日 const String HOUR_NAMES[] = {"00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24"};//时 const String MIN_NAMES[] = {"00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12", "13","14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "50", "51", "52", "53", "54", "55", "56", "57", "58", "59", "60"}; //分 const String WDAY_NAMES[] = {"Sun.", "Mon.", "Tues.", "Wed.", "Thur.", "Fri.", "Sat."}; //星期 //天气相关参数 String API = "上文提到的私钥"; String WeatherURL = ""; String CITY = "自己所在城市的代码"; String url_xinzhi = ""; String Weather = "0"; String Temperature = "0"; String Name = "0"; long sum = 0; /* 创建实例 */ HTTPClient http; String GitURL(String api,String city) { url_xinzhi = "https://api.seniverse.com/v3/weather/now.json?key="; url_xinzhi += api; url_xinzhi += "&location="; url_xinzhi += city; url_xinzhi += "&language=en&unit=c"; return url_xinzhi; } void ParseWeather(String url) { int Year,Mon,Day,Hour,Min,Wday; struct tm timeInfo; //声明一个结构体 DynamicJsonDocument doc(1024); //分配内存,动态 DynamicJsonDocument dat(1024); http.begin(url); int httpGet = http.GET(); if(httpGet > 0) { //Serial.printf("HTTPGET is %d",httpGet); if(httpGet == HTTP_CODE_OK) { if (!getLocalTime(&timeInfo)) { //一定要加这个条件判断,否则内存溢出 // Serial.println("Failed to obtain time"); return; } String date = WDAY_NAMES[timeInfo.tm_wday]; // Serial.println(date.c_str()); // sprintf_P(buff1, PSTR("%04d-%02d-%02d %s"), timeInfo.tm_year + 1900, timeInfo.tm_mon + 1, timeInfo.tm_mday, WDAY_NAMES[timeInfo.tm_wday].c_str()); String shuju = String(timeInfo.tm_year + 1900); //年 shuju += "-"; shuju += timeInfo.tm_mon + 1; //月 shuju += "-"; shuju += timeInfo.tm_mday; //日 shuju += " "; shuju += timeInfo.tm_hour; //时 shuju += ":"; shuju += timeInfo.tm_min; shuju += ":"; shuju += timeInfo.tm_sec; shuju += " "; shuju += WDAY_NAMES[timeInfo.tm_wday].c_str(); //星期 String json = http.getString(); deserializeJson(doc, json); //location dat["results"][0]["location"]["id"] = doc["results"][0]["location"]["id"].as(); dat["results"][0]["location"]["name"] = doc["results"][0]["location"]["name"].as(); dat["results"][0]["location"]["country"] = doc["results"][0]["location"]["country"].as(); dat["results"][0]["location"]["path"] = doc["results"][0]["location"]["path"].as(); dat["results"][0]["location"]["timezone"] = doc["results"][0]["location"]["timezone"].as(); dat["results"][0]["location"]["timezone_offset"] = doc["results"][0]["location"]["timezone_offset"].as(); //now dat["results"][0]["now"]["text"] = doc["results"][0]["now"]["text"].as(); dat["results"][0]["now"]["code"] = doc["results"][0]["now"]["code"].as(); dat["results"][0]["now"]["temperature"] = doc["results"][0]["now"]["temperature"].as(); dat["results"][0]["now"]["mon"]=MONTH_NAMES[timeInfo.tm_mon ].c_str(); dat["results"][0]["now"]["day"]=DAY_NAMES[timeInfo.tm_mday].c_str(); dat["results"][0]["now"]["hour"]=HOUR_NAMES[timeInfo.tm_hour].c_str(); dat["results"][0]["now"]["min"]=MIN_NAMES[timeInfo.tm_min].c_str(); dat["results"][0]["now"]["wday"]=WDAY_NAMES[timeInfo.tm_wday].c_str(); dat["results"][0]["last_update"]= doc["results"][0]["last_update"].as(); char json_string[1024]; serializeJson(dat,json_string); Serial.println(json_string); } else { Serial.printf("ERROR1!!"); } } else { Serial.printf("ERROR2!!"); } http.end(); } void setup() { Serial.begin(115200); //==================wifi连接================== // Serial.println("WiFi:"); // Serial.println(ID); // Serial.println("PASSWORLD:"); // Serial.println(PASSWORD); WiFi.mode(WIFI_STA); WiFi.begin(ID,PASSWORD); while(WiFi.status()!=WL_CONNECTED) { delay(500); // Serial.println("Connecting..."); } // Serial.println("Connect OK!"); //==================wifi连接================== WeatherURL = GitURL(API,CITY); configTime(8 * 3600, 0, NTP1, NTP2, NTP3); } void loop() { // Serial.println("连接成功!"); delay(20000); }

esp32代码中所需的心知天气城市代码文档:城市代码

桌面天气全套文件:全套文件 包括源码以及图形库,字库等,word文档解答了遇到的问题。

总结

以上就是今天要讲的内容,本文介绍了桌面天气时钟的开发过程。 成品照片过几天会上传,屏幕由于操作失误烧掉了,重新购买了=-=

如果大家觉得还算有用的话 悄悄告诉你们一个催更小技巧 点赞、收藏、关注,可以加速更新嗷!!!



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

      专题文章
        CopyRight 2018-2019 实验室设备网 版权所有