W801 实现获取天气情况

        看了小安派(AiPi-Eyes 天气站)的源码,感觉用W801也可以实现。

一、部分源码

main.c

#include "wm_include.h"
#include "Lcd_Driver.h"

void UserMain(void)
{
	printf("\n user task \n");

	Lcd_Init();
	Lcd_Clear(RED);

	CreateWeatherTask();
}

 weather.c(该文件需保存为UTF8格式)

#include "Lcd_Driver.h"
#include "wm_include.h"
#include "LCD_calculate.h"
#include "cJSON.h"
#include "ctype.h"


#define SSID		"SSID"
#define PASSWORD 	"PASSWORD"

#define HTTPURL		"http://v1.yiketianqi.com/api?unescape=1&version=v61&appid=此处需替换为自己的KEY"

#define    DEMO_TASK_SIZE      2048
static tls_os_queue_t 	*weather_q = NULL;
static OS_STK 			WeatherTaskStk[DEMO_TASK_SIZE];


extern int demo_connect_net(void *, ...);
extern int http_get_demo(void *, ...);





/**
 * @brief
 *
 * @param weather_data
*/
void cjson_get_weather(char* weather_data)
{
	cJSON * item = NULL;//cjson对象

    cJSON* root = cJSON_Parse(weather_data );
	
	if (!root) 
	{
		//printf("Error before: [%s]\n",cJSON_GetErrorPtr());
	}
	else
	{
		Gui_DrawFont_GBK16(5,95,WHITE,RED,"                           ");
			
		item = cJSON_GetObjectItem(root, "city");			//城市
		Gui_DrawFont_utf8_3bytes_16(5,15,WHITE,RED,item->valuestring);
		
		item = cJSON_GetObjectItem(root, "cityEn");			//城市英文
		Gui_DrawFont_utf8_3bytes_16(40,15,WHITE,RED,item->valuestring);

		item = cJSON_GetObjectItem(root, "wea");
		Gui_DrawFont_utf8_3bytes_16(5,35,WHITE,RED,"天气:");
		Gui_DrawFont_utf8_3bytes_16(60,35,WHITE,RED,item->valuestring);
		
		item = cJSON_GetObjectItem(root, "tem");			//温度
		Gui_DrawFont_utf8_3bytes_16(5,55,WHITE,RED,"温度:");
		Gui_DrawFont_GBK24(60,55,WHITE,RED,item->valuestring);
		Gui_DrawFont_utf8_3bytes_16(100,55,WHITE,RED,"℃");
		
		item = cJSON_GetObjectItem(root, "win");			//风
		Gui_DrawFont_utf8_3bytes_16(5,75,WHITE,RED,item->valuestring);
		
		item = cJSON_GetObjectItem(root, "air_level");		//空气质量
		Gui_DrawFont_utf8_3bytes_16(69,75,WHITE,RED,item->valuestring);
		
	}
	
	cJSON_free(item);
    cJSON_Delete(root);
	
}





void weather_task(void *sdata)
{
	Gui_DrawFont_GBK16(5,95,WHITE,RED,"Start......                     ");

	if(demo_connect_net(SSID,PASSWORD)==WM_SUCCESS)
	{
		Gui_DrawFont_GBK16(5,95,WHITE,RED,"Connected                    ");
		tls_os_time_delay(3000);
		http_get_demo(HTTPURL);
	}
	
    for(;;)
    {

		tls_os_time_delay(100);
	}	
}

 void CreateWeatherTask(void)
{
    tls_os_queue_create(&weather_q, DEMO_QUEUE_SIZE);
    tls_os_task_create(NULL, NULL,
                       weather_task,
                       NULL,
                       (void *)WeatherTaskStk,          /* task's stack start address */
                       DEMO_TASK_SIZE * sizeof(u32), /* task's stack size, unit:byte */
                       DEMO_TASK_PRIO,
                       0);
}


 Gui_DrawFont_utf8_3bytes_16函数,用来显示3字节UTF8编码的汉字

void Gui_DrawFont_utf8_3bytes_16(unsigned int x, unsigned int y, unsigned int fc, unsigned int bc, char *s)
{
	unsigned char i,j;
	unsigned short k,x0;
	x0=x;

	while(*s) 
	{	
		for (k=0;k<sizeof(UTF8_hz16)/sizeof(UTF8_hz16[0]);k++) 
		{
			if ((UTF8_hz16[k].Index[0]==*s)&&(UTF8_hz16[k].Index[1]==*(s+1))&&(UTF8_hz16[k].Index[2]==*(s+2)))
			{ 
				for(i=0;i<16;i++)
				{
					for(j=0;j<8;j++) 
					{
						if(UTF8_hz16[k].Msk[i*2]&(0x80>>j))	Gui_DrawPoint(x+j,y+i,fc);
						else {
							if (fc!=bc) Gui_DrawPoint(x+j,y+i,bc);
						}
					}
					for(j=0;j<8;j++) 
					{
						if(UTF8_hz16[k].Msk[i*2+1]&(0x80>>j))	Gui_DrawPoint(x+j+8,y+i,fc);
						else 
						{
							if (fc!=bc) Gui_DrawPoint(x+j+8,y+i,bc);
						}
					}
				}
				break;
			}
		}
		if(k!=sizeof(UTF8_hz16)/sizeof(UTF8_hz16[0]))
		{
			s+=3;x+=16;
		}
		else		//ASC字符
		{
			k=*s;
			if (k>32) k-=32; else k=0;

			for(i=0;i<16;i++)
			for(j=0;j<8;j++) 
			{
				if(asc16[k*16+i]&(0x80>>j))	
				Gui_DrawPoint(x+j,y+i,fc);
				else 
				{
					if (fc!=bc) Gui_DrawPoint(x+j,y+i,bc);
				}
			}
			s++;x+=8;
		}
	}
}

 字模文件(UTF8格式文件)

#ifndef __FONTUTF8_H__
#define __FONTUTF8_H__

struct typFNT_UrlCode
{
       unsigned char Index[3];	
       char Msk[32];
};
//阴码、逐行、顺向
const struct typFNT_UrlCode UTF8_hz16[] = {

"城",0x20,0x28,0x20,0x24,0x20,0x20,0x27,0xFE,0x24,0x20,0xFC,0x20,0x24,0x24,0x27,0xA4,0x24,0xA4,0x24,0xA8,0x24,0xA8,0x3C,0x90,0xE6,0x92,0x49,0x2A,0x08,0x46,0x10,0x82,/*"城",0*/
"市",0x02,0x00,0x01,0x00,0x00,0x00,0x7F,0xFC,0x01,0x00,0x01,0x00,0x01,0x00,0x3F,0xF8,0x21,0x08,0x21,0x08,0x21,0x08,0x21,0x08,0x21,0x28,0x21,0x10,0x01,0x00,0x01,0x00,/*"市",1*/
"京",0x02,0x00,0x01,0x00,0xFF,0xFE,0x00,0x00,0x00,0x00,0x1F,0xF0,0x10,0x10,0x10,0x10,0x10,0x10,0x1F,0xF0,0x01,0x00,0x11,0x10,0x11,0x08,0x21,0x04,0x45,0x04,0x02,0x00,/*"京",1*/

}
#endif

在wm_sdk_w80x_20211115\demo\wm_http_demo.c中http_snd_req函数,增加一行:cjson_get_weather(Buffer);用于处理返回的json信息。


u32 http_snd_req(HTTPParameters ClientParams, HTTP_VERB verb, char *pSndData, u8 parseXmlJson)
{
    int                   nRetCode;
    u32                   nSize, nTotal = 0;
    char                 *Buffer = NULL;
    HTTP_SESSION_HANDLE   pHTTP;
    u32                   nSndDataLen ;
    do
    {
        Buffer = (char *)tls_mem_alloc(HTTP_CLIENT_BUFFER_SIZE);
        if(Buffer == NULL)
        {
            return HTTP_CLIENT_ERROR_NO_MEMORY;
        }
        memset(Buffer, 0, HTTP_CLIENT_BUFFER_SIZE);
        printf("HTTP Client v1.0\r\n");
        nSndDataLen = (pSndData == NULL ? 0 : strlen(pSndData));
        // Open the HTTP request handle
        pHTTP = HTTPClientOpenRequest(0);
        if(!pHTTP)
        {
            nRetCode =  HTTP_CLIENT_ERROR_INVALID_HANDLE;
            break;
        }
        // Set the Verb
        nRetCode = HTTPClientSetVerb(pHTTP, verb);
        if(nRetCode != HTTP_CLIENT_SUCCESS)
        {
            break;
        }
#if TLS_CONFIG_HTTP_CLIENT_AUTH
        // Set authentication
        if(ClientParams.AuthType != AuthSchemaNone)
        {
            if((nRetCode = HTTPClientSetAuth(pHTTP, ClientParams.AuthType, NULL)) != HTTP_CLIENT_SUCCESS)
            {
                break;
            }

            // Set authentication
            if((nRetCode = HTTPClientSetCredentials(pHTTP, ClientParams.UserName, ClientParams.Password)) != HTTP_CLIENT_SUCCESS)
            {
                break;
            }
        }
#endif //TLS_CONFIG_HTTP_CLIENT_AUTH
#if TLS_CONFIG_HTTP_CLIENT_PROXY
        // Use Proxy server
        if(ClientParams.UseProxy == TRUE)
        {
            if((nRetCode = HTTPClientSetProxy(pHTTP, ClientParams.ProxyHost, ClientParams.ProxyPort, NULL, NULL)) != HTTP_CLIENT_SUCCESS)
            {

                break;
            }
        }
#endif //TLS_CONFIG_HTTP_CLIENT_PROXY
        if((nRetCode = HTTPClientSendRequest(pHTTP, ClientParams.Uri, pSndData, nSndDataLen, verb == VerbPost || verb == VerbPut, 0, 0)) != HTTP_CLIENT_SUCCESS)
        {
            break;
        }
        // Retrieve the the headers and analyze them
        if((nRetCode = HTTPClientRecvResponse(pHTTP, 30)) != HTTP_CLIENT_SUCCESS)
        {
            break;
        }
        printf("Start to receive data from remote server...\r\n");

        // Get the data until we get an error or end of stream code
        while(nRetCode == HTTP_CLIENT_SUCCESS || nRetCode != HTTP_CLIENT_EOS)
        {
            // Set the size of our buffer
            nSize = HTTP_CLIENT_BUFFER_SIZE;
            // Get the data
            nRetCode = HTTPClientReadData(pHTTP, Buffer, nSize, 300, &nSize);
            if(nRetCode != HTTP_CLIENT_SUCCESS && nRetCode != HTTP_CLIENT_EOS)
                break;
          
			
			cjson_get_weather(Buffer);        //增加了这一句
            nTotal += nSize;
        }
    }
    while(0);   // Run only once
    tls_mem_free(Buffer);

    if(pHTTP)
        HTTPClientCloseRequest(&pHTTP);
    if(ClientParams.Verbose == TRUE)
    {
        printf("\n\nHTTP Client terminated %d (got %d b)\n\n", nRetCode, nTotal);
    }
    return nRetCode;
}

二、说明 

1、W801的SDK中DEMO程序有2个函数可以直接用:

extern int demo_connect_net(void *, ...);    //用于连上wifi
extern int http_get_demo(void *, ...);       //用于打开网页获得数据

本质也是lwip。

2、W801的实时操作系统底层还是freertos,只是SDK对freertos进行了封装。。

3、SDK中自带了cjson,但是版本太低,最好替换为最新的。

4、一般显示汉字的部分都是GB2312编码,但是从yiketianqi.com/获取的json格式是UTF8的,所以修改了所有相关函数、字模为UTF8编码。

5、程序修改自SDK 的DEMO,还在整理中。

6、程序烧写及调试信息:

  • 9
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值