Nota
Ciao, benvenuto nella community di appassionati SunFounder Raspberry Pi & Arduino & ESP32 su Facebook! Approfondisci Raspberry Pi, Arduino ed ESP32 insieme ad altri appassionati.
Perché unirti?
Supporto Esperto: Risolvi problemi post-vendita e sfide tecniche con l’aiuto della nostra community e del team.
Impara e Condividi: Scambia suggerimenti e tutorial per migliorare le tue competenze.
Anteprime Esclusive: Ottieni accesso anticipato a nuovi annunci di prodotti e anteprime.
Sconti Speciali: Approfitta di sconti esclusivi sui nostri prodotti più recenti.
Promozioni Festive e Giveaway: Partecipa a giveaway e promozioni festive.
👉 Pronto per esplorare e creare con noi? Clicca [Qui] e unisciti oggi!
WeatherTime Screen
Questo sketch si connette a una rete WiFi, recupera i dati meteo da OpenWeatherMap ogni minuto, ottiene l’ora corrente da un server NTP e visualizza il giorno, l’ora e le informazioni meteorologiche su uno schermo OLED.
Componenti Necessari
In questo progetto, abbiamo bisogno dei seguenti componenti.
È sicuramente conveniente acquistare un kit completo, ecco il link:
Nome |
ARTICOLI IN QUESTO KIT |
LINK |
|---|---|---|
Elite Explorer Kit |
300+ |
È anche possibile acquistarli separatamente dai link sottostanti.
INTRODUZIONE AI COMPONENTI |
LINK PER L’ACQUISTO |
|---|---|
- |
|
Cablaggio
Schema
OpenWeather
Ottieni le chiavi API di OpenWeather
OpenWeather è un servizio online, di proprietà di OpenWeather Ltd, che fornisce dati meteorologici globali tramite API, inclusi dati meteorologici attuali, previsioni, nowcast e dati storici per qualsiasi posizione geografica.
Visita OpenWeather per accedere o creare un account.
Clicca sulla pagina delle API dalla barra di navigazione.
Trova Current Weather Data e clicca su Iscriviti.
Sotto Current weather and forecasts collection, iscriviti al servizio appropriato. Nel nostro progetto, la versione gratuita è sufficiente.
Copia la chiave dalla pagina API keys.
Copiala nel file
arduino_secrets.h.#define SECRET_SSID "<SSID>" // your network SSID (name) #define SECRET_PASS "<PASSWORD>" // your network password #define API_KEY "<OpenWeather_API_KEY>" #define LOCATION "<YOUR CITY>"
Imposta il fuso orario della tua posizione.
Prendi la capitale della Svezia, Stoccolma, come esempio. Cerca «fuso orario Stoccolma» su Google.
Nei risultati della ricerca, vedrai «GMT+1», quindi imposta il parametro della funzione sottostante su
3600 * 1secondi.timeClient.setTimeOffset(3600 * 1); // Regola per il tuo fuso orario (questo è +1 ora)
Installa la Libreria
Per installare la libreria, utilizza il Gestore delle Librerie Arduino e cerca «ArduinoMqttClient», «FastLED», «Adafruit GFX» e «Adafruit SSD1306» e installale.
ArduinoJson.h: Utilizzato per gestire i dati JSON (dati ottenuti da OpenWeatherMap).
NTPClient.h: Utilizzato per ottenere l’ora in tempo reale.
Adafruit_GFX.h, Adafruit_SSD1306.h: Utilizzati per il modulo OLED.
Esegui il Codice
Nota
Puoi aprire il file
06_weather_oled.inonel percorsoelite-explorer-kit-main\iot_project\06_weather_oleddirettamente.Oppure copia questo codice nell’IDE di Arduino.
Nota
Nel codice, SSID e password sono memorizzati in arduino_secrets.h. Prima di caricare questo esempio, è necessario modificarli con le proprie credenziali WiFi. Inoltre, per motivi di sicurezza, assicurati che queste informazioni siano mantenute riservate durante la condivisione o la memorizzazione del codice.
#define SECRET_SSID "your_ssid" // your network SSID (name)
#define SECRET_PASS "your_password" // your network password (use for WPA, or use as key for WEP)
#define API_KEY "your_key"
#define LOCATION "your_location"
1/*
2 The code fetches and shows weather information such as temperature, humidity, pressure,
3 and wind details. This information is obtained from the OpenWeatherMap API through a WiFi
4 connection. The program initially connects to the WiFi network and retrieves the current
5 time from an NTP server. It then regularly sends HTTP requests to retrieve weather data
6 from the OpenWeatherMap API. Upon receiving a JSON response, it parses the data and displays
7 both the weather information and current time on the OLED screen.
8
9 Board: Arduino Uno R4 WiFi
10 Component: OLED
11 Library: https://github.com/bblanchon/ArduinoJson (ArduinoJson by Benoit Blanchon)
12 https://github.com/adafruit/Adafruit_SSD1306 (Adafruit SSD1306 by Adafruit)
13 https://github.com/adafruit/Adafruit-GFX-Library (Adafruit GFX Library by Adafruit)
14 https://github.com/arduino-libraries/NTPClient (NTPClient by Fabrice Weinberg)
15
16*/
17
18#include "WiFiS3.h"
19#include <ArduinoJson.h> // JSON decoding library
20#include "arduino_secrets.h"
21
22// NTP client setup to get real-time data
23#include <NTPClient.h>
24#include <WiFiUdp.h>
25WiFiUDP ntpUDP;
26NTPClient timeClient(ntpUDP, "pool.ntp.org"); // NTP server
27
28// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
29#include <SPI.h>
30#include <Wire.h>
31#include <Adafruit_GFX.h>
32#include <Adafruit_SSD1306.h>
33#define SCREEN_WIDTH 128 // OLED display width, in pixels
34#define SCREEN_HEIGHT 64 // OLED display height, in pixels
35#define OLED_RESET 4 // Reset pin # (or -1 if sharing Arduino reset pin)
36Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
37
38// WiFi credentials and server information
39char ssid[] = SECRET_SSID; // your network SSID (name)
40char pass[] = SECRET_PASS; // your network password
41int status = WL_IDLE_STATUS;
42char server[] = "api.openweathermap.org"; // name address for OWM (using DNS)
43
44// Timing variables to manage update intervals
45unsigned long lastConnectionTime = 0; // last time you connected to the server, in milliseconds
46const unsigned long postingInterval = 60L * 1000L; // delay between updates, in milliseconds
47
48// WiFi client for connecting to the API server
49WiFiClient client;
50
51void setup() {
52 //Initialize serial and wait for port to open:
53 Serial.begin(9600);
54 while (!Serial) {
55 ; // wait for serial port to connect. Needed for native USB port only
56 }
57
58 // check for the WiFi module:
59 if (WiFi.status() == WL_NO_MODULE) {
60 Serial.println("Communication with WiFi module failed!");
61 // don't continue
62 while (true)
63 ;
64 }
65
66 String fv = WiFi.firmwareVersion();
67 if (fv < WIFI_FIRMWARE_LATEST_VERSION) {
68 Serial.println("Please upgrade the firmware");
69 }
70
71 // attempt to connect to WiFi network:
72 while (status != WL_CONNECTED) {
73 Serial.print("Attempting to connect to SSID: ");
74 Serial.println(ssid);
75 status = WiFi.begin(ssid, pass);
76 delay(5000); // Wait 5 seconds before retrying
77 }
78
79 printWifiStatus();
80
81 // Initialize and clear OLED display
82 display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
83 display.display();
84 display.clearDisplay();
85
86 // Initialize and clear OLED display
87 timeClient.begin();
88 timeClient.setTimeOffset(3600 * 8); // Adjust for your time zone (this is +8 hour)
89}
90
91void loop() {
92
93 read_response();
94 timeClient.update();
95
96 // Check if it's time to send a new request
97 if (!lastConnectionTime || millis() - lastConnectionTime > postingInterval) {
98 httpRequest();
99 }
100}
101
102
103void read_response() {
104 uint32_t received_data_num = 0;
105 String payload = "";
106 bool jsonDetected = false;
107
108 // Read data from the client connection
109 while (client.available()) {
110 /* actual data reception */
111 char c = client.read();
112
113 // for debug
114 Serial.print(c);
115
116 if ('{' == c) {
117 jsonDetected = true;
118 }
119 if (jsonDetected) {
120 payload += c;
121 }
122 received_data_num++;
123 }
124 if (jsonDetected) {
125 /* print data to serial port */
126 // Serial.print("data num : ");
127 // Serial.println(received_data_num);
128 // Serial.print("data : ");
129 // Serial.println(payload);
130 DynamicJsonDocument root(1024);
131 DeserializationError error = deserializeJson(root, payload);
132 if (error) {
133 Serial.print("Deserialization failed with code: ");
134 Serial.println(error.c_str());
135 return;
136 }
137
138 String weather = (root["weather"][0]["main"]);
139 float temp = (float)(root["main"]["temp"]) - 273.15; // get temperature in °C
140 int humidity = root["main"]["humidity"]; // get humidity in %
141 float pressure = (float)(root["main"]["pressure"]) / 1000; // get pressure in bar
142 float wind_speed = root["wind"]["speed"]; // get wind speed in m/s
143 int wind_degree = root["wind"]["deg"]; // get wind degree in °
144
145 // // print data
146 // Serial.println("Temperature= " + String(temp) + " °C");
147 // Serial.println("Humidity = " + String(humidity) + " %");
148 // Serial.println("Pressure = " + String(pressure) + " bar");
149 // Serial.println("Wind speed = " + String(wind_speed) + " m/s");
150 // Serial.println("Wind degree = " + String(wind_degree) + " °");
151 displayWeatherData(weather, temp, humidity, pressure, wind_speed);
152 }
153}
154
155
156void httpRequest() {
157 // close any connection before send a new request.
158 client.stop();
159
160 // Construct HTTP GET request for OpenWeatherMap API
161 String httpRequest = "";
162 httpRequest += "GET /data/2.5/weather?q=" LOCATION "&APPID=" API_KEY " HTTP/1.1";
163
164 // if you get a connection, report back via serial:
165 if (client.connect(server, 80)) {
166 Serial.println("connected");
167 // Make a HTTP request:
168 client.println(httpRequest);
169 client.println("Host: api.openweathermap.org");
170 client.println("Connection: close");
171 client.println();
172 // note the time that the connection was made:
173 lastConnectionTime = millis();
174 } else {
175 // if you couldn't make a connection:
176 Serial.println("connection failed");
177 }
178}
179
180void printWifiStatus() {
181 // print the SSID of the network you're attached to:
182 Serial.print("SSID: ");
183 Serial.println(WiFi.SSID());
184
185 // print your board's IP address:
186 IPAddress ip = WiFi.localIP();
187 Serial.print("IP Address: ");
188 Serial.println(ip);
189
190 // print the received signal strength:
191 long rssi = WiFi.RSSI();
192 Serial.print("signal strength (RSSI):");
193 Serial.print(rssi);
194 Serial.println(" dBm");
195}
196
197void displayWeatherData(String weather, float temp, int humidity, float pressure, float wind_speed) {
198 display.clearDisplay();
199 display.setTextSize(1); // Normal 1:1 pixel scale
200 display.setTextColor(SSD1306_WHITE); // Draw white text
201 display.setCursor(0, 0); // Start at top-left corner
202
203 // Display Day of the Week
204 String daysOfTheWeek[7] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };
205 display.print(daysOfTheWeek[timeClient.getDay()]);
206
207 display.print(" ");
208 if (timeClient.getHours() < 10) display.print("0"); // Add leading zero for hours < 10
209 display.print(timeClient.getHours());
210 display.print(":");
211 if (timeClient.getMinutes() < 10) display.print("0"); // Add leading zero for minutes < 10
212 display.println(timeClient.getMinutes());
213
214 display.println();
215 display.print(LOCATION);
216 display.println(" " + weather);
217
218 // Display Weather
219 display.print("Temperature: ");
220 display.print(temp);
221 display.println(" C");
222
223 display.print("Humidity: ");
224 display.print(humidity);
225 display.println(" %");
226
227 display.print("Pressure: ");
228 display.print(pressure);
229 display.println(" bar");
230
231 display.print("Wind: ");
232 display.print(wind_speed);
233 display.println(" m/s");
234
235 display.display();
236}
Come Funziona?
Librerie e Definizioni:
WiFiS3.h: Probabilmente una libreria specifica per un modulo WiFi o una scheda per gestire le connessioni WiFi.ArduinoJson.h: Questa libreria è utilizzata per decodificare (e codificare) dati JSON.arduino_secrets.h: Un file separato in cui sono memorizzati i dati sensibili (come le credenziali WiFi). Questa è una buona pratica per mantenere le credenziali fuori dal codice principale.NTPClient & WiFiUdp: Sono utilizzati per recuperare l’ora corrente da un server NTP (Network Time Protocol).
Librerie Adafruit: Utilizzate per gestire il display OLED.
Varie variabili globali: Includono le credenziali WiFi, i dettagli del server e altro, che saranno utilizzati durante tutto il programma.
setup():Inizializza la comunicazione seriale.
Controlla e stampa la versione del firmware del modulo WiFi.
Tenta di connettersi alla rete WiFi utilizzando l’SSID e la password forniti.
Stampa lo stato della connessione WiFi (SSID, IP, Intensità del segnale).
Inizializza il display OLED.
Avvia il client NTP per recuperare l’ora corrente e imposta un offset temporale (in questo caso, 1 ora, che potrebbe corrispondere a un fuso orario specifico).
read_response():Legge la risposta dal server, cercando specificamente dati JSON (denotati da
{e}).Se vengono trovati dati JSON, li decodifica per estrarre dettagli meteo come temperatura, umidità, pressione, velocità del vento e direzione del vento.
Chiama la funzione
displayWeatherDataper visualizzare le informazioni meteorologiche sullo schermo OLED.
httpRequest():Chiude eventuali connessioni esistenti per garantire che il socket del modulo WiFi sia libero.
Tenta di connettersi al server OpenWeatherMap.
Se connesso, invia una richiesta GET HTTP per recuperare i dati meteorologici per una specifica posizione definita da
LOCATION(probabilmente definita inarduino_secrets.ho altrove).Registra l’ora in cui è stata effettuata la richiesta.
loop():Chiama la funzione
read_responseper elaborare eventuali dati in arrivo dal server.Aggiorna l’ora dal server NTP.
Verifica se è il momento di effettuare un’altra richiesta al server meteorologico (basato sull’intervallo di pubblicazione,
postingInterval). Se sì, chiama la funzionehttpRequest.
printWifiStatus():Stampa l’SSID della rete connessa.
Stampa l’indirizzo IP locale della scheda.
Stampa l’intensità del segnale (RSSI).
displayWeatherData():Cancella lo schermo OLED.
Visualizza il giorno della settimana corrente.
Visualizza l’ora corrente nel formato HH:MM.
Visualizza i dati meteorologici forniti (temperatura, umidità, pressione e velocità del vento).