基于esp8266网络气象时钟(一)

您所在的位置:网站首页 wl-02d接线 基于esp8266网络气象时钟(一)

基于esp8266网络气象时钟(一)

2023-06-09 17:26| 来源: 网络整理| 查看: 265

成品效果

在这里插入图片描述在这里插入图片描述在这里插入图片描述

功能(视频效果):

1、网络自动校准时间(日期、星期、时间)

2、显示当前城市的天气情况

3、显示最近三天的天气预报

4、显示当前室内的温度

DIY esp8266迷你气象台

准备 硬件

1、Esp8266 mini D1 2、1.3英寸Oled屏幕(SH1106/SSD1306) IIC 4线版(本程序仅适用于IIC 4线版本 SPI 7线版本需要改程序) 3、DS18B20 / 4.7k 上拉电阻 4、外壳(3D打印、纸皮、积木等)

软件

Arduino 库 1.自行设置安装ESP8266开发板 进入首选项(Preferences),找到附加开发板管理器地址(Additional Board Manager URLs),并在其后添加如下信息: http://arduino.esp8266.com/stable/package_esp8266com_index.json 在这里插入图片描述 开发板 - 开发板管理器 搜索ESP8266并安装。 在这里插入图片描述 2.Library Manager中安装 ArduinoJson库 用于解析和风天气API response的JSON DS18B20库 用于读取DS18B20的温度,检测房间内实时温度 ESP8266 and ESP32 OLED driver for SSD1306 displays库 用于驱动OLED屏幕显示内容 OneWire库 用于连接DS18B20

连线

我的接线方法:(你也可以按你的喜好来,注意修改程序中的接口信息) 在这里插入图片描述

3D打印外壳

模型是别人做的 作者Qrome 一个是0.96英寸版本的 一个是1.3英寸版本的 他的项目是用于显示3D打印机打印状态的 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述

程序 #include #include #include #include #include #include // time #include // time() ctime() #include // struct timeval #include // settimeofday_cb() #include "SH1106Wire.h"//or #include "SSD1306Wire.h" #include "OLEDDisplayUi.h" #include "Wire.h" #include "HeFeng.h" #include "WeatherStationFonts.h" #include "WeatherStationImages.h" /*************************** * Begin Settings **************************/ DS18B20 ds(D7); //时区以及夏令时设置 #define TZ 8 // (utc+) TZ in hours #define DST_MN 0 // use 60mn for summer time in some countries // 第二屏实时天气 第三屏预报的更新频率 const int UPDATE_INTERVAL_SECS = 20 * 60; // Update every 20 minutes online weather // DS18B20更新频率 const int UPDATE_CURR_INTERVAL_SECS = 10; // Update every 10 secs DS18B20 // OLED地址以及管脚信息 const int I2C_DISPLAY_ADDRESS = 0x3c; #if defined(ESP8266) const int SDA_PIN = D2; const int SDC_PIN = D5; #endif const String WDAY_NAMES[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; const String MONTH_NAMES[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; /*************************** * End Settings **************************/ // Initialize the oled display for address 0x3c // sda-pin=14 and sdc-pin=12 SH1106Wire display(I2C_DISPLAY_ADDRESS, SDA_PIN, SDC_PIN); // or SSD1306Wire display(I2C_DISPLAY_ADDRESS, SDA_PIN, SDC_PIN); OLEDDisplayUi ui( &display ); HeFengCurrentData currentWeather; HeFengForeData foreWeather[3]; HeFeng HeFengClient; //OpenWeatherMapForecastData forecasts[MAX_FORECASTS]; //OpenWeatherMapForecast forecastClient; #define TZ_MN ((TZ)*60) #define TZ_SEC ((TZ)*3600) #define DST_SEC ((DST_MN)*60) const char* HEFENG_KEY="9d883c83e6064d63b1132b664ff45623";//和风天气KEY 城市ID 自行去https://dev.heweather.com/ 注册 城市代码查询https://dev.heweather.com/docs/refer/city const char* HEFENG_LOCATION="shenzhen";//我的城市地点是深圳 time_t now; // flag changed in the ticker function every 10 minutes bool readyForWeatherUpdate = false; String lastUpdate = "--"; long timeSinceLastWUpdate = 0; long timeSinceLastCurrUpdate = 0; String currTemp="-1.0"; //declaring prototypes void drawProgress(OLEDDisplay *display, int percentage, String label); void updateData(OLEDDisplay *display); void drawDateTime(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y); void drawCurrentWeather(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y); void drawForecast(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y); void drawForecastDetails(OLEDDisplay *display, int x, int y, int dayIndex); void drawHeaderOverlay(OLEDDisplay *display, OLEDDisplayUiState* state); void setReadyForWeatherUpdate(); // Add frames // this array keeps function pointers to all frames // frames are the single views that slide from right to left FrameCallback frames[] = { drawDateTime, drawCurrentWeather,drawForecast }; //drawForecast int numberOfFrames = 3; OverlayCallback overlays[] = { drawHeaderOverlay }; int numberOfOverlays = 1; bool autoConfig() { WiFi.mode(WIFI_STA); WiFi.begin(); Serial.print("AutoConfig Waiting......"); int counter = 0; for (int i = 0; i Serial.println("AutoConfig Success"); Serial.printf("SSID:%s\r\n", WiFi.SSID().c_str()); Serial.printf("PSW:%s\r\n", WiFi.psk().c_str()); WiFi.printDiag(Serial); return true; } else { delay(500); Serial.print("."); display.clear(); display.drawString(64, 10, "Connecting to WiFi"); display.drawXbm(46, 30, 8, 8, counter % 3 == 0 ? activeSymbole : inactiveSymbole); display.drawXbm(60, 30, 8, 8, counter % 3 == 1 ? activeSymbole : inactiveSymbole); display.drawXbm(74, 30, 8, 8, counter % 3 == 2 ? activeSymbole : inactiveSymbole); display.display(); counter++; } } Serial.println("AutoConfig Faild!" ); return false; } ESP8266WebServer server(80); String str = "ESP8266网页配网function wifi(){var ssid = aa.value;var password = bb.value;var xmlhttp=new XMLHttpRequest();xmlhttp.open(\"GET\",\"/HandleWifi?ssid=\"+ssid+\"&password=\"+password,true);xmlhttp.send();xmlhttp.onload = function(e){alert(this.responseText);}}hello,我是fxy,输入wifi信息给wifi时钟配网: WiFi名称:WiFi密码:"; void handleRoot() { server.send(200, "text/html", str); } void HandleWifi() { String wifis = server.arg("ssid"); //从JavaScript发送的数据中找ssid的值 String wifip = server.arg("password"); //从JavaScript发送的数据中找password的值 Serial.println("received:"+wifis); server.send(200, "text/html", "连接中.."); WiFi.begin(wifis,wifip); } void handleNotFound() { String message = "File Not Found\n\n"; message += "URI: "; message += server.uri(); message += "\nMethod: "; message += (server.method() == HTTP_GET) ? "GET" : "POST"; message += "\nArguments: "; message += server.args(); message += "\n"; for (uint8_t i = 0; i WiFi.mode(WIFI_AP_STA);//设置模式为AP+STA WiFi.softAP("wifi_clock"); IPAddress myIP = WiFi.softAPIP(); if (MDNS.begin("clock")) { Serial.println("MDNS responder started"); } server.on("/", handleRoot); server.on("/HandleWifi", HTTP_GET, HandleWifi); server.onNotFound(handleNotFound);//请求失败回调函数 MDNS.addService("http", "tcp", 80); server.begin();//开启服务器 Serial.println("HTTP server started"); int counter = 0; while(1) { server.handleClient(); MDNS.update(); delay(500); display.clear(); display.drawString(64, 5, "WIFI AP:wifi_clock"); display.drawString(64, 20, "192.168.4.1"); display.drawString(64, 35, "waiting for config wifi."); display.drawXbm(46, 50, 8, 8, counter % 3 == 0 ? activeSymbole : inactiveSymbole); display.drawXbm(60, 50, 8, 8, counter % 3 == 1 ? activeSymbole : inactiveSymbole); display.drawXbm(74, 50, 8, 8, counter % 3 == 2 ? activeSymbole : inactiveSymbole); display.display(); counter++; if (WiFi.status() == WL_CONNECTED) { Serial.println("HtmlConfig Success"); Serial.printf("SSID:%s\r\n", WiFi.SSID().c_str()); Serial.printf("PSW:%s\r\n", WiFi.psk().c_str()); Serial.println("HTML连接成功"); break; } } server.close(); WiFi.mode(WIFI_STA); } void setup() { Serial.begin(115200); Serial.println(); Serial.println(); // initialize dispaly display.init(); display.clear(); display.display(); //display.flipScreenVertically(); display.setFont(ArialMT_Plain_10); display.setTextAlignment(TEXT_ALIGN_CENTER); display.setContrast(255); bool wifiConfig = autoConfig(); if(wifiConfig == false){ htmlConfig();//HTML配网 } ui.setTargetFPS(30); ui.setActiveSymbol(activeSymbole); ui.setInactiveSymbol(inactiveSymbole); // You can change this to // TOP, LEFT, BOTTOM, RIGHT ui.setIndicatorPosition(BOTTOM); // Defines where the first frame is located in the bar. ui.setIndicatorDirection(LEFT_RIGHT); // You can change the transition that is used // SLIDE_LEFT, SLIDE_RIGHT, SLIDE_TOP, SLIDE_DOWN ui.setFrameAnimation(SLIDE_LEFT); ui.setFrames(frames, numberOfFrames); ui.setTimePerFrame(7500); ui.setOverlays(overlays, numberOfOverlays); // Inital UI takes care of initalising the display too. ui.init(); Serial.println(""); configTime(TZ_SEC, DST_SEC, "pool.ntp.org","0.cn.pool.ntp.org","1.cn.pool.ntp.org"); updateData(&display); } void loop() { if (millis() - timeSinceLastWUpdate > (1000L*UPDATE_INTERVAL_SECS)) { setReadyForWeatherUpdate(); timeSinceLastWUpdate = millis(); } if (millis() - timeSinceLastCurrUpdate > (1000L*UPDATE_CURR_INTERVAL_SECS)) { if( ui.getUiState()->frameState == FIXED) { currTemp=String(ds.getTempC()-3, 1);//由于我的传感器的检测误差,调整一下温度 timeSinceLastCurrUpdate = millis(); } } if (readyForWeatherUpdate && ui.getUiState()->frameState == FIXED) { updateData(&display); } int remainingTimeBudget = ui.update(); if (remainingTimeBudget > 0) { // You can do some work here // Don't do stuff if you are below your // time budget. delay(remainingTimeBudget); } } void drawProgress(OLEDDisplay *display, int percentage, String label) { display->clear(); display->setTextAlignment(TEXT_ALIGN_CENTER); display->setFont(ArialMT_Plain_10); display->drawString(64, 10, label); display->drawProgressBar(2, 28, 124, 10, percentage); display->display(); } void updateData(OLEDDisplay *display) { drawProgress(display, 30, "Updating weather..."); for(int i=0;i break;} } drawProgress(display, 50, "Updating forecasts..."); for(int i=0;i break;} } readyForWeatherUpdate = false; drawProgress(display, 100, "Done..."); delay(1000); } void drawDateTime(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) { now = time(nullptr); struct tm* timeInfo; timeInfo = localtime(&now); char buff[16]; display->setTextAlignment(TEXT_ALIGN_CENTER); display->setFont(ArialMT_Plain_16); String date = WDAY_NAMES[timeInfo->tm_wday]; sprintf_P(buff, PSTR("%04d-%02d-%02d, %s"), timeInfo->tm_year + 1900, timeInfo->tm_mon+1, timeInfo->tm_mday, WDAY_NAMES[timeInfo->tm_wday].c_str()); display->drawString(64 + x, 5 + y, String(buff)); display->setFont(ArialMT_Plain_24); sprintf_P(buff, PSTR("%02d:%02d:%02d"), timeInfo->tm_hour, timeInfo->tm_min, timeInfo->tm_sec); display->drawString(64 + x, 22 + y, String(buff)); display->setTextAlignment(TEXT_ALIGN_LEFT); } void drawCurrentWeather(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) { display->setFont(ArialMT_Plain_10); display->setTextAlignment(TEXT_ALIGN_CENTER); display->drawString(64 + x, 38 + y, currentWeather.cond_txt+" | Wind: "+currentWeather.wind_sc); display->setFont(ArialMT_Plain_24); display->setTextAlignment(TEXT_ALIGN_LEFT); String temp = currentWeather.tmp + "°C" ; display->drawString(60 + x, 3 + y, temp); display->setFont(ArialMT_Plain_10); display->drawString(70 + x, 26 + y, currentWeather.fl+"°C | "+currentWeather.hum+"%"); display->setFont(Meteocons_Plain_36); display->setTextAlignment(TEXT_ALIGN_CENTER); display->drawString(32 + x, 0 + y, currentWeather.iconMeteoCon); } void drawForecast(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) { drawForecastDetails(display, x, y, 0); drawForecastDetails(display, x + 44, y, 1); drawForecastDetails(display, x + 88, y, 2); } void drawForecastDetails(OLEDDisplay *display, int x, int y, int dayIndex) { display->setTextAlignment(TEXT_ALIGN_CENTER); display->setFont(ArialMT_Plain_10); display->drawString(x + 20, y, foreWeather[dayIndex].datestr); display->setFont(Meteocons_Plain_21); display->drawString(x + 20, y + 12, foreWeather[dayIndex].iconMeteoCon); String temp=foreWeather[dayIndex].tmp_min+" | "+foreWeather[dayIndex].tmp_max; display->setFont(ArialMT_Plain_10); display->drawString(x + 20, y + 34, temp); display->setTextAlignment(TEXT_ALIGN_LEFT); } void drawHeaderOverlay(OLEDDisplay *display, OLEDDisplayUiState* state) { now = time(nullptr); struct tm* timeInfo; timeInfo = localtime(&now); char buff[14]; sprintf_P(buff, PSTR("%02d:%02d"), timeInfo->tm_hour, timeInfo->tm_min); display->setColor(WHITE); display->setFont(ArialMT_Plain_10); display->setTextAlignment(TEXT_ALIGN_LEFT); display->drawString(6, 54, String(buff)); display->setTextAlignment(TEXT_ALIGN_RIGHT); String temp =currTemp +"°C"; display->drawString(128, 54, temp); display->drawHorizontalLine(0, 52, 128); } void setReadyForWeatherUpdate() { Serial.println("Setting readyForUpdate to true"); readyForWeatherUpdate = true; } 注意

OLED屏幕一般有两种驱动SSD1306和SH1106 根据你买的屏幕 更改如下两行的信息 用错了会花屏 #include “SH1106Wire.h”//or #include “SSD1306Wire.h” SH1106Wire display(I2C_DISPLAY_ADDRESS, SDA_PIN, SDC_PIN); // or SSD1306Wire display(I2C_DISPLAY_ADDRESS, SDA_PIN, SDC_PIN);

配网

HTML配网 连接ESP8266建立的wifi 手机或电脑浏览器访问http://192.168.4.1 即可配网

其他

和风天气目前免费版API提供了实时天气 天气预报 市级的空气质量等 可用的信息很多 如果你想显示其他信息 请查看API

https://dev.heweather.com/docs/api/

并更改HeFeng.app HeFeng.h中的结构体以及JSON解析信息 如果你想用其他网站的API 请自行修改HeFeng.app HeFeng.h

欢迎QQ群交流:247620001 验证信息:esp8266 基于esp8266网络气象时钟(二)



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3