read serial problemi + proposta mini paginetta su arduino.cc

salve.
ho fatto un mini programmino con python che mi scrive su seriale ad arduino.

import serial
sr=serial.Serial("/dev/tty.usbmodemfd121", 9600)
sr.write("a")

in sostanza questo codice per chi non sapesse invia "a", che poi su arduino questo evento lo collego ad un led,
quindi se arriva la lettera "a" il led 13 si accende se arriva "s" si spegne

int sr;
void setup() {
  pinMode(13, OUTPUT);
  Serial.begin(9600);  
}

void loop() {
   sr=Serial.read();
   if(sr=='a'){
     digitalWrite(13, HIGH);
   }else if(sr=='s') {
     digitalWrite(13, LOW);
   }
}

quello che non capisco è perche se invio più di una lettera a volta non mi funziona esempio se invia "accendi" e "spegni" cambiando anche il codice in arduino non succede nulla

Anche io una volta avevo questo problema. Prova a mettere il testo tra " " e fammi sapere.

se scrivo

 if(sr=="a")

mi segna la riga come errore

non puoi usare il == per fare confronti tra stringhe char* o char[](mentre puoi con String)..cerca su google strcmp..

Perchè inizializzi sr come int se poi lo confronti con un char?

ho cercato strcmp ma non capisco.
cosa devo fare?

modifca sr da int a uint_8 oppure byte (che è un define di uint_8).
dovrebbe funzionare.

ok ho capito finalmente una cosa arduino legge un carattere alla volta.
provate questo

char sr;
void loop() {

   if ( Serial.available()){
     sr=Serial.read();
     Serial.println(sr);
   }

}

andando su serial monitor di arduino se scrivo es. "ciao" arduino capisce "c", "i", "a", "o"
pensavo di creare un'array dove raggruppare il tutto ma non so come posso sapere quando finisce una riga e farei l'errore di unire le rige

prova a mandare dal pyton un carattere in più che tu interpreti come fine riga...quando leggi quello dall'arduino smetti di inserire elementi nell'array

nella seriale ogni lettera è un messaggio a se. quindi se scrivi "ciao" sul monito seriale, in un loop potresti vedere 1, 2, 3 oppure 4 lettere disponibili alla lettura (la seriale è molto lenta, quindi sì, può capitare di leggere solo parte di quello che ERRONEAMENTE pensi un messaggio unico)

il trucco è:

  1. usare un carattere di fine riga, di solito si una lo '\n' (il '\0' non credo si possa inviare via seriale ma magri erro)
  2. creare una stringa globale
  3. ogni loop aggiungere una lettera letta da seriale alla stringa, se la lettera è '\n' o il carattere terminatore scelto, copiare il contenuto della stringa da un'altra parte per la successiva elaborazione, cancellare la stringa di partenza, elaborare la copia facendo ciò che bisogna fare, ricomincare da capo.

un altro trucco molto usato è mettere la read in un while fichè non è letto il carattere '\n'; vantaggio codice più semplice e non necessiti della stringa globale; svantaggio è che non puoi fare nient'altro mentre il codice legge la seriale (in pratica hai una delay finchè non arriva '\n')

vedi te cosa vuoi fare e qual'è la soluzione migliore

ho fatto:
ho creato un funzione carina che permette di leggere una riga da serial e la fine è marcata da ""

  String testo;
  void setup() {
    Serial.begin(9600);
  }

  void loop() {
    if(Serial.available()){
      testo=SerialRead();
      Serial.println(testo);
    }
  }
  
  String SerialRead(){
    String seriale;
    char rx;    
    while(rx!='\\'){
      if(Serial.available()){
          seriale=seriale+String(rx);
          rx=Serial.read(); 
      }
    }
    return seriale;
  }

ora vorrei propporre un cosa.
da quello che ho notato su google io sono l'ultimo di una lunghissima lista di persone che non saprebbero come fare questo.
forse è la prima volta che si risolve decentemente con una semplicissima funzione il problema.
volevo chiedere se è possibile da chi di dovere di magari perfezionare la mia funzione e di creare una mini paginetta sul sito arduino.cc dove spiega come fare, così si evita che ci siano altre domande del genere.

usi rx prima di inizializzarla. il suo contenuto è random e può esssere fonte di problemi. Quindi char rx='';.
Al primo giro sommi rx (non inizializzata) con un la stringa, quindi aggiungi un carattere a caso alla stringa.
" String(rx)" è evitabile, crei una classe per nulla. seriale=seriale+rx; va più che bene
Anche seriale non è inizializzata,potrebbe essere un problema, dipende come funziona la String internamente

quindi

String SerialRead(){
    String seriale = "";
    char rx = '';
    do{
      seriale=seriale+rx; //add last char to seriale, that is nothing if it is the first loop
      while(!Serial.available()){
          ;// do nothing
      }
      //now there is at least one char in Serial, read it
      rx=Serial.read(); 
    }while(rx!='\\');
    return seriale;
}

ecco bene siamo arrivati a una versione stabili adesso funziona.
chi quota la mini paginetta su arduino.cc??

perchè quotarla?direi che è un problema di conoscenza di programmazione,non un baco di arduino..
in giro ci sono molti esempi(TROPPI),ma pochi li degnano di uno sguardo..e a volte uno nella marea di esempi ci affoga..

m_ri ha ragione, la domanda di leggere stringhe da seriale compare almeno 2 o 3 volte alla settimana

lesto:
m_ri ha ragione, la domanda di leggere stringhe da seriale compare almeno 2 o 3 volte alla settimana

Ciao Lesto, appunto per questo sarebbe utile inserire nella demo-repository standard degli sketch di Arduino un tutorial con codice commentato sulla ricomposizione di quanto arriva dalla seriale. Che poi sia con array, string o altro fa niente, basta contemplarlo nei commenti...

Anche perché è più facile imparare copiando che inventando (anche se dipende molto dai motivi per cui uno si interessa di Arduino...)

Ciao, Salvatore