久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 9490|回復: 4
打印 上一主題 下一主題
收起左側

【零知ESP8266】教程:OLED天氣時鐘

  [復制鏈接]
跳轉到指定樓層
樓主
本文演示通過OLED顯示時鐘和天氣情況,主要利用的是openweathermap的免費天氣API。
1、硬件準備
(1)零知ESP8266開發板

(2)OLED SSD1306模塊(3)若干杜邦線
2、電路連接
接線很簡單,I2C接口對應連接即可:



接好后實物圖如下:



2、軟件代碼
使用零知開發工具,使用了OLED和WeatherStation相關的軟件庫,因此需要安裝對應的庫:
esp8266-weather-station-1.6.6.rar (885.92 KB, 下載次數: 190)

安裝完成后,我們新建工程:
  1. /*
  2. 2019年6月13日13:47:26
  3. by 零知實驗室
  4. */

  5. #include <ESPWiFi.h>
  6. #include <ESPHTTPClient.h>
  7. #include <JsonListener.h>

  8. // time
  9. #include <time.h>                       // time() ctime()
  10. #include <sys/time.h>                   // struct timeval
  11. #include <coredecls.h>                  // settimeofday_cb()

  12. #include "SSD1306Wire.h"
  13. #include "OLEDDisplayUi.h"
  14. #include "Wire.h"
  15. #include "OpenWeatherMapCurrent.h"
  16. #include "OpenWeatherMapForecast.h"
  17. #include "WeatherStationFonts.h"
  18. #include "WeatherStationImages.h"


  19. /***************************
  20. * Begin Settings
  21. **************************/

  22. // WIFI
  23. const char* WIFI_SSID = "xx";
  24. const char* WIFI_PWD = "xx";

  25. #define TZ              8       // (utc+) TZ in hours
  26. #define DST_MN          60      // use 60mn for summer time in some countries

  27. // Setup
  28. const int UPDATE_INTERVAL_SECS = 20 * 60; // Update every 20 minutes

  29. // Display Settings
  30. const int I2C_DISPLAY_ADDRESS = 0x3c;

  31. const int SDA_PIN = D3;
  32. const int SDC_PIN = D4;

  33. // OpenWeatherMap Settings
  34. // Sign up here to get an API key:


  35. // Pick a language code from this list:
  36. // Arabic - ar, Bulgarian - bg, Catalan - ca, Czech - cz, German - de, Greek - el,
  37. // English - en, Persian (Farsi) - fa, Finnish - fi, French - fr, Galician - gl,
  38. // Croatian - hr, Hungarian - hu, Italian - it, Japanese - ja, Korean - kr,
  39. // Latvian - la, Lithuanian - lt, Macedonian - mk, Dutch - nl, Polish - pl,
  40. // Portuguese - pt, Romanian - ro, Russian - ru, Swedish - se, Slovak - sk,
  41. // Slovenian - sl, Spanish - es, Turkish - tr, Ukrainian - ua, Vietnamese - vi,
  42. // Chinese Simplified - zh_cn, Chinese Traditional - zh_tw.
  43. String OPEN_WEATHER_MAP_LANGUAGE = "zh_cn";
  44. const uint8_t MAX_FORECASTS = 4;

  45. const boolean IS_METRIC = true;

  46. // Adjust according to your language
  47. const String WDAY_NAMES[] = {"SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"};
  48. const String MONTH_NAMES[] = {"JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"};

  49. /***************************
  50. * End Settings
  51. **************************/
  52. // Initialize the oled display for address 0x3c
  53. // sda-pin=14 and sdc-pin=12
  54. SSD1306Wire     display(I2C_DISPLAY_ADDRESS, SDA_PIN, SDC_PIN);
  55. OLEDDisplayUi   ui( &display );

  56. OpenWeatherMapCurrentData currentWeather;
  57. OpenWeatherMapCurrent currentWeatherClient;

  58. OpenWeatherMapForecastData forecasts[MAX_FORECASTS];
  59. OpenWeatherMapForecast forecastClient;

  60. #define TZ_MN           ((TZ)*60)
  61. #define TZ_SEC          ((TZ)*3600)
  62. #define DST_SEC         ((DST_MN)*60)
  63. time_t now;

  64. // flag changed in the ticker function every 10 minutes
  65. bool readyForWeatherUpdate = false;

  66. String lastUpdate = "--";

  67. long timeSinceLastWUpdate = 0;

  68. //declaring prototypes
  69. void drawProgress(OLEDDisplay *display, int percentage, String label);
  70. void updateData(OLEDDisplay *display);
  71. void drawDateTime(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y);
  72. void drawCurrentWeather(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y);
  73. void drawForecast(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y);
  74. void drawForecastDetails(OLEDDisplay *display, int x, int y, int dayIndex);
  75. void drawHeaderOverlay(OLEDDisplay *display, OLEDDisplayUiState* state);
  76. void setReadyForWeatherUpdate();


  77. // Add frames
  78. // this array keeps function pointers to all frames
  79. // frames are the single views that slide from right to left
  80. FrameCallback frames[] = { drawDateTime, drawCurrentWeather, drawForecast };
  81. int numberOfFrames = 3;

  82. OverlayCallback overlays[] = { drawHeaderOverlay };
  83. int numberOfOverlays = 1;

  84. void setup() {
  85.   Serial.begin(115200);
  86.   Serial.println();
  87.   Serial.println();

  88.   // initialize dispaly
  89.   display.init();
  90.   display.clear();
  91.   display.display();

  92.   //display.flipScreenVertically();
  93.   display.setFont(ArialMT_Plain_10);
  94.   display.setTextAlignment(TEXT_ALIGN_CENTER);
  95.   display.setContrast(255);

  96.   WiFi.begin(WIFI_SSID, WIFI_PWD);

  97.   int counter = 0;
  98.   while (WiFi.status() != WL_CONNECTED) {
  99.     delay(500);
  100.     Serial.print(".");
  101.     display.clear();
  102.     display.drawString(64, 10, "Connecting to WiFi");
  103.     display.drawXbm(46, 30, 8, 8, counter % 3 == 0 ? activeSymbole : inactiveSymbole);
  104.     display.drawXbm(60, 30, 8, 8, counter % 3 == 1 ? activeSymbole : inactiveSymbole);
  105.     display.drawXbm(74, 30, 8, 8, counter % 3 == 2 ? activeSymbole : inactiveSymbole);
  106.     display.display();

  107.     counter++;
  108.   }
  109.   // Get time from network time service
  110.   configTime(TZ_SEC, DST_SEC, "pool.ntp.org");

  111.   ui.setTargetFPS(30);

  112.   ui.setActiveSymbol(activeSymbole);
  113.   ui.setInactiveSymbol(inactiveSymbole);

  114.   // You can change this to
  115.   // TOP, LEFT, BOTTOM, RIGHT
  116.   ui.setIndicatorPosition(BOTTOM);

  117.   // Defines where the first frame is located in the bar.
  118.   ui.setIndicatorDirection(LEFT_RIGHT);

  119.   // You can change the transition that is used
  120.   // SLIDE_LEFT, SLIDE_RIGHT, SLIDE_TOP, SLIDE_DOWN
  121.   ui.setFrameAnimation(SLIDE_LEFT);

  122.   ui.setFrames(frames, numberOfFrames);

  123.   ui.setOverlays(overlays, numberOfOverlays);

  124.   // Inital UI takes care of initalising the display too.
  125.   ui.init();

  126.   Serial.println("");

  127.   updateData(&display);

  128. }

  129. void loop() {

  130.   if (millis() - timeSinceLastWUpdate > (1000L*UPDATE_INTERVAL_SECS)) {
  131.     setReadyForWeatherUpdate();
  132.     timeSinceLastWUpdate = millis();
  133.   }

  134.   if (readyForWeatherUpdate && ui.getUiState()->frameState == FIXED) {
  135.     updateData(&display);
  136.   }

  137.   int remainingTimeBudget = ui.update();

  138.   if (remainingTimeBudget > 0) {
  139.     // You can do some work here
  140.     // Don't do stuff if you are below your
  141.     // time budget.
  142.     delay(remainingTimeBudget);
  143.   }


  144. }

  145. void drawProgress(OLEDDisplay *display, int percentage, String label) {
  146.   display->clear();
  147.   display->setTextAlignment(TEXT_ALIGN_CENTER);
  148.   display->setFont(ArialMT_Plain_10);
  149.   display->drawString(64, 10, label);
  150.   display->drawProgressBar(2, 28, 124, 10, percentage);
  151.   display->display();
  152. }

  153. void updateData(OLEDDisplay *display) {
  154.   drawProgress(display, 10, "Updating time...");
  155.   drawProgress(display, 30, "Updating weather...");
  156.   currentWeatherClient.setMetric(IS_METRIC);
  157.   currentWeatherClient.setLanguage(OPEN_WEATHER_MAP_LANGUAGE);
  158.   currentWeatherClient.updateCurrentById(¤tWeather, OPEN_WEATHER_MAP_APP_ID, OPEN_WEATHER_MAP_LOCATION_ID);
  159.   drawProgress(display, 50, "Updating forecasts...");
  160.   forecastClient.setMetric(IS_METRIC);
  161.   forecastClient.setLanguage(OPEN_WEATHER_MAP_LANGUAGE);
  162.   uint8_t allowedHours[] = {12};
  163.   forecastClient.setAllowedHours(allowedHours, sizeof(allowedHours));
  164.   forecastClient.updateForecastsById(forecasts, OPEN_WEATHER_MAP_APP_ID, OPEN_WEATHER_MAP_LOCATION_ID, MAX_FORECASTS);

  165.   readyForWeatherUpdate = false;
  166.   drawProgress(display, 100, "Done...");
  167.   delay(1000);
  168. }



  169. void drawDateTime(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) {
  170.   now = time(nullptr);
  171.   struct tm* timeInfo;
  172.   timeInfo = localtime(&now);
  173.   char buff[16];


  174.   display->setTextAlignment(TEXT_ALIGN_CENTER);
  175.   display->setFont(ArialMT_Plain_10);
  176.   String date = WDAY_NAMES[timeInfo->tm_wday];

  177.   sprintf_P(buff, PSTR("%s, %02d/%02d/%04d"), WDAY_NAMES[timeInfo->tm_wday].c_str(), timeInfo->tm_mday, timeInfo->tm_mon+1, timeInfo->tm_year + 1900);
  178.   display->drawString(64 + x, 5 + y, String(buff));
  179.   display->setFont(ArialMT_Plain_24);

  180.   sprintf_P(buff, PSTR("%02d:%02d:%02d"), timeInfo->tm_hour, timeInfo->tm_min, timeInfo->tm_sec);
  181.   display->drawString(64 + x, 15 + y, String(buff));
  182.   display->setTextAlignment(TEXT_ALIGN_LEFT);
  183. }

  184. void drawCurrentWeather(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) {
  185.   display->setFont(ArialMT_Plain_10);
  186.   display->setTextAlignment(TEXT_ALIGN_CENTER);
  187.   display->drawString(64 + x, 38 + y, currentWeather.description);

  188.   display->setFont(ArialMT_Plain_24);
  189.   display->setTextAlignment(TEXT_ALIGN_LEFT);
  190.   String temp = String(currentWeather.temp, 1) + (IS_METRIC ? "°C" : "°F");
  191.   display->drawString(60 + x, 5 + y, temp);

  192.   display->setFont(Meteocons_Plain_36);
  193.   display->setTextAlignment(TEXT_ALIGN_CENTER);
  194.   display->drawString(32 + x, 0 + y, currentWeather.iconMeteoCon);
  195. }


  196. void drawForecast(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) {
  197.   drawForecastDetails(display, x, y, 0);
  198.   drawForecastDetails(display, x + 44, y, 1);
  199.   drawForecastDetails(display, x + 88, y, 2);
  200. }

  201. void drawForecastDetails(OLEDDisplay *display, int x, int y, int dayIndex) {
  202.   time_t observationTimestamp = forecasts[dayIndex].observationTime;
  203.   struct tm* timeInfo;
  204.   timeInfo = localtime(&observationTimestamp);
  205.   display->setTextAlignment(TEXT_ALIGN_CENTER);
  206.   display->setFont(ArialMT_Plain_10);
  207.   display->drawString(x + 20, y, WDAY_NAMES[timeInfo->tm_wday]);

  208.   display->setFont(Meteocons_Plain_21);
  209.   display->drawString(x + 20, y + 12, forecasts[dayIndex].iconMeteoCon);
  210.   String temp = String(forecasts[dayIndex].temp, 0) + (IS_METRIC ? "°C" : "°F");
  211.   display->setFont(ArialMT_Plain_10);
  212.   display->drawString(x + 20, y + 34, temp);
  213.   display->setTextAlignment(TEXT_ALIGN_LEFT);
  214. }

  215. void drawHeaderOverlay(OLEDDisplay *display, OLEDDisplayUiState* state) {
  216.   now = time(nullptr);
  217.   struct tm* timeInfo;
  218.   timeInfo = localtime(&now);
  219.   char buff[14];
  220.   sprintf_P(buff, PSTR("%02d:%02d"), timeInfo->tm_hour, timeInfo->tm_min);

  221.   display->setColor(WHITE);
  222.   display->setFont(ArialMT_Plain_10);
  223.   display->setTextAlignment(TEXT_ALIGN_LEFT);
  224.   display->drawString(0, 54, String(buff));
  225.   display->setTextAlignment(TEXT_ALIGN_RIGHT);
  226.   String temp = String(currentWeather.temp, 1) + (IS_METRIC ? "°C" : "°F");
  227.   display->drawString(128, 54, temp);
  228.   display->drawHorizontalLine(0, 52, 128);
  229. }

  230. void setReadyForWeatherUpdate() {
  231.   Serial.println("Setting readyForUpdate to true");
  232.   readyForWeatherUpdate = true;
  233. }
復制代碼
注意代碼里面填寫自己的APIkey和要查詢的城市名稱,這里填寫的是深圳-shenzhen。
3、驗證測試
將代碼驗證并上傳到零知-ESP8266上面,打開串口調試工具,可以看到如下結果:


獲取返回結果代碼為:200,即表示成功了;如果是錯誤碼,可以把地址粘貼到瀏覽器里看看是什么原因。
成功后OLED就會顯示天氣情況:


更多詳細資料可到零知實驗室免費獲取。


分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏10 分享淘帖 頂1 踩
回復

使用道具 舉報

沙發
ID:502479 發表于 2020-2-28 21:30 | 只看該作者
庫安裝失敗
回復

使用道具 舉報

板凳
ID:141648 發表于 2021-6-16 17:26 | 只看該作者
編譯錯誤,不能用
回復

使用道具 舉報

地板
ID:925265 發表于 2021-8-28 21:29 | 只看該作者
頭文件不足發出來也沒用
回復

使用道具 舉報

5#
ID:791181 發表于 2023-6-6 15:53 | 只看該作者
求完整資料
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 欧美日韩亚洲视频 | 狠狠久| 99精品久久 | 91精品久久久久久久久久小网站 | h视频在线免费 | 欧美黑人又粗大 | 国产精品久久久久久久久久久久冷 | 色视频在线观看 | 久久91| 国产一区二区免费在线 | 亚洲成人av一区二区 | 欧美视频一区 | 国内精品久久久久久 | 啪啪免费| 天天看天天摸天天操 | 婷婷在线免费 | 色资源在线 | 在线观看中文字幕亚洲 | 古装三级在线播放 | 91文字幕巨乱亚洲香蕉 | 91资源在线 | 最新国产精品视频 | 欧美国产一区二区 | 中文字幕视频在线观看 | 欧州一区二区三区 | 午夜视频免费网站 | 色婷婷综合久久久中字幕精品久久 | 精品视频久久久 | 日日夜夜精品视频 | 精品一区电影 | 亚洲欧美在线一区 | 欧日韩在线观看 | 四虎伊人 | 成人免费观看视频 | 欧美aaaa视频 | 91视频在线看 | 超碰在线国产 | 成人亚洲精品 | 91精品国产手机 | 一区二区三区高清 | 国产日韩一区二区 |