Stazione Meteo con Arduino – i dettagli

Bene. Se siete qui probabilmente siete interessati a realizzare la Stazione Meteo con Arduino presentata in questo articolo: Stazione Meteo con Arduino. Se non avete letto l’articolo vi invito a farlo in modo da avere una visione più completa del sistema che andrò adesso ad illustrarvi dall’interno.

Ecco come si presenta Arduino Mega 2560 nella sua board standard:

Il sistema è composto da vari componenti connessi ad Arduino per consentire a quest’ultimo di gestire le funzionalità tipiche di una stazione meteo alla quale però sono state aggiunte delle personalizzazioni.

Vediamo le varie parti:

  • temperatura ed umidità:
    sensore DHT22 (AR2303)
    digitale con sistema di comunicazione bus 1-Wire
    > link qui
  • direzione ed intensità vento:
    anemometro integrato con bandieruola vento Davis
    un segnale analogico per la direzione del vento ed un segnale impulsivo per la velocità
    > link qui
  • luminosità ambiente:
    un sensore di luminosità TEMT6000
    segnale analogico
    > link qui
  • pressione barometrica:
    un sensore MS5611
    digitale con sistema di comunicazione bus I2C
    > link qui
  • calendario in tempo reale
    modulo RTC DS1307 con comunicazione bus I2C
    > link qui
  • dati al Server WEB
    gestione del modulo SIM800L via seriale per l’invio dei dati al Server
    > link qui

Visualizza direttamente qui, a questo link, i dati.

Rilevamento temperatura ed umidità (interni ed esterni)

Per il rilevamento dei dati di temperatura ed umidità interni ed esterni ho scelto un sensore DHT22 anche conosciuto come AR2303, essenzialmente un sensore dotato di bus 1-Wire, che vuol dire fondamentalmente che può comunicare con il processore con un solo filo. Il sensore si presenta come in foto qui sotto:

Per poterlo far funzionare è necessario collegarlo al processore. Avremo bisogno di una resistenza di pull-up (da collegare tra la linea del bus e l’alimentazione +5V) di 4,7kOhm. Seguiremo il seguente schema di collegamento:

Sceglieremo il PIN da usare come ingresso di Arduino per il bus dati. Per il mio caso ho utilizzato il PIN 6 per il sensore interno ed il PIN 7 per il sensore esterno.

A questo punto, sistemato l’hardware, passeremo al software ed useremo un paio di librerie software che ci consentiranno senza grande sforzo di scrivere il codice strettamente necessario senza troppe complicazioni.

Tanto per iniziare dichiariamo le librerie che ci occorrono e alcune label per i PIN di ingresso, unitamente alle variabili della stazione meteo:

/*
//---------------------------------------------------------------
//   STANDARD ARDUINO LIBRARIES DECLARATIVES
//---------------------------------------------------------------
*/
#include "Arduino.h"
#include <Wire.h>    // libreria di comunicazione 1-Wire

//---------------------------------------------------------------
// sensore di umidita'  e temperatura ambiente DHT AM2303
//---------------------------------------------------------------
Utilizza la connessione di comunicazione 1-wire su un pin
*/
#include "DHT.h"
DHT dht;
DHT dht2;
#define sensorUmiditaTemperatura 6         // pin sensore interno
float sensorUmidita     = 0.0;
float sensorTemperatura = 0.0;
#define sensorUmiditaTemperatura2 7        // pin sensore esterno
float sensorUmidita2     = 0.0;
float sensorTemperatura2 = 0.0;

Dopo la dichiarazione abbiamo bisogno di inizializzare gli oggetti creati nelle dichiarazioni DHT.

Quindi nella funzione setup andremo a scrivere:

void setup() {

  // inizializzazione sensore umidita'  temperatura
  dht.setup(sensorUmiditaTemperatura); 
  dht2.setup(sensorUmiditaTemperatura2); 

}

A questo punto gli oggetti sono inizializzati e pronti per essere utilizzati nel resto del codice della Stazione Meteo con Arduino.

Andremo quindi a leggere i valori di umidità e temperatura per ognuno dei sensori connessi.

Utilizzeremo un paio di funzioni della libreria DHT inclusa nelle dichiarazioni.

Nel ciclo loop inseriremo quindi:

void loop() {
        /* -------------------------------------------------
           lettura sensore umidita'  e temperatura
           ------------------------------------------------- */
        sensorUmidita     = dht.getHumidity();       // lettura umidità interna
        sensorTemperatura = dht.getTemperature();    // lettura temperatura interna
        sensorUmidita2     = dht2.getHumidity();     // lettura umidità esterna
        sensorTemperatura2 = dht2.getTemperature();  // lettura temperatura esterna
  }

Dopo l’esecuzione delle istruzioni su indicate avremo nelle variabili i dati letti dai sensori. Il gioco è fatto!

Rilevamento direzione ed intensità del vento

L’anemometro direzionale, un Davis per applicazioni professionali, è costituito da un potenziometro multigiro senza fine con passaggio di zero per la che fornisce la direzione del vento con un segnale analogico continuo (si veda sotto) ed un sensore a rilevamento magnetico che genera un impulso per ogni giro dell’anemometro, costituito dalle tre classiche semisfere montate su un supporto a cuscinetto per la rotazione continua.

L’anemometro è riportato in foto qui sotto:

Il collegamento elettrico è assicurato da un cavo lungo 15mt a 4 fili colorati così come riportato nel seguente schema:

Il filo GIALLO è l’alimentazione +5V mentre il ROSSO è il negativo.

I fili VERDE e NERO sono rispettivamente il segnale della direzione del vento e l’impulso della velocità.

Questi due segnali saranno trattati in maniera differente per via della loro natura:

  • il segnale della direzione del vento è un analogico, cioè varia da +0V a +5V per via del potenziometro
    questo segnale sarà letto da una funzione nativa di Arduino che consente appunto di leggere un segnale analogico collegato su un pin di ingresso e tradurlo in un corrispettivo valore numerico secondo la seguente regola:
    +0V –> 0
    +5V –> 1023
    tutti i valori intermedi saranno un valore di una retta passante per questi due punti, quindi ad esempio il valore di tensione di +2,5V sarà convertito in Arduino in un valore di 511 (arrotondamento incluso)
  • il segnale della velocità del vento è un impulso, quindi digitale, che sarà proporzionale alla velocità stessa del vento, quindi tanto più ravvicinati saranno tra loro questi impulsi, tanto maggiore è la velocità del vento. Esso, guardando sui datasheet del dispositivo, segue la seguente legge:
    V=P(2.25/T)
    dove V è la velocità in miglia orarie, P è il numero di impulsi nell’intervallo considerato T e 2.25 è una costante del dispositivo.

Per questa applicazione non abbiamo bisogno di librerie ma sicuramente avremo bisogno di qualche dichiarazione. Iniziamo con la direzione del vento. Una premessa è che il NORD non corrisponde necessariamente a 0° o alla posizione 0 del potenziometro, quest’ultimo infatti durante il montaggio può essere posizionato liberamente. Oltretutto una persona potrebbe scegliere di montare in posizioni diverse l’anemometro direzionale, quindi relativamente al NORD potrebbe avere una posizione diversa. Per questo motivo anche nelle stazioni meteo professionali esiste la funzione di taratura del NORD. Ed è quello che faremo anche noi. Una apposita funzione interna di correzione farà in modo di tenere conto della posizione reale del NORD correggendola. Iniziamo con qualche dichiarazione, per esempio variabili e label. Nella mia applicazione ho collegato il direzionale al PIN analogico A0 di Arduino:

/*
//---------------------------------------------------------------
//   ANEMOMETRO E DIREZIONALE VENTO DECLARATIVES
//---------------------------------------------------------------
Anemometro : connessione e decodifica
----------------------------------------------------------------
*/
#define sensorWindDirection      A0
int     sensorWindDirectionInstant, sensorWindDirectionMax = 1023;
int     sensorWindDirectionCorrectionValue = -155;
int     sensorWindDirectionValueDegrees = 0;
String  sensorWindDirectionDescription;

Nel loop andremo a leggere il valore del pin analogico. Tenendo conto che il suo valore sarà compreso tra 0 e 1023 dovremo occuparci di scalarlo nel campo 0..360 gradi e correggere quindi la posizione del NORD (nel mio caso il NORD è corretto a -155°), successivamente dai gradi ricavati andremo a titolare il nome del vento, il tutto nel seguente codice:

void loop() {
        /* -------------------------------------------------
           lettura direzione sensore vento
           ------------------------------------------------- */
        // lettura istantanea valore di ingresso analogico dal windwane
        sensorWindDirectionInstant = analogRead(sensorWindDirection);
        // trasformazione in gradi angolari
        sensorWindDirectionValueDegrees = map(sensorWindDirectionInstant, 0, sensorWindDirectionMax, 0, 360);
        // funzione per la correzione del nord
        if (sensorWindDirectionValueDegrees > 360) {
          sensorWindDirectionValueDegrees -= 360;
        }
        if (sensorWindDirectionValueDegrees < 0) {
          sensorWindDirectionValueDegrees += 360;
        }
        /*  Abbreviamento	Direzione di vento	Gradi
          N	North	0°
          NNE	Nord-Nord-Est	22.5°
          NE	Nord-Est	45°
          ENE	Est-Nord-Est	67.5°
          E	Est	90°
          ESE	Est-Sud-Est	112.5°
          SE	Sud-Est	135°
          SSE	Sud-Sud-Est	157.5°
          S	Sud	180°
          SSW	Sud-Sud-Ovest	202.5°
          SW	Sud-Ovest	225°
          WSW	Ovest-Sud-Ovest	247.5°
          W	Ovest	270°
          WNW	Ovest-Nord-Ovest	292.5°
          NW	Nord-Ovest	315°
          NNW	Nord-Nord-Ovest	337.5°*/
        if (sensorWindDirectionValueDegrees > 347 || sensorWindDirectionValueDegrees < 12 ) { sensorWindDirectionDescription = " N "; } else {
          if (sensorWindDirectionValueDegrees > 11 && sensorWindDirectionValueDegrees < 34 ) { sensorWindDirectionDescription = "NNE"; } else {
            if (sensorWindDirectionValueDegrees > 33 && sensorWindDirectionValueDegrees < 57 ) { sensorWindDirectionDescription = "NE "; } else {
              if (sensorWindDirectionValueDegrees > 56 && sensorWindDirectionValueDegrees < 79 ) { sensorWindDirectionDescription = "ENE"; } else {
                if (sensorWindDirectionValueDegrees > 78 && sensorWindDirectionValueDegrees < 102 ) { sensorWindDirectionDescription = " E "; } else {
                  if (sensorWindDirectionValueDegrees > 101 && sensorWindDirectionValueDegrees < 124 ) { sensorWindDirectionDescription = "ESE"; } else {
                    if (sensorWindDirectionValueDegrees > 123 && sensorWindDirectionValueDegrees < 147 ) { sensorWindDirectionDescription = "SE "; } else {
                      if (sensorWindDirectionValueDegrees > 146 && sensorWindDirectionValueDegrees < 169 ) { sensorWindDirectionDescription = "SSE"; } else {
                        if (sensorWindDirectionValueDegrees > 168 && sensorWindDirectionValueDegrees < 192 ) { sensorWindDirectionDescription = " S "; } else {
                          if (sensorWindDirectionValueDegrees > 191 && sensorWindDirectionValueDegrees < 214 ) { sensorWindDirectionDescription = "SSO"; } else {
                            if (sensorWindDirectionValueDegrees > 213 && sensorWindDirectionValueDegrees < 237 ) { sensorWindDirectionDescription = "SO "; } else {
                              if (sensorWindDirectionValueDegrees > 236 && sensorWindDirectionValueDegrees < 259 ) { sensorWindDirectionDescription = "OSO"; } else {
                                if (sensorWindDirectionValueDegrees > 258 && sensorWindDirectionValueDegrees < 282 ) { sensorWindDirectionDescription = " O "; } else {
                                  if (sensorWindDirectionValueDegrees > 281 && sensorWindDirectionValueDegrees < 304 ) { sensorWindDirectionDescription = "ONO"; } else {
                                    if (sensorWindDirectionValueDegrees > 303 && sensorWindDirectionValueDegrees < 327 ) { sensorWindDirectionDescription = "NO "; } else {
                                      if (sensorWindDirectionValueDegrees > 326 && sensorWindDirectionValueDegrees < 348 ) { sensorWindDirectionDescription = "NNO"; } else {
                                      }
                                    }
                                  }
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
     
}

A questo punto abbiamo la direzione del vento in gradi ed il suo relativo nome.

Ma la Stazione Meteo con Arduino è in grado anche di ottenere la velocità del vento grazie al segnale impulsivo.

Per poter determinare il giusto valore di velocità ricorreremo ad una funzione nativa del core di Arduino: gli interrupt. Cosa sono? Un interrupt è una interruzione nel ciclo normale dell’esecuzione del programma. Al verificarsi di un evento il processore congela le attività, salta ad uno specifico pezzo di programma, lo esegue e torna poi ad occuparsi del resto. In pratica è un modo “veloce” ed “immediato” di reagire ad un evento. Esistono interrupt di diverso tipo, essenzialmente interni ed esterni. Cioè generati da eventi che lo stesso processore crea oppure da eventi esterni come ad esempio la variazione di un segnale su un PIN, ed è questo che andremo a sfruttare. Per farlo abbiamo bisogno di dichiarare l’interrupt e fornire ad Arduino la routine da eseguire.

Vediamo come fare. Innanzi tutto partiamo dalle dichiarazioni delle variabili.

/*
//---------------------------------------------------------------
//   ANEMOMETRO E DIREZIONALE VENTO DECLARATIVES
//---------------------------------------------------------------
Anemometro : connessione e decodifica
----------------------------------------------------------------
*/
#define sensorWindSpeed          2
// per determinare gli impulsi dall'anemometro
volatile unsigned long windTrigger     = 0;
unsigned long          windCalculationTime = 0;
unsigned long          windCalcutationInterval = 3000;
int                    windRotation = 0;
float                  windSpeed1      = 0.0;
/*

Adesso che abbiamo definito dove è collegato il segnale dell’impulsivo (nel mio caso al PIN 2) e abbiamo dichiarato alcune speciali variabili VOLATILE (perchè saranno utilizzate nel ciclo di interrupt) possiamo dichiarare l’interrupt nel blocco setup.

void setup() {
  // inizializzazione ingresso per sensore del vento
  pinMode(sensorWindSpeed, INPUT);
  attachInterrupt(digitalPinToInterrupt(sensorWindSpeed), windInterrupt, FALLING);
}

L’interrupt interverrà quando il segnale sul PIN 2 genererà un fronte di discesa (FALLING) cioè passerà dallo stato logico 1 (+5V) allo stato logico 0 (+0v). Verrà richiamata una routine windInterrupt, che è la seguente:

/**************************************************************************
   routine INTERRUPT per la rilevazione degli impulsi dall'anemometro
***************************************************************************/
void windInterrupt() {
  if((millis() - windTrigger) > 15 ) { // debounce the switch contact. 
    windRotation++; 
    windTrigger = millis(); 
  } 
}

In pratica la routine viene chiamata ad ogni impulso e dopo un debounce del segnale di 15 millisecondi (è un modo per filtrare i rimbalzi generati da un impulso che cambia così velocemente) una variabile (windRotation) viene incrementata.

Per determinare la velocità del vento nel loop andremo ad utilizzare il seguente codice:

void loop() {
  // calcolo velocità del vento
  // calculation is executed every 3 seconds
  if (windCalculationTime < millis()) {
    // convert to mp/h using the formula V=P(2.25/T) 
    // V = P(2.25/3) = P * 0.75 
    // the computation is executed according to carefully keep in account the interval time
    windSpeed1 = windRotation * (float)(2250.0 / (windCalcutationInterval + millis() - windCalculationTime)) * 1.6093; 
    windRotation = 0;
    windCalculationTime = millis() + windCalcutationInterval;
  }

}

In pratica viene deteminato il valore di velocità ogni 3 secondi (3000 millisecondi) nella formula:

windSpeed1 = windRotation * (float)(2250.0 / (windCalcutationInterval + millis() – windCalculationTime)) * 1.6093;

dove viene tenuto conto della latenza del ciclo. Teniamo presente che Arduino sarà impegnato in altro, cioè in tutto il resto della gestione della stazione meteo, inclusa la gestione degli SMS e dei dati da inviare al Server WEB, quindi il ciclo di esecuzione dell’interno programma potrebbe essere molto instabile in termini di tempo. Grazie a questa formula viene tenuto in considerazione la latenza del ciclo è con la moltiplicazione * 1.6093 il valore del vento sarà convertito da miglia orarie a chilometri orari.

Rilevamento luminosità ambiente esterna

A questo punto ci dobbiamo occupare della lettura della luminosità esterna con il sensore TEMT6000, si tratta di un sensore che genera un segnale analogico proporzionale alla luminosità. Esso si presenta come segue:

Va alimentato a +5V ed il segnale di uscita analogico S va collegato al nostro Arduino.

Come al solito procediamo alla dichiarazione delle variabili iniziali, nel mio caso il sensore è connesso al PIN A1 analogico:

/*
//---------------------------------------------------------------
// sensore luminosità TEMT6000
//---------------------------------------------------------------
*/
#define sensorLight              A1
int     sensorLightValue = 0;
float   sensorLightLux   = 0.0;

A questo punto non ci resta che leggerne il valore e convertirlo in lux. Nel loop:

void loop() {
        sensorLightValue = analogRead(sensorLight);
        sensorLightLux   = sensorLightValue * 0.9765625;
}

la costante 0.9765625 converte il valore letto in intero 0..10123 nel corrispettivo in lux.

Rilevamento pressione barometrica atmosferica

Adesso ci dobbiamo occupare di leggere il valore barometrico della pressione attraverso il sensore MS5611.

Il sensore si presenta come in foto:

Va collegato al bus I2C che per Arduino Mega è sui pin 20-SDA 21-SCL, non modificabili. Dobbiamo collegare il canale SDA del sensore al PIN 20 di Arduino ed SCL al 21.

Ricorrendo ad alcune librerie anche questa volta riusciremo a cavarcela con poco.

Iniziamo con le solide dichiarazioni di variabili e librerie:

*
//---------------------------------------------------------------
//   SENSORE BAROMETRICO MS5611 + TEMP.
//---------------------------------------------------------------
Utilizza il bus I2C sui pin 20-SDA 21-SCL
*/
#include <MS5611.h>
MS5611 ms5611;
float sensorBaroPressione = 0.0;

Nel setup dovremo attivare la libreria:

void setup() {
  // attesa attivazione barometro MS5611
  while(!ms5611.begin()) {
    delay(500);
  }
}

ed infine nel loop leggere il valore della pressione barometrica atmosferica:

void loop() {
        /* -------------------------------------------------
           lettura sensore barometrico + temperatura
           ------------------------------------------------- */
        sensorBaroPressione   = ms5611.readPressure() / 100.0;

}

A questo punto abbiamo tutti i dati pronti.

Lettura del calendario del clock in tempo reale

Adesso dobbiamo leggere i dati dal clock in tempo reale, dal modulo DS1307.

Il modulo si presente come segue:

Anche in questo caso siamo di fronte ad un dispositivo con bus di comunicazione I2C, quindi seguiremo le stesse regole citate su per il MS5611. Collegheremo cioè il canale SDA del modulo sul PIN 20 di Arduino, in parallelo ed insieme al segnale del MS5611 e faremo la stessa cosa per il canale SCL.

Nelle dichiarazioni, useremo la libreria DS1307 pronta per facilitarci la vita. Includeremo anche la libreria Time.h per agevolarci nella manipolazione dei valori di data ed ora.

/*
//---------------------------------------------------------------
//   DS1307 RTC DECLARATIVES
//---------------------------------------------------------------
Utilizza il bus I2C sui pin 20-SDA 21-SCL
*/
#include <Time.h>
#include <DS1307.h>
DS1307 rtc(SDA, SCL);
long RTCPollingTime;
String RTCGeneral, RTCDate, RTCClock;

Successivamente andremo ad inizializzare il tutto nel blocco setup, come segue:

void setup() {
  // controllo RTC
  // Initialize the rtc object
  rtc.begin();
  // Set the clock to run-mode
  rtc.halt(false);
  RTC_Check();
}

la funzione RTC_Check() servirà a leggere ogni volta che vogliamo il clock dal modulo e sarà la seguente:

/**************************************************************************
   DATE / TIME ROUTINES
***************************************************************************/
void RTC_Check() {
  RTCDate    = rtc.getDateStr(); //String(dayName[weekday(now()) - 1]) + " " + intToStringZ((int)tm.Day, 2) + "/" + intToStringZ((int)tm.Month, 2) + "/" + intToStringZ((int)(tmYearToCalendar(tm.Year)), 4);
  //RTCClock   = String(rtc.getDOWStr(FORMAT_SHORT)) + " " + rtc.getTimeStr(); //intToStringZ((int)tm.Hour, 2) + ":" + intToStringZ((int)tm.Minute, 2);
  RTCClock   = rtc.getTimeStr(); //intToStringZ((int)tm.Hour, 2) + ":" + intToStringZ((int)tm.Minute, 2);
  RTCGeneral = RTCDate + " " + RTCClock;
}

a questo punto nel ciclo del loop:

void loop() {
   RTC_Check();
}

Ed il gioco è fatto.

A questo punto dobbiamo preoccuparci di inviare i dati al Server WEB, memorizzarli nel database e successivamente renderli disponibili per la visualizzazione su una apposita pagina web grafica, magari corredata di grafici, come di seguito visualizzato.

Invio dati al Server WEB

Adesso la parte di invio dati, affidata al modulo SIM800L connesso in seriale ad una delle porte UART di Arduino. Nel mio caso ho utilizzato la SERIAL1.

Il modulo si presenta come segue:

A seconda della versione che avrete scelto (in commercio ve ne sono tante), andrà collegata la linea della +5V alla alimentazione e la linea GND allo zero della scheda di Arduino ed i PIN di comunicazione come segue:

ARDUINO SERIAL1 PIN TX 18 al PIN RX del modulo SIM800L

ARDUINO SERIAL1 PIN RX 19 al PIN TX del modulo SIM800L

Quindi senza necessità di librerie extra iniziamo con la dichiarazione delle variabili e poi direttamente dal blocco setup:

/*
//---------------------------------------------------------------
// DATI AL SERVER
//---------------------------------------------------------------
*/
unsigned long secondsTimer;
unsigned long secondsCounter;
unsigned long secondsCounterSet = 600; // intervallo in secondi caricamento dati sul server
bool server_Cycle;
int server_Cycle_idx;
unsigned long server_polling;

void setup() {
  // inizializzazione porta seriale 1 per modem GSM
  Serial1.begin(57600);
}

A questo punto faremo in modo che ogni 10 minuti la Stazione Meteo invii i dati al server. Utilizzeremo il metodo HTTP GET per passare i parametri al server che consiste essenzialmente nel chiamare una pagina web del server passando i parametri direttamente nell’URL della pagina.

Vediamo come fare:

void loop()  {
  // controlla il tempo per caricare i dati sul server
  if (secondsTimer < millis() && !server_Cycle) {
    secondsTimer = millis() + 1000;
    secondsCounter++;
    // carica i dati al server ogni secondsCounterSet secondi
    if (secondsCounter > secondsCounterSet) {
      server_Cycle = true;
      server_Cycle_idx = 0;
    }
  }
  if (server_Cycle && server_polling < millis()) {
    switch (server_Cycle_idx) {
      case 0:  
        Serial1.print("AT+SAPBR=3,1,\"CONTYPE\",\"GPRS\"\r\n");
        break;
      case 1:
        Serial1.print("AT+SAPBR=3,1,\"APN\",\"il_tuo_punto_di_accesso_APN_del_tuo_gestore_di_telefonia\"\r\n");
        break;
      case 2:
        Serial1.print("AT+SAPBR=1,1\r\n");
        break;
      case 3:
        Serial1.print("AT+SAPBR=2,1\r\n");
        break;
      case 4:
        Serial1.print("AT+HTTPINIT\r\n");
        break;
      case 5:
        Serial1.print("AT+HTTPPARA=\"CID\",1\r\n");
        break;
      case 6:
        Serial1.print("AT+HTTPPARA=\"URL\",\"http://www.tuosito.ext/tua_pagina.php?vb=" + String(battery_Voltage) + 
            "&tb=" + String(sensorBaroTemperatura) + 
            "&vg=" + String(sensorWindDirectionValueDegrees) + 
            "&vv=" + String(windSpeed1) + 
            "&ti=" + String(sensorTemperaturaK) + 
            "&ui=" + String(sensorUmiditaK) + 
            "&to=" + String(sensorTemperaturaK2) +
            "&uo=" + String(sensorUmiditaK2) + 
            "&pa=" + String(sensorBaroPressione) + 
            "&le=" + String(sensorLightLux) + "\"\r\n");
        break;
      case 7:
        Serial1.print("AT+HTTPACTION=0\r\n");
        break;
      case 8:
        secondsCounter = 0;
        server_Cycle = false;
        server_Cycle_idx = 0;
        break;
    }
    server_Cycle_idx++;
    server_polling = millis() + 35;
  }
}

Per la parte WEB, cioè la preparazione del database, la pagina PHP di caricamento dati e la pagina per la visualizzazione, rimanete sintonizzati su questo sito, presto posterò tutti i dettagli del caso. 😉

Dati e Grafici dalla Stazione Meteo con Arduino in tempo reale