Arduino Web Server, Ethernet2 Shield + SD Card, HTML + AJAX

Buongiorno. Ho bisogno di:

  1. Completare lo script di questa pagina web affinché effettui le richieste al web server Arduino.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Arduino Web Server + HTML on sd card + AJAX</title>
</head>
<body>
<table>
<tr>
<td>Data</td><td><span id="data"></span></td>
<td>Ora</td><td><span id="ora"></span></td>
<td>Altro</td><td><span id="altro"></span></td>
</tr>	
<script>
// Esegui le funzioni ogni 2 secondi
setInterval(function() {
getData();
getOra();
getAltro();
}, 2000);
</script>
</body>
</html>
  1. Scrivere lo sketch per Arduino in grado di rispondere alle richieste della pagina html (client), tendendo presente che il file html della pagina client si trova sulla SD card inserita nel Ethernet2 Shield.

Grazie in anticipo

:warning:
Ti segnalo che, nella sezione in lingua Inglese, si può scrivere SOLO in Inglese ... quindi, per favore, la prossima volta presta più attenzione in quale sezione metti i tuoi post; questa volta esso è stato spostato, da un moderatore della sezione di lingua Inglese, nella sezione di lingua Italiana ... la prossima volta potrebbe venire direttamente eliminato. Grazie.

1 Like

A quanto detto da J-M-L aggiungo ...

... cortesemente, come prima cosa, leggi attentamente il REGOLAMENTO della sezione Italiana del forum, (... e, per evitare future possibili discussioni/incomprensioni, prestando sempre molta attenzione al punto 15), dopo di che, come da suddetto regolamento (punto 16.7), fai la tua presentazione NELL'APPOSITA DISCUSSIONE spiegando bene quali esperienze hai in elettronica e programmazione, affinché noi possiamo conoscere la tua esperienza ed esprimerci con termini adeguati.

Grazie,

Guglielmo

P.S.: Ti ricordo che, purtroppo, fino a quando non sarà fatta la presentazione nell’apposita discussione, nel rispetto del succitato regolamento nessuno ti risponderà (eventuali risposte o tuoi ulteriori post, verrebbero temporaneamente nascosti), quindi ti consiglio di farla al più presto. :wink:

P.P.S.: Vista la richiesta ... ti consiglio di leggere molto attentamente il punto 16.1 del nostro REGOLAMENTO :roll_eyes:

1 Like

Emmm ... e quindi ti aspetti che li scriviamo noi? :thinking:

Hai letto attentamente il REGOLAMENTO al punto 16.1 ?

Tenete sempre presente che qui sul forum nessuno scrive software per conto terzi o realizza schemi su ordinazione, ma si aiuta chi viene qui a correggere/ottimizzare il software che lui scrive o gli schemi che lui realizza .

Tu scrivi il tutto e se ci sono errori ti aiutiamo a corregerli, ma il codice devi farlo tu ... :roll_eyes:

Guglielmo

Ok, mi sembra giusto.

Data questa pagina client "index.html" (che si trova sulla SD card inserita nell' Ethernet2 Shield):

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Arduino Web Server + HTML on sd card + AJAX</title>
</head>
<body>
<table>
<tr>
<td>Data</td><td><span id="data"></span></td>
<td>Ora</td><td><span id="ora"></span></td>
<td>Altro</td><td><span id="altro"></span></td>
</tr>	
<script>
// Esegui le funzioni ogni 2 secondi
setInterval(function() {
getData();
getOra();
getAltro();
}, 2000);

function getData()
  {
    var dataRequest = new XMLHttpRequest();
    dataRequest.onreadystatechange = function()
    {
      if(this.readyState == 4 && this.status == 200 && this.responseText != null)
      {
        document.getElementById("data").innerHTML = this.responseText;
      }
    };
    dataRequest.open("GET", "readData", true);
    dataRequest.send();
  }

function getOra()
  {
    var oraRequest = new XMLHttpRequest();
    oraRequest.onreadystatechange = function()
    {
      if(this.readyState == 4 && this.status == 200 && this.responseText != null)
      {
        document.getElementById("ora").innerHTML = this.responseText;
      }
    };
    oraRequest.open("GET", "readOra", true);
    oraRequest.send();
  }

function getAltro()
  {
    var altroRequest = new XMLHttpRequest();
    altroRequest.onreadystatechange = function()
    {
      if(this.readyState == 4 && this.status == 200 && this.responseText != null)
      {
        document.getElementById("altro").innerHTML = this.responseText;
      }
    };
    altroRequest.open("GET", "readAltro", true);
    altroRequest.send();
  }

</script>
</body>
</html>

Mi chiedevo come modificare il seguente Arduino Web Server in modo che possa rispondere singolarmente ma contemporaneamente (ogni 2 secondi) a più diverse richieste http della pagina "index.html".

#include <SPI.h>
#include <Ethernet.h>
#include <SD.h>

//------------------------------------------------

File HMTL_file;
String data = "data";
String ora = "ora";
String altro = "altro";
//------------------------------------------------
byte mac[] = {0x90, 0xA2, 0xDA, 0x00, 0x4A, 0xE0};
EthernetServer server(80);
//==================================================================================
void setup()
{
  Serial.begin(9600);
  //-----------------------------------------------------
  Serial.println(F("Initializing SD card..."));
  if(!SD.begin(4))
  {
    Serial.println(F("Initialization failed!")); return;
  }
  Serial.println(F("Initialization OK"));
  //-----------------------------------------------------
  if(!SD.exists("index.html"))
  {
    Serial.println(F("index.html non trovato!")); return;
  }
  Serial.println(F("index.html trovato"));
  //-----------------------------------------------------
  Ethernet.begin(mac);
  server.begin();
  Serial.print(F("Server Started...\nLocal IP: "));
  Serial.println(Ethernet.localIP());
}
//==================================================================================
void loop()
{
  String HTTP_req;
  EthernetClient client = server.available();
  //---------------------------------------------------------------------------
  if(client)
  {
    boolean currentLineIsBlank = true;
    while (client.connected())
    {
      if(client.available())
      { 
        char c = client.read();
        HTTP_req += c;
        if(c == '\n' && currentLineIsBlank)
        {
          client.println("HTTP/1.1 200 OK\n\rContent-Type: text/html\n\r\n\r");
          //-------------------------------------------------------------------
          if(HTTP_req.indexOf("readData") != -1)
          {
            client.println(data);
          }
          if(HTTP_req.indexOf("readOra") != -1)
          {
            client.println(ora);
          }
          if(HTTP_req.indexOf("readAltro") != -1)
          {
            client.println(altro);
          }
          //-------------------------------------------------------------------
          else
          {
            HMTL_file = SD.open("index.html");
            if(HMTL_file)
            {
              while(HMTL_file.available()) client.write(HMTL_file.read());
              HMTL_file.close();
            }
          }
          //-------------------------------------------------------------------
          //HTTP_req = "";
          break;
        }
        //---------------------------------------------------------------------
        if(c == '\n') currentLineIsBlank = true;
        else if(c != '\r') currentLineIsBlank = false;
      }
    }
    delay(2000);
    client.stop();
  }
}

Ovviamente le variabili data, ora e altro sono solo come esempio...Facciamo finta che siano letture di sensori i quali valori cambiano continuamente, è possibile avere questa tabelina html lato client aggiornata in tempo reale con le risposte dell'Arduino Web Server?
Probabilmente gli errori si trovano nelle httpRequest dello script di index.html o nelle risposte dell' Arduino Web Server. Chiedo questo semplice aiutino...

La tabella HTML è formatta male, manca il tag di chiusura </table>

Ad ogni modo il problema principale è l'utilizzo del solito delay() nello sketch Arduino.
Lato JavaScript, tu fai 3 richieste AJAX simultanee ogni 2 secondi ma nello sketch ogni volta che ne ricevi una metti in pausa il micro per 2 secondi accumulando ritardo su ritardo nella risposta che il server deve inviare alla pagina (fino al timeout probabilmente).

Aggiungo inoltre qualche consiglio:

  • Indenta sempre il codice per bene, anche nell'HTML (avresti individuato subito il tag mancante).

  • Non ha senso fare una chiamata HTTP per ogni variabile, fanne una sola e rispondi con un messaggio contenente i valori di tutte e tre contemporaneamente. Il consiglio è di usare la formattazione JSON perché è nativamente supportata da JavaScript.

  • Visto che sei agli inizi, usa il più moderno (ed efficiente) fetch al posto di XMLHttpRequest.

  • Con questo semplice esempio, stai inserendo dei valori nella stessa riga dove hai le intestazioni (per le quali avresti dovuto usare il tag <th> al posto di <td>). Non sarebbe meglio accodare gli ultimi valori alla tabella creando una nuova riga di volta in volta?
    Esempio:
<table id="my-table">
  <tr>
    <th>Data</th>
    <th>Ora</th>
    <th>Giorno</th>
  </tr>	
</table>

<script>
// rowData può essere un array o meglio ancora un object
// Facciamo l'esempio inc ui sia un array
function appendRow(rowData) {
  // Recuperiamo l'elemento con id my-table
  var table = document.getElementById('my-table');
  // Creo una nuova riga a runtime
  var row  = document.createElement('tr');  
  // Popolo la riga con i valori presenti nell'array rowData
  rowData.forEach( (el => {
    // Creo un nuvo elemento cella td
    var td = document.createElement('td');
    // Imposto il valore della cella
    td.innerHTML = el;
    // Lo inserisco nella riga appena creata
    row.appendChild(td);
  }))
  
  // Accodo la nuova riga alla tabella my-table
  table.appendChild(row);
}

// Dovrai sviluppare una funzione che esegue la chiamata AJAX  (fetch o XMLHttpRequest)
// ed in seguito alla risposta creare un array popolato con i dati recuperati dal server Arduino
// A quel punto chiami la funzione appendRow() passandogli l'array.

// Giusto per testarne il funzionamento,
// chiamo la funzione appendRow passandogli un array statico
var arr1 = ['16/03/2023', '08:45', 'Giovedì']
appendRow(arr1);

appendRow(['17/03/2023', '09:00', 'Venerdì']);

Ciao @cotestatnt, grazie mille per la risposta!
Effettivamente la tabella html ha diversi problemi.
Questo è il file "index.html" corretto:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Arduino Web Server + HTML on sd card + AJAX</title>
</head>
<body>
<table>
	<tr>
		<td>Lettura sensore 1</td><td><span id="val1"></span></td>
	</tr>
	<tr>
		<td>Lettura sensore 2</td><td><span id="val2"></span></td>
	</tr>
	<tr>
		<td>Lettura sensore 3</td><td><span id="val3"></span></td>
	</tr>
</table>
<script>
// Esegui la funzione una volta al secondo
setInterval(function() {
getVals();
}, 1000);

function getVals() {
  fetch('/getValues') // Richiesta GET ai valori dei sensori tramite API "/getValues"
    .then(response => response.json()) // Converte la risposta in formato JSON
    .then(data => { // Assegna i valori ai rispettivi campi della tabella HTML
      document.getElementById("val1").innerHTML = data.val1;
      document.getElementById("val2").innerHTML = data.val2;
      document.getElementById("val3").innerHTML = data.val3;
    })
    .catch(error => console.error(error)); // Gestisce eventuali errori
}
</script>
</body>
</html>

Sketch Arduino:

#include <SPI.h>
#include <SD.h>
#include <Ethernet.h>
#include <ArduinoJson.h>

// Ethernet shield MAC address
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
// Ethernet shield IP address
IPAddress ip(192, 168, 1, 177);
// Ethernet server port
EthernetServer server(80);
// Analog sensor pins
int sensor1 = A0;
int sensor2 = A1;
int sensor3 = A2;

void setup() {
  // Initialize serial communication
  Serial.begin(9600);

  // Initialize SD card
  if (!SD.begin(4)) {
    Serial.println("SD card initialization failed.");
    return;
  }

  // Initialize Ethernet connection and start server
  Ethernet.begin(mac, ip);
  server.begin();
  Serial.print("Server started at ");
  Serial.println(Ethernet.localIP());
}

void loop() {
  // Listen for incoming client connections
  EthernetClient client = server.available();
  if (client) {
    Serial.println("New client connected.");
    // Wait for client to send request
    while (!client.available()) {
      delay(1);
    }
    // Read request and respond
    String request = client.readStringUntil('\r');
    Serial.println(request);
    if (request.indexOf("/getValues") != -1) { // API endpoint to get sensor values
      // Get sensor values
      int val1 = analogRead(sensor1);
      int val2 = analogRead(sensor2);
      int val3 = analogRead(sensor3);
      // Create JSON object and serialize
      StaticJsonDocument<200> jsonDoc;
      jsonDoc["val1"] = val1;
      jsonDoc["val2"] = val2;
      jsonDoc["val3"] = val3;
      String response;
      serializeJson(jsonDoc, response);
      // Send response
      client.println("HTTP/1.1 200 OK");
      client.println("Content-Type: application/json");
      client.println("Connection: close");
      client.println();
      client.println(response);
      delay(1);
      client.stop();
      Serial.println("Client disconnected.");
    } else { // Serve HTML page
      // Open file
      File file = SD.open("index.html");
      // Send HTTP headers
      client.println("HTTP/1.1 200 OK");
      client.println("Content-Type: text/html");
      client.println("Connection: close");
      client.println();
      // Send file contents
      while (file.available()) {
        client.write(file.read());
      }
      // Close file and connection
      file.close();
      delay(1);
      client.stop();
      Serial.println("Client disconnected.");
    }
  }
}

Dovrebbe funzionare, grazie mille @cotestatnt

L'API builtin fetch, se hai letto l'articolo che ti ho linkato (uno dei primi che è venuto fuori con Google, forse non il migliore in effetti) è molto semplice da usare, basta avere chiaro il meccanismo di funzionamento.
Quando invii una richiesta HTTP ad un server, la risposta di questo non sarà immediata, ma ti arriverà dopo un certo ritardo che dipende da fattori esogeni (velocità della rete, carico di lavoro del server etc etc).
E' necessario quindi gestire questo meccanismo.

La differenza principale tra XMLHttpRequest e fetch è che, per gestire l'asincronismo implicito di una richiesta HTTP, la prima usa il meccanismo delle funzioni di callback associate ad eventi, mentre la seconda quello più moderno delle promise.
Se guardi con attenzione come è scritta la seguente funzione, hai un'idea chiara della sequenzialità delle operazioni:

  1. La funzione fetch() restituisce una promise, ovvero il prototipo di qualcosa che accadrà nell'immediato futuro. Quando questo "qualcosa" accadrà, il risultato sarà passato al successivo .then()
  2. Anche questo .then() restituisce una promise ovvero il parsing del JSON (è una promise, perché in fase di dichiarazione questo JSON ancora non esiste).
  3. Quando il primo .then() avrà processato il JSON ricevuto, passerà il risultato al successivo .then() che a questo punto farà quel che deve con l'object ricevuto come parametro in ingresso (response.json() ritorna un object JavaScript, se si trattava di testo semplice potevi usare response.text()).

L'ultima riga invece è utile (ma non obbligatoria) per intercettare eventuali errori e gestirli (un JSON scritto male, l'indirizzo richiesto non esistente etc etc).

Puoi concatenare quanti .then() vuoi e saranno sempre eseguiti in modo sequenziale: il blocco che segue riceve come parametri in ingresso il risultato del blocco che lo precede.
Ad esempio prova ad aggiungere questo .then(() => console.log('Tutte le operazioni precedenti sono state eseguite')) e vedi come si comporta (usando i devTools del browser, tasto F12):

function getVals(){
  fetch('/getVals')                     // Do the HTTP request (default GET)
  .then(response => response.json())    // Parse the response as JSON
  .then(obj => {                        // DO something with response
    console.log(obj);
    document.getElementById('val1').innerHTML = obj.val1;
    document.getElementById('val2').innerHTML = obj.val2;
    document.getElementById('val3').innerHTML = obj.val3;
  })
  .catch(err => console.log("Something went wrong!", err));   // Error handling
}

Lato Arduino, dovrai rispondere con questo famoso JSON da "costruire" a runtime con i valori dei sensori. La risposta dovrà informare il client che si tratta di testo formattato JSON e quindi deve contenere l'header Content-Type: application/json (mentre tu adesso stai usando Content-Type: text/html)

Puoi usare una libreria (come l'ottima ArduinoJSON) oppure visto che si tratta di poche righe, costruire la stringa pezzo per pezzo.
Un JSON è del semplice testo formattato secondo una logica {chiave: valore}. se il valore è una stringa va racchiuso tra le virgolette "sono una stringa" (quindi devi usare la combinazione con il carattere di escape \" in C++), se invece è un valore numerico o booleano non serve.

{
  "key1": val1,
  "key2": val2,
  "key3": val3
}

//Esempio Arduino:
int val1, val2, val3;
String json;
json += "{\"val1\": ";  
json += val1;
json += ", \"val2\": ";
json += val2;
json += ", \"val3\": ";
json += val3;
json += "}";
1 Like

Ho visto che hai aggiornato il codice.

Giusto un ultimo appunto... Tu leggi fino al carattere di fine linea \r ma è molto più frequente che l'ultimo carattere che tu riceva sia il new line \n oppure la combinazione \r\n

String request = client.readStringUntil('\r');

ciao a tutti,
sto sperimentando quanto riportato in questa discussione... quello che non riesco a capire è se posso mettere questa parte di codice(per provare l'esempio e poi modificarlo in base a quello che vorrei fare) direttamente nel condice arduino e non utilizzare quindi una SD esterna dove salvarlo.... è possibile?

ho provato a metterlo all'interno di un array di char in questo modo:

char HTML[] {
// codice Html QUOTATO SOPRA
}

per poi richiamrlo nella chiamata del web server con un client.print(HTML) ma non va...

Non so se è solo un errore di copia/incolla in questo post, ma il codice che hai quotato è incompleto.

Inoltre per risparmiare preziosa RAM è sempre consigliabile mettere queste stringhe cosi lunghe nello spazio programma usando la keyword PROGMEM

static const char HTML[] PROGMEM = R"EOF(
<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>Arduino Web Server + HTML on sd card + AJAX</title>
	</head>
	<body>
		<table>
			<tr><td>Lettura sensore 1</td><td><span id="val1"></span></td></tr>
			<tr><td>Lettura sensore 2</td><td><span id="val2"></span></td></tr>
			<tr><td>Lettura sensore 3</td><td><span id="val3"></span></td></tr>
		</table>
	<script>
	// Esegui la funzione una volta al secondo
	setInterval(function() {
		getVals();
	}, 1000);

	function getVals() {
		fetch('/getValues') // Richiesta GET ai valori dei sensori tramite API "/getValues"
		.then(response => response.json()) // Converte la risposta in formato JSON
		.then(data => { // Assegna i valori ai rispettivi campi della tabella HTML
			document.getElementById("val1").innerHTML = data.val1;
			document.getElementById("val2").innerHTML = data.val2;
			document.getElementById("val3").innerHTML = data.val3;
		})
		.catch(error => console.error(error)); // Gestisce eventuali errori
	}
	</script>
	</body>
</html>
)EOF";

Se metti il codice completo è meglio, ma ad ogni modo ricorda che è sempre necessario rispondere al client anche con gli headers affinché la risposta sia correttamente interpretata:

      client.println("HTTP/1.1 200 OK");
      client.println("Content-Type: text/html");
      client.println("Connection: close");
      client.println();
      client.println(HTML);

ok grazie mille!!! si durante il copy paste mi sa che è successo qualcosa...

faccio un pò di prove e smanetto e vi faccio sapere.

al momento l'unica domanda che ho è se val 1 , val 2 e val 3 devono essere per forza valori interi, oppure come penso no? mi potrei trovare davanti a variabili unsigned long, double , float... insomma un pò tutte...

poi mi chiedevo, vedo un uso della classe String:

String request = client.readStringUntil('\r');
String response;

non vanno evitate come la peste?

grazie

Va evitato di usarle senza cognizione di causa, ma questo è valido per qualsiasi costrutto.

Nello sketch in questione, le due variabili di tipo String sono entrambe locali quindi la memoria necessaria viene allocata solo quando si ha un client connesso e poi viene liberata al termine del blocco istruzioni senza causare framentazioni dell'heap.

if (client) {
  .....
}

Io vedo con molta più diffidenza questo blocco ad esempio. Se il client non risponde per qualsiasi ragione c'è un dead loop senza uscita (sarebbe meglio prevedere un timeout).

    // Wait for client to send request
    while (!client.available()) {
      delay(1);
    }

A voler ottimizzare un po', si potrebbe "riciclare" la prima String dichiarata per formattare il JSON (magari mettendo un nome più generico alla variabile) e considerando che si tratta di una manciata di byte, usare il metodo reserve() per evitare di riallocare continuamente memoria.

   // Read request and respond
    String buffer;
    buffer.reserv(256);
    buffer = client.readStringUntil('\r');
    Serial.println(buffer);
    if (buffer.indexOf("/getValues") != -1) { // API endpoint to get sensor values
      // Get sensor values
      int val1 = analogRead(sensor1);
      int val2 = analogRead(sensor2);
      int val3 = analogRead(sensor3);
      // Create JSON object and serialize
      StaticJsonDocument<200> jsonDoc;
      jsonDoc["val1"] = val1;
      jsonDoc["val2"] = val2;
      jsonDoc["val3"] = val3;      
      serializeJson(jsonDoc, buffer);
      ....

ho capito grazie, non sapevo che la classe string se usata come variabile locale non era poi cosi problematica...

al momento sto facendo prove con questo mio codice semplificato(sotto sotto dopo la parte di codice che non riesco ad integrare :slight_smile: ) ma non riesco ad integrare la parte mancante(subito sotto :slight_smile: ) con quello che sto usando io.... sto provando a metterlo dopo il buf.push(c); ma non va... continuo a provare...

intanto grazie

// Read request and respond
    String buffer;
    buffer.reserv(256);
    buffer = client.readStringUntil('\r');
    Serial.println(buffer);
    if (buffer.indexOf("/getValues") != -1) { // API endpoint to get sensor values
      // Get sensor values
      double val1 = Tpercepita8;
      //int val2 = analogRead(sensor2);
      //int val3 = analogRead(sensor3);
      // Create JSON object and serialize
      StaticJsonDocument<200> jsonDoc;
      jsonDoc["val1"] = val1;
      jsonDoc["val2"] = val2;
      jsonDoc["val3"] = val3;      
      serializeJson(jsonDoc, buffer);
#include "Seeed_BME280.h"
BME280 bme280;
#include "WiFiEsp.h"
//Emulate Serial1 on pins 6/7 if not present
#ifndef HAVE_HWSERIAL3
#endif
char ssid[] = "*******";            // your network SSID (name)
char pass[] = "*******";        // your network password
int status = WL_IDLE_STATUS;     // the Wifi radio's status
WiFiEspServer server(300);
RingBuffer buf(8);
double Tpercepita8 = 0;                     // calcolo temperatura percepita

static const char HTML[] PROGMEM = R"EOF(
<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>Arduino Web Server + HTML on sd card + AJAX</title>
	</head>
	<body>
		<table>
			<tr><td>Lettura sensore 1</td><td><span id="val1"></span></td></tr>
			<tr><td>Lettura sensore 2</td><td><span id="val2"></span></td></tr>
			<tr><td>Lettura sensore 3</td><td><span id="val3"></span></td></tr>
		</table>
	<script>
	// Esegui la funzione una volta al secondo
	setInterval(function() {
		getVals();
	}, 1000);

	function getVals() {
		fetch('/getValues') // Richiesta GET ai valori dei sensori tramite API "/getValues"
		.then(response => response.json()) // Converte la risposta in formato JSON
		.then(data => { // Assegna i valori ai rispettivi campi della tabella HTML
			document.getElementById("val1").innerHTML = data.val1;
			document.getElementById("val2").innerHTML = data.val2;
			document.getElementById("val3").innerHTML = data.val3;
		})
		.catch(error => console.error(error)); // Gestisce eventuali errori
	}
	</script>
	</body>
</html>
)EOF";



void connessioneinternet() {
  Serial.begin(9600);
  Serial3.begin(9600);
  WiFi.init(&Serial3);

  // check for the presence of the shield
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("WiFi shield not present");
    statoconnessione = false;
    startingTimewifi = millis();
  }
  // attempt to connect to WiFi network
  if ( status != WL_CONNECTED) {
    Serial.print("Attempting to connect to WPA SSID: ");
    Serial.println(ssid);
    // Connect to WPA/WPA2 network
    status = WiFi.begin(ssid, pass);
  }
  if ( status == WL_CONNECT_FAILED) {
    Serial.println("You're NOT connected to the network");
    statoconnessione = false;
    startingTimewifi = millis();
  }
  if ( status == WL_CONNECTED) {
    Serial.println("You're connected to the network");
    printWifiStatus();
    // start the web server on port 80
    server.begin();
    statoconnessione = true;
  }
}

void printWifiStatus()
{
  // print the SSID of the network you're attached to
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print your WiFi shield's IP address
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);

  // print where to go in the browser
  Serial.println();
  Serial.print("To see this page in action, open a browser to http://");
  Serial.println(ip);
  Serial.println();
}



void setup() {
  Serial.begin(9600);
  bme280.init(0x76);
  connessioneinternet();
}


void loop() {

  Tpercepita8 = bme280.getTemperature();
  Serial.println(Tpercepita8);

  void inviodati() {
    // listen for incoming clients
    WiFiEspClient client = server.available();
    if (client) {
      buf.init();
      // an http request ends with a blank line
      while (client.connected()) {
        if (client.available()) {
          char c = client.read();
          buf.push(c);
          // if you've gotten to the end of the line (received a newline
          // character) and the line is blank, the http request has ended,
          // so you can send a reply
          if (buf.endsWith("\r\n\r\n")) {
            client.println("HTTP/1.1 200 OK");
            client.println("Content-Type: application/json");
            client.println();
            client.println(HTML);
          }
        }
      }
      // give the web browser time to receive the data
      delay(10);
      // close the connection:
      client.stop();
    }
  }
}

Ogni variabile "locale", se non dichiarata "static", viene creata al momento in cui richiami la funzione in cui è dichiarata e distrutta, rilasciando la memoria, nel momento in cui la funzione termina.

Per questo la classe "String", usata in locale, fa meno danni di quando usata come "globale" dato che ... viene allocata memoria (nello stack), usata e poi totalmente rilasciata.

In ogni caso ... è una "classe" con i suoi metodi e, ovviamente, oltra ai possibili problemi di cui si è più volte ampiamente discusso, è normalmente più lenta se comparata con le stringhe classiche del 'C' :wink:

Guglielmo

Per questo la classe "String", usata in locale, fa meno danni di quando usata come "globale"

che intendi per meno danni? li fa o non li fa?

Di per sé una "classe" non fa danni, è sempre l'uso che se ne fa che può creare problemi ... relativamente alla classe "String" abbiamo più e più volte spiegato quali sono i problemi che può creare ed in quali condizioni ... quindi ... NON esiste che li fa o non li fa ... dipende da chi programma :grin:

Guglielmo

QUESTO primo vecchio post del thread spiegava abbastanza bene i problemi che tale classe può creare, in funzione dell'uso che se ne fa (e della MCU su cui si usa).

Guglielmo

si ok questo si è capito!!!! :slight_smile:

usata in questo modo crea danni?

In QUESTO post cotestatnt ti ha fornito tutte le indicazioni esatte, anche come pre-allocare la memoria che serve alla tua String ... segui le sue indicazioni e non avrai problemi :wink:

Guglielmo