Inviare numeri e stringhe via Seriale (con xbee)

Sto impazzendo!
Ho la necessità di inviare le letture di un encoder via seriale in modo da inviarle da modulo xbee e di riuscire a leggerle tramite l'altro modulo.
In particolare vorrei inviare i valori della velocità e della distanza con qualcosa di simile:

vel40
dist50

dove 40 e 50 sono i valori della velocità e della distanza.

Il problema è che riesco a inviare e riconoscere (dall'altro lato) le stringhe di caratteri, ma non capisco come fare a splittare le stringhe definendo eventualmente un carattere di delimitazione (una virgola o il carriage return).

Oppure se questo è un pò troppo complesso, mi basterebbe anche solo inviare i valori degli impulsi letti e poi fare i calcoli con i dati ricevuti sull'altro modulo però anche qui non riesco ad inviare unicamente degli interi perchè da quanto ho capito si possono solo inviare dei caratteri tramite Serial.print().

Mi aiutate, per favore? :slight_smile:

Sulla seriale i dati viaggiano per singoli byte per cui la stringa "vel40" che invii arriva come 5 caratteri distinti. Lato PC non devi far altro che riassemblare i singoli byte in un'unica stringa.

No, non è lato pc, ma uso due Arduino, quindi dall'altro lato c'è sempre Arduino.

Al momento, dall'altro lato, faccio così:

 inputSize = 0;

 if (Serial.available() > 0) {
  
   inputSize = Serial.available();
   for (int i = 0; i < inputSize; i++){
     myCmd[i] = Serial.read();
     myCmd[i+1] = '\0';
   }

Ma non riesco a dividere e salvare in due variabili distinte la stringa del comando e il valore intero.

Allora fai in un modo più semplice, spedisci singoli byte. Ti crei un piccolo protocollo di trasmissione con un piccolo elenco dei "comandi" supportati.

Ad esempio (il $ indica valori in esadecimale):
$00 - vel
$01 - dist
$02 - butt la past
ecc...

Se poi i numeri che devi spedire stanno tutti in un singolo byte (che ricordo va da 0 a 255 come valori), puoi spedire subito il valore.
Esempio:
$00$32 per vel50

Sull'altro Arduino non devi fare altro che stare in ascolto sulla seriale. Appena arriva qualcosa, raccogli i byte. Sai che il primo è il comando, quindi ti serve ad interpretare il dato che arriva dopo. Lo assegni ad una variabile ed hai subito questa che contiene il valore spedito.

Se i valori possono essere maggiori, spedisci un int diviso in 2 byte e poi ricomponi il dato.
Esempio:
int dato=1000;
Serial.write(1); //comando per "dist"
Serial.write(highByte(dato)); //parte alta di "dato"
Serial.write(lowByte(dato)); //parte bassa di "dato"

Sull'altro Arduino ricomponi con
dato=Serial.read()*256; //rimetti a posto la parte alta
data = dato + Serial.read(); //aggiungi la parte bassa

Ciao leo, ti ringrazio per l'aiuto!
Tuttavia, la vedo un pò troppo difficile da implementare così come l'hai proposta e per quelle che sono le mie conoscenze..

Perché ragioni in termini di linguaggi più evoluti dove hai questi che protocollano la trasmissione dei tuoi dati mentre qui sei costretto a fare tutto tu :wink:

Infatti è vero! :slight_smile:

In C++ farei molto prima..

Prova a vedere se ti va bene il codice nell'ultimo post :slight_smile: [Risolto] Xbee:inviare 2 o più valori contemporaneamente - #21 by sciorty - Generale - Arduino Forum

Invii una stringa ad esempio a120b123c123 e metti un ";" alla fine come fine della trasmissione! Ovviamente puoi inviare solo la "a" oppure aggiungere altre lettere per altre variabili!

Ti ringrazio per lo spunto!

Ho provato ad usare il codice per vedere come funzionava, però dando una stringa del tipo "a123b345c456;" non mi trova nulla e quindi non mi stampa nulla.

Non so se magari il problema è perchè uso Arduino 1.0.1 in cui la libreria NewSoftSerial è diventata SoftwareSerial..

Lo sketch si compila senza errori, comunque..

if(my.available()>0)
  {
    
    val=my.read();
    
    while(val!=';'){
     if(my.available()>0)
     {
       string+=val;
       val=my.read();     
     }
    }
    
    Serial.println(string);
}

Prova solo questo intanto..

Adesso funziona, ma dovuto sostituire tutte le occorrenze di NewSoftSerial con Serial standard, solo che comunque se gli mando degli interi grandi non li legge bene :frowning:

Si se non ricordo male è dovuto alla conversione del valore da stringa a intero, ma non ricordo perchè, dato che quella funzione l'ho solo copiata!

Il problema è che i miei interi crescono al passare del tempo, quindi quella soluzione andrebbe bene all'inizio ma poi dopo no perchè gli interi a 4 cifre non sempre gli vanno a genio :slight_smile:

Uhmm ma tu stai usando questo?

#include <NewSoftSerial.h>
NewSoftSerial my(3,2);

char val;
String string="";
String a="";
String b="";
String c="";
int a_int,b_int,c_int;

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

void loop(){
  
  
  
  if(my.available()>0)
  {
    a=b=c=string="";
    
    val=my.read();
    
    while(val!=';'){
     if(my.available()>0)
     {
       string+=val;
       val=my.read();     
     }
    }
    
    Serial.println(string);
      
    for(int i=0;i<string.length();i++){
      if(string.substring(i,i+1).equals("a"))
      {
        i++;
        while(!string.substring(i,i+1).equals("b")){ 
          a+=string.substring(i,i+1); 
          i++;
        }
      }
      if(string.substring(i,i+1).equals("b"))
      {
        i++;
        while(!string.substring(i,i+1).equals("c")){ 
          b+=string.substring(i,i+1); 
          i++;
        }
      }
      if(string.substring(i,i+1).equals("c"))
      {
        i++;
        while(!string.substring(i,i+1).equals("")){ 
          c+=string.substring(i,i+1); 
          i++;
        }
      }
    }
    a_int=stoi(a);
    b_int=stoi(b);
    c_int=stoi(c);
    Serial.print(a_int);
    Serial.print("--");
    Serial.print(b_int);
    Serial.print("--");
    Serial.println(c_int);
    
   
    
  }
  
  
}

int stoi(String text)
{
  char temp[20];
  text.toCharArray(temp, 19);
  int x = atoi(temp);
  if (x == 0 && text != "0")
  {
    x = -1;
  }
  return x;
}

Si si, però ho dovuto togliere la libreria newsoftserial perchè non mi funzionava bene e non mi leggeva nulla.
Utilizzo lo stesso codice, ma faccio tutto con Serial..

Appena ho l'arduino a portata ti faccio sapere :slight_smile: ma che mi ricordi ho usato questo..

ok, fammi sapere perchè ci tengo :slight_smile:

Io l'ho provato e purtroppo non mi fa il parsing correttamente :frowning:

Guarda, a me funziona quello.. Ho messo pure qualche piccolo accorgimento nel caso in cui si volessero inviare solo alcuni valori e non tutti, tipo a100c101;

#include <NewSoftSerial.h>
NewSoftSerial my(3,2);

char val;
String string="";
String a="";
String b="";
String c="";
int a_int,b_int,c_int;

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

void loop(){
  
  
  
  if(my.available()>0)
  {
    a=b=c=string="";
    
    val=my.read();
    
    while(val!=';'){
     if(my.available()>0)
     {
       string+=val;
       val=my.read();     
     }
    }
    
    Serial.println(string);
      
    for(int i=0;i<string.length();i++){
      if(string.substring(i,i+1).equals("a"))
      {
        i++;
        while(!string.substring(i,i+1).equals("b")&&!string.substring(i,i+1).equals("")){ 
          a+=string.substring(i,i+1); 
          i++;
        }
      }
      
      if(string.substring(i,i+1).equals("b"))
      {
        i++;
        while(!string.substring(i,i+1).equals("c")&&!string.substring(i,i+1).equals("")){ 
          b+=string.substring(i,i+1); 
          i++;
        }
      }
      
      if(string.substring(i,i+1).equals("c"))
      {
        i++;
        while(!string.substring(i,i+1).equals("")){ 
          c+=string.substring(i,i+1); 
          i++;
        }
      }
      
    }
    
    if(!a.equals(""))a_int=stoi(a);
    if(!b.equals(""))b_int=stoi(b);
    if(!c.equals(""))c_int=stoi(c);
    
    Serial.print(a_int);
    Serial.print("--");
    Serial.print(b_int);
    Serial.print("--");
    Serial.println(c_int);
    

  }
  
 
  
}


int stoi(String text)
{
  char temp[20];
  text.toCharArray(temp, 19);
  int x = atoi(temp);
  if (x == 0 && text != "0")
  {
    x = -1;
  }
  return x;
}

Prova questo, magari hai una botta ci cu :smiley:

Attenzione, aggiungere delay(2000) prima del serial.begin(9600) rischio impallamento....

Mi da un errore di compilazione:

sketch_jul04b.cpp: In function 'void loop()':
sketch_jul04b:65: error: 'stoi' was not declared in this scope
sketch_jul04b:66: error: 'stoi' was not declared in this scope
sketch_jul04b:67: error: 'stoi' was not declared in this scope

in quale libreria è definita la funzione stoi()?