Protocollo seriale

buon giorno,
forse la domanda che sto per fare è banale, ma essendo io più elettronico che informatico, è per mè complessa.

duonque fino ad ora riesco a far accendere e spegnere un led con un carattere mandato via seriale (usb)

a = accendi led
b = spegni led
ecc...

void setup() {
pinMode(11, OUTPUT);
pinMode(10, OUTPUT);
Serial.begin(9600);

void loop() {

int pippo = 0;

if (Serial.available() > 0) {

pippo = Serial.read();

// Serial.println (pippo);

if (pippo == 'a') {Serial.println ("Attivo Led 1");digitalWrite (11, HIGH);}
if (pippo == 'b') {Serial.println ("Disattivo Led 1");digitalWrite (11, LOW);}
if (pippo == 'c') {Serial.println ("Attivo Led 2");digitalWrite (10, HIGH);}
if (pippo == 'd') {Serial.println ("Disattivo Led 2");digitalWrite (10, LOW);}
}
}

giusto per capirsi!

ora vorei fare qualcosa di meglio, ovvero sempre accendere e spegnere un led, ma invece di usare solo il carttere "a", "b", eccc

magari fare:

al1 = accendi led 1
sl1 = spegni led 1

e così via....

come si può fare?
Grazie a tutti x l'eventale aiuto!

Devi per primo scrivere i dati della seriale in un array, poi controllare i singoli caratteri ( carattere 1 se Spegi o accendi; carattere 3 quale LED.
Il codice per leggere dalla seriale posso dartelo stasera.
Ciao Uwe

Questo è il codice che utilizzo per ricevere delle stringhe da pc:

time=millis();
while(millis()<(time+2000)){
      if(Serial.available()>0){
        text=text.concat((byte)Serial.read());  
        if(text.endsWith('\n')){
          break;
        }
        l++;
      }
    }

praticamente salva, se presenti i dati della seriale per un tempo massimo di 2sec o termina prima se riceve il carattere '\n'. Il tutto è salvato in una stringa text con cui dopo faccio i controlli sui dati ricevuti.

interessantissimo!!!!

non è che avete (o sapete dove trovare per studiarlo) un programmino che faccia ciò? una cosa proprio didattica senza troppo fronzoli :slight_smile:

grazie

p.s. uwefed....se hai qualcosa da passarmi (con tutta la calma, non ce fretta) mi farebbe davvero molto piacere XD

Se intedi un prog per windows che invii dati tramite seriale c'è questo:
http://msmvps.com/blogs/coad/archive/2005/03/23/SerialPort-_2800_RS_2D00_232-Serial-COM-Port_2900_-in-C_2300_-.NET.aspx
o puoi usare hyperterminal

no no la parte di programmazione sul pc (per ora non mi interressa) è prprio capire passo passo come aquisite i vari byt (in un array) e poi farci i controlli a posteriori...argomento afascinantissimo :slight_smile:

il codice non sarà dei migliori o pulitisso, ma fa un pò di tutto.
funziona così: ogni loop() chiami la funzione, la funzione legge un dato formato in questo modo:
*nome comando:valore numerico\n

  • indica l'inizio del condo (non dovrebbe essercene bisogno, ma non si sa mai... quindi il comando non può contenere *. Il comando può essere lungo al massimo 9 caratteri(array input2)
    : indica che il nome del comando è finito e inizia l'inserimento del valore numerico
    il valore numerico può essere sia negativo che un numero con la virgola (ma NON si usa la virgola ma il punto, per esempio -34.6)
    Non c'è controllo che l'input sia un vero e proprio numero, e ciò può creare valori random se si inseriscono lettere al posto dei numeri.
    \n è il carattere di fine stringa, non devi scriverlo a mano, ma se usi il terminale di arduino devi dirgli di usarlo, nel menù a tendina scegli (dove c'è "no line ending") "newline"

codice:

char input1;
char input2[10];
int indexInput2=0;
boolean inputValue=false;
boolean negativo=false;
void readSerial(){
  /*
  input data: *name:value\n
   */
  while (Serial.available() > 0){
    char c = Serial.read();
    if (c =='*'){
      indexInput2=0;
      inputValue=false;
      negativo=false;
      //      Serial.println("starting input");
    }
    else{
      if (c =='\n'){
        input2[indexInput2]='\0';
        //        Serial.print("value: ");
        //        Serial.println(input2);
        int point=0, i=0;
        float ris=0;
        while(input2[i]!='\0'){
          if (input2[i]=='.'){
            point=indexInput2-i-1;
          }
          else{
            ris=(ris*10)+input2[i]-'0';
          }
          i++;
        }
        /*      
         Serial.print("ris: ");
         Serial.println(ris);
         Serial.print("point: ");
         Serial.println(point);
         */
        ris/=pow(10, point);
        if (negativo){
          ris*=-1;
        }
        executeCommand(input1, ris);
      }
      else{
        if (inputValue){
          if (indexInput2==0 && c=='-'){
            negativo = true;
          }
          else{
            input2[indexInput2]=c;
            indexInput2++;
          }
        }
        else{
          if (c ==':'){
            //            Serial.println("command ok, waiting value");
            inputValue=true;
          }
          else{
            input1=c;
          }
        }
      }
    }
  }

}

bene grazie, mo lo stampo e lo studio!

se non capisco (cosa probabile) vi romperò ancora le scatole con altre domande XD

grazie a tutti...x ora!

ma il codice sopra è funzionante (da solo) o ci sono funzioni extra (non dichiarate)???

avrei bisogno di qualcosa funzionante x analizzarlo (rivoltarnlo, manipolarlo e forse alla fine capire) :smiley:

lo so son piattoloso.... grazie ragazi di tutto!

questo codice non legge un messaggio ogni loop, ma raccoglie i pezzi di dato disponibili ogni loop e quando ha raccolto tutti i dati chiama una funzione di nome "executeCommand(input1, ris);"
dove input1 è il nome del comando, e ris è il valore numerico.
ovviamente sarà questa funzione a eseguire il tuo comando desiderato.

sono nuovissimo di arduino con un'infarinatura di Visual Basic, quindi l'ultimo ragazzo alla faccia della terra in grado di aiutarti.
ho dovuto inserire un delay perchè altrimenti i primi 2 caratteri me li riscontrava come singoli (sicuramente troppo rapido il loop rispetto al trasferimento dati), però sembra funzionare.
diciamo che è da rimettere a posto.
p.s. almeno c'ho provato :wink:

void setup()
{
Serial.begin(9600);

}

void loop() {
delay(500);
String StringaRicevuta;
if (Serial.available() > 0) {
while (Serial.available() > 0) {
StringaRicevuta = StringaRicevuta + char(Serial.read());

}
Serial.println(StringaRicevuta);
}

}

il problema nel tuo codice è che ogni loop crei una nuova stringa, quindi se i dati ci meettono troppo ad arrivare non leggerari la stringa completa(motivo dei due caratteri singoli). Potresti usare un while per aspettare finchè non ricevi tutta la stringa, però è tempo cpu perso, un problema per progetti in cui i tempi di risposta sono importanti

mi rendo conto lesto, infatti come descritto dal precedente post "c'ho provato" nonostante mi rendessi conto da solo (fatto in 5 minuti) che il codice è molto "primitivo".
sto cercando di studiare il tuo codice chea me risulta abbastanza complesso e mi genera alcuni errori.
continuo nel mio studio per hobby sperando un giorno di essere in grado di aiutarvi.

che tipo di errori? a parte che manca executeCommand e che devi chiamare la funzione ogni tanto dovrebbe funzionare

caro lesto,
per me un'errore è anche il fatto che mancano i void setup e loop perchè di arduino veramente non ne so molto.
cmq me lo sto studiando piano piano.
se ho qualche lacuna(cosa probabilissima) sarai il primo a saperlo :wink:

intanto ti ringrazio per gli aiuti che ci dai (giro spesso per i forum anche se non scrivo e ti ho visto da parecchie parti) e ti reputo una persona molto informata.

grazie ancora e buon arduino a tutti :smiley: