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

本文涉及的产品
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 当前文章介绍如何使用ESP8266和STM32微控制器,搭配OLED显示屏,制作一个能够实时显示天气预报的智能设备。将使用心知天气API来获取天气数据,并使用MQTT协议将数据传递给STM32控制器,最终在OLED显示屏上显示。

一、实现功能

当前文章介绍如何使用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数据非常简单,只需要按照以下步骤操作:

  1. 引入CJSON库文件
#include <cJSON.h>
  1. 解析JSON数据并创建cJSON对象
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);

在这个代码片段中,首先定义了一个字符串类型的变量json_data,用于存储上述JSON数据。然后,调用cJSON_Parse()函数来解析JSON数据,并将解析结果保存在root指针所指向的cJSON对象中。

  1. 从cJSON对象中提取数据
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;

在这个代码片段中,使用cJSON_GetObjectItem()函数从root指针所指向的cJSON对象中提取一个名为location的JSON对象,并从该JSON对象中获取名为name的字符串类型变量。类似地,也可以从root指针所指向的cJSON对象中提取名为now的JSON对象,并从该JSON对象中获取名为temperaturetext的整型和字符串类型变量。

  1. 释放cJSON对象
cJSON_Delete(root);

最后,需要释放之前创建的cJSON对象,以释放内存空间。

完整的代码示例如下:

#include <cJSON.h>
#include <stdio.h>

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: %s\n", city);
    printf("Temperature: %d\n", temperature);
    printf("Weather: %s\n", text);

    cJSON_Delete(root);

    return 0;
}

在这个代码示例中,使用了cJSON_Parse()cJSON_GetObjectItem()cJSON_Delete()等函数来解析和处理JSON数据。

3.4 获取数据

下面是ESP8266访问HTTP接口请求的代码:

#include <SoftwareSerial.h>

// 定义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.1\r\n" +
                   "Host: api.seniverse.com\r\n" +
                   "User-Agent: STM32/1.0\r\n" +
                   "Connection: close\r\n\r\n";
  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连接并等待一秒钟,然后重复上述步骤。

目录
相关文章
|
28天前
|
人工智能 自然语言处理 前端开发
SpringBoot + 通义千问 + 自定义React组件:支持EventStream数据解析的技术实践
【10月更文挑战第7天】在现代Web开发中,集成多种技术栈以实现复杂的功能需求已成为常态。本文将详细介绍如何使用SpringBoot作为后端框架,结合阿里巴巴的通义千问(一个强大的自然语言处理服务),并通过自定义React组件来支持服务器发送事件(SSE, Server-Sent Events)的EventStream数据解析。这一组合不仅能够实现高效的实时通信,还能利用AI技术提升用户体验。
143 2
|
13天前
|
自然语言处理 数据可视化 前端开发
从数据提取到管理:合合信息的智能文档处理全方位解析【合合信息智能文档处理百宝箱】
合合信息的智能文档处理“百宝箱”涵盖文档解析、向量化模型、测评工具等,解决了复杂文档解析、大模型问答幻觉、文档解析效果评估、知识库搭建、多语言文档翻译等问题。通过可视化解析工具 TextIn ParseX、向量化模型 acge-embedding 和文档解析测评工具 markdown_tester,百宝箱提升了文档处理的效率和精确度,适用于多种文档格式和语言环境,助力企业实现高效的信息管理和业务支持。
3935 2
从数据提取到管理:合合信息的智能文档处理全方位解析【合合信息智能文档处理百宝箱】
|
3天前
|
存储 分布式计算 Java
存算分离与计算向数据移动:深度解析与Java实现
【11月更文挑战第10天】随着大数据时代的到来,数据量的激增给传统的数据处理架构带来了巨大的挑战。传统的“存算一体”架构,即计算资源与存储资源紧密耦合,在处理海量数据时逐渐显露出其局限性。为了应对这些挑战,存算分离(Disaggregated Storage and Compute Architecture)和计算向数据移动(Compute Moves to Data)两种架构应运而生,成为大数据处理领域的热门技术。
17 2
|
9天前
|
JavaScript API 开发工具
<大厂实战场景> ~ Flutter&鸿蒙next 解析后端返回的 HTML 数据详解
本文介绍了如何在 Flutter 中解析后端返回的 HTML 数据。首先解释了 HTML 解析的概念,然后详细介绍了使用 `http` 和 `html` 库的步骤,包括添加依赖、获取 HTML 数据、解析 HTML 内容和在 Flutter UI 中显示解析结果。通过具体的代码示例,展示了如何从 URL 获取 HTML 并提取特定信息,如链接列表。希望本文能帮助你在 Flutter 应用中更好地处理 HTML 数据。
92 1
|
22天前
|
人工智能 前端开发 JavaScript
拿下奇怪的前端报错(一):报错信息是一个看不懂的数字数组Buffer(475) [Uint8Array],让AI大模型帮忙解析
本文介绍了前端开发中遇到的奇怪报错问题,特别是当错误信息不明确时的处理方法。作者分享了自己通过还原代码、试错等方式解决问题的经验,并以一个Vue3+TypeScript项目的构建失败为例,详细解析了如何从错误信息中定位问题,最终通过解读错误信息中的ASCII码找到了具体的错误文件。文章强调了基础知识的重要性,并鼓励读者遇到类似问题时不要慌张,耐心分析。
|
26天前
|
数据采集 XML 前端开发
Jsoup在Java中:解析京东网站数据
Jsoup在Java中:解析京东网站数据
|
9天前
|
JSON 前端开发 JavaScript
API接口商品详情接口数据解析
商品详情接口通常用于提供特定商品的详细信息,这些信息比商品列表接口中的信息更加详细和全面。以下是一个示例的JSON数据格式,用于表示一个商品详情API接口的响应。这个示例假定API返回一个包含商品详细信息的对象。
|
22天前
|
API
Vue3组件通信全解析:利用props、emit、provide/inject跨层级传递数据,expose与ref实现父子组件方法调用
Vue3组件通信全解析:利用props、emit、provide/inject跨层级传递数据,expose与ref实现父子组件方法调用
260 0
|
22天前
|
前端开发 算法 JavaScript
无界SaaS模式深度解析:算力算法、链接力、数据确权制度
私域电商的无界SaaS模式涉及后端开发、前端开发、数据库设计、API接口、区块链技术、支付和身份验证系统等多个技术领域。本文通过简化框架和示例代码,指导如何将核心功能转化为技术实现,涵盖用户管理、企业店铺管理、数据流量管理等关键环节。
|
28天前
|
缓存 Java 程序员
Map - LinkedHashSet&Map源码解析
Map - LinkedHashSet&Map源码解析
62 0

热门文章

最新文章

推荐镜像

更多