Salvare ultima scritta display su SD

Salve,
ho fatto un progetto basato su Arduino che vorrei implementare con il vostro aiuto.
Si tratta di un commutatore d'antenna (ma anche di qualunque cosa necessiti di relè) wi-fi.
Ho una base con display dalla quale seleziono l'antenna che desidero usare schiacciando un pulsante.
Sul display appare il nome dell'antenna e una conferma di avvenuta commutazione.
Per vedere il macchinario all'opera vi rimando qui:IZ3ZLU Antenna switcher wi-fi con Arduino release 3 - YouTube
I relè sono di quelli che rimangono nella posizione datagli in modo da non avere correnti che girano vicine a cavi schermati da antenna.
Quindi se si spegne il macchinario tutto rimane come lo si è lasciato.
Se il giorno dopo lo riaccendo, mi piacerebbe che il display mostrasse le antenne che avevo collegato l'ultima volta.
Mi sono procurato un lettore SD Adafruit.
In che modo posso salvare le sole scritte nel momento dello spegnimento?
Trattandosi solo delle scritte che in quel momento appaiono sul display, è meglio usare la EEPRON?
Grazie mille per ogni aiuto.

Lanfranco IZ3ZLU

Scusate..... EEPROM

lanjazz:
Trattandosi solo delle scritte che in quel momento appaiono sul display, è meglio usare la EEPRON?

… beh … hai 1KB di memoria EEPROM che sta li a fare nulla, è molto più facile da usare e molto più veloce di una SD … se ti basta 1KB (… e immagino di si) … usala e non aggiungere inutile HW :wink:

Guglielmo

Ti rammento che l’IDE di Arduino include sempre la AVR libc in cui trovi, in <eeprom.h>, molte funzioni ottimizzate per l’uso della EEPROM senza dover usare classi o altre librerie :wink:

Guglielmo

Grazie Guglielmo per la Supervelocità con cui mi hai risposto.
Stai però parlando con un neofita e avrei bisogno di avere un’idea di partenza per poi lavorarci.
Se ad esempio mostro una parte dello sketch:

if(hasBeenPressed(PIN_BUTTON1)){
   Data = 1;
   sendData(Data);
   Serial.println(Data);
   lcd.setCursor(0, 1); 
   lcd.print("HF-       DeltaLoop "); // Visualizzo il messaggio sul display
 }
 if(Data==6){             //se il dato ricevuto è 6 sono certo che il relè ha collegato l'antenna selezionata   
 Serial.println(Data);
 lcd.setCursor(0, 0);
 lcd.print("Controllo...........");
 delay(1000);
 digitalWrite(13, HIGH); 
 delay(500);
 digitalWrite(13, LOW);
 lcd.setCursor(0, 1); 
 lcd.print("HF-       DELTALOOP "); // quindi visualizzo il messaggio sul display Maiuscolo
 lcd.setCursor(0, 0);
 lcd.print("controllo antenna ok");

Questo è la parte di programma che mi commuta un’antenna…
Come posso dirgli di scrivere il cambio di stato sulla EEPROM?
Conviene scriverlo ogni volta che commuto in modo che poi posso spegnere senza salvare niente di più?
O conviene usare la SD per memorizzare lo stato prima di spegnere il commutatore… magari con un pulsante?
Della velocità non mi preoccupo nel senso che tra una commutazione e l’altra possono passare minuti come ore o giorni.
Grazie mille per la disponibilità.

Lanfranco IZ3ZLU

... scusa, ma lo "stato" in cui ti trovi, a parte quello che può essere scritto sul display che ha poca importanza, non lo hai in una "variabile di stato" ? ? ?

Cioè, una variabile che se vale 1 significa che hai attivato l'antenna 1, se vale 2 significa che hai attivato l'antenna 2 ... e così via dicendo ...
... in pratica una variabile che ti dice COSA hai attivato.

Guglielmo

Una volta che Arduino ha inviato il segnale al ricevitore, questo leggendo il numero che ha ricevuto manda corrente ad un dato relè e poi la toglie dopo mezzo secondo. Questo perchè i relè utilizzati rimangono nella posizione datagli.
Quando premi un altro pulsante, prima vengono eccitati tutti i relè in modo che tornino aperti e poi dopo mezzo secondo parte l’impulso a quello giusto per chiuderlo.
Una volta spento Arduino i relè eccitati rimangono nell’ultimo stato in cui erano… per questo vorrei fare questo “optional”, per sapere a che punto ero quando ho spento.
Allego lo sketch completo della parte trasmittente ( ma anche ricevente visto che riceve le conferme…):

#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
#include <VirtualWire.h>

LiquidCrystal_I2C lcd(0x27,20,4);  // set the LCD address to 0x27 for a 16 chars and 2 line display

const int RX_DIO_Pin = 12;
const int TX_DIO_Pin = 2;
const int PIN_BUTTON1 = A0; //antenna Delta Loop 20 e 10 mt
const int PIN_BUTTON2 = A1; //antenna Dipolo Meandri 40mt
const int PIN_BUTTON3 = A2; //antenna Dipolo rigido 15mt
const int PIN_BUTTON4 = A3; //Quadrifilare
const int PIN_BUTTON5 = A6; //antenna dualband V/UHF

unsigned int Data;

void setup()
{
 pinMode(13, OUTPUT);
 Serial.begin(9600);
 lcd.init();                      // initialize the lcd 

 // Print a message to the LCD.
 lcd.backlight();
 lcd.print("   Antenna Switch");
 lcd.setCursor(0,1);
 lcd.print("       IZ3ZLU");
 delay(500);
 lcd.setCursor(0,2);
 lcd.print("  Controllo wi-fi");
 lcd.setCursor(0,3);
 lcd.print("    Con conferma");


 vw_set_tx_pin(TX_DIO_Pin);//imposto il pin di trasmissione
 vw_set_rx_pin(RX_DIO_Pin);//imposto il pin di ricezione

 vw_set_ptt_inverted(true); 
 
vw_setup(1000); 
vw_rx_start(); 
}

/* Main program */
void loop()
{
 uint8_t Buffer_Size = 2;
 

unsigned int Data;
 

uint8_t RxBuffer[Buffer_Size];


if (vw_get_message(RxBuffer, &Buffer_Size)){

Data = RxBuffer[0] << 8 | RxBuffer[1];
       }
 
 if(hasBeenPressed(PIN_BUTTON1)){
   Data = 1;
   sendData(Data);
   Serial.println(Data);
   lcd.setCursor(0, 1); 
   lcd.print("HF-       DeltaLoop "); // Visualizzo il messaggio sul display
 }
 if(Data==6){             //se il dato ricevuto è 6 sono certo che il relè ha collegato l'antenna selezionata   
 Serial.println(Data);
 lcd.setCursor(0, 0);
 lcd.print("Controllo...........");
 delay(1000);
 digitalWrite(13, HIGH); 
 delay(500);
 digitalWrite(13, LOW);
 lcd.setCursor(0, 1); 
 lcd.print("HF-       DELTALOOP "); // quindi visualizzo il messaggio sul display Maiuscolo
 lcd.setCursor(0, 0);
 lcd.print("controllo antenna ok");
 
 

 }
 if(hasBeenPressed(PIN_BUTTON2)){
   Data = 2;
   sendData(Data);
   Serial.println(Data);
 lcd.setCursor(0, 1); 
 lcd.print("HF-Dipolo meandri40m"); // Visualizzo il messaggio sul display
 }
 if(Data==7){                
 Serial.println(Data);
 lcd.setCursor(0, 0);
 lcd.print("Controllo...........");
 delay(1000);
 digitalWrite(13, HIGH); 
 delay(500);
 digitalWrite(13, LOW);
 lcd.setCursor(0, 1); 
 lcd.print("HF-DIPOLO MEANDRI40m"); // quindi visualizzo il messaggio sul display Maiuscolo
 lcd.setCursor(0, 0);
 lcd.print("controllo antenna ok");
 
   
 }
 if(hasBeenPressed(PIN_BUTTON3)){
   Data = 3;
   sendData(Data);
   Serial.println(Data);
 lcd.setCursor(0, 1);
 lcd.print("HF-     15mt Dipole "); // Visualizzo il messaggio sul display
 }
 if(Data==8){                
 Serial.println(Data);
 lcd.setCursor(0, 0);
 lcd.print("Controllo...........");
 delay(1000);
 digitalWrite(13, HIGH); 
 delay(500);
 digitalWrite(13, LOW);
 lcd.setCursor(0, 1); 
 lcd.print("HF-     15mt DIPOLE "); // quindi visualizzo il messaggio sul display Maiuscolo
 lcd.setCursor(0, 0);
 lcd.print("controllo antenna ok");
 
}
if(hasBeenPressed(PIN_BUTTON4)){
   Data = 4;
   sendData(Data);
   Serial.println(Data);
 lcd.setCursor(0, 2);
 lcd.print("V/UHF- Quadrifilare "); // Visualizzo il messaggio sul display
  }
 if(Data==9){                
 Serial.println(Data);
 lcd.setCursor(0, 3);
 lcd.print("Controllo...........");
 delay(1000);
 digitalWrite(13, HIGH); 
 delay(500);
 digitalWrite(13, LOW);
 lcd.setCursor(0, 2); 
 lcd.print("V/UHF- QUADRIFILARE "); // quindi visualizzo il messaggio sul display Maiuscolo
 lcd.setCursor(0, 3);
 lcd.print("controllo antenna ok");
 
 
}
if(hasBeenPressed(PIN_BUTTON5)){
   Data = 5;
   sendData(Data);
   Serial.println(Data);
 lcd.setCursor(0, 2);
 lcd.print("V/UHF- Yagi Dualband"); // Visualizzo il messaggio sul display
  }
 if(Data==0){                
 Serial.println(Data);
 lcd.setCursor(0, 3);
 lcd.print("Controllo...........");
 delay(1000);
 digitalWrite(13, HIGH); 
 delay(500);
 digitalWrite(13, LOW);
 lcd.setCursor(0, 2); 
 lcd.print("V/UHF- YAGI DUALBAND"); // quindi visualizzo il messaggio sul display Maiuscolo
 lcd.setCursor(0, 3);
 lcd.print("controllo antenna ok");

}
}

boolean hasBeenPressed(int pin){
 if(analogRead(pin)>1000){
   return true;
 }else{
   return false;
 }
}  
 
void sendData(int Data){
 byte TxBuffer[2];
 TxBuffer[0] = Data >> 8;
 TxBuffer[1] = Data;
 digitalWrite(13, HIGH); 
 vw_send((byte *)TxBuffer, 2);
 vw_wait_tx(); 
 digitalWrite(13, LOW); 
 delay(1000);
}

Nel rispetto del regolamento ed in particolare del punto 7, ti prego di editare il tuo post e di racchiudere il codice negli appositi tag CODE (quando vai in edit sono il primo bottone a sinistra fatto così: </>) …

… detto questo, molto semplicemente ti devi creare una variabile dove salvi, ogni volta che cambi antenna, un numero (tipo quello che hai nella variabile Data) che poi scrivi anche nella EEPROM.

Alla ripartenza, basta che leggi tale numero dalla EEPROM (è sufficiente 1 byte visto che puoi andare da 0 a 255) e sai quale era la configurazione di quando hai spento :wink:

Guglielmo

Grazie Guglielmo e ... mi scuso per lo sketch fuori posto.... conoscevo questa regola ma, frequentando molti forum e con questo caldo allucinante, ho perso la ragione. Mi scuso ancora con te e con tutto il Forum.
Ti chiedo gentilmente un'ultima cosa....
Il salvataggio va "scritto" dopo ogni comando (pulsante 1, pulsante 2 ecc ecc) o si può definire nel void setup?
Potresti farmi un esempio... una cosa semplice tipo... accendo un led, spengo Arduino e lui alla riaccensione si ricorda se era acceso o spento?
Se non ti disturbo troppo, potresti fare un esempio per l'utilizzo della EEPROM e (per capire la differenza) anche per l'utilizzo dello shield SD?
Grazie per la pazienza.
Non sono un tecnico e tutto lo sforzo che sto facendo è per eliminare l'onnipresente pc dalla mia stazione radio. Arduino è un gioiello che merita invece di starci.
La maggior parte dei miei progetti li ho realizzati con Arduino (iz3zlu.weebly.com), mentre il progetto del commutatore wi-fi è apparso su RadioRivista di Luglio. Capirai che per un 53enne con terza media e da due anni Radioamatore è una bella soddisfazione.
Grazie mille.

Lanfranco

… allora, come ti dicevo ti è sufficiente un solo byte per sapere quale antenna hai selezionato, basta che le numeri da 0 a 255 (… e non credo arrivi a 255 antenne :smiley: :smiley: :smiley:).

Dopo di che, OGNI VOLTA che cambi antenna, in una variabile di tipo byte, es. “byte numAntenna;” ti memorizzi il numero dell’antenna. Fatto questo, lo vai a salvare anche in una posizione a tua scelta, tra 0 e 1023 (… ricorda che hai 1024 bytes disponibili nella EEPROM) nella EEPROM con la semplice istruzione : “EEPROM.write(posizione, numAntenna);”.

Nel setup(), ovvero quando il programma si avvia, non dovrai fare altro che leggere il valore che è nella EEPROM nella posizione che hai scelto, con una semplice “numAntenna = EEPROM.read(posizione);” e riselezionare l’antenna che ti trovi appunto in numAntenna.

Ricorda che ad inizio di programma devi mettere la include per la EEPROM ovvero “#include <EEPROM.h>”.

Tutto qui … :slight_smile:

Un problema però c’è … ed è la prima volta in assoluto che lanci il programma …
… non avendo mai girato, nella cella di EEPROM scelta c’è un valore a caso e quindi, la prima volta rischi di leggere un’antenna che ovviamente NON esiste. Due sono le soluzioni …

a) fai un programmino per inizializzare, che so io, ad esempio a zero, la cella di EEPROM che poi userai

b) la prima volta che lo usi NON attacchi veramente i relè, nel setup() leggi una porcheria, la scarti, e poi selezioni un relè e così salvi il valore corretto nella EEPROM.

Ogni successivo lancio del programma troverà nella posizione da te scelta della EEPROM l’ultimo valore che ci hai salvato :slight_smile:

Guglielmo

P.S.: Devo assentarmi alcuni giorni, quindi … per un po’ non potrò seguire il thread …

GRAZIE MILLE!
Mi ci metto subito.
Buone ferie.

Lanfranco

OK!
Grazie alle spiegazioni di Guglielmo ora scrivo il dato sulla EEPROM ogni volta che seleziono un'antenna.
Avendo diviso il commutatore in due parti, una parte per le antenne HF e una per le antenne V/UHF,
ho fatto in modo che le HF si salvino sulla memoria 1 della EEPROM, mentre le altre sulla memoria 2.
Controllando con EEPROM read sul monitor seriale i conti tornano.... perfetto.
Ora giunge il momento di far comparire l'antenna che avevo selezionato... qui qualcosa non va.
Io ho fatto così ma mi va tutto in loop:

void loop()
{
 byte numAntenna;
 numAntenna = EEPROM.read(1);
 numAntenna = EEPROM.read(2);
if(numAntenna=1, 13);
  lcd.setCursor(0, 1); 
  lcd.print("HF-       DELTALOOP "); 
if(numAntenna=1, 14);
  lcd.setCursor(0, 1); 
  lcd.print("HF-Dipolo meandri40m");
if(numAntenna=1, 15);
  lcd.setCursor(0, 1); 
  lcd.print("HF-     15mt DIPOLE ");
if(numAntenna=2, 16);
  lcd.setCursor(0, 2); 
  lcd.print("V/UHF- QUADRIFILARE ");
if(numAntenna=2, 17);
  lcd.setCursor(0, 2); 
  lcd.print("V/UHF- YAGI DUALBAND"); 
if(numAntenna=2, 18);
  lcd.setCursor(0, 2); 
  lcd.print("   Nessuna antenna  ");

Certo che ti va in loop, lo hai messo nel loop :slight_smile:

Mettilo nel setup così te lo fa solo all'accensione.

Ciao Paulus1969…e grazie.
Si, scusa ho sbagliato a copiare il vecchio sketch.
Già ieri avevo capito la volpata fatta e ho messo in void setup il tutto…
Ora all’accensione mi mostra l’ultima antenna di ogni posizione sull’EEPROM…
Quindi non tiene conto di ciò che legge… mentre ciò che scrive è perfetto.
In pratica “salta” tutti gli IF che ci sono e si ferma all’ultima voce di EEPROM.read(1) e di EEPROM.read(2) mostrandomi sempre gli stessi due nomi.
Qualcosa di sbagliato nella compilazione? o è proprio errato lo sketch?
Ora funzionerebbe se mi accontentassi di vedere il numero che corrisponde all’antenna… ma penso che sia possibile mostrare un nome in relazione al numero…
Grazie mille per la disponibilità.

Lanfranco

void setup()
numAntenna = EEPROM.read(1); 
  lcd.setCursor(0, 0); 
  lcd.print("Leggo EEPROM HF..... ");
  lcd.setCursor(0, 1); 
  lcd.print("                    ");
  Serial.println(numAntenna);
  delay(2000);
  lcd.setCursor(9, 1); 
  lcd.print(   numAntenna    );
  lcd.setCursor(0, 0); 
  lcd.print(" letta EEPROM HF    ");
  delay(500);
  if(numAntenna=13);{
  lcd.setCursor(0, 1); 
  lcd.print("  DELTALOOP "); }
  if(numAntenna=14);{
  lcd.setCursor(0, 1); 
  lcd.print(" Meandri40mt "); }
  if(numAntenna=15);{
  lcd.setCursor(0, 1); 
  lcd.print(" Dipolo15mt "); }

numAntenna = EEPROM.read(2); 
  lcd.setCursor(0, 2); 
  lcd.print("Leggo EEPROM V/UHF.. ");
  lcd.setCursor(0, 3); 
  lcd.print("                    ");
  Serial.println(numAntenna);
  delay(500);
  lcd.setCursor(9, 3); 
  lcd.print(   numAntenna    );
  lcd.setCursor(0, 2); 
  lcd.print(" letta EEPROM V/UHF ");
  }

Risolto!! Avevo dimenticato che per fare il confronto ci volevano ==…
Grazie ad un utente di AriFidenza ora funziona tutto.
Vi ringrazio per l’aiuto.
Ovviamente non è finita… :slight_smile:
Ora mi metto a studiare per fare la stessa cosa su uno shield SD che è arrivato ieri. :o

numAntenna = EEPROM.read(1);
  if (numAntenna =1){                   <---------------------Qui era l'errore,ci vogliono ==
  lcd.setCursor(0, 0); 
  lcd.print("Leggo EEPROM HF.....");
  lcd.setCursor(0, 1); 
  lcd.print("                   ");
  Serial.println(numAntenna);
  delay(2000);
  lcd.setCursor(0, 1); 
  lcd.print("HF-       DeltaLoop ");
  lcd.setCursor(0, 0); 
  lcd.print("letta EEPROM HF     ");
  delay(500);}

Visto il titolo vorrei approfittare ancora delle vostre menti.....
Sto cercando di fare la stessa cosa con uno shield SD (catalex micro SD card adapter).
Se uso lo sketch degli esempi, tutto funziona perfettamente, ma inserendolo nello sketch del commutatore non riesco a farlo andare... o mi si blocca il display o l'SD o i pulsanti di selezione antenna.
Di certo è una questione di compilazione... una qualche parentesi messa male... Arduino mi carica tutto ma non funziona.... Qualche idea su cosa ho di certo sbagliato?
Grazie di cuore.

void setup()

{ 
 lcd.init();                      // initialize the lcd 
 
  // Print a message to the LCD.
  lcd.backlight();
  lcd.print("   Antenna Switch");
  lcd.setCursor(0,1);
  lcd.print("       IZ3ZLU");
  delay(1000);
  lcd.setCursor(0,2);
  lcd.print("  Controllo wi-fi");
  lcd.setCursor(0,3);
  lcd.print("    Con conferma");
  delay(2500);
  vw_set_tx_pin(TX_DIO_Pin);//imposto il pin di trasmissione
  vw_set_rx_pin(RX_DIO_Pin);//imposto il pin di ricezione
 
  vw_set_ptt_inverted(true); 

 vw_setup(1000); 
 vw_rx_start(); 


pinMode(CS_pin, OUTPUT);
Serial.begin(9600);
if (!SD.begin(CS_pin)) {
Serial.println("Avvio SD Card fallito!");
return;
}
Serial.println("SD Card avviata.");
File myFile;
/* Scrittura del file *******************************************/
myFile = SD.open("test.txt", FILE_WRITE);
if (myFile) {
Serial.println("Mi preparo a scrivere il file test.txt ...");
myFile.println("Prova.");
myFile.close();
Serial.println("scrittura eseguita correttamente.");
}
else {
Serial.println("Non è stato possibile scrivere il file test.txt!");
}
/* Lettura del file *******************************************/
myFile = SD.open("test.txt", FILE_READ);
if (myFile) {
Serial.println("Leggo il contenuto di test.txt :");
while (myFile.available()) {
Serial.write(myFile.read());
}
myFile.close();
}
else {
Serial.println("Non è stato possibile leggere il file test.txt!");
}
}
void loop()
{