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
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy