ESP8266 显示实时天气信息
Posted h4lo
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ESP8266 显示实时天气信息相关的知识,希望对你有一定的参考价值。
代码文件
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 显示实时天气信息的主要内容,如果未能解决你的问题,请参考以下文章
利用ESP8266+OLED(I2C)打造智能时钟(网络校时+实时天气+天气预报)