风筝
发表于: 2020-4-13 17:07:01 | 显示全部楼层

在本篇文章中,我们将学习如何使用ESP8266 NodeMCU(ESP-12E)Wi-Fi开发板和SSD1306 OLED显示屏(128×64像素)制作基于物联网的简单实时气象站。对于想了解有关从在线Internet服务器到NodeMCU板中检索数据的物联网初学者而言,该项目是一个很棒的项目。


NodeMCU从openweathermap.org的天气网站中提取温度、湿度、压力、风速和风向等天气数据,并将其显示在SSD1306液晶显示屏上。

IOT-Weather-Station-with-NodeMCU-OLED-OpenWeatherMap.jpg


所需的组件

主题很明确,我们只需要该项目的OLED显示屏和NodeMCU wifi模块即可。

●    NodeMCU ESP8266 12E模块

●    0.96英寸OLED显示屏


物联网气象站的功能框图

以下是物联网气象站的简单框图,仅说明了系统的工作原理。

Block-Diagram.jpg


openweathermap.org网站提供了有关天气数据和天气预报的在线服务。数据上传到云服务器上。 NodeMCU ESP8266 Wifi模块在线收集数据信息,并下载/检索温度、湿度、压力、风速和风向等信息。


这些数据显示在0.96英寸SSD1306 OLED显示屏上,同时显示了所在的城市名称。


连接电路图

使用NodeMCU和OpenWeatherMap制作的物联网气象站连接电路图:

Circuit-Diagram-1.png


I2C总线的SDA和SCL线分别连接NodeMCU板的GPIO4(D2)和GPIO0(D3),然后连接到SSD1306显示模块的SDA和SCL(SCK)引脚。 OLED显示模块由NodeMCU板的Vin引脚提供5V电压。


从OpenWeatherMap获取API

OpenWeatherMap访问任何位置的当前天气数据,包括全球200,000多个城市。超过40,000个气象站更新当前天气。数据以JSON、XML或HTML格式提供。本文将使用JSON格式的数据。


访问https://openweathermap.org,并使用您的帐户登录。

1-2.png


根据检索数据的需要创建或生成您的API密钥。

2-2.png


通过输入城市名称选择城市和国家/地区代码。示例:Jaipur,IN,Jaipur是一个城市,IN是印度(India)的国家代码。必须在代码中输入城市名称和国家/地区代码。

3.png


源代码/程序

以下是使用NodeMCU和OpenWeatherMap制作的物联网气象站的代码。为此,您需要3个不同的库,即Adafruit_GFX.h、Adafruit_SSD1306.h和ArduinoJson.h。您可以从“库管理器”中获取所有这些库。


输入WIFI SSID、密码和国家/地区代码、城市名称。现在,您可以将此代码上传到NodeMCU开发板。

  1. #include <ESP8266WiFi.h>
  2. #include <ESP8266HTTPClient.h> // http web access library
  3. #include <ArduinoJson.h> // JSON decoding library
  4. // Libraries for SSD1306 OLED display
  5. #include <Wire.h> // include wire library (for I2C devices such as the SSD1306 display)
  6. #include <Adafruit_GFX.h> // include Adafruit graphics library
  7. #include <Adafruit_SSD1306.h> // include Adafruit SSD1306 OLED display driver

  8. #define OLED_RESET 5 // define SSD1306 OLED reset at ESP8266 GPIO5 (NodeMCU D1)
  9. Adafruit_SSD1306 display(OLED_RESET);

  10. // set Wi-Fi SSID and password
  11. const char *ssid = "Your Wifi SSID";
  12. const char *password = "Your Wifi Password";

  13. // set location and API key
  14. String Location = "City Name, Country Code";
  15. String API_Key = "Your API Key";

  16. void setup(void)
  17. {
  18. Serial.begin(9600);
  19. delay(1000);

  20. Wire.begin(4, 0); // set I2C pins [SDA = GPIO4 (D2), SCL = GPIO0 (D3)], default clock is 100kHz

  21. // by default, we'll generate the high voltage from the 3.3v line internally! (neat!)
  22. display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // initialize with the I2C addr 0x3D (for the 128x64)
  23. // init done

  24. Wire.setClock(400000L); // set I2C clock to 400kHz

  25. display.clearDisplay(); // clear the display buffer
  26. display.setTextColor(WHITE, BLACK);
  27. display.setTextSize(1);
  28. display.setCursor(0, 0);
  29. display.println(" Internet Weather");
  30. display.print(" Station - Jaipur");
  31. display.display();

  32. WiFi.begin(ssid, password);

  33. Serial.print("Connecting.");
  34. display.setCursor(0, 24);
  35. display.println("Connecting...");
  36. display.display();
  37. while ( WiFi.status() != WL_CONNECTED )
  38. {
  39. delay(500);
  40. Serial.print(".");
  41. }
  42. Serial.println("connected");
  43. display.print("connected");
  44. display.display();
  45. delay(1000);

  46. }

  47. void loop()
  48. {
  49. if (WiFi.status() == WL_CONNECTED) //Check WiFi connection status
  50. {
  51. HTTPClient http; //Declare an object of class HTTPClient

  52. // specify request destination
  53. http.begin("http://api.openweathermap.org/data/2.5/weather?q=" + Location + "&APPID=" + API_Key); // !!

  54. int httpCode = http.GET(); // send the request

  55. if (httpCode > 0) // check the returning code
  56. {
  57. String payload = http.getString(); //Get the request response payload

  58. DynamicJsonBuffer jsonBuffer(512);

  59. // Parse JSON object
  60. JsonObject& root = jsonBuffer.parseObject(payload);
  61. if (!root.success()) {
  62. Serial.println(F("Parsing failed!"));
  63. return;
  64. }

  65. float temp = (float)(root["main"]["temp"]) - 273.15; // get temperature in °C
  66. int humidity = root["main"]["humidity"]; // get humidity in %
  67. float pressure = (float)(root["main"]["pressure"]) / 1000; // get pressure in bar
  68. float wind_speed = root["wind"]["speed"]; // get wind speed in m/s
  69. int wind_degree = root["wind"]["deg"]; // get wind degree in °

  70. // print data
  71. Serial.printf("Temperature = %.2f°C\r\n", temp);
  72. Serial.printf("Humidity = %d %%\r\n", humidity);
  73. Serial.printf("Pressure = %.3f bar\r\n", pressure);
  74. Serial.printf("Wind speed = %.1f m/s\r\n", wind_speed);
  75. Serial.printf("Wind degree = %d°\r\n\r\n", wind_degree);

  76. display.setCursor(0, 24);
  77. display.printf("Temperature: %5.2f C\r\n", temp);
  78. display.printf("Humidity : %d %%\r\n", humidity);
  79. display.printf("Pressure : %.3fbar\r\n", pressure);
  80. display.printf("Wind speed : %.1f m/s\r\n", wind_speed);
  81. display.printf("Wind degree: %d", wind_degree);
  82. display.drawRect(109, 24, 3, 3, WHITE); // put degree symbol ( ° )
  83. display.drawRect(97, 56, 3, 3, WHITE);
  84. display.display();

  85. }

  86. http.end(); //Close connection

  87. }

  88. delay(60000); // wait 1 minute

  89. }
  90. // End of code.
复制代码

跳转到指定楼层
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

主题 700 | 回复: 1480



手机版|

GMT+8, 2024-4-20 11:14 , Processed in 0.138393 second(s), 6 queries , Gzip On, MemCache On. Powered by Discuz! X3.5

YiBoard一板网 © 2015-2022 地址:河北省石家庄市长安区高营大街 ( 冀ICP备18020117号 )

快速回复 返回顶部 返回列表