ESP8266 顯示實時天氣信息
阿新 • • 發佈:2019-05-11
sda 6.5 reat cit cal nts all percent con
代碼文件
getdata.h
#include <ESP8266WiFi.h> #include <ESP8266HTTPClient.h> #include <ArduinoJson.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <cstring> #define DEBUG 1 #define MAX_CONTENT_SIZE 2000 const char* ssid = "***"; // wifi 賬號密碼 const char* password = "****"; WiFiClient client; HTTPClient http; char response[MAX_CONTENT_SIZE]; const char* HOST = "api.seniverse.com"; const char* APIKEY = "***"; // 心知天氣接口私鑰 const char* CITY = "haikou"; typedef struct UserData{ char city[16]; char weather[32]; char temp[16]; }data; data d; bool parseData(data &d); data getdata(); bool WifiConfig(); void weather_init(); bool sendRequest(const char* host, const char* cityid, const char* apiKey); void clearResponseBuffer(); void clearResponseBuffer(){ memset(response, 0, MAX_CONTENT_SIZE); //清空 memset(d.city,0,sizeof(d.city)); memset(d.weather,0,sizeof(d.weather)); memset(d.temp,0,sizeof(d.temp)); } data getdata(){ char error[5] = "NULL"; clearResponseBuffer(); if(sendRequest(HOST,CITY,APIKEY)){ Serial.println("Request success!\n\n"); } if(parseData(d)){ return d; }else{ strcpy(d.city,error); strcpy(d.weather,error); strcpy(d.temp,error); return d; } } bool WifiConfig(){ WiFi.begin(ssid,password); while (WiFi.status() != WL_CONNECTED){ delay(500); Serial.print("."); } Serial.println("Connected success!"); Serial.println(""); Serial.println("IP address: "); Serial.println(WiFi.localIP()); return true; } bool parseData(data &d){ DynamicJsonBuffer jsonBuffer; JsonObject& root = jsonBuffer.parseObject(response); if(!root.success()){ Serial.println("JSON parse failed!\n"); return false; } strcpy(d.city,root["results"][0]["location"]["name"]); strcpy(d.weather,root["results"][0]["now"]["text"]); strcpy(d.temp,root["results"][0]["now"]["temperature"]); return true; } bool sendRequest(const char* host, const char* cityid, const char* apiKey) { //const char *response; char *Url = (char *)malloc(0x100); String payload; sprintf(Url,"%s%s%s%s%s%s%s","http://",host,"/v3/weather/now.json?key=",apiKey,"&location=",cityid,"&language=en"); 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 == HTTP_CODE_OK){ payload = http.getString(); Serial.println(payload); }else{ return false; } }else{ Serial.println("Something error!"); return false; } strcpy(response,payload.c_str()); // convert to const char * free(Url); return true; } void weather_init(){ WifiConfig(); }
配置完 wifi 之後,請求心知天氣的 API 接口,得到 JSON 數據之後,解析返回主代碼文件。
主代碼文件(.ino)
得到返回的數據體解析並顯示在屏幕上(drawstring),5s 鐘更新一次。
#include <Wire.h> // Only needed for Arduino 1.6.5 and earlier #include "SSD1306Wire.h" // legacy include: `#include "SSD1306.h"` // or #include "SH1106Wire.h", legacy include: `#include "SH1106.h"` // For a connection via I2C using brzo_i2c (must be installed) include // #include <brzo_i2c.h> // Only needed for Arduino 1.6.5 and earlier // #include "SSD1306Brzo.h" // #include "SH1106Brzo.h" #include <SPI.h> // Only needed for Arduino 1.6.5 and earlier #include "SSD1306Spi.h" // #include "SH1106SPi.h" #include "images.h" // Initialize the OLED display using SPI // D5 -> CLK // D7 -> MOSI (DOUT) // D0 -> RES // D2 -> DC // D8 -> CS SSD1306Spi display(D0, D2, D8); // or // SH1106Spi display(D0, D2); // Initialize the OLED display using brzo_i2c // D3 -> SDA // D5 -> SCL // SSD1306Brzo display(0x3c, D3, D5); // or // SH1106Brzo display(0x3c, D3, D5); // Initialize the OLED display using Wire library //SSD1306Wire display(0x3c, D3, D5); // SH1106 display(0x3c, D3, D5); #include "getdata.h" #define DEMO_DURATION 3000 typedef void (*Demo)(void); int demoMode = 0; int counter = 1; void setup() { Serial.begin(115200); Serial.println(); Serial.println(); weather_init(); // Initialising the UI will init the display too. display.init(); display.flipScreenVertically(); display.setFont(ArialMT_Plain_10); } void drawFontFaceDemo() { char city[10]; char weather[20]; char temp[10]; sprintf(city,"%s: %s","City",getdata().city); sprintf(weather,"%s: %s","Weather",getdata().weather); sprintf(temp,"%s: %s","temp",getdata().temp); // create more fonts at http://oleddisplay.squix.ch/ display.setFont(ArialMT_Plain_16); display.setTextAlignment(TEXT_ALIGN_LEFT); display.drawString(10, 0, city); display.drawString(0, 20, weather); display.drawString(0, 40, temp); } void drawTextFlowDemo() { display.setFont(ArialMT_Plain_10); display.setTextAlignment(TEXT_ALIGN_LEFT); display.drawStringMaxWidth(0, 0, 128, "Lorem ipsum\n dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore." ); } void drawTextAlignmentDemo() { // Text alignment demo display.setFont(ArialMT_Plain_10); // The coordinates define the left starting point of the text display.setTextAlignment(TEXT_ALIGN_LEFT); display.drawString(0, 10, "Left aligned (0,10)"); // The coordinates define the center of the text display.setTextAlignment(TEXT_ALIGN_CENTER); display.drawString(64, 22, "Center aligned (64,22)"); // The coordinates define the right end of the text display.setTextAlignment(TEXT_ALIGN_RIGHT); display.drawString(128, 33, "Right aligned (128,33)"); } void drawRectDemo() { // Draw a pixel at given position for (int i = 0; i < 10; i++) { display.setPixel(i, i); display.setPixel(10 - i, i); } display.drawRect(12, 12, 20, 20); // Fill the rectangle display.fillRect(14, 14, 17, 17); // Draw a line horizontally display.drawHorizontalLine(0, 40, 20); // Draw a line horizontally display.drawVerticalLine(40, 0, 20); } void drawCircleDemo() { for (int i=1; i < 8; i++) { display.setColor(WHITE); display.drawCircle(32, 32, i*3); if (i % 2 == 0) { display.setColor(BLACK); } display.fillCircle(96, 32, 32 - i* 3); } } void drawProgressBarDemo() { int progress = (counter / 5) % 100; // draw the progress bar display.drawProgressBar(0, 32, 120, 10, progress); // draw the percentage as String display.setTextAlignment(TEXT_ALIGN_CENTER); display.drawString(64, 15, String(progress) + "%"); display.setTextAlignment(TEXT_ALIGN_LEFT); display.setFont(ArialMT_Plain_10); display.drawString(10, 0, "H4lo nb!"); } void drawImageDemo() { // see http://blog.squix.org/2015/05/esp8266-nodemcu-how-to-create-xbm.html // on how to create xbm files display.drawXbm(34, 14, WiFi_Logo_width, WiFi_Logo_height, WiFi_Logo_bits); } //Demo demos[] = {drawFontFaceDemo, drawTextFlowDemo, drawTextAlignmentDemo, drawRectDemo, drawCircleDemo, drawProgressBarDemo, drawImageDemo}; Demo demos[] = {drawFontFaceDemo}; int demoLength = (sizeof(demos) / sizeof(Demo)); long timeSinceLastModeSwitch = 0; void loop() { // clear the display display.clear(); demos[demoMode](); delay(5000); //延遲 display.setTextAlignment(TEXT_ALIGN_RIGHT); display.drawString(10, 128, String(millis())); // write the buffer to the display display.display(); if (millis() - timeSinceLastModeSwitch > DEMO_DURATION) { demoMode = (demoMode + 1) % demoLength; timeSinceLastModeSwitch = millis(); } counter++; delay(10); }
效果
ESP8266 顯示實時天氣信息