[RISOLTO] Implementazione tasto invio

Salve a tutti ragazzi

Avrei bisogno di un consiglio da parte vostra....
Sto utilizzando arduino uno con ethenet shield e quello che vorrei fare è scrivere con una tastiera PS2 su la micro sd e mettere in rete il file di testo che ho creato
Tutto ciò è stato fatto abbastanza agevolmente, ma il problema che ho è il seguente:
Nel momento in cui scrivo con la mia tastiera PS2 (collegata ad arduino con libreria PS2Keyboard) stampo correttamente i caratteri sul monitor seriale, ma contemporaneamente scrivo anche sul file di testo nella SD e quindi sostanzialmente chi si connette in rete al mio arduino legge automaticamente i caratteri che ho digitato (aggiornando la pagina ovviamente). Quello che vorrei fare è inserire il tasto invio dalla mia tastiera, ovvero fare in modo che il contenuto del mio file di testo sia reso disponibile a chi legge nel momento in cui premo invio dalla mia PS2Keyboard.
Cio che ho pensato di fare è copiare all'interno di un array di caratteri tutti i tasti che ho digitato da tastiera e attraverso un if else dare il consenso alla scrittura sul file txt dell'array di caratteri. Di seguito riporto la parte di sketch che ho pensato di fare:

#define SIZE 300
int i=0;
char temp[SIZE];
 
if(keyboard.available()) {

char d= keyboard.read();
Serial.print(d);

if(d!='\n') {
temp[i]=d;
i++;}
else
{
File=SD.open("prova.txt",FILE_WRITE);
File.print(temp);
File.close();
}

Il problema è che sul monitor del client non leggo i caratteri correttamente, ma cose strane :smiley: ........Qualche consiglio ?

Mi sembra ci sia un errore nell'assegnazione del vettore temp:

  if (d != '\n') {
    temp[i] = d;
    i++;
  }

Si si la dicitura corretta è quella che lei ha appena scritto

In ogni caso ora il problema è cambiato....effettivamente l'if else scritto in questa maniera funziona, ma il problema è la copia dei caratteri all'interno dell'array....infatti la stampa che ottengo è sempre l'ultima lettera di cio che digito dalla PS2Keyboard

tntsix, ricordati che le stringhe del C (array di char) DEVONO essere sempre null-terminated ovvero DEVONO avere come ultimo carattere 0x00. Quindi, quando ricevi il CR nell'array devi inserire 0x00.

Comunque ... io farei, dopo i++; anche un controllo sul valore di i perché se supera (SIZE-1) ovvero hai scritto (SIZE) caratteri, sfori di memoria ed ciò che fa il programma non è più prevedibile :roll_eyes:

Guglielmo

Stavo pensando anche a questo Gugliemo (ti do del tu perdonami )

Ma mi è venuta un idea.......potrei utilizzare le stringhe di arduino, ovvero fare una cosa del tipo

String string;
int i=0;
 //lettura keyboard e memorizzazione nella variabile d
if(d!='\n') {
string.setcharAt(i,d);
i++;}
else
// scrittura su SD di string
}

solo che non mi riconosce la funzione setcharAt....probabilmente sarà cambiata

Avrò detto mille volte di NON utilizzare la classe String !!! :0

NON sei su un PC dove c'è un sistema operativo ed un "garbage collector", sei su una piccola MCU con solo 2KBytes di SRAM, dove devi fare tutto tu e dove usare la classe "String", a causa dell'allocazione e riallocazione dinamica della memoria, porta quasi sempre ... a sicuri problemi ! ]:smiley:

Fino a quando non siete obbligati (a causa di una libreria esterna che vuole necessariamente tale classe) evitatela ed usate le stringhe classiche del C :slight_smile:

Guglielmo

P.S. : ... tranquillo, qui ci diamo tutti del tu :wink:

Ok allora utilizzo i vettori di caratteri, impelmentando il null ('\0')....vediamo che ne esce fuori.

Dovresti provare una cosa del genere :

char d;
...
...
i = 0;
while (true) {
   d = keyboard.read();      // leggi un carattere
   Serial.print(d);          // lo visualizzi sul monitor
   if (d == '\n') break;     // se è CR esci dal while
   temp[i]=d;                // ... altrimenti lo metti nell'array
   i++;                      // incrementi l'indice
   if (i == (SIZE-1)) break; // se l'indice è al massimo esci
}
temp[i]=0x00;                // alla posizione dell'indice metti il terminatore di stringa
//
File=SD.open("prova.txt",FILE_WRITE);
File.print(temp);
File.close();

Guglielmo

perdonami Gugliemo ma non bisognerebbe mettere il terminatore di stringa nella posizione temp[i+1]?

@tntsix, il codice DEVE essere racchiuso nei tag code. Vedi sezione 7 del regolamento, spiega bene come fare.
Altrimenti parte del codice può essere interpretato male. Soprattutto le quadre.
Vedi questo tuo primo post, a un certo punto il codice perde un pezzo e diventa in italico.

Grazie per la dritta Nid !!! la prox volta metto il codice correttamente

tntsix:
Grazie per la dritta Nid !!! la prox volta metto il codice correttamente

Prego :grin:

tntsix:
perdonami Gugliemo ma non bisognerebbe mettere il terminatore di stringa nella posizione temp[i+1]?

No, i all'uscita dal while è già andato in posizione successiva, in quanto aumenti i con i++ e poi fai il test per uscire dal while.

Vero vero!!!!! avete ragione!

tntsix:
Vero vero!!!!! avete ragione!

Ne dubitavi ??? :astonished: :astonished: :astonished:

Scherzo ovviamente ... :grin: :grin: :grin:

Guglielmo

Nono ci mancherebbe :smiley:

Comunque con il tuo codice Gugliemo sono riuscito a copiare i caratteri della tastiera all'interno di un array e a stamparlo sulla SD.......il problema è che il tasto invio non ha alcun effetto, nel senso che cio che si vede sui client (i pc connessi alla rete) è effettivamente cio che ho scritto sul monitor seriale però su due variabili distinte (il vettore di caratteri per il client e la tastiera per il monitor seriale), ma ho trasparenza tra le due cose, nel senso che anche se non premo il tasto invio, la scrittura su Sd viene effettuata

... se viene effettuata la scrittura sei uscito dal while e se sei uscito dal while ... o hai premuto CR o hai battuto più di (SIZE-1) caratteri.

Oppure ... hai programmato male il Serial Monitor e LUI trasmette il CR ... guarda in basso, a sinistra della velocità, ci deve essere "no line ending" ... altrimenti ...

Guglielmo

Questo è lo skatch

#define SIZE 300
  //
int i = 0 ;
char temp[SIZE];
//

    if(keyboard.available()) {
      while(1) {
   char d = keyboard.read();
    Serial.print(d);
    if(d =='\n') break;
    temp[i]=d;
    i++; 
    if(i=(SIZE-1)) break;    
  }
//
temp[i]=0x00; 
//
    Myfile=SD.open("test.txt",FILE_WRITE);
    Myfile.print(temp);
    Myfile.close();
}

Ma continua ad uscire dal ciclo while.....e non ho premuto nessun invio purtroppo.......per quanto riguarda il monitor seriale c'è scritto nessun fine riga per cui immagino che vada bene .....

Come hai detto tu il problema è che esce dal ciclo while

tntsix ... lo credo !!!
Legge a raffica chissà cosa ... visto che hai messo il if(keyboard.available()) FUORI dal while() ... :roll_eyes:

Comincia a controllare, dentro al while() che ci sia veramente qualche cosa da leggere e, solo se c'è, leggere e fare il resto !

Guglielmo

Perfetto....la scrittura ora funziona correttamente.....quando premo invio da tastiera viene effettuata la scrittura sulla SD......
Per verificare l'effettiva scrittura sulla SD ho semplicemente messo la Sd nel computer e ho visto che scrivendo sul serial monitor senza premere invio non veniva memorizzato nulla sulla Sd, mentre scrivendo su monitor seriale e premendo invio la scrittura veniva effettuata!!!
il problema però è che non riesce a caricarlo piu in rete il file di testo in questa maniera!!!!

tntsix:

  if(keyboard.available()) 

{
   while(1)
   {
     ......
     if(i==(SIZE-1)) break;    
   }
 }

Consiglio, metti le graffe aperte su riga nuova e poi usa il tasto CTRL+T nell'IDE. Magicamente avrai l'indentazione che ti fa capire cosa c'e' nei blocchi e le graffe aperte/chiuse che sono nelle stesse colonne. :wink: