Come usare F() ? Arduino uno rev3 + scheda ethernet shield

Ciao ragazzi, ho appena sprecato tutto la giornata di ieri ed anche questa mattina per mi si impallava il programma. Ho scoperto che finiva la RAM e quindi si impallava, ho girato sul forum ed ho visto che usando:

client.print(F("Content-Type: text/html\r\nConnection: keep-alive\r\n\r\n"));

al posto di:

client.println("Content-Type: text/html");
client.println("Connection: keep-alive");
client.println();

Qualcuno sa dirmi perché o cosa fa la funzione F() ? conviene utilizzarla per tutti i client.print e anche per Serial.print ?

Grazie a tutto come sempre

davidino81:
Qualcuno sa dirmi perché o cosa fa la funzione F() ?
conviene utilizzarla per tutti i client.print e anche per Serial.print ?

La F() serve per porre degli array di testo nella flash invece che nella ram, in linea di massima conviene usarla sempre per i messaggi di testo fissi in modo da risparmiare la ram.
Esempio pratico, se scrivi Serial.print(“123456”) occupi 6 byte di preziosa ram per memorizzare “123456”, se scrivi Serial.print(F(“123456”) occupi sei byte di flash per la scritta “123456” e zero byte di ram.

astrobeed: La F() serve per porre degli array di testo nella flash invece che nella ram, in linea di massima conviene usarla sempre per i messaggi di testo fissi in modo da risparmiare la ram. Esempio pratico, se scrivi Serial.print("123456") occupi 6 byte di preziosa ram per memorizzare "123456", se scrivi Serial.print(F("123456") occupi sei byte di flash per la scritta "123456" e zero byte di ram.

Grazie mille, c'è un modo per sapere quando memoria stai occupando o quanta te ne rimane per enrtmbe le memorie? Grazie

La Flash si, lo vedi in fondo quando compili lo sketch La Sram no, perchè varia da funzione a funzione e da istante a istante, puoi sapere quanta sram ti è rimasta dopo che hai dichiarato le var globali, quella è fissa e rimane tale.

Se c'è un punto critico del codice che la usa tutta non puoi saperlo da un alert durante la compilazione, ma tu sommando le globali + quelle all'interno della funzione puoi fare una linea di massima.

davidino81: Grazie mille, c'è un modo per sapere quando memoria stai occupando o quanta te ne rimane per enrtmbe le memorie?

Quando compili l'IDE ti dice sempre quanta flash occupi, con il nuovo IDE 1.6.x, ma anche con le precedenti 1.5.x, ti dice pure la quantità di ram statica impegnata dal sistema e dalle variabili globali, c'è sempre il rischio sforare con l'uso della ram dinamica, non è prevedibile durante la compilazione.

pablos:
La Sram no, perchè varia da funzione a funzione, puoi sapere quanta sram ti è rimasta dopo che hai dichiarato le var globali, quella è fissa e rimane tale.

Quello che può cambiare è solo l’uso della ram dinamica, basta non usare cose come string e similiari, ovvero lavori solo con variabili predefinite e il problema non esiste :slight_smile:

Puoi anche spezzare la riga scrivendo

client.println(F("Content-Type: text/html"));
client.println(F("Connection: keep-alive"));
client.println();

Occhio alla doppia parentesi in chiusura.

PaoloP:
Puoi anche spezzare la riga scrivendo

client.println(F("Content-Type: text/html"));

client.println(F(“Connection: keep-alive”));
client.println();




Occhio alla doppia parentesi in chiusura.

Grazie, spezzando così ho qualche vantaggio o è solo una questione di leggibilità del codice ?

astrobeed: Quello che può cambiare è solo l'uso della ram dinamica, basta non usare cose come string e similiari, ovvero lavori solo con variabili predefinite e il problema non esiste :)

Grazie per le risposte ma non ho capito come faccio a lavorare senza string ? come faccio ad impostarle delle variabili predefinite ? Grazie ancora

davidino81: Grazie per le risposte ma non ho capito come faccio a lavorare senza string ?

Tutte le variabili globali sono predefinite e l'occupazione di ram è nota, le variabili locali vengono poste nello spazio riservato, dal compilatore, per heap e stak, pure questo è noto e prefissato dal compilatore. Però se cominci ad usare tipi dati che utlizzano l'allocazione dinamica della ram, p.e. "string", inteso come tipo dato C++ e non come stringa C, sono due cose diverse, l'allocazione in ram avviene durante il run time e non è prevedibile quanto spazio richiede, è un attimo riempire meno di 2k ram e finire in uno straripamento della stessa con conseguente crash del programma.