所用开发板:OneNET NB-IoT 开发板 V2.1 需要ESP8266 需要注册心知天气账号(自行百度)
1、头文件
#ifndef __SHOW_WEATHER_H
#define __SHOW_WEATHER_H
#include "OLED.h"
#include <string.h>
#include <stdlib.h>
#include "usart.h"
#include "delay.h"
#include "led.h"
extern char usart2Buf[512];
extern int usart2Len;
extern char usart1Buf[512];
extern int usart1Len;
struct cn_and_num{
char cn[4];
int num;
};
void init_cnnum(struct cn_and_num *cnnum,int len);
void change_cn_num(int *cn_num,char *cn_buf,int cn_buf_len,
struct cn_and_num *cnnum,int cnnum_len);
void show_wether(int *cn_num,int temp,char *time);
void data_parsing(char *tmp,int len,char *time_buf,
char *cn_buf,int *wendu);
void get_city_weather(int type);
void show_city_weather(int type,int *check);
#endif
usart.h delay.h led.h OLED.h
2、具体实现
2.1、说明
获取原始数据 --> 解析提取 --> 获取汉字在字库的位置 --> 显示 显示核心函数:OLED_ShowCN(uint8_t x,uint8_t y,uint8_t index) 即根据汉字在字库中的位置 index来显示汉字
================= 南充abc阴abc 34 2022-08-08 10:46 ================= 心知天气返回的数据为UTF-8编码(每个汉字3个字节) 把城市和天气放一起是为了方便后面显示 abc为分割标志
2.2、让keil能够编译UTF-8的数据
–locale=english
2.3、未解决的问题
使用AT+RST命令后必须重置开发板否则会卡死 也就是AT+RST命令和天气查询不能共存
2.4、代码
#include "show_weather.h"
static int loop_i;
static int loop_j;
static int loop_b;
void init_cnnum(struct cn_and_num *cnnum,int len){
loop_i = 0;
loop_j = 18;
strncpy(cnnum[loop_i].cn,"成",3);
cnnum[loop_i].cn[3] = 0;
cnnum[loop_i].num = loop_j;
loop_i++;
loop_j++;
strncpy(cnnum[loop_i].cn,"都",3);
cnnum[loop_i].cn[3] = 0;
cnnum[loop_i].num = loop_j;
loop_i++;
loop_j++;
strcpy(cnnum[loop_i].cn,"拉");
cnnum[loop_i].cn[3] = 0;
cnnum[loop_i].num = loop_j;
loop_i++;
loop_j++;
strcpy(cnnum[loop_i].cn,"萨");
cnnum[loop_i].cn[3] = 0;
cnnum[loop_i].num = loop_j;
loop_i++;
loop_j++;
strcpy(cnnum[loop_i].cn,"石");
cnnum[loop_i].cn[3] = 0;
cnnum[loop_i].num = loop_j;
loop_i++;
loop_j++;
strcpy(cnnum[loop_i].cn,"家");
cnnum[loop_i].cn[3] = 0;
cnnum[loop_i].num = loop_j;
loop_i++;
loop_j++;
strcpy(cnnum[loop_i].cn,"庄");
cnnum[loop_i].cn[3] = 0;
cnnum[loop_i].num = loop_j;
loop_i++;
loop_j++;
strcpy(cnnum[loop_i].cn,"南");
cnnum[loop_i].cn[3] = 0;
cnnum[loop_i].num = loop_j;
loop_i++;
loop_j++;
strcpy(cnnum[loop_i].cn,"充");
cnnum[loop_i].cn[3] = 0;
cnnum[loop_i].num = loop_j;
loop_i++;
loop_j++;
strcpy(cnnum[loop_i].cn,"乌");
cnnum[loop_i].cn[3] = 0;
cnnum[loop_i].num = loop_j;
loop_i++;
loop_j++;
strcpy(cnnum[loop_i].cn,"鲁");
cnnum[loop_i].cn[3] = 0;
cnnum[loop_i].num = loop_j;
loop_i++;
loop_j++;
strcpy(cnnum[loop_i].cn,"木");
cnnum[loop_i].cn[3] = 0;
cnnum[loop_i].num = loop_j;
loop_i++;
loop_j++;
strcpy(cnnum[loop_i].cn,"齐");
cnnum[loop_i].cn[3] = 0;
cnnum[loop_i].num = loop_j;
loop_i++;
loop_j++;
strcpy(cnnum[loop_i].cn,"晴");
cnnum[loop_i].cn[3] = 0;
cnnum[loop_i].num = loop_j;
loop_i++;
loop_j++;
strcpy(cnnum[loop_i].cn,"阴");
cnnum[loop_i].cn[3] = 0;
cnnum[loop_i].num = loop_j;
loop_i++;
loop_j++;
strcpy(cnnum[loop_i].cn,"多");
cnnum[loop_i].cn[3] = 0;
cnnum[loop_i].num = loop_j;
loop_i++;
loop_j++;
strcpy(cnnum[loop_i].cn,"云");
cnnum[loop_i].cn[3] = 0;
cnnum[loop_i].num = loop_j;
loop_i++;
loop_j++;
strcpy(cnnum[loop_i].cn,"转");
cnnum[loop_i].cn[3] = 0;
cnnum[loop_i].num = loop_j;
loop_i++;
loop_j++;
strcpy(cnnum[loop_i].cn,"大");
cnnum[loop_i].cn[3] = 0;
cnnum[loop_i].num = loop_j;
loop_i++;
loop_j++;
strcpy(cnnum[loop_i].cn,"小");
cnnum[loop_i].cn[3] = 0;
cnnum[loop_i].num = loop_j;
loop_i++;
loop_j++;
strcpy(cnnum[loop_i].cn,"到");
cnnum[loop_i].cn[3] = 0;
cnnum[loop_i].num = loop_j;
loop_i++;
loop_j++;
strcpy(cnnum[loop_i].cn,"暴");
cnnum[loop_i].cn[3] = 0;
cnnum[loop_i].num = loop_j;
loop_i++;
loop_j++;
strcpy(cnnum[loop_i].cn,"雨");
cnnum[loop_i].cn[3] = 0;
cnnum[loop_i].num = loop_j;
loop_i++;
loop_j++;
strcpy(cnnum[loop_i].cn,"中");
cnnum[loop_i].cn[3] = 0;
cnnum[loop_i].num = loop_j;
loop_i++;
loop_j++;
strcpy(cnnum[loop_i].cn,"获");
cnnum[loop_i].cn[3] = 0;
cnnum[loop_i].num = loop_j;
loop_i++;
loop_j++;
strcpy(cnnum[loop_i].cn,"取");
cnnum[loop_i].cn[3] = 0;
cnnum[loop_i].num = loop_j;
loop_i++;
loop_j++;
strcpy(cnnum[loop_i].cn,"失");
cnnum[loop_i].cn[3] = 0;
cnnum[loop_i].num = loop_j;
loop_i++;
loop_j++;
strcpy(cnnum[loop_i].cn,"败");
cnnum[loop_i].cn[3] = 0;
cnnum[loop_i].num = loop_j;
loop_i++;
strcpy(cnnum[loop_i].cn,"abc");
cnnum[loop_i].cn[3] = 0;
cnnum[loop_i].num = -1;
loop_i++;
strcpy(cnnum[loop_i].cn,"abc");
cnnum[loop_i].cn[3] = 0;
cnnum[loop_i].num = -1;
loop_i = 0;
loop_j = 0;
}
void change_cn_num(int *cn_num,char *cn_buf,int cn_buf_len,
struct cn_and_num *cnnum,int cnnum_len){
int head,tail;
head = 0;
for(loop_i=0;loop_i<cn_buf_len/3;loop_i++){
tail = cnnum_len+1;
for(loop_j = head;loop_j<tail;loop_j++){
if(cnnum[loop_j].num == -1){
loop_j = 0;
tail = head;
}
else if(strncmp(cn_buf+loop_i*3,"abc",3) == 0){
cn_num[loop_i] = -1;
head = loop_j;
break;
}
else if(strncmp(cnnum[loop_j].cn,cn_buf+loop_i*3,3) == 0){
cn_num[loop_i] = cnnum[loop_j].num;
head = loop_j;
break;
}
}
}
}
void show_wether(int *cn_num,int temp,char *time){
OLED_Clear();
OLED_ShowCN(0,0,13);
OLED_ShowCN(16,0,14);
OLED_ShowChar(1,5,':');
for(loop_i = 0;loop_i<30;loop_i++){
if(cn_num[loop_i] == -1){
loop_j = loop_i +1;
break;
}
OLED_ShowCN(42+loop_i*16,0,cn_num[loop_i]);
}
OLED_ShowCN(0,2,15);
OLED_ShowCN(16,2,16);
OLED_ShowChar(2,5,':');
for(loop_i = loop_j;loop_i<30;loop_i++){
if(cn_num[loop_i] == -1){
break;
}
OLED_ShowCN(42+(loop_i-loop_j)*16,2,cn_num[loop_i]);
}
OLED_ShowCN(0,4,11);
OLED_ShowCN(16,4,17);
OLED_ShowChar(3,5,':');
OLED_ShowNum(3,6,temp,2);
OLED_ShowString(4,1,time);
}
void data_parsing(char *tmp,int len,char *time_buf,
char *cn_buf,int *wendu){
char temp_buf[3];
int temp;
memset(temp_buf,0,3);
OLED_weather_loading(30,0);
for(loop_i = 46;loop_i< len - 10;loop_i++){
if(tmp[loop_i] == 'n' && tmp[loop_i+1] == 'a' &&
tmp[loop_i+2] == 'm' && tmp[loop_i+3] == 'e'){
loop_j = loop_i + 7;
loop_b = 0;
while ( tmp[loop_j] != '\"' && loop_b<20){
cn_buf[loop_b] = tmp[loop_j];
loop_b++;
loop_j++;
OLED_weather_loading(31,loop_b%99);
}
cn_buf[loop_b] = 'a';
loop_b++;
cn_buf[loop_b] = 'b';
loop_b++;
cn_buf[loop_b] = 'c';
loop_b++;
cn_buf[loop_b] = 0;
}
else if(tmp[loop_i] == 't' && tmp[loop_i+1] == 'e' &&
tmp[loop_i+2] == 'x' && tmp[loop_i+3] == 't'){
loop_j = loop_i + 7;
while ( tmp[loop_j] != '\"'&& loop_b<40){
cn_buf[loop_b] = tmp[loop_j];
loop_b++;
loop_j++;
OLED_weather_loading(32,loop_b%99);
}
cn_buf[loop_b] = 'a';
loop_b++;
cn_buf[loop_b] = 'b';
loop_b++;
cn_buf[loop_b] = 'c';
loop_b++;
cn_buf[loop_b] = 0;
UsartPrintf(USART1, cn_buf);
}
else if(tmp[loop_i] == 't' && tmp[loop_i+1] == 'u' &&
tmp[loop_i+2] == 'r' && tmp[loop_i+3] == 'e'){
loop_j = loop_i + 7;
loop_b = 0;
while ( tmp[loop_j] != '\"'&& loop_b<3){
temp_buf[loop_b] = tmp[loop_j];
loop_b++;
loop_j++;
OLED_weather_loading(33,loop_b%99);
}
temp_buf[loop_b] = '\0';
temp = (temp_buf[0] - 48)*10 + temp_buf[1] - 48;
*wendu = temp;
UsartPrintf(USART1, temp_buf);
}
else if(tmp[loop_i] == 'd' && tmp[loop_i+1] == 'a' &&
tmp[loop_i+2] == 't' && tmp[loop_i+3] == 'e') {
loop_j = loop_i + 12;
loop_b = 0;
while ( tmp[loop_j] != '+'&& tmp[loop_j] != '}' && loop_b<16){
time_buf[loop_b] = tmp[loop_j];
loop_b++;
loop_j++;
OLED_weather_loading(34,loop_b%99);
}
time_buf [5] = ' ';
time_buf [loop_b] = 0;
UsartPrintf(USART1, time_buf);
OLED_weather_loading(34,loop_b);
break;
}
OLED_weather_loading(30,loop_i%99);
}
}
void get_city_weather(int city){
char conn_server[] = "AT+CIPSTART=\"TCP\",\"api.seniverse.com\",80\r\n";
switch(city){
case 0:
{
unsigned char query_weather[] = "GET https://api.seniverse.com/v3/weather/now.json?key=SpKydYpilyEAHrt6C&location=nanchong&language=zh-Hans&unit=c\r\n";
OLED_weather_loading(2,1);
Usart_SendString(USART2,(unsigned char *)"+++",3);
Delay_ms(1000);
OLED_weather_loading(2,2);
Usart_SendString(USART2,(unsigned char *)"+++",3);
Delay_ms(1000);
OLED_weather_loading(2,3);
Usart_SendString(USART2,(unsigned char *)"+++",3);
Delay_ms(500);
OLED_weather_loading(2,42);
Usart_SendString(USART2, (unsigned char *)"AT+CIPMUX=0\r\n",sizeof("AT+CIPMUX=0\r\n"));
Delay_ms(500);
OLED_weather_loading(2,5);
Usart_SendString(USART2,(unsigned char *)conn_server,strlen(conn_server));
Delay_ms(500);
OLED_weather_loading(2,6);
Usart_SendString(USART2, (unsigned char *)"AT+CIPMODE=1\r\n",sizeof("AT+CIPMODE=1\r\n"));
Delay_ms(500);
OLED_weather_loading(2,7);
Usart_SendString(USART2, (unsigned char *)"AT+CIPSEND\r\n",sizeof("AT+CIPSEND\r\n"));
Delay_ms(500);
usart2Len = 0;
Usart_SendString(USART2,(unsigned char *)query_weather,sizeof(query_weather));
OLED_weather_loading(25,0);
break;
}
case 1:
{
unsigned char query_weather[] = "GET https://api.seniverse.com/v3/weather/now.json?key=SpKydYpilyEAHrt6C&location=chengdu&language=zh-Hans&unit=c\r\n";
usart2Len = 0;
Usart_SendString(USART2,(unsigned char *)query_weather,sizeof(query_weather));
OLED_weather_loading(25,1);
break;
}
case 2:
{
unsigned char query_weather[] = "GET https://api.seniverse.com/v3/weather/now.json?key=SpKydYpilyEAHrt6C&location=nanchong&language=zh-Hans&unit=c\r\n";
usart2Len = 0;
Usart_SendString(USART2,query_weather,sizeof(query_weather));
OLED_weather_loading(25,2);
break;
}
case 3:
{
unsigned char query_weather[] = "GET https://api.seniverse.com/v3/weather/now.json?key=SpKydYpilyEAHrt6C&location=lasa&language=zh-Hans&unit=c\r\n";
usart2Len = 0;
Usart_SendString(USART2,query_weather,sizeof(query_weather));
OLED_weather_loading(25,3);
break;
}
case 4:
{
unsigned char query_weather[] = "GET https://api.seniverse.com/v3/weather/now.json?key=SpKydYpilyEAHrt6C&location=shijiazhuang&language=zh-Hans&unit=c\r\n";
usart2Len = 0;
Usart_SendString(USART2,query_weather,sizeof(query_weather));
OLED_weather_loading(25,4);
break;
}
case 5:
{
unsigned char query_weather[] = "GET https://api.seniverse.com/v3/weather/now.json?key=SpKydYpilyEAHrt6C&location=wulumuqi&language=zh-Hans&unit=c\r\n";
usart2Len = 0;
Usart_SendString(USART2,query_weather,sizeof(query_weather));
OLED_weather_loading(25,5);
break;
}
default:
break;
}
Delay_ms(500);
}
void show_city_weather(int type,int *check){
char data_tmp[300] = "{\"results\":[{\"location\":{\"id\":\"WM6N2PM3WY2K\",\"name\":\"获取失败\",\"country\":\"CN\",\"path\":\"xx,xx,xx,xx\",\"timezone\":\"Asia/Shanghai\",\"timezone_offset\":\"+08:00\"},\"now\":{\"text\":\"获取失败\",\"code\":\"0\",\"temperature\":\"0\"},\"last_update\":\"0000-00-00T00:00:00+00:00\"}]}";
int temp;
char time_buf[20];
char cn_buf[50];
int cn_num[40];
struct cn_and_num cnnum[128];
OLED_weather_loading(1,0);
memset(cnnum,0,sizeof(cnnum));
memset(cn_num,-1,sizeof(cn_num));
memset(cn_buf,0,sizeof(cn_buf));
init_cnnum(cnnum,128);
Delay_ms(500);
get_city_weather(type);
OLED_weather_loading(1,1);
Delay_ms(500);
if(strncmp(usart2Buf,"{\"results\":",10) == 0){
memset(data_tmp,0,sizeof(data_tmp));
strncpy(data_tmp,usart2Buf,strlen(usart2Buf));
OLED_weather_loading(1,2);
usart2Len = 0;
}
data_parsing(data_tmp,strlen(data_tmp),time_buf,cn_buf,&temp);
OLED_weather_loading(1,3);
change_cn_num(cn_num,cn_buf,sizeof(cn_buf),cnnum,30);
OLED_weather_loading(1,4);
show_wether(cn_num,temp,time_buf);
*check = 0;
return ;
}
2.5、效果图
|