[RISOLTO] Scrivere un file

Salve a tutti
Sto realizzando un irrigatore controllato da un sensore di umidità. In questi giorni sto cercando di tararlo e mi è venuta in mente l'idea di lascare il sensore in una pianta per 24h, memorizzare ogni ora le letture del sensore in una variabile e stampare quest'ultima alla fine del codice. Ma come posso memorizzare tutti i valori in una variabile senza che si sovrascrivino. Mi era venuto anche in mente di creare un file di testo nel mio pc, ma ho letto che questo con arduino non era possibile, ma c'è la possibilita di collegare un codice C++ ad arduino che legga i valori provenienti dalla seriale e li scriva in un file di testo? Oppure posso creare un file di testo nella memoria EEPROM di Arduino?

Vi ringrazio in anticipo :joy:

Certo che è possibile (in qualsiasi linguaggio che possa aprire una porta COM qundi C++, C#, VB, Java, quello che ti pare e ti è più comodo).

La EEPROM è in genere utilizzata solo per memorizzare dati di configurazione o comunque dati non variabili, comunque lo spazio disponibile è diverso a seconda del tipo di board, ma diciamo che in genere si considera la UNO per cui avresti solo 1024 byte. Se devi acquisire un valore ogni ora, e assumendo che ogni lettura sia di 2 byte, avresti 48 byte al giorno quindi 1024 divisi per 48 fa 21: finisci la memoria in soli 21 giorni, e poi che fai?
Discorso comunque simile anche per l'uso della RAM (2k).

Soluzione alternativa è quella di registrare i dati accumulandoli (append) dentro ad un file su una scheda SD, a quel punto hai a disposizione ANNI di registrazioni, e non ti richiede la presenza di un programma su PC che vada a catturare le informazioni. Per acquisire i dati ti basta spegnere Arduino, estrarre la SD, copiare il file sul PC rimuovendolo dalla SD, e reinserirla in Arduino ed accenderlo. E secondo me è la cosa migliore.

va bene grazie mille, alla fine si tratta solo di un giorno perchè questi dati mi servono solo per tarare il sensore. Per inviare i dati alla porta seriale che deve essere letta dal c++ come posso fare?

Il problema non è trasmetterli da arduino
Ma farli capire al PC
Tu risolvi quello, che poi con una serial.println() te la cavi

Se ti basta un solo giorno parliamo di 24 valori, ossia 48 byte se memorizzati come int. Ma che dati devi mandare? Se basta un valore numerico, ad esempio in una variabile "valore", fai semplicemente "Serial.println(valore)". Dall'altra parte ossia lato PC, devi aprire la seriale ed attendere di ricevere un dato per ogni riga di testo (quindi con i caratteri CR+LF come separatori di riga, ossia byte 13 e 10), devi leggere i byte ricevuti e poi quando ricevi il carattere LF prendere il dato come stringa e farci quello che ti pare, puoi salvarli su file o mostrarli a video. O, più semplicemente, apri la seriale con Putty ed attivando la registrazione del log di comunicazione puoi far andare su file direttamente quello che rivevi da Arduino.
Io conosco il VB ed il C# su Windows quindi lato PC non posso darti indicazioni più precise non avendo mai programmato in C++ (tra l'altro non hai neanche specificato se sei su Windows, Linux, Mac o cosa).

Si scusami sono su windows, comunque io volevo memorizzare questi valori numerici in una variabile valore e poi leggerli dopo 24h. Quindi facendo Serial.println(valore) mi stampa solo il valore di quell'ora. Tu mi consigli di usare eeprom o utilizzare il C++ per salvare i dati provenienti dalla seriale?

Le cose che si possono fare sono molte, ma... visto che parli di seriale collegata al pc, se puoi tenere il sensore+arduino collegato via usb al pc ... ti basta mandare il dato con serial.print e poi usare il plotter seriale nell'IDE così hai un bel grafico e i valori letti.

Mi scuso della mia tarda risposta.
No, a me servirebbe leggere i file alla fine dell'esperimento, inoltre la mia intenzione era quella di staccarlo dal pc e alimentarlo tramite delle batterie. Per questo motivo volevo utilizzare la memoria EEPROM di arduino.

La memoria EEPROM NON è nata per questo scopo e NON va usata in questo modo. E' una memoria che ha una vita limitata (numero limitato di scritture per singola cella) e che serve a memorizzare informazioni che devono essere presenti all'avvio del codice, come, ad esempio, parametri di configurazione, valori salvati prima dello spegnimento, ecc. ecc.

O utilizzi una memoria su scheda SD o ti orienti su altri tipi di memorie esterne SPI/I2C cercando quelle che hanno un numero di scritture praticamente illimitato (tipo FRAM, EERAM, NVSRAM).

Guglielmo

Ah ho capito grazie. Allora questi dati in che modo posso visionarli alla fine dell'esperimento? Dove li posso salvare?

Mi sembra che te l'ho detto ...

Guglielmo

Ho capito grazie, visto che ho poco tempo per comprare il necessario utilizzo un array all'interno del codice e memorizzo i dati letti li dentro.
Grazie mille a tutti mi siete stati molto d'aiuto

Attenzione perché su Arduino UNO hai solo 2 KBytes di SRAM che serve però per tutto, variabili, stack, ecc. ecc.

Altrimenti devi pensare ad un modello differente.

Guglielmo

ah, ma credo che mi basti perchè devo memorizzare solo 24 dati e il codice è molto piccolo.
Grazie mille

Non credo, se usi la RAM ed Arduino lo alimenti con una pila, quando connetti la USB ti si resetta e perdi tutti i dati.

Sinceramente non ho ancora ben capito lo scopo di tutto questo, soprattutto a che ti serva il PC se deve essere un irrigatore autonomo. Oltre al chiedermi perché parli sempre di C++: hai già pratica con questo linguaggio? Perché se non ce l'hai e magari non hai ancora tanta pratica in generale con la programmazione, ti consiglio comunque, anche se hanno le stesse potenzialità perché sono pur sempre entrambi .NET Framework, di provare il VB.NET che è un po' più sempice da imparare e gestire, oppure il C# (se vuoi avere una base anche più ampia per il futuro visto che, dopo Java, è il linguaggio più usato attualmente). Comunque con Visual Studio Community puoi scegliere uno dei tre linguaggi, quello che preferisci.

In ogni caso, a meno che tu questa cosa non debba farla solo pochissime volte e non credo che in realtà lo sia (cos'è solo un esercizio di scuola?) un irrigatore automatico si dovrebbe auto-calibrare giorno per giorno in base all'umidità rilevata, quindi ok che gli bastano magari le statistiche del giorno precedente, ma sono 24 dati numerici ossia 48 byte che cambiano una volta al giorno. Per evitare la precoce usura della EEPROM (di cui ti hanno già accennato) dovresti fare in modo di usare blocchi di 48 byte differenti, ma devi anche tenere in memoria qual è il blocco attualmente usato. Diciamo che l'indice è ad indirizzo 0 (un byte è sufficiente, per avere l'indirizzo lo moltiplichi per 48 e sommi 1), quindi il primo giorno scrivi agli indirizzi 1-48, il secondo 49-96 e così via. Arrivato al ventunesimo giorno (indice 47) riporti l'indice a zero, per cui teoricamente con 50.000 scritture per cella (la vita media stimata è 100.000 ma cerchiamo di essere sempre pessimisti) dovresti poter usare la EEPROM per qualche anno.

Se proprio devi invece tirare fuori i dati per potrtarli su PC magari per farti una tua prima calibrazione, per un giorno lascia il PC collegato alla USB e su Arduino scrivi su seriale i dati orari.

In alternativa, sempre se necessiti di un collegamento costante ed evitare i memorizzare su EEPROM, so che è un po' più complicato, ma puoi usare un collegamento di rete, io in genere preferisco o una Ethernet Shield su Arduino, oppure usare direttamente una scheda WeMos, praticamente identica al 98% ad Arduino come programmazione, ma ha già il WiFi on board) per trasmettere e quindi sul PC devi restare "in ascolto" su una certa porta (magari UDP broadcast per evitare sia si dover impostare su Arduno un IP del server, sia per non stare a lavorare con connessioni).

Mah ... si stanno facendo tante complicazioni quando, come ho detto, basta ...

... in particolare, con una spesa ridicola, aggiunge ad Arduino UNO uno shield con NVSRAM come quello che è stato da me presentato su Elettronica In N. 252 – Marzo 2021 (... senza voler fare alcuna pubblicità, dato che, come dico sempre, fortunatamente non serve :grin:) con capacità di 64 o 128 KBytes, più che sufficienti per le sue esigenze :slight_smile:

Guglielmo

va bene grazie mille, gli darò un'occhiata.