SafeString: conversione da numero a SafeString

come fai a dire che non "parte" il codice?...intendi che non si connette al WIFI?...o cosa?

PS: non è una risposta legata ad un post specifico e non è mirato risolvere un problema.
Una operazione tra variabili unsigned non potrà avere mai valore negativo, cioè <0. Semplicemente non ha senso, e forse su ESP-32 non c'è proprio owerflow.

Ciao.

Diciamo che non vedendo arrivare i dati ho sempre dato per scontato che il problema fosse che non venisse eseguito il codice all'avvio.. Non pensavo potessero esserci tutte queste problematiche varie..
Ci sono alternative o modifiche che mi consigliate per rendere il codice più affidabile?

Quindi questa parte di codice può essere eliminata?

bhe...sicuramente va sistemato il "conteggio" delle posizioni degli array...poi va sistemato la verifica del tempo trascorso...poi va aggiunta verifica della connessione al wifi con relativa gestione della non o perdita di connessione...poi andrebbero aggiunte almeno delle "stampe" per fare un po' di debug...

ok, in merito al conteggio degli array ho capito e sto provvedendo.

Come mi consigli di migliorare invece la parte di verifica del tempo trascorso e la gestione della connessione wifi e relativa non perdita della connessione?

Grazie mille

la libreria WIFI mette a disposizione il metodo ".staus()" che ritorna:

Value Constant Meaning
0 WL_IDLE_STATUS temporary status assigned when WiFi.begin() is called
1 WL_NO_SSID_AVAIL when no SSID are available
2 WL_SCAN_COMPLETED scan networks is completed
3 WL_CONNECTED when connected to a WiFi network
4 WL_CONNECT_FAILED when the connection fails for all the attempts
5 WL_CONNECTION_LOST when the connection is lost
6 WL_DISCONNECTED when disconnected from a network

quindi nel setup(), dopo il ".begin(xxx,yyy)" puoi mettere:

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
\\fai qualche cosa...
  }

nel loop() fai lo stesso controllo ma con un "if" ed ogni tot di tempo, non serve ad ogni ciclo loop(), e se torna false fai quello che vuoi...resetti l'esp, chiudi il Wifi e provi una nuova connessione..etc etc...e magari fai un tot di lampeggi del LED dell'esp per dire che c'è problema con la connessione.

lo stesso per gli altri sensori che leggi...se uno torna un errore devi decidere cosa fare...

Utilizzo esp32 di Espressif Systems versione 3.0.4

Ti ringrazio per questi consigli preziosi, ho già aggiunto le modifiche per la parte di connessione wifi.
In merito ai sensori, come faccio a capire se un sensore è in errore?

dando un'occhiata veloce alla libreria BME280 sembra che le letture di umidità, temperatura e pressione ritornino NAN il sensore è disabilitato...la pressione ritorna "0" in caso si una division eper "0".
anche per il sensore il ".begin(xxx)" ti ritorna true o false...

consiglio sempre valido...le librerie vanno studiate.

Ho fatto delle prove tutta oggi.
Mi sono accorto che se stampo i valori salvati nell'array dopo ogni lettura che effettuo ogni minuto, è tutto corretto, tranne nell'ultima delle 10 letture, dove riscontro una anomalia che manda in blocco l'esecuzione dell'intero programma.
Nella decima lettura infatti, se stampo il valore dell'umidità salvata nell'array, invece di ottenere per esempio 82, trovo un valore enorme. Mentre se stampo la pressione salvata nell'array sempre alla decima e ultima lettura, a video leggo ovf.
Come mai questo mi accade solo nella decima lettura mentre tutte le altre sono salvate correttamente?
È un problema di variabili e di array?

Grazie mille

posta il codice delle prove...

#include <Adafruit_Sensor.h>      //per gestire il sensore BME280
#include <Adafruit_BME280.h>      //per gestire il sensore BME280
#include <WiFiClientSecure.h>     //per gestire la connessione alla rete Wifi e al client
#include <WiFi.h>                 //per gestire la connessione wifi
#include <Wire.h>                 //per gestire I2C

//dati per la connessione alla rete Wifi
const char* SSID = "xxx";
const char* PASSWORD = "xxx";

//dati per la connessione
const char* server = "www.xxx.it";
const uint16_t port = 443;

//dati intervallo lettura sensori
unsigned long tempo_start_lettura_sensori;
unsigned long intervallo_lettura_sensori = 60000;           //effettuiamo una lettura dei sensori ogni 60 secondi

//dati sensore BME280
Adafruit_BME280 sensore_temp_umid_press_BME280;

//dati sensore fotoresistenza
const int pinFotoresistenza = 32;

//dati anemometro
const float pigreco = 3.141593; 
const float raggio = 0.06;            //raggio dell'anemometro in metri
const int pinAnemometro = 27;     
int stato_reed_anemometro = 0; 
int stato_reed_old_anemometro = 0;    //variabile per evitare doppie pulsazioni
int num_pulsazioni = 0;               //numero di pulsazioni (una per giro, c'è un solo magnete)
unsigned long int tempo_start_anemometro = 0;       //memorizza i millisecondi dalla prima pulsazione conteggiata
unsigned long int tempo_trascorso_anemometro = 0;   //conteggia il tempo trascorso dalla prima pulsazione
unsigned long int tempo_massimo_anemometro = 2000;  //tempo (in millisecondi) dopo il quale calcolare la velocità e azzerare il numero di pulsazioni
                                                    //così non si conteggiano brevi folate di vento
unsigned long int inizio_elaborazione_anemometro;
float velocita_vento_max;                           //velocita vento massima misurata nelle 10 rilevazioni
float velocita_vento_min;                           //velocita vento minima misurata nelle 10 rilevazioni

//dati pluviometro
const float mmBasculata = 0.40;                     //millimetri per ogni basculata
const int pinPluviometro = 13;                      
int basculate = 0;                                  //conteggio numero basculate
float mmPrecipitazioni = 0.0;                       //conteggio millimetri di pioggia
int stato_reed_pluviometro = 0; 
int stato_reed_old_pluviometro = 0;                 //variabile per evitare doppie pulsazioni
                           
//dichiarazione variabili ed array
int num_rilevazioni = 0;

float temperatura[9];
long umidita[9]; 
float pressione[9];
float luminosita[9];  
float velocita_vento[9];   

float temperatura_media;
float umidita_media;
float pressione_media;
float luminosita_media;
float velocita_vento_media;      

float temperatura_tot;
float umidita_tot;
float pressione_tot;
float luminosita_tot;
float velocita_vento_tot;  

float precipitazioni;         //valore da trasmettere al database

void setup() {

  delay(500);

  Serial.begin(9600);
  
  //connessione Wifi
  WiFi.begin(SSID, PASSWORD);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.println("Tentativo di connessione");
  }
  Serial.println("Connesso");

  //impostazione avvio millis per lettura sensori
  tempo_start_lettura_sensori = millis();
  
  //inizializzazione I2C
  Wire.begin();        

  //inizializzazione sensore BME280      
  sensore_temp_umid_press_BME280.begin(0x76);

  //impostazione pin anemometro
  pinMode(pinAnemometro, INPUT);  

  //impostazione pin pluviometro
  pinMode(pinPluviometro, INPUT);         
}

void loop() {
  Serial.println(num_rilevazioni);

  //reset di tempo_start_lettura_sensori in caso di overflow di millis che si azzera
  if (millis()-tempo_start_lettura_sensori<0) {
    tempo_start_lettura_sensori = millis();
  }

  //pluviometro
  stato_reed_pluviometro = digitalRead(pinPluviometro);         //legge il contatto reed 

  if (stato_reed_pluviometro != stato_reed_old_pluviometro){    //verifica se è cambiato lo stato
        
    stato_reed_old_pluviometro = stato_reed_pluviometro;        //se SI aggiorna lo stato
  
    if (stato_reed_pluviometro == HIGH){                        //controlla se lo stato è alto (passaggio magnete)
          
      basculate++;                                              //incrementa il numero di basculate
      mmPrecipitazioni = mmPrecipitazioni + mmBasculata;        //sommatoria millimetri di pioggia rilevati
    }
  }

  //verifica se è trascorso l'intervallo per la lettura dei sensori
  if ((millis()-tempo_start_lettura_sensori) > intervallo_lettura_sensori){

    tempo_start_lettura_sensori = millis();
    
    //anemometro    
    inizio_elaborazione_anemometro = millis();      //memorizza l'inizio dell'elaborazione (in caso di nessun impulso dopo tot tempo sospendiamo la rilevazione dell'anemometro)
  
    while (tempo_trascorso_anemometro < tempo_massimo_anemometro) { //esegue fino a quando il tempo trascorso è minore al tempo massimo impostato
      stato_reed_anemometro = digitalRead(pinAnemometro);    //legge il contatto reed 

      if (stato_reed_anemometro != stato_reed_old_anemometro) {         //verifica se è cambiato lo stato
        stato_reed_old_anemometro = stato_reed_anemometro;              //se SI aggiorna lo stato
  
        if (stato_reed_anemometro == HIGH) {                            //controlla se lo stato è alto (passaggio magnete)
          if (num_pulsazioni == 0) {tempo_start_anemometro = millis();}       //se è il primo passaggio memorizza il tempo di partenza
          
          num_pulsazioni = num_pulsazioni + 1;                                //aggiorna il contatore delle pulsazioni    
          tempo_trascorso_anemometro = (millis() - tempo_start_anemometro);   //conteggia il tempo trascorso dallo start
        }
      }
      delay(10);
      if ((millis() - inizio_elaborazione_anemometro > 3000) || (inizio_elaborazione_anemometro > millis())) {    //inizio_elaborazione_anemometro > millis() per effettuare un eventuale reset di millis (se millis torna a 0, quindi minore di inizio_elaborazione_anemometro)
        tempo_trascorso_anemometro = tempo_massimo_anemometro;
      } 
    }
    
    float tempo_trascorso_anemometro_in_secondi = (tempo_trascorso_anemometro/1000.0);            //converte in secondi
    //velocita_vento[num_rilevazioni] = (3.6*num_pulsazioni*2*pigreco*raggio)/tempo_trascorso_anemometro_in_secondi;      //velocità in km/h (formula iniziale non utilizzata)

    //2 impulsi/sec -> velocità vento 5km/h quindi: 5km/h : 2 impulsi/sec = velcoità vento : (impulsi/secondo rilevati)
    //coefficiente correzione attrito x2.5
    velocita_vento[num_rilevazioni]=((num_pulsazioni/tempo_trascorso_anemometro_in_secondi) * 5 / 2) * 2.5;
    
    Serial.println(velocita_vento[num_rilevazioni]);

    num_pulsazioni = 0;       //azzera il contatore delle pulsazioni per una nuova lettura        
    tempo_trascorso_anemometro = 0;
    
    //sensore BME280
    temperatura[num_rilevazioni]=sensore_temp_umid_press_BME280.readTemperature();
    umidita[num_rilevazioni]=sensore_temp_umid_press_BME280.readHumidity();
    pressione[num_rilevazioni]=sensore_temp_umid_press_BME280.readPressure();

    Serial.println(temperatura[num_rilevazioni]);
    Serial.println(umidita[num_rilevazioni]);
    Serial.println(pressione[num_rilevazioni]);

    //sensore fotoresistenza
    luminosita[num_rilevazioni]=analogRead(pinFotoresistenza);

    Serial.println(luminosita[num_rilevazioni]);

    //operazioni da eseguire alla decima lettura eseguita
    if (num_rilevazioni==9){

      //azzeramento del contatore
      num_rilevazioni=0; 

      //impostazione dei valori delle variabili prima del ciclo while
      int i = 1;
      temperatura_tot=0;
      umidita_tot=0;
      pressione_tot=0;
      luminosita_tot=0;
      velocita_vento_tot=0;

      velocita_vento_max=0;
      velocita_vento_min=1000;

      precipitazioni=0;   //valore da trasmettere al database

      //scorre i dieci valori degli array
      while (i<11) {  
        
        //calcolo del totale delle 10 rilevazioni per determinare la media
        temperatura_tot=temperatura_tot+temperatura[i];
        umidita_tot=umidita_tot+(float)umidita[i];
        pressione_tot=pressione_tot+pressione[i];
        luminosita_tot=luminosita_tot+luminosita[i];
        velocita_vento_tot=velocita_vento_tot+velocita_vento[i];

        //calcolo velocita_vento_max
        
        if (velocita_vento[i]>=velocita_vento_max){
          velocita_vento_max=velocita_vento[i];
        }

        //calcolo velocita_vento_min
        
        if (velocita_vento[i]<=velocita_vento_min){
          velocita_vento_min=velocita_vento[i];
        }
  
        i++;
        
      }

      //calcolo dei valori da trasmettere al database
      temperatura_media=temperatura_tot / 10.00;
      umidita_media=umidita_tot / 10.00;
      pressione_media=pressione_tot / 10.00;
      luminosita_media=luminosita_tot / 10.00;
      velocita_vento_media=velocita_vento_tot / 10.00;

      precipitazioni=mmPrecipitazioni;

      //azzeramento valori pluviometro per prossime letture
      basculate=0;                                      
      mmPrecipitazioni=0;
      
      //trasmissione dati al server

      if (WiFi.status() != WL_CONNECTED) {
      //verifica connessione Wifi

        //connessione Wifi
        WiFi.begin(SSID, PASSWORD);
        while (WiFi.status() != WL_CONNECTED) {
          delay(500);
          Serial.println("Tentativo di connessione");
        }
        Serial.println("Connesso");

      }

      if(WiFi.status()== WL_CONNECTED){
      //verifica che il collegamento wifi sia attivo

        String var="temp=" + String(temperatura_media) + "&umid=" + String(umidita_media) + "&pres=" + String(pressione_media) + "&lumi=" + String(luminosita_media) + "&velo=" + String(velocita_vento_media) + "&velo_max=" + String(velocita_vento_max) + "&velo_min=" + String(velocita_vento_min) + "&prec=" + String(precipitazioni);
        String url = "GET /aggiungi.php?" + var + " HTTP/1.1";

        Serial.println(url);

        //collegamento all'host
        
        WiFiClientSecure client;
        client.setInsecure();               //non si utilizzano certificati di sicurezza

        if (client.connect(server, port)) {
        //verifica che il collegamento col client sia andato a buon fine

          client.println(url);
          client.println("Host: www.xxx.it");
          client.println("Access-Control-Allow-Origin: *");
          client.println("Connection: close");
          client.println();

          delay(500);             //delay fondamentale altrimenti a volte chiude la connessione prima che la pagina sia stata correttamente interrogata
     
          client.stop();

          Serial.println("Caricamento dati");
        }

      }

    }
  
    num_rilevazioni=num_rilevazioni+1;

  } //millis lettura sensori

} //loop


Cosa hai combinato qui??
Non è la dimensione quella che è sbagliata nel tuo sketch, ma l'indice che usi per muoverti all'interno dell'array ovvero il valore che assume la variabile num_rilevazioni nel corso dell'esecuzione del programma.

Ti invito a leggere con più attenzione le risposte che ti hanno già fornito perché sono scritte in modo chiaro: se dichiari un array da 10 posizioni è il valore dell'indice che non deve essere maggiore di 9 perché si parte sempre da 0.

Per quanto riguarda lo sketch in generale, ci sono tante cose che si possono migliorare, ma per adesso è inutile aggiungere carne al fuoco perché gli array sono un tipo di dati base che è fondamentale saper gestire correttamente.

Aggiungo qualche altra considerazione personale sullo sketch più in generale:

  • Ci sono tecniche di filtraggio dei valori provenienti dai sensori più "efficaci" della classica media aritmetica. Ad esempio per valori "lenti" come quelli relativi a dati climatici dove di base quello che conta è il trend, io userei un filtro a media mobile esponenziale ponderata (cerca EWMA se vuoi approfondire).

  • L'ESP32 gestisce in modo automatico la perdita di connessione e la successiva riconnessione automatica. Dai un'occhiata all'esempio incluso WiFiClientEvents.ino (il print dell'evento non è obbligatorio, viene comunque gestita la riconnessione).

  • Ti consiglio di "raccogliere" i blocchi di codice in funzioni distinte in modo da rendere più leggibile il codice: ad esempio tutto il pezzo con il ciclo per il calcolo della media aritmetica oppure quello dove invii i darti al server.

void mediaAritmetica() {
   etc etc
}

bool inviaDatiAlServer() {
  // ritorna true se eseguita successo
  return true;
  // false se c'è errore di comunicazione (che andrebbe quindi gestito)
  return false;
}