esp8266气象站2
承接上一篇,使用的数据源仍然是心知天气提供的数据接口,可以每分钟查询20次,也就是做多3s请求一次数据
替换原有的nodemcu,使用了ttgo-display,芯片esp32,自带一个1.14‘的ips显示屏
2,实现查询最近三天的天气信息,串口终端以及tft显示,界面还有问题,下次换屏。
通过轮询的方式查询多地的天气,
3,存在的问题,tft_espi显示函数不太熟悉,缺少全面的函数调用说明/应该可以找到吧,依然是一个测试版本。
4,改进,下一版本准备中文字库,或许添加图标
/* esp32 weather station * 191130,ver2 * ttgo_版本,同时查询四个城市的天气状况,使用心天气api * 串口打印所有的天气信息 * 适配ttgo屏幕 */ // Libraries //#include <ESP8266WiFi.h> #include <WiFi.h> //esp32used #include <HTTPClient.h> #include <ArduinoJson.h> //使用ArduinoJson库 #include <TFT_eSPI.h> // Graphics and font library for ST7735 driver chip #include <SPI.h> #include <Button2.h> #ifndef TFT_DISPOFF #define TFT_DISPOFF 0x28 #endif #ifndef TFT_SLPIN #define TFT_SLPIN 0x10 #endif #define TFT_MOSI 19 #define TFT_SCLK 18 #define TFT_CS 5 #define TFT_DC 16 #define TFT_RST 23 #define TFT_BL 4 // Display backlight control pin #define ADC_EN 14 #define ADC_PIN 34 #define BUTTON_1 35 #define BUTTON_2 0 #define TFT_GREY 0x5AEB // New colour #define MAX_CONTENT_SIZE 2000 TFT_eSPI tft = TFT_eSPI(135,240); // Invoke library, pins defined in User_Setup.h Button2 btn1(BUTTON_1); Button2 btn2(BUTTON_2); int btnCick = false; // WiFi settings const char* ssid = "xxxxxx"; const char* password = "12345677"; // API server const char* host = "api.seniverse.com"; const char* API_key = "xyMNfwsL07QDmljCq"; //查询城市 const char* req_city0 = "hangzhou"; const char* req_city1 = "jilin"; const char* req_city2 = "hefei"; const char* req_city3 = "wuhan"; //选择语言 //const char* language = "en"; const char* language = "zh-Hans"; String weather_data; HTTPClient http; char response[MAX_CONTENT_SIZE]; // void espDelay(int ms) { esp_sleep_enable_timer_wakeup(ms * 1000); esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH,ESP_PD_OPTION_ON); esp_light_sleep_start(); } //---------------------------------------------按键操作函数 /* void button_init() { btn1.setLongClickHandler([](Button2 & b) { btnCick = false; int r = digitalRead(TFT_BL); tft.fillScreen(TFT_BLACK); tft.setTextColor(TFT_GREEN, TFT_BLACK); tft.setTextDatum(MC_DATUM); tft.drawString("Press again to wake up", tft.width() / 2, tft.height() / 2 ); espDelay(6000); digitalWrite(TFT_BL, !r); tft.writecommand(TFT_DISPOFF); tft.writecommand(TFT_SLPIN); esp_sleep_enable_ext1_wakeup(GPIO_SEL_35, ESP_EXT1_WAKEUP_ALL_LOW); esp_deep_sleep_start(); }); btn1.setPressedHandler([](Button2 & b) { Serial.println("Detect Voltage.."); btnCick = true; }); btn2.setPressedHandler([](Button2 & b) { btnCick = false; Serial.println("btn press wifi scan"); wifi_scan(); }); } void button_loop() { btn1.loop(); btn2.loop(); } */ //-------------------------------连接wifi设置 void connect_wifi(){ Serial.print("Connecting to WIFI"); Serial.println(ssid); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(1000); Serial.print("."); } Serial.println(""); Serial.println("WiFi connected"); Serial.println("IP address: "); Serial.println(WiFi.localIP()); } //----------------------------------------------------连接到服务器 void connect_API(){ // Connect to API Serial.print("connecting to XinZhi"); Serial.println(host); // Use WiFiClient class to create TCP connections WiFiClient client; const int httpPort = 80; if (!client.connect(host, httpPort)) { Serial.println("connection failed"); return; } } //----------------------------------------------------获取返回数据 String sendRequest(const char* host, const char* cityid, const char* apiKey) { //const char *response; char *Url = (char *)malloc(0x100); String payload; //https://api.seniverse.com/v3/weather/daily.json?key=SyMNfwsL07QDmljCq&location=beijing&language=zh-Hans&unit=c&start=0&days=3 sprintf(Url,"%s%s%s%s%s%s%s","http://",host,"/v3/weather/daily.json?key=",apiKey,"&location=",cityid,"&language=en&unit=c&start=0&days=3"); Serial.printf("GET URL: %s\n",Url); http.begin(Url); int httpCode = http.GET(); if(httpCode>0){ Serial.printf("[HTTP] GET... code: %d\n",httpCode); if(httpCode == 200){ payload = http.getString(); Serial.println(payload); }else{ delay(5000); sendRequest(host,cityid,apiKey); } }else{ delay(5000); sendRequest(host,cityid,apiKey); } strcpy(response,payload.c_str()); // convert to const char * free(Url); return payload; } //----------------------------------------------------切片解析来自arduino jason void process_jason(String jason_data){ // Process weather_json //// Serial.println(); // Serial.println("jason_data: "); // Serial.println(jason_data); // Convert to JSON String json_weather_data; int jsonIndex; for (int i = 0; i < jason_data.length(); i++) { if (jason_data[i] == '{') { jsonIndex = i; break; } } // Get JSON data json_weather_data = jason_data.substring(jsonIndex); // Serial.println(); // Serial.println("json_weather_data: "); // Serial.println(json_weather_data); //利用arduinoJson库解析心知返回的json天气数据 //可以利用 https://arduinojson.org/v5/assistant/ Arduinojson助手生成相关json解析代码 很方便!!! const size_t capacity = JSON_ARRAY_SIZE(1) + JSON_ARRAY_SIZE(3) + JSON_OBJECT_SIZE(1) + JSON_OBJECT_SIZE(3) + JSON_OBJECT_SIZE(6) + 3*JSON_OBJECT_SIZE(12) + 720; DynamicJsonBuffer jsonBuffer(capacity); //const char* json = "{\"results\":[{\"location\":{\"id\":\"WTMKQ069CCJ7\",\"name\":\"杭州\",\"country\":\"CN\",\"path\":\"杭州,杭州,浙江,中国\",\"timezone\":\"Asia/Shanghai\",\"timezone_offset\":\"+08:00\"},\"daily\":[{\"date\":\"2019-06-30\",\"text_day\":\"暴雨\",\"code_day\":\"16\",\"text_night\":\"中雨\",\"code_night\":\"14\",\"high\":\"29\",\"low\":\"25\",\"precip\":\"\",\"wind_direction\":\"北\",\"wind_direction_degree\":\"0\",\"wind_speed\":\"15\",\"wind_scale\":\"3\"},{\"date\":\"2019-07-01\",\"text_day\":\"中雨\",\"code_day\":\"14\",\"text_night\":\"中雨\",\"code_night\":\"14\",\"high\":\"27\",\"low\":\"24\",\"precip\":\"\",\"wind_direction\":\"无持续风向\",\"wind_direction_degree\":\"\",\"wind_speed\":\"10\",\"wind_scale\":\"2\"},{\"date\":\"2019-07-02\",\"text_day\":\"小雨\",\"code_day\":\"13\",\"text_night\":\"小雨\",\"code_night\":\"13\",\"high\":\"24\",\"low\":\"22\",\"precip\":\"\",\"wind_direction\":\"东\",\"wind_direction_degree\":\"90\",\"wind_speed\":\"15\",\"wind_scale\":\"3\"}],\"last_update\":\"2019-06-30T11:00:00+08:00\"}]}"; JsonObject& root = jsonBuffer.parseObject(json_weather_data); JsonObject& results_0 = root["results"][0]; JsonObject& results_0_location = results_0["location"]; const char* results_0_location_id = results_0_location["id"]; // "WTMKQ069CCJ7" const char* results_0_location_name = results_0_location["name"]; // "杭州" const char* results_0_location_country = results_0_location["country"]; // "CN" const char* results_0_location_path = results_0_location["path"]; // "杭州,杭州,浙江,中国" const char* results_0_location_timezone = results_0_location["timezone"]; // "Asia/Shanghai" const char* results_0_location_timezone_offset = results_0_location["timezone_offset"]; // "+08:00" tft.println(results_0_location_name); JsonArray& results_0_daily = results_0["daily"]; JsonObject& results_0_daily_0 = results_0_daily[0]; const char* results_0_daily_0_date = results_0_daily_0["date"]; // "2019-06-30" const char* results_0_daily_0_text_day = results_0_daily_0["text_day"]; // "暴雨" const char* results_0_daily_0_code_day = results_0_daily_0["code_day"]; // "16" const char* results_0_daily_0_text_night = results_0_daily_0["text_night"]; // "中雨" const char* results_0_daily_0_code_night = results_0_daily_0["code_night"]; // "14" const char* results_0_daily_0_high = results_0_daily_0["high"]; // "29" const char* results_0_daily_0_low = results_0_daily_0["low"]; // "25" const char* results_0_daily_0_precip = results_0_daily_0["precip"]; // "" const char* results_0_daily_0_wind_direction = results_0_daily_0["wind_direction"]; // "北" const char* results_0_daily_0_wind_direction_degree = results_0_daily_0["wind_direction_degree"]; // "0" const char* results_0_daily_0_wind_speed = results_0_daily_0["wind_speed"]; // "15" const char* results_0_daily_0_wind_scale = results_0_daily_0["wind_scale"]; // "3" JsonObject& results_0_daily_1 = results_0_daily[1]; const char* results_0_daily_1_date = results_0_daily_1["date"]; // "2019-07-01" const char* results_0_daily_1_text_day = results_0_daily_1["text_day"]; // "中雨" const char* results_0_daily_1_code_day = results_0_daily_1["code_day"]; // "14" const char* results_0_daily_1_text_night = results_0_daily_1["text_night"]; // "中雨" const char* results_0_daily_1_code_night = results_0_daily_1["code_night"]; // "14" const char* results_0_daily_1_high = results_0_daily_1["high"]; // "27" const char* results_0_daily_1_low = results_0_daily_1["low"]; // "24" const char* results_0_daily_1_precip = results_0_daily_1["precip"]; // "" const char* results_0_daily_1_wind_direction = results_0_daily_1["wind_direction"]; // "无持续风向" const char* results_0_daily_1_wind_direction_degree = results_0_daily_1["wind_direction_degree"]; // "" const char* results_0_daily_1_wind_speed = results_0_daily_1["wind_speed"]; // "10" const char* results_0_daily_1_wind_scale = results_0_daily_1["wind_scale"]; // "2" JsonObject& results_0_daily_2 = results_0_daily[2]; const char* results_0_daily_2_date = results_0_daily_2["date"]; // "2019-07-02" const char* results_0_daily_2_text_day = results_0_daily_2["text_day"]; // "小雨" const char* results_0_daily_2_code_day = results_0_daily_2["code_day"]; // "13" const char* results_0_daily_2_text_night = results_0_daily_2["text_night"]; // "小雨" const char* results_0_daily_2_code_night = results_0_daily_2["code_night"]; // "13" const char* results_0_daily_2_high = results_0_daily_2["high"]; // "24" const char* results_0_daily_2_low = results_0_daily_2["low"]; // "22" const char* results_0_daily_2_precip = results_0_daily_2["precip"]; // "" const char* results_0_daily_2_wind_direction = results_0_daily_2["wind_direction"]; // "东" const char* results_0_daily_2_wind_direction_degree = results_0_daily_2["wind_direction_degree"]; // "90" const char* results_0_daily_2_wind_speed = results_0_daily_2["wind_speed"]; // "15" const char* results_0_daily_2_wind_scale = results_0_daily_2["wind_scale"]; // "3" const char* results_0_last_update = results_0["last_update"]; // "2019-06-30T11:00:00+08:00" if (!root.success()) { Serial.println("parseObject() failed"); return; } //串口显示 Serial.println(); Serial.print("城市: "); Serial.println(results_0_location_name); Serial.print("今天天气: "); Serial.print(results_0_daily_0_text_day); Serial.print("今天气温: "); Serial.print( results_0_daily_0_low); Serial.print("~"); Serial.println( results_0_daily_0_high); Serial.print("明天天气: "); Serial.print(results_0_daily_1_text_day); Serial.print("明天气温: "); Serial.print( results_0_daily_1_low); Serial.print("~"); Serial.println( results_0_daily_1_high); Serial.print("后天天气: "); Serial.print(results_0_daily_2_text_day); Serial.print("后天气温: "); Serial.print( results_0_daily_2_low); Serial.print("~"); Serial.println( results_0_daily_2_high); Serial.print("风向:"); Serial.print(results_0_daily_2_wind_direction); Serial.print(" 风速:"); Serial.print( results_0_daily_2_wind_speed); Serial.print(" 风力:"); Serial.println( results_0_daily_2_wind_scale); //液晶显示 tft.fillScreen(TFT_WHITE); tft.setTextColor(TFT_RED); // tft.setTextSize(2); // tft.setTextFont(3); tft.drawString(results_0_location_name, 0, 0, 4); tft.drawString("day:", 0, 26, 4); tft.drawString(results_0_daily_0_text_day, 70, 26, 4); tft.drawString("night:", 0, 52, 4); tft.drawString(results_0_daily_0_text_night, 70, 52, 4); // tft.setTextColor(TFT_BLUE);tft.setTextFont(1); tft.drawString("temp1:", 0, 78, 4); tft.drawString(results_0_daily_0_low, 80, 78, 4);tft.drawString(results_0_daily_0_high, 130, 78, 4); // tft.setTextColor(TFT_GREEN);tft.setTextFont(2); tft.drawString("temp2:", 0, 104, 4);tft.drawString(results_0_daily_1_low, 80, 104, 4);tft.drawString(results_0_daily_1_high, 130, 104, 4); // tft.setTextColor(TFT_BLACK);tft.setTextFont(4); tft.drawString("temp3:", 0, 130, 4);tft.drawString(results_0_daily_2_low, 80, 130, 4);tft.drawString(results_0_daily_2_high, 130, 130, 4); // delay(WAIT); } //---------------------------------------------------- void setup() { // Serial Serial.begin(115200); delay(10); tft.init(); tft.setRotation(1); //显示方向 tft.fillScreen(TFT_BLACK); connect_wifi();//连接wifi //tft.setCursor(0, 0, 2); tft.setTextColor(TFT_WHITE,TFT_BLACK); tft.drawCentreString("connecting wifi", 0, 0, 3); delay(100); } void loop() { tft.fillScreen(TFT_WHITE); // tft.setCursor(0, 0, 2);//2font tft.setTextColor(TFT_RED); // tft.setTextSize(2); // tft.setTextFont(1); connect_API(); // req_data(req_city1,language); weather_data = sendRequest(host, req_city0, API_key); process_jason(weather_data); delay(15000); delay(15000); weather_data = sendRequest(host, req_city1, API_key); process_jason(weather_data); delay(15000); delay(15000); weather_data = sendRequest(host, req_city2, API_key); process_jason(weather_data); delay(15000); delay(15000); weather_data = sendRequest(host, req_city3, API_key); process_jason(weather_data); //-------------------------------------打印结果 // Wait 5 seconds delay(15000); delay(15000); }