zoukankan      html  css  js  c++  java
  • 天气预报

    借鉴代码  菜鸟 https://blog.csdn.net/dpjcn1990/article/details/92830087

    /**
    * Demo:
    * 天气信息,并输出
    * @author lsq
    * @date 2019/12/30
    */
    #include <ESP8266WiFi.h>
    #include <ArduinoJson.h>
    #include <Adafruit_GFX.h> // Core graphics library
    #include <Adafruit_ST7735.h> // Hardware-specific library
    #include <SPI.h>
    //以下三个定义为调试定义
    #define DebugBegin(baud_rate) Serial.begin(baud_rate)
    #define DebugPrintln(message) Serial.println(message)
    #define DebugPrint(message) Serial.print(message)

    //显示屏信息
    // For the breakout, you can use any 2 or 3 pins
    // These pins will also work for the 1.8" TFT shield
    #define TFT_CS D1
    #define TFT_RST D2 // you can also connect this to the Arduino reset
    // in which case, set this #define pin to 0!
    #define TFT_DC D3

    // Option 1 (recommended): must use the hardware SPI pins
    // (for UNO thats sclk = 13 and sid = 11) and pin 10 must be
    // an output. This is much faster - also required if you want
    // to use the microSD card (see the image drawing example)
    Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);

    // Option 2: use any pins but a little slower!
    #define TFT_SCLK 13 // set these to be whatever pins you like!
    #define TFT_MOSI 11 // set these to be whatever pins you like!
    //Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST);

    #define WEATHER_CODE_DAY_SUN "0" //晴(国内城市白天晴)
    #define WEATHER_CODE_NIGHT_SUN "1" //晴(国内城市夜晚晴)
    #define WEATHER_CODE_DAY_SUN1 "2" //晴(国外城市白天晴)
    #define WEATHER_CODE_NIGHT_SUN2 "3" //晴(国外城市夜晚晴)
    #define WEATHER_CODE_CLOUDY "4" //多云
    #define WEATHER_CODE_DAY_PARTLY_CLOUDY "5" //白天晴间多云
    #define WEATHER_CODE_NIGHT_PARTLY_CLOUDY "6" //夜晚晴间多云
    #define WEATHER_CODE_DAY_MOSTLY_CLOUDY "7" //白天大部多云
    #define WEATHER_CODE_NIGHT_MOSTLY_CLOUDY "8" //夜晚大部多云
    #define WEATHER_CODE_OVERCAST "9" //阴
    #define WEATHER_CODE_SHOWER "10" //阵雨
    #define WEATHER_CODE_THUNDERSHOWER "11" //雷阵雨
    #define WEATHER_CODE_THUNDERSHOWER_WITH_HAIL "12" //雷阵雨伴有冰雹
    #define WEATHER_CODE_LIGHT_RAIN "13" //小雨
    #define WEATHER_CODE_MODERATE_RAIN "14" //中雨
    #define WEATHER_CODE_HEAVY_RAIN "15" //大雨
    #define WEATHER_CODE_STORM "16" //暴雨
    #define WEATHER_CODE_HEAVY_STORM "17" //大暴雨
    #define WEATHER_CODE_SEVERE_STORM "18" //特大暴雨
    #define WEATHER_CODE_ICE_RAIN "19" //冻雨
    #define WEATHER_CODE_SLEET "20" //雨夹雪
    #define WEATHER_CODE_SNOW_FLURRY "21" //阵雪
    #define WEATHER_CODE_LIGHT_SNOW "22" //小雪
    #define WEATHER_CODE_MODERATE_SNOW "23" //中雪
    #define WEATHER_CODE_HEAVY_SNOW "24" //大雪
    #define WEATHER_CODE_SNOW_STORM "25" //暴雪


    unsigned char quan[] = {0x01,0x00,0x02,0x00,0x1F,0xF0,0x10,0x10,0x10,0x10,0x1F,0xF0,0x10,0x10,0x10,0x10,0x1F,0xF0,0x01,0x04,0x7D,0x88,0x09,0x50,0x11,0x20,0x21,0x18,0xC5,0x06,0x02,0x00};
    unsigned char zhou[] = {0x10,0x04,0x10,0x84,0x10,0x84,0x10,0x84,0x10,0x84,0x54,0xA4,0x52,0x94,0x52,0x94,0x90,0x84,0x10,0x84,0x10,0x84,0x10,0x84,0x20,0x84,0x20,0x84,0x40,0x04,0x80,0x04};
    unsigned char wen[] = {0x00,0x00,0x23,0xF8,0x12,0x08,0x12,0x08,0x83,0xF8,0x42,0x08,0x42,0x08,0x13,0xF8,0x10,0x00,0x27,0xFC,0xE4,0xA4,0x24,0xA4,0x24,0xA4,0x24,0xA4,0x2F,0xFE,0x00,0x00};
    unsigned char du[] = {0x01,0x00,0x00,0x80,0x3F,0xFE,0x22,0x20,0x22,0x20,0x3F,0xFC,0x22,0x20,0x22,0x20,0x23,0xE0,0x20,0x00,0x2F,0xF0,0x24,0x10,0x42,0x20,0x41,0xC0,0x86,0x30,0x38,0x0E};
    unsigned char qing[] = {0x00,0x20,0x00,0x20,0x7B,0xFE,0x48,0x20,0x49,0xFC,0x48,0x20,0x4B,0xFE,0x78,0x00,0x49,0xFC,0x49,0x04,0x49,0xFC,0x49,0x04,0x79,0xFC,0x49,0x04,0x01,0x14,0x01,0x08};

    const char* ssid = "kangtine"; // XXXXXX -- 使用时请修改为当前你的 wifi ssid
    const char* password = "87602261"; // XXXXXX -- 使用时请修改为当前你的 wifi 密码
    const char* host = "api.seniverse.com";
    const char* APIKEY = "wcmquevztdy1jpca"; //API KEY
    const char* city = "quanzhou";
    const char* language = "zh-Hans";//zh-Hans 简体中文 会显示乱码
    const char* city2 = "qingdao";
    const unsigned long BAUD_RATE = 115200; // serial connection speed
    const unsigned long HTTP_TIMEOUT = 5000; // max respone time from server
    const size_t MAX_CONTENT_SIZE = 10000; // max size of the HTTP response

    // 我们要从此网页中提取的数据的类型
    struct WeatherData {
    char city[16];//城市名称
    char weather[32];//天气介绍(多云...)
    char temp[16];//温度
    char udate[32];//更新时间
    };

    WiFiClient client;
    char response[MAX_CONTENT_SIZE];
    char endOfHeaders[] = " ";

    void setup() {
    // put your setup code here, to run once:
    WiFi.mode(WIFI_STA); //设置esp8266 工作模式
    DebugBegin(BAUD_RATE);
    DebugPrint("Connecting to ");//写几句提示,哈哈
    DebugPrintln(ssid);
    WiFi.begin(ssid, password); //连接wifi
    WiFi.setAutoConnect(true);
    while (WiFi.status() != WL_CONNECTED) {
    //这个函数是wifi连接状态,返回wifi链接状态
    delay(500);
    DebugPrint(".");
    }
    DebugPrintln("");
    DebugPrintln("WiFi connected");
    delay(500);
    DebugPrintln("IP address: ");
    DebugPrintln(WiFi.localIP());//WiFi.localIP()返回8266获得的ip地址
    client.setTimeout(HTTP_TIMEOUT);


    // Use this initializer (uncomment) if you're using a 1.44" TFT
    tft.initR(INITR_144GREENTAB); // initialize a ST7735S chip, black tab

    DebugPrintln("init");


    DebugPrintln("This is a test of the rotation capabilities of the TFT library!");
    DebugPrintln("Press <SEND> (or type a character) to advance");
    //使能软件看门狗的触发间隔
    ESP.wdtEnable(5000);
    }

    void loop() {
    // put your main code here, to run repeatedly:
    //判断tcp client是否处于连接状态,不是就建立连接
    while (!client.connected()){
    if (!client.connect(host, 80)){
    DebugPrintln("connection....");
    delay(500);
    ESP.wdtFeed();
    }
    }
    //发送http请求 并且跳过响应头 直接获取响应body
    if (sendRequest(host, city2, APIKEY) && skipResponseHeaders()) {
    //清除缓冲
    clrEsp8266ResponseBuffer();
    //读取响应数据
    readReponseContent(response, sizeof(response));
    WeatherData weatherData;
    if (parseUserData(response, &weatherData)) {
    printUserData(&weatherData);
    }
    else
    {
    tft.fillScreen(ST7735_BLACK);
    tft.setCursor(0, 10);
    tft.setTextColor(ST7735_YELLOW);
    tft.setTextSize(2);
    tft.println("can't find weather ");
    delay(1000);
    }
    }

    delay(50000);//每50s调用一次
    ESP.wdtFeed();
    }

    /**
    * @发送http请求指令
    */
    bool sendRequest(const char* host, const char* cityid, const char* apiKey) {
    // We now create a URI for the request
    //心知天气 发送http请求
    String GetUrl = "/v3/weather/now.json?key=";
    GetUrl += apiKey;
    GetUrl += "&location=";
    GetUrl += city;
    GetUrl += "&language=";
    GetUrl += language;
    // This will send the request to the server
    client.print(String("GET ") + GetUrl + " HTTP/1.1 " +
    "Host: " + host + " " +
    "Connection: close ");
    DebugPrintln("create a request:");
    DebugPrintln(String("GET ") + GetUrl + " HTTP/1.1 " +
    "Host: " + host + " " +
    "Connection: close ");
    delay(1000);
    return true;
    }

    /**
    * @Desc 跳过 HTTP 头,使我们在响应正文的开头
    */
    bool skipResponseHeaders() {
    // HTTP headers end with an empty line
    bool ok = client.find(endOfHeaders);
    if (!ok) {
    DebugPrintln("No response or invalid response!");
    }
    return ok;
    }

    /**
    * @Desc 从HTTP服务器响应中读取正文
    */
    void readReponseContent(char* content, size_t maxSize) {

    size_t length = client.readBytes(content, maxSize);
    delay(1000);
    DebugPrintln("MaxSize");
    DebugPrint(client.available());
    DebugPrintln("readSize");
    DebugPrint(length);
    DebugPrintln("Get the data from Internet!");
    content[length] = 0;
    DebugPrintln(content);
    DebugPrintln("Read data Over!");
    client.flush();//清除一下缓冲
    }

    /**
    * @Desc 解析数据 Json解析
    * 数据格式如下:
    * {
    * "results": [
    * {
    * "location": {
    * "id": "WX4FBXXFKE4F",
    * "name": "北京",
    * "country": "CN",
    * "path": "北京,北京,中国",
    * "timezone": "Asia/Shanghai",
    * "timezone_offset": "+08:00"
    * },
    * "now": {
    * "text": "多云",
    * "code": "4",
    * "temperature": "23"
    * },
    * "last_update": "2017-09-13T09:51:00+08:00"
    * }
    * ]
    *}
    */
    bool parseUserData(char* content, struct WeatherData* weatherData) {
    // -- 根据我们需要解析的数据来计算JSON缓冲区最佳大小
    // 如果你使用StaticJsonBuffer时才需要
    // const size_t BUFFER_SIZE = 1024;
    // 在堆栈上分配一个临时内存池
    // StaticJsonBuffer<BUFFER_SIZE> jsonBuffer;
    // -- 如果堆栈的内存池太大,使用 DynamicJsonBuffer jsonBuffer 代替
    DynamicJsonBuffer jsonBuffer;

    JsonObject& root = jsonBuffer.parseObject(content);

    if (!root.success()) {
    DebugPrintln("JSON parsing failed!");
    return false;
    }
    if(root.containsKey("status"))
    {
    DebugPrintln("Time out");
    return false;
    }
    else
    {
    //复制我们感兴趣的字符串
    strcpy(weatherData->city, root["results"][0]["location"]["name"]);
    strcpy(weatherData->weather, root["results"][0]["now"]["text"]);
    strcpy(weatherData->temp, root["results"][0]["now"]["temperature"]);
    strcpy(weatherData->udate, root["results"][0]["last_update"]);
    // -- 这不是强制复制,你可以使用指针,因为他们是指向“内容”缓冲区内,所以你需要确保
    // 当你读取字符串时它仍在内存中
    }

    return true;
    }
    //输出中文
    void printChinese(uint x,uint y,unsigned char *Hz_code)
    {
    int tbl_size=sizeof(Hz_code)/sizeof(char);
    short int temp_code=0;
    int i,j,k;

    for(i=0;i<16;i++)
    for(j=0;j<2;j++)
    for(k=0;k<8;k++)
    if(((Hz_code[i*2+j]>>(7-k))&0x1)!=NULL)
    tft.drawPixel(x+8*j+k,y+i, ST7735_WHITE);
    }

    // 打印从JSON中提取的数据
    void printUserData(const struct WeatherData* weatherData) {

    tft.fillScreen(ST7735_BLACK);
    // Serial.println(tft.getRotation(), DEC);

    if(strcmp(weatherData->city,"泉州")==0)
    {
    //tft.WindowMax(0,30,16,46);
    tft.setCursor(0, 0);
    printChinese(4,0,quan);
    printChinese(20,0,zhou);

    tft.setCursor(44, 0);
    tft.setTextColor(ST7735_YELLOW);
    tft.setTextSize(2);
    tft.print(weatherData->temp);
    printChinese(70,0,du);

    if(strcmp(weatherData->weather,"晴")==0)
    printChinese(96,0,qing);
    }
    }

    // 关闭与HTTP服务器连接
    void stopConnect() {
    DebugPrintln("Disconnect");
    client.stop();
    }

    void clrEsp8266ResponseBuffer(void){
    memset(response, 0, MAX_CONTENT_SIZE); //清空
    }

  • 相关阅读:
    Yii2 DetailView小部件
    Yii2 数组助手类arrayHelper
    Yii2 查询构建器 QueryBuilder
    yii2 数据库和ActiveRecord
    Freemake Video Converter视频转换软件下载地址及去广告
    Photoshop独立安装包下载页面
    Photoshop快捷键整理
    json-lib和dom4j实现JSON转XML
    SpringMVC文件上传
    java http 伪造请求头
  • 原文地址:https://www.cnblogs.com/Lonelychampion/p/12120487.html
Copyright © 2011-2022 走看看