Domotica Arduino Integrazione WiFi
From Aino Wiki
Introduzione
Sincronizzazione NTP
Il seguente è un esempio comlesso, contiene più del necessario: usa un modulo RTC, imposta un allarme sonoro ogni minuto, per capire se l'RTC è stato già impostato lo preleva dalla memoria flash ed infine si connette al WiFi e scarica comunque l'ora aggiornata da un server NTP usando il protocollo UDP.
L'orario è visualizzato su un display a cristalli liquindi di quattro righe.
La password e il SSID del WiFi sono memorizzati in due costanti inserite nel file ArduinoSecret.h, questo file è nella stessa cartella del file contenente lo sketch (implementato in VS Code + plugin PlatformIO).
La parte relativa all'uso del NTP è presa dal video di Paolo Aliverti: [1].
#include <Arduino.h> //Per ipotesi: Arduino Nano 33 IoT #include <NTPClient.h> #include <time.h> // Libreria standard per manipolare il tempo #include <SPI.h> #include <WiFiNINA.h> #include "ArduinoSecret.h" #include <Wire.h> //Per la comunicazione I2C #include <DS3231.h> #include <LiquidCrystal_I2C.h> #include <FlashStorage.h> // Libreria di Cristian Maglie e che sostituisce EEPROM.h char c_ssid[] = SECRET_SSID; char c_pass[] = SECRET_PASS; bool m_isNTPUpdated = false; //byte c_jetLag = 2; // Fuso orario, valore delle ore da aggiunere all'orario di Grewnich int m_keyIndex = 0; //WiFi Network key index (necessario per WEP) int m_status = WL_IDLE_STATUS; // Stato della connessione WiFi WiFiUDP m_ntpUDP; // NTPClient richiede l'offset in secondi. Per l'Italia usa 3600 (ora solare) o 7200 (ora legale) NTPClient m_timeClient(m_ntpUDP, "pool.ntp.org", 3600); // 3600 = GMT+1 (Italia) LiquidCrystal_I2C m_lcd(0x27,16,2); // set the LCD address to 0x27 for a 16 chars and 2 line display DS3231 m_rtc; // Definisce una variabile persistente di tipo byte e la chiama "g_isSetStorage" // in realtà punta ad una locazione di memoria flesh per cui ci scrive o legge meddiante // funzioni dedicate: // read() // write(0xAA) <-- Scrive nella locazione 0xAA FlashStorage(g_isSetStorage, byte); const int c_buzzerPin = 2; unsigned long m_previousMillis = millis(); unsigned long m_currentMillis = millis(); void setup() { Serial.begin(9600); Wire.begin(); m_rtc.begin(); while (!Serial && (m_currentMillis - m_previousMillis <= 2000)) { //timeout 2s per evitare di restare bloccati m_currentMillis = millis(); } m_lcd.init(); m_lcd.clear(); m_lcd.backlight(); // Make sure backlight is on // Legge il valore memorizzato nella Flash byte isSet = g_isSetStorage.read(); if (isSet != 0xAA) { Serial.println("Primo avvio dopo compilazione: imposto data e ora..."); m_rtc.setDateTime(__DATE__, __TIME__); //Inserisce la data ed ora al momento della compilazione // Es.: __DATE__ = "Mar 13 2026" __TIME__ = "20:19:09" // Salva il flag (0xAA) nella Flash g_isSetStorage.write(0xAA); } else { Serial.println("RTC già configurato."); } //Allarme orologio m_rtc.setAlarm1(0, 0, 0, 0, DS3231_MATCH_S); // every minute //Verifica sul WiFi funzinate---------------------------- if (WiFi.status() == WL_NO_MODULE) { Serial.println("Comunicazione col WiFi fallita!"); m_lcd.println("1. WiFi KO..."); } else { //Connessione al WiFi while (m_status != WL_CONNECTED) { Serial.print("Connessione al WiFi: "); Serial.println(c_ssid); m_status = WiFi.begin(c_ssid, c_pass); delay(1000); } Serial.println("WiFi connesso"); m_lcd.setCursor(0,0); m_lcd.print("WiFi OK"); m_timeClient.begin(); } delay(2000); //Per dare il tempo di leggere il display } void loop() { m_previousMillis = millis(); m_currentMillis = millis(); while (!Serial && (m_currentMillis - m_previousMillis < 1000)) { m_currentMillis = millis(); } //Orario da NTP via UDP ed attraverso il WiFi !!!!! if (m_status == WL_CONNECTED) { //WiFi OK if (m_timeClient.update()) { //Ottiene data ed orario e restituisce l'esito Serial.println("Elaborazione Data e Orario con libreria NTP."); //m_timeClient.setTimeOffset(1); !!! // +1 è ilTimeOffset/fuso orario per l'Italia // Ottieni il timestamp Unix time_t epochTime = m_timeClient.getEpochTime(); // Converti in struttura temporale (tm) struct tm *ptm = gmtime ((time_t *)&epochTime); int day = ptm->tm_mday; int month = ptm->tm_mon + 1; // I mesi partono da 0 int year = ptm->tm_year + 1900; // Gli anni partono dal 1900 Serial.print("Data formattata: "); Serial.print(day); Serial.print("/"); Serial.print(month); Serial.print("/"); Serial.println(year); //setDateTime(uint16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t minute, uint8_t second) m_rtc.setDateTime(year, month, day, m_timeClient.getHours(), m_timeClient.getMinutes(), m_timeClient.getSeconds()); Serial.println("Orario sincronizzato con NTP."); m_isNTPUpdated = true; tone(c_buzzerPin, 5000, 660); } } else { Serial.println("WiFi non connesso."); } //------------------------------------------------ m_lcd.setCursor(0,0); RTCDateTime dt = m_rtc.getDateTime(); //Prende la data ed ora dell'istante corrente m_lcd.print(m_rtc.dateFormat("d-m-Y H:i:s", dt)); // Forza la conversione della temperatura per avere un dato aggiornato m_rtc.forceConversion(); // Lettura della temperatura (restituisce un valore float) float temperature = m_rtc.readTemperature(); m_lcd.setCursor(0,1); m_lcd.print(temperature); m_lcd.print(" C"); if (m_rtc.isAlarm1()) { Serial.println("Allarme"); tone(c_buzzerPin, 3000, 440); //La m_lcd.setCursor(0,2); m_lcd.print("Allarme!"); } else { m_lcd.setCursor(0,2); if (m_isNTPUpdated) { m_lcd.print("NTP "); m_isNTPUpdated = false; } else { m_lcd.print(" "); } } }
Etc
(Mappa e Link)
Integrazioni tipiche | Arduino indice | Arduino Progetti
C++ Info fondamentali | ESP32 indice | ESP8266 | Domotica | Dizionario Elettronica | Elettronica | Elettronica Appunti
Parole chiave:
