ESP8266获取天气预报信息,并使用CJSON解析天气预报数据

一、实现功能 当前文章介绍如何使用esp8266和stm32微控制器,搭配oled显示屏,制作一个能够实时显示天气预报的智能设备。将使用心知天气api来获取天气数据,并使用mqtt协议将数据传递给stm32控制器,最终在oled显示屏上显示。
心知天气是一家专业的气象数据服务提供商,致力于为全球用户提供高质量、定制化的气象数据服务。其主要产品包括天气api、空气质量api、灾害预警api等。用户可以通过心知天气的api接口,获取准确、实时的天气数据,从而为各种应用场景提供支持,例如智能家居、出行、电商等。心知天气的数据覆盖全球200多个国家和地区,每日处理超过10亿次api请求,是业内领先的气象数据服务提供商之一。
二、硬件准备 1. esp8266模块 esp8266是一款wifi模块,它具有强大的网络连接功能,可以轻松地连接到互联网。将使用esp8266模块来获取天气数据,并将其发送给stm32控制器。具体来说,我们将使用正点原子atk-esp8266模块,这是一款集成esp8266芯片的小板子。
2. stm32微控制器 stm32是一款强大的32位微控制器,具有多种接口和功能。将使用stm32f103c8t6控制器,这是一款非常流行的型号,易于获得且价格较为合理。
3. oled显示屏 oled是一种非常流行的显示技术,具有高对比度、低功耗、快速响应等优点。将使用0.96英寸128x64像素的oled显示屏。
三、cjson解析天气预报数据 3.1 接口返回的数据 {   results: [    {       location: {         id: wtemh46z5n09,         name: 合肥,         country: cn,         path: 合肥,合肥,安徽,中国,         timezone: asia/shanghai,         timezone_offset: +08:00      },       now: {         text: 阴,         code: 9,         temperature: 12,         feels_like: 18,         pressure: 1000,         humidity: 89,         visibility: 12.0,         wind_direction: 西南,         wind_direction_degree: 245,         wind_speed: 19.0,         wind_scale: 3,         clouds: 85,         dew_point:       },       last_update: 2023-04-04t14:20:13+08:00    }  ] } 3.2 cjson是什么 cjson是一款轻量级的c语言json解析器,其全称是“cjson”,由dave gamble编写。它简单易用,可嵌入到c应用程序中,既支持json字符串的解析,也支持json对象的创建及操作。cjson不依赖于任何其他的库或组件,使用它只需要引入其头文件即可。
cjson的使用方式相对来说比较简单,需要进行以下几个步骤:
 1. 在应用程序中包含cjson的头文件:#include cjson.h。 2. 调用cjson_parse函数,将json字符串转换为cjson对象。 3. 使用cjson提供的api函数对cjson对象进行操作,包括读取、修改、删除、添加等。 4. 在程序结束时,记得释放cjson对象的内存空间,避免内存泄漏。 cjson的解析速度相对较快,占用的内存开销也比较小,因此非常适用于资源有限的嵌入式系统中使用。
3.3 解析数据 使用cjson解析上述json数据非常简单,只需要按照以下步骤操作:
引入cjson库文件 ccopy code#include 解析json数据并创建cjson对象 ccopy codechar* json_data = {results:[{location:{id:wtemh46z5n09,name:合肥,country:cn,path:合肥,合肥,安徽,中国,timezone:asia/shanghai,timezone_offset:+08:00},now:{text:阴,code:9,temperature:12,feels_like:18,pressure:1000,humidity:89,visibility:12.0,wind_direction:西南,wind_direction_degree:245,wind_speed:19.0,wind_scale:3,clouds:85,dew_point:},last_update:2023-04-04t14:20:13+08:00}]}; cjson* root = cjson_parse(json_data); 在这个代码片段中,我们首先定义了一个字符串类型的变量json_data,用于存储上述json数据。然后,我们调用cjson_parse()函数来解析json数据,并将解析结果保存在root指针所指向的cjson对象中。
从cjson对象中提取数据 ccopy codecjson* location = cjson_getobjectitem(root, location); char* city = cjson_getobjectitem(location, name)->valuestring; cjson* now = cjson_getobjectitem(root, now); int temperature = cjson_getobjectitem(now, temperature)->valueint; char* text = cjson_getobjectitem(now, text)->valuestring; 在这个代码片段中,我们使用cjson_getobjectitem()函数从root指针所指向的cjson对象中提取一个名为location的json对象,并从该json对象中获取名为name的字符串类型变量。类似地,我们也可以从root指针所指向的cjson对象中提取名为now的json对象,并从该json对象中获取名为temperature和text的整型和字符串类型变量。
释放cjson对象 ccopy codecjson_delete(root); 最后,我们需要释放之前创建的cjson对象,以释放内存空间。
完整的代码示例如下:
 ccopy code#include  #include  ​ int main() {     char* json_data = {results:[{location:{id:wtemh46z5n09,name:合肥,country:cn,path:合肥,合肥,安徽,中国,timezone:asia/shanghai,timezone_offset:+08:00},now:{text:阴,code:9,temperature:12,feels_like:18,pressure:1000,humidity:89,visibility:12.0,wind_direction:西南,wind_direction_degree:245,wind_speed:19.0,wind_scale:3,clouds:85,dew_point:},last_update:2023-04-04t14:20:13+08:00}]};     cjson* root = cjson_parse(json_data); ​     cjson* location = cjson_getobjectitem(root, location);     char* city = cjson_getobjectitem(location, name)->valuestring;     cjson* now = cjson_getobjectitem(root, now);     int temperature = cjson_getobjectitem(now, temperature)->valueint;     char* text = cjson_getobjectitem(now, text)->valuestring; ​     printf(city: %sn, city);     printf(temperature: %dn, temperature);     printf(weather: %sn, text); ​     cjson_delete(root); ​     return 0; } 在这个代码示例中,使用了cjson_parse()、cjson_getobjectitem()、cjson_delete()等函数来解析和处理json数据。
3.4 获取数据 下面是esp8266访问http接口请求的代码:
 #include  ​ // 定义esp8266串口对象 softwareserial esp8266(pa10, pa9); // rx, tx ​ void setup() {   serial.begin(9600); ​   // 初始化esp8266串口通信波特率为9600   esp8266.begin(9600); ​   // 发送at指令测试esp8266是否正常工作   esp8266.println(at);   delay(500);   if (esp8266.find(ok)) {     serial.println(esp8266 is working properly.);  } else {     serial.println(esp8266 is not working properly.);  } } ​ void loop() {   // 向esp8266发送http请求   esp8266.println(at+cipstart=tcp,api.seniverse.com,80);   if (esp8266.find(ok)) {     serial.println(tcp connection established.);  } else {     serial.println(tcp connection failed.);  } ​   string url = /v3/weather/now.json?key=your_api_key&location=your_location;   string request = get + url + http/1.1rn +                    host: api.seniverse.comrn +                    user-agent: stm32/1.0rn +                    connection: closernrn;   int length = request.length();   string cmd = at+cipsend= + string(length);   esp8266.println(cmd);   if (esp8266.find(>)) {     serial.println(sending http request...);     esp8266.print(request);  } else {     serial.println(failed to send http request.);  } ​   // 接收http响应   while (esp8266.available()) {     string response = esp8266.readstringuntil('n');     serial.println(response);  } ​   // 关闭tcp连接   esp8266.println(at+cipclose);   delay(1000); } 在这个示例代码中,初始化了esp8266串口对象,并通过发送at指令测试esp8266是否正常工作。然后,在loop()函数中,向esp8266发送一个http请求,包括请求头和请求体。发送完毕后,等待esp8266返回http响应并将其打印出来。最后,关闭tcp连接并等待一秒钟,然后重复上述步骤。


又一科技巨头驶入智能汽车赛道
TE Connectivity推出LGA 3647插座产品系列
JX-100 LED贴片机将亮相2010成都NEPCON西部
数字金融,缓解企业资金压力
太阳能光伏系统的组成及其原理的介绍
ESP8266获取天气预报信息,并使用CJSON解析天气预报数据
免费的午餐!魅族官方公布首批机型名单,即日起15天内可免费更换电池
一款新型的柔性振动盘,能够快速切换生产品种
台积电高雄厂将以 2 纳米先进制程技术进行生产规划
vivo指纹解锁手机有哪些
可现场装配无须特殊工具的Han DD模块
调光、闪烁两用插座工作原理及制作
部分韩国民众请求政府否决中国私募基金收购美格纳半导体
用于 IoT 应用的住宅智能家居网关参考设计
浅谈ICA算法的概念、本质和流程
小米mix2、小米note3发布会ppt泄露:外观、配置、价格曝光,性价比依旧,发布会直播地址这里有
无线路由器wan未连接的解决办法
变频器不接负载能运行吗
中国联通公布2018年移动用户全年累计净增数约3087.3万户
谷歌宣布谷歌Pixel5将于9月30日正式发布