【Arduino TFT】Arduino uzlib库,用于解压gzip流,解析和风天气返回数据

忘记过去,超越自己

  • ❤️ 博客主页 单片机菜鸟哥,一个野生非专业硬件IOT爱好者 ❤️
  • ❤️ 本篇创建记录 2023-10-21 ❤️
  • ❤️ 本篇更新记录 2023-10-21 ❤️
  • 🎉 欢迎关注 🔎点赞 👍收藏 ⭐️留言📝
  • 🙏 此博客均由博主单独编写,不存在任何商业团队运营,如发现错误,请留言轰炸哦!及时修正!感谢支持!
  • 🔥 Arduino ESP8266教程累计帮助过超过1W+同学入门学习硬件网络编程,入选过选修课程,刊登过无线电杂志 🔥零基础从入门到熟悉Arduino平台下开发ESP8266,同时会涉及网络编程知识。专栏文章累计超过60篇,分为基础篇、网络篇、应用篇、高级篇,涵盖ESP8266大部分开发技巧。

快速导航
单片机菜鸟的博客快速索引(快速找到你要的)

如果觉得有用,麻烦点赞收藏,您的支持是博主创作的动力。

1. 前言

在做和风天气获取天气信息的时候,由于和风天气采用Gzip压缩方式返回数据流,返回的数据需要解压。

默认,已经申请了和风天气免费Key
https://dev.qweather.com/docs/api/weather/weather-now/
在这里插入图片描述

而刚好有一个Arduino库用于这种功能,

https://github.com/tignioj/ArduinoUZlib
在这里插入图片描述

2. 相关代码

和风天气API采用HTTPS方式获取相关天气数据,并且返回数据采用GZIP压缩方式。
获取数据后,使用UZlib库里的 int result=ArduinoUZlib::decompress(inbuff, size, outbuf,outsize);函数进行解压。

HeFeng.h代码


#pragma once
#include <ArduinoJson.h>

typedef struct HeFengCurrentData {

  String cond_txt;
  String fl;
  String tmp;
  String hum;
  String wind_sc;
  String iconMeteCon;
}
HeFengCurrentData;
typedef struct HeFengForeData {
  String dateStr;
  String tmp_min;
  String tmp_max;
  String iconMeteCon;

}
HeFengForeData;
class HeFeng {
  private:
    String getMeteConIcon(String cond_code);
    bool fetchBuffer(const char* url);
    static uint8_t _buffer[1024 * 3]; //gzip流最大缓冲区
    static size_t _bufferSize;
  public:
    HeFeng();
    void doUpdateCurr(HeFengCurrentData *data, String key, String location);
    void doUpdateFore(HeFengForeData *data, String key, String location);
};

HeFeng.cpp代码


#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClientSecureBearSSL.h>
#include "ArduinoUZlib.h" // gzip库
#include "HeFeng.h"

uint8_t HeFeng::_buffer[1024 * 3];
size_t HeFeng::_bufferSize = 0;

HeFeng::HeFeng() {
}

bool HeFeng::fetchBuffer(const char *url)
{
    _bufferSize = 0;
    std::unique_ptr<WiFiClientSecure> client(new WiFiClientSecure);
    client->setInsecure();
    HTTPClient https;
    Serial.print("[HTTPS] begin...now\n");
    if (https.begin(*client, url))
    {
        https.addHeader("Accept-Encoding", "gzip");
        https.setUserAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/115.0");
        int httpCode = https.GET();
        if (httpCode > 0)
        {
            if (httpCode == HTTP_CODE_OK)
            {
                int len = https.getSize(); // get length of document (is -1 when Server sends no Content-Length header)
                static uint8_t buff[128 * 1] = {0}; // create buffer for read
                int offset = 0;                 // read all data from server
                while (https.connected() && (len > 0 || len == -1))
                {
                    size_t size = client->available(); // get available data size
                    if (size)
                    {
                        int c = client->readBytes(buff, ((size > sizeof(buff)) ? sizeof(buff) : size));
                        memcpy(_buffer + offset, buff, sizeof(uint8_t) * c);
                        offset += c;
                        if (len > 0)
                        {
                            len -= c;
                        }
                    }
                    delay(1);
                }
                _bufferSize = offset;
            }
        }
        else
        {
            Serial.printf("[HTTPS] GET... failed, error: %s\n", https.errorToString(httpCode).c_str());
        }
        https.end();
    }else{
        Serial.printf("Unable to connect\n");
    }
    Serial.print("[HTTPS] end...now\n");
    return _bufferSize > 0;
}

void HeFeng::doUpdateCurr(HeFengCurrentData *data, String key, String location) {  //获取天气

  String url = "https://devapi.qweather.com/v7/weather/now?lang=en&gzip=n&location=" + location + "&key=" + key;
  Serial.print("[HTTPS] begin...now\n");
  fetchBuffer(url.c_str()); // HTTPS获取数据流
  if (_bufferSize){
     Serial.print("bufferSize:");
     Serial.println(_bufferSize, DEC);
     uint8_t *outBuf=NULL;
     size_t outLen = 0;
     ArduinoUZlib::decompress(_buffer, _bufferSize, outBuf, outLen); // GZIP解压
     // 输出解密后的数据到控制台。
     Serial.write(outBuf,outLen);
     if(outBuf && outLen){
         DynamicJsonDocument  jsonBuffer(2048);
         deserializeJson(jsonBuffer, (char*)outBuf,outLen);
         JsonObject root = jsonBuffer.as<JsonObject>();

         String tmp = root["now"]["temp"];//温度
         data->tmp = tmp;
         String fl = root["now"]["feelsLike"];//体感温度
         data->fl = fl;
         String hum = root["now"]["humidity"];//湿度
         data->hum = hum;
         String wind_sc = root["now"]["windScale"];//风力
         data->wind_sc = wind_sc;
         String cond_code = root["now"]["icon"];//天气图标
         String meteConIcon = getMeteConIcon(cond_code);
         String cond_txt = root["now"]["text"];//天气
         data->cond_txt = cond_txt;
         data->iconMeteCon = meteConIcon;

         jsonBuffer.clear();
      } else {
         Serial.println("doUpdateCurr failed");
         data->tmp = "-1";
         data->fl = "-1";
         data->hum = "-1";
         data->wind_sc = "-1";
         data->cond_txt = "no network";
         data->iconMeteCon = ")";
      }
      //一定要记得释放内存
      if(outBuf != NULL) {
         free(outBuf);
         outBuf=NULL;
      }
     _bufferSize = 0;
  }
}

void HeFeng::doUpdateFore(HeFengForeData *data, String key, String location) {  //获取预报

  String url = "https://devapi.qweather.com/v7/weather/3d?lang=en&gzip=n&location=" + location + "&key=" + key;
  Serial.print("[HTTPS] begin...forecast\n");
  fetchBuffer(url.c_str()); // HTTPS获取数据流
  if (_bufferSize){
     Serial.print("bufferSize:");
     Serial.println(_bufferSize, DEC);
     uint8_t *outBuf=NULL;
     size_t outLen = 0;
     ArduinoUZlib::decompress(_buffer, _bufferSize, outBuf, outLen); // GZIP解压
     // 输出解密后的数据到控制台。
     Serial.write(outBuf,outLen);
     if(outBuf && outLen){
         DynamicJsonDocument  jsonBuffer(2048);
         deserializeJson(jsonBuffer, (char*)outBuf,outLen);
         JsonObject root = jsonBuffer.as<JsonObject>();

         int i;
         for (i = 0; i < 3; i++) {
           String dateStr = root["daily"][i]["fxDate"];
           data[i].dateStr = dateStr.substring(5, dateStr.length());
           String tmp_min = root["daily"][i]["tempMin"];
           data[i].tmp_min = tmp_min;
           String tmp_max = root["daily"][i]["tempMax"];
           data[i].tmp_max = tmp_max;
           String cond_code = root["daily"][i]["iconDay"];
           String meteConIcon = getMeteConIcon(cond_code);
           data[i].iconMeteCon = meteConIcon;
         }

         jsonBuffer.clear();
      } else {
         int i;
         for (i = 0; i < 3; i++) {
           data[i].tmp_min = "-1";
           data[i].tmp_max = "-1";
           data[i].dateStr = "N/A";
           data[i].iconMeteCon = ")";
         }
      }
      //一定要记得释放内存
      if(outBuf != NULL) {
         free(outBuf);
         outBuf=NULL;
      }
     _bufferSize = 0;
  }
}

String HeFeng::getMeteConIcon(String cond_code) {  //获取天气图标  见 https://dev.qweather.com/docs/start/icons/
  if (cond_code == "100" || cond_code == "150" || cond_code == "9006") {//晴 Sunny/Clear
    return "B";
  }
  if (cond_code == "101") {//多云 Cloudy
    return "Y";
  }
  if (cond_code == "102") {//少云 Few Clouds
    return "N";
  }
  if (cond_code == "103" || cond_code == "153") {//晴间多云 Partly Cloudy/
    return "H";
  }
  if (cond_code == "104" || cond_code == "154") {//阴 Overcast
    return "D";
  }
  if (cond_code == "300" || cond_code == "301") {//阵雨 Shower Rain 301-强阵雨 Heavy Shower Rain
    return "T";
  }
  if (cond_code == "302" || cond_code == "303") {//302-雷阵雨  Thundershower / 303-强雷阵雨
    return "P";
  }
  if (cond_code == "304" || cond_code == "313" || cond_code == "404" || cond_code == "405" || cond_code == "406") {
    //304-雷阵雨伴有冰雹 Freezing Rain
    //313-冻雨 Freezing Rain
    //404-雨夹雪 Sleet
    //405-雨雪天气 Rain And Snow
    //406-阵雨夹雪  Shower Snow
    return "X";
  }
  if (cond_code == "305" || cond_code == "308" || cond_code == "309" || cond_code == "314" || cond_code == "399") {
    //305-小雨 Light Rain
    //308-极端降雨 Extreme Rain
    //309-毛毛雨/细雨 Drizzle Rain
    //314-小到中雨 Light to moderate rain
    //399-雨 Light to moderate rain
    return "Q";
  }
  if (cond_code == "306" || cond_code == "307" || cond_code == "310" || cond_code == "311" || cond_code == "312" || cond_code == "315" || cond_code == "316" || cond_code == "317" || cond_code == "318") {
    //306-中雨 Moderate Rain
    //307-大雨 Heavy Rain
    //310-暴雨  Storm
    //311-大暴雨 Heavy Storm
    //312-特大暴雨 Severe Storm
    //315-中到大雨 Moderate to heavy rain
    //316-大到暴雨 Heavy rain to storm
    //317-暴雨到大暴雨 Storm to heavy storm
    //318-大暴雨到特大暴雨 Heavy to severe storm
    return "R";
  }
  if (cond_code == "400" || cond_code == "408") {
    //400-小雪 Light Snow
    //408-小到中雪 Light to moderate snow
    return "U";
  }
  if (cond_code == "401" || cond_code == "402" || cond_code == "403" || cond_code == "409" || cond_code == "410") {
    //401-中雪 Moderate Snow
    //402-大雪 Heavy Snow
    //403-暴雪 Snowstorm
    //409-中到大雪 Moderate to heavy snow
    //410-大到暴雪 Heavy snow to snowstorm
    return "W";
  }
  if (cond_code == "407") {
    //407-阵雪 Snow Flurry
    return "V";
  }
  if (cond_code == "499" || cond_code == "901") {
    //499-雪 Snow
    //901-冷 Cold
    return "G";
  }
  if (cond_code == "500") {
    //500-薄雾 Mist
    return "E";
  }
  if (cond_code == "501" || cond_code == "509" || cond_code == "510" || cond_code == "514" || cond_code == "515") {
    //501-雾 Foggy
    return "M";
  }
  if (cond_code == "502" || cond_code == "511" || cond_code == "512" || cond_code == "513") {
    //502-霾 Haze
    return "L";
  }
  if (cond_code == "503" || cond_code == "504" || cond_code == "507" || cond_code == "508") {
    //503-扬沙 Sand
    return "F";
  }
  
  if (cond_code == "999") {//未知
    return ")";
  }
  if (cond_code == "213") {
    return "O";
  }
  if (cond_code == "200" || cond_code == "201" || cond_code == "202" || cond_code == "203" || cond_code == "204" || cond_code == "205" || cond_code == "206" || cond_code == "207" || cond_code == "208" || cond_code == "209" || cond_code == "210" || cond_code == "211" || cond_code == "212") {
    return "S";
  }
  return ")";
}

  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
Arduino TFT是一个用于控制液晶触摸屏显示的。它可以与各种TFT液晶屏幕一起使用,例如ILI9341、ILI9488等。使用这个,你可以在Arduino上显示图形、文本和图像,并且还可以通过触摸屏进行交互。 TFT提供了一系列函数和方法来控制液晶屏的各种功能,如绘制形状、显示文本、设置背光亮度等。它还支持触摸屏的输入,可以检测触摸位置和手势操作。 要使用TFT,首先需要下载并安装它。你可以在Arduino官方网站上找到这个,并通过Arduino IDE的管理器进行安装。安装完成后,你就可以在代码中引用TFT,并使用它提供的函数和方法来控制液晶屏了。 下面是一个简单的示例代码,演示了如何使用TFT在液晶屏上显示文本: ```cpp #include <Adafruit_GFX.h> // 引用TFT #include <Adafruit_ILI9341.h> // 引用具体的液晶屏驱动 // 定义液晶屏引脚连接 #define TFT_CLK 13 #define TFT_MISO 12 #define TFT_MOSI 11 #define TFT_CS 10 #define TFT_DC 9 #define TFT_RST 8 // 创建液晶屏对象 Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CLK, TFT_MISO, TFT_MOSI, TFT_CS, TFT_DC, TFT_RST); void setup() { // 初始化液晶屏 tft.begin(); // 设置文本颜色和大小 tft.setTextColor(ILI9341_WHITE); tft.setTextSize(2); // 清空屏幕并显示文本 tft.fillScreen(ILI9341_BLACK); tft.setCursor(50, 50); tft.println("Hello, TFT!"); } void loop() { // 无需循环执行任何操作 } ``` 这只是一个简单的示例,你可以根据自己的需求来使用TFT进行更复杂的操作,如绘制图形、显示图像等。希望能对你有所帮助!如果你有更多问题,请随时提问。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

单片机菜鸟哥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值