Go Down

Topic: Serial.read di un numero (Read 1 time) previous topic - next topic

Gono

Ciao a tutti! Rieccomi partito in quarta a fare domande  :D
Quello che volevo fare è inviare dal computer (con python) un numero da 0 a 255 per il PWM.
Il problema è che il Serial.read mi legge solo un carattere alla volta e quindi non mi funziona nulla  :(
Avete qualche idea per poter ricevere il numero tutto intero?
SO Linux - Ubuntu 12.04 - Arduino Uno R3 - IDE 1.0.5

leo72

L'argomento dell'invio di dati sulla seriale è stato affrontato un migliaio di volte  :smiley-sweat:
Onde evitare di riscrivere post su post, ti consiglio di fare una ricerca per tirar fuori le info che ti servono.

Gono

Forse sono io incapace a cercare (cosa molto probabile  :D), ma non ho trovato nulla di esaustivo.
SO Linux - Ubuntu 12.04 - Arduino Uno R3 - IDE 1.0.5

ale92

leggermente differente ma praticamente lo stesso argomento, se cerchi ci sono anche varie soluzioni
http://arduino.cc/forum/index.php/topic,119694

Gono

In linea di massima dovrebbe funzionare questo: (quello dell'ultima pagina del topic linkato da ale92)

Code: [Select]

int vet[3] = { -2, -2, -2 };  //numero arbitrario, usato per vedere se è stato inserito un numero o no (non so perchè tu abbia messo -3 in quello da tre cifre, il -2 non centra niente con la dimensione dell'array) non ho
//usato -1 perchè significa che non ci sono dati da leggere (secondo la serial available) quindi si poteva fare confusione
int cont = 0;
int x = 0;

void setup()
{
  // start serial port at 9600 bps:
  Serial.begin(9600);
}

void loop()
{
  while (Serial.available() > 0)
  {
    vet[cont] = Serial.read()-48;   //trasformo da codice ascii a numero utilizzabile
    cont++;
    delay(50); //sinceramente non so il motivo tecnico ma l'ho messo perchè mi si è accesa una lampadina, senza la serial available da dei "falsi negativi" cioè legge un byte, poi anche sei hai messo 2 numeri l'istruzione //dice che non c'è più niente da leggere e quindi esce dal while, forse l'esecuzione è troppo veloce per i sui gusti, non so....
  }
 
   if (vet[0] < -2 || vet[1] < -2 || vet[2] < -2 )  Serial.println("E' STATO INSERIRTO UN CARATTERE INSERIRE SOLO NUMERI DA 1 A 999  ");

   if (vet[0] > 9 || vet[1] > 9 || vet[2] > 9)  Serial.println("E' STATO INSERIRTO UN CARATTERE  INSERIRE SOLO NUMERI DA 1 A 999  ");
   


  if(cont > 0) //se ho letto qualcosa fai la conversione altrimenti niente
  {
    cont = 0;
    if (vet[1] == -2 && vet[2] == -2) //se vet[1] = a -2 cioè il valore iniziale significa che c'era solo un numero da leggere quindi è un numero da 0 a 9
    {
      x = vet[0];
    }
    else
    if ( vet[2] == -2) //se vet[1] = a -2 cioè il valore iniziale significa che c'era solo un numero da leggere quindi è un numero da 0 a 9
    {
      x = vet[0] * 10 + vet[1];
    }
    else
    {
      x = vet[0] * 100 + vet[1]* 10+ vet[2]; //altrimenti faccio la formulina perchè è un numero da 10 a 99
    }
   
         if (vet[0] < -2 || vet[1] < -2 || vet[2] < -2 ) x =0;
   if (vet[0] > 9 || vet[1] > 9 || vet[2] > 9)  x =0;
    Serial.println(x);
    vet[0] = -2;   //fix per il bug della versione precedente
    vet[1] = -2;
    vet[2] = -2;
  }
}


L'unico problema è che utilizzando una scroolbar da python per inviarli un valore, lui da difficoltà a riceverli velocemente.
SO Linux - Ubuntu 12.04 - Arduino Uno R3 - IDE 1.0.5

leo72

Questo è il primo che ho trovato:
http://arduino.cc/forum/index.php/topic,115283.0.html

Poi a seguire questo:
http://arduino.cc/forum/index.php/topic,89421.0.html

Ti linko questo mio post che spiega come arrivano i dati sulla seriale:
http://arduino.cc/forum/index.php/topic,119694.msg903096.html#msg903096

gingardu


Ciao a tutti! Rieccomi partito in quarta a fare domande  :D
Quello che volevo fare è inviare dal computer (con python) un numero da 0 a 255 per il PWM.
Il problema è che il Serial.read mi legge solo un carattere alla volta e quindi non mi funziona nulla  :(
Avete qualche idea per poter ricevere il numero tutto intero?


qui c' è  il codice che ho "aggiustato"  puoi inviare numeri da 0 a 999999999
la variabile x assume il valore e viene stampata
se si prova a inviare una lettera appare il messaggio ATTENZIONE ...........

Code: [Select]
long vet[9] = {-2, -2, -2, -2, -2, -2, -2, -2, -2 };
     
long cont = 0;
long x = 0;

void setup()
{

  Serial.begin(9600);
}

void loop()
{
  while (Serial.available() > 0)
  {
    vet[cont] = Serial.read()-48; 
    cont++;
    delay(60);
         
  }
 
   if (vet[0] < -2 || vet[1] < -2 || vet[2] < -2 || vet[3] < -2 || vet[4] < -2 || vet[5] < -2 || vet[6] < -2 || vet[7] < -2 || vet[8] < -2)
   Serial.println(" ATTENZIONE DEVI  INSERIRE SOLO NUMERI DA 1 A 999999999  ");

   if (vet[0] > 9 || vet[1] > 9 || vet[2] > 9 || vet[3] > 9 || vet[4] > 9 || vet[5] > 9 || vet[6] > 9 || vet[7] > 9 || vet[8] > 9)
   Serial.println("   ATTENZIONE DEVI  INSERIRE SOLO NUMERI DA 1 A 999999999  ");
   


  if(cont > 0)
  {
    cont = 0;
   
   
      if (vet[8] == -2 && vet[7] == -2 && vet[6] == -2 &&  vet[5] ==  -2  && vet[4] ==  -2  && vet[3] ==  -2  && vet[2] ==  -2  && vet[1] ==  -2 )
                                                                               
    {                                                                     
      x = vet[0];                                                           
    }
    else
   
    if (vet[8] == -2 && vet[7] == -2 && vet[6] == -2 && vet[5] ==  -2  && vet[4] ==  -2  && vet[3] ==  -2  && vet[2] ==  -2 ) // 
    {
      x = (vet[0]* 10 +   vet[1]    );
    }
    else
    if  (vet[8] == -2 && vet[7] == -2 && vet[6] == -2 &&  vet[5] ==  -2  && vet[4] ==  -2  && vet[3] ==  -2 ) //
    {
      x = (vet[0] * 100 + vet[1]* 10+ vet[2]);
    }
    else
    if  (vet[8] == -2 && vet[7] == -2 && vet[6] == -2 && vet[5] ==  -2  && vet[4] ==  -2  )
    {
      x = (vet[0] * 1000 + vet[1] * 100 + vet[2]* 10 + vet[3]); 
      } else
      if  (vet[8] == -2 && vet[7] == -2 && vet[6] == -2 && vet[5] ==  -2   )
      {
      x = (vet[0] * 10000 + vet[1] * 1000 + vet[2]* 100 + vet[3]* 10 + vet[4]); 
     
      } else
       if  (vet[8] == -2 && vet[7] == -2 && vet[6] == -2 )
      {
      x = (vet[0] * 100000 + vet[1] * 10000 + vet[2]* 1000 + vet[3]* 100 + vet[4]* 10 + vet[5]); 
     
      } else
       
        if  (vet[8] == -2 && vet[7] == -2 )
      {
      x = (vet[0] * 1000000 + vet[1] * 100000 + vet[2]* 10000 + vet[3]* 1000 + vet[4]* 100 + vet[5]* 10+ vet[6]); 
     
      } else 
       
          if  (vet[8] == -2 )
      {
      x = (vet[0] * 10000000 + vet[1] * 1000000 + vet[2]* 100000 + vet[3]* 10000 + vet[4]* 1000 + vet[5]* 100 + vet[6]* 10+ vet[6]); 
     
      } else
       
       
       
x = (vet[0] * 100000000 + vet[1] * 10000000 + vet[2]* 1000000 + vet[3]* 100000 + vet[4]* 10000 + vet[5]* 1000 + vet[6]* 100 + vet[7] * 10 + vet[8]);
       
     
if (vet[0] < -2 || vet[1] < -2 || vet[2] < -2 || vet[3] < -2 || vet[4] < -2 || vet[5] < -2 || vet[6] < -2 || vet[7] < -2 || vet[8] < -2 ) x = 0;
if (vet[0] > 9 || vet[1] > 9 || vet[2] > 9 || vet[3] > 9 || vet[4] > 9 || vet[5] > 9 || vet[6] > 9 || vet[7] > 9 || vet[8] > 9)  x = 0;

if (x == -2 || x== -1) x=0;
         
   
     
if (vet[0] >= -2 && vet[1]  >= -2 &&  vet[2]  >= -2 &&  vet[3] >= -2 && vet[4] >= -2 && vet[5] >= -2 && vet[6] >= -2 && vet[7] >= -2 && vet[8] >= -2 &&
  vet[0] <= 9 && vet[1] <= 9 &&  vet[2] <= 9 &&  vet[3] <= 9 &&  vet[4] <= 9 &&  vet[5] <= 9 &&  vet[6] <= 9 &&  vet[7] <= 9 &&  vet[8] <= 9 )
     Serial.println(" NUMERO INSERITO  "),   Serial.println(x);

   //if (x == 0)   Serial.println(" REINSERISCI UN  NUMERO DA 1 A 999999999  ")  ;
         
   

   
    vet[0] = -2; 
    vet[1] = -2;
    vet[2] = -2;
    vet[3] = -2;
    vet[4] = -2;
    vet[5] = -2;
    vet[6] = -2;
    vet[7] = -2;
    vet[8] = -2;       
  }

}
Le cose si possono considerare facili in due casi: quando le si conosce bene o quando non le si conosce affatto...

Gono

Intanto vi ringrazio tutti per le numerose risposte!

@GINGARDU
Ti ringrazio per avermi postato il codice, ma mi sembra che sia quasi uguale a quello che avevo visto prima.
Il problema è che c'è quel delay() che rallenta il tutto!

Con i link che mi avete postato sono riuscito a fare qualcosa di interessante e sembra funzionare.
Ecco il codice che ho un po' modificato:

Code: [Select]

char temp[10];
int cont_t;
boolean inizio_t = false;
boolean fine_t = false;
int pwm;


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

}

void loop()
{
 
   if(Serial.available() > 0)
   {
     ottieni_dati();
     
     }
}

// -------------------- METODI -------------------

void ottieni_dati()
{
char rx = Serial.read();
// --------------- TEMPERATURA -------------

          if(rx == '<')
{
     inizio_t = true;
     cont_t = 0;
     temp[cont_t] = '\0';
}
else if(rx == '>')
{
     fine_t = true;
}
else if(inizio_t == true)
{
     temp[cont_t] = rx;
     cont_t++;
     temp[cont_t] = '\0';
   
}
   
   if(inizio_t && fine_t)
   {
// Converto la stringa in intero
int tempInt = atoi(temp);

// Uso il valore
        //Serial.print("Valore: ");
        Serial.println(tempInt);
        pwm = tempInt;
  // Azzero tutto per la possima lettura
inizio_t = false;
fine_t = false;

cont_t = 0;
temp[cont_t] = '\0';
   }
   
}

Se a qualcuno dovesse servire:

-Per inviare un valore numerico esso deve essere racchiuso tra '<' e '>' ad esempio per inviare il numero 300 devo inviare '<300>'.
-Funziona anche se invio dati velocemente, per esempio io con la scroolbar in meno di un secondo potrei inviare più di 200 valori.
-Ho notato che se decommento la riga "Serial.print("Valore: ");" oltre ad inviare 200 valori invierei anche 200 volte la parola "Valore:" e quindi inizierebbe a inviare dati a scatti con alcuni valori sballati. Io ho risolto aumentando il baud a 115200.
SO Linux - Ubuntu 12.04 - Arduino Uno R3 - IDE 1.0.5

ale92

il delay io l'avevo messo perchè il Serial.available mi dava dei falsi negativi (cioè mi diceva che non c'era più niente da leggere mentre invece c'era) e avevo risolto con il delay...probabilmente tu visto che hai messo delle istruzioni tra una lettura e l'altra hai colmato comunque quel tempo che invece io davo con il delay (tutte supposizioni)

lesto



Ciao a tutti! Rieccomi partito in quarta a fare domande  :D
Quello che volevo fare è inviare dal computer (con python) un numero da 0 a 255 per il PWM.
Il problema è che il Serial.read mi legge solo un carattere alla volta e quindi non mi funziona nulla  :(
Avete qualche idea per poter ricevere il numero tutto intero?


qui c' è  il codice che ho "aggiustato"  puoi inviare numeri da 0 a 999999999
la variabile x assume il valore e viene stampata
se si prova a inviare una lettera appare il messaggio ATTENZIONE ...........

Code: [Select]
long vet[9] = {-2, -2, -2, -2, -2, -2, -2, -2, -2 };
     
long cont = 0;
long x = 0;

void setup()
{

  Serial.begin(9600);
}

void loop()
{
  while (Serial.available() > 0)
  {
    vet[cont] = Serial.read()-48; 
    cont++;
    delay(60);
         
  }
 
   if (vet[0] < -2 || vet[1] < -2 || vet[2] < -2 || vet[3] < -2 || vet[4] < -2 || vet[5] < -2 || vet[6] < -2 || vet[7] < -2 || vet[8] < -2)
   Serial.println(" ATTENZIONE DEVI  INSERIRE SOLO NUMERI DA 1 A 999999999  ");

   if (vet[0] > 9 || vet[1] > 9 || vet[2] > 9 || vet[3] > 9 || vet[4] > 9 || vet[5] > 9 || vet[6] > 9 || vet[7] > 9 || vet[8] > 9)
   Serial.println("   ATTENZIONE DEVI  INSERIRE SOLO NUMERI DA 1 A 999999999  ");
   


  if(cont > 0)
  {
    cont = 0;
   
   
      if (vet[8] == -2 && vet[7] == -2 && vet[6] == -2 &&  vet[5] ==  -2  && vet[4] ==  -2  && vet[3] ==  -2  && vet[2] ==  -2  && vet[1] ==  -2 )
                                                                               
    {                                                                     
      x = vet[0];                                                           
    }
    else
   
    if (vet[8] == -2 && vet[7] == -2 && vet[6] == -2 && vet[5] ==  -2  && vet[4] ==  -2  && vet[3] ==  -2  && vet[2] ==  -2 ) // 
    {
      x = (vet[0]* 10 +   vet[1]    );
    }
    else
    if  (vet[8] == -2 && vet[7] == -2 && vet[6] == -2 &&  vet[5] ==  -2  && vet[4] ==  -2  && vet[3] ==  -2 ) //
    {
      x = (vet[0] * 100 + vet[1]* 10+ vet[2]);
    }
    else
    if  (vet[8] == -2 && vet[7] == -2 && vet[6] == -2 && vet[5] ==  -2  && vet[4] ==  -2  )
    {
      x = (vet[0] * 1000 + vet[1] * 100 + vet[2]* 10 + vet[3]); 
      } else
      if  (vet[8] == -2 && vet[7] == -2 && vet[6] == -2 && vet[5] ==  -2   )
      {
      x = (vet[0] * 10000 + vet[1] * 1000 + vet[2]* 100 + vet[3]* 10 + vet[4]); 
     
      } else
       if  (vet[8] == -2 && vet[7] == -2 && vet[6] == -2 )
      {
      x = (vet[0] * 100000 + vet[1] * 10000 + vet[2]* 1000 + vet[3]* 100 + vet[4]* 10 + vet[5]); 
     
      } else
       
        if  (vet[8] == -2 && vet[7] == -2 )
      {
      x = (vet[0] * 1000000 + vet[1] * 100000 + vet[2]* 10000 + vet[3]* 1000 + vet[4]* 100 + vet[5]* 10+ vet[6]); 
     
      } else 
       
          if  (vet[8] == -2 )
      {
      x = (vet[0] * 10000000 + vet[1] * 1000000 + vet[2]* 100000 + vet[3]* 10000 + vet[4]* 1000 + vet[5]* 100 + vet[6]* 10+ vet[6]); 
     
      } else
       
       
       
x = (vet[0] * 100000000 + vet[1] * 10000000 + vet[2]* 1000000 + vet[3]* 100000 + vet[4]* 10000 + vet[5]* 1000 + vet[6]* 100 + vet[7] * 10 + vet[8]);
       
     
if (vet[0] < -2 || vet[1] < -2 || vet[2] < -2 || vet[3] < -2 || vet[4] < -2 || vet[5] < -2 || vet[6] < -2 || vet[7] < -2 || vet[8] < -2 ) x = 0;
if (vet[0] > 9 || vet[1] > 9 || vet[2] > 9 || vet[3] > 9 || vet[4] > 9 || vet[5] > 9 || vet[6] > 9 || vet[7] > 9 || vet[8] > 9)  x = 0;

if (x == -2 || x== -1) x=0;
         
   
     
if (vet[0] >= -2 && vet[1]  >= -2 &&  vet[2]  >= -2 &&  vet[3] >= -2 && vet[4] >= -2 && vet[5] >= -2 && vet[6] >= -2 && vet[7] >= -2 && vet[8] >= -2 &&
  vet[0] <= 9 && vet[1] <= 9 &&  vet[2] <= 9 &&  vet[3] <= 9 &&  vet[4] <= 9 &&  vet[5] <= 9 &&  vet[6] <= 9 &&  vet[7] <= 9 &&  vet[8] <= 9 )
     Serial.println(" NUMERO INSERITO  "),   Serial.println(x);

   //if (x == 0)   Serial.println(" REINSERISCI UN  NUMERO DA 1 A 999999999  ")  ;
         
   

   
    vet[0] = -2; 
    vet[1] = -2;
    vet[2] = -2;
    vet[3] = -2;
    vet[4] = -2;
    vet[5] = -2;
    vet[6] = -2;
    vet[7] = -2;
    vet[8] = -2;       
  }

}



oddio piuttosto che usare un array di long, semplicemente fai
variabile = variabile*10+cifraLetta;

non solo risparmi un sacco di righer di codice, ma puoi leggere numeri di grandezza arbitrartia, ed in oltre risparmi un sacco di RAM. All In ;)
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Go Up