Pages: [1] 2 3   Go Down
Author Topic: ricezione stringa seriale aiuto per interpretazione dati?  (Read 3885 times)
0 Members and 2 Guests are viewing this topic.
livorno
Offline Offline
Newbie
*
Karma: 0
Posts: 25
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

ciao a tutti,

avrei bisogno di superare un punto morto e non ho trovato discussioni simili, qualcuno sa farmi superare questo scoglio?
la mia idea è far comunicare due arduino a distanza, io vorrei inviare dall'arduino master una stringa con variabili separate da virgole (tipo stringa NMEA), vorrei far ricevere dallo slave i dati e far riconoscere le variabili, ma non sono in grado di separare i diversi dati e farli riconoscere come variabili.
mi sono spiegato da cane, faccio un esempio, voglio mandare una stringa tipo:
$GSUB,(variabile1 da 0 a 255),(variabile2 da 0 a 255),(variabile3 da 0 a 255),(variabile4 da 0 a 255),#
con $ inizio stringa e # fine stringa.
c'è qualche libreria o codice che mi fa riconoscere la stringa in ingresso ad esempio come un array dove posso dire all'arduino slave che ad esempio array [1] è la variabile 1 e così via?
scusate se sono stato lungo, e grazie.

Paolo
Logged

Signori si nasce, io spero di esserlo diventato

Bergamo
Offline Offline
God Member
*****
Karma: 1
Posts: 663
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

ciao

non ho ben capito la domanda... in pratica vuoi far parlare due arduino via seriale con un protocollo tuo?
Hai già visto come inviare dati su seriale? In ricezione ricevi un byte alla volta quindi ti basta una semplice macchina a stati che faccia qualcosa tipo:

STATO 1: aspetto l'inizio $
STATO 2: sto ricevendo il pacchetto

ricevo un nuovo carattere
sono in stato 1? Sì, il carattere è $? Si passo in stato 2, No resto in stato 1
Sono in stato 2? Sì, il carattere è #? Sì passo in stato 1, No salvo il carattere nell'array di ricezione incrementando un contatore che mi dice a che punto sono arrivato
Logged

lucadentella.it

livorno
Offline Offline
Newbie
*
Karma: 0
Posts: 25
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

ciao luca,
intanto grazie per l'appoggio!
si vorrei far parlare i due arduino con una seriale inventata a distanza.
si credo di aver visto come inviare dati via seriale, e non ho problemi per l'invio (ho testato con porta com del pc tramite max 232).
volevo fare qualcosa di simile a quello che mi hai consigliato te, ma mi sono inchiodato pesantemente, in pratica se quello che ricevevo lo mettevo ad esempio in un Serial.print mi dava sul serial monitor la stringa da me inviata, ma non sono stato in grado di "infilare la stringa " in un array di ricezione.
c'è qualche codice che per esempio mi dica array[]={stringa ricevuta};
comunque hai capito il punto, mi puoi chiarire il concetto di macchina a stati (io sono un po' verde, in genere uso l'if).
comunque grazie di nuovo

paolo
Logged

Signori si nasce, io spero di esserlo diventato

Bergamo
Offline Offline
God Member
*****
Karma: 1
Posts: 663
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

ciao

vista la trasmissione seriale, dovrai essere tu a fare qualcosa tipo:

char rx_buffer[20];
int rx_position = 0;

if (Serial.available()) {
 rx_buffer[rx_position++];
 if(rx_position == 20) rx_position = 0;
}

in questo modo:

- ogni volta che è disponibile un byte via seriale lo metti nel buffer, incrementando la posizione in cui "salvi" i dati
- se vai oltre la dimensione del tuo buffer devi per forza ripartire da 0 sovrascrivendo...

La macchina a stati è solo un "modello", in pratica si riduce a mettere degli IF(...), tipo:

#define STATO1 1
#define STATO2 2
int stato_attuale;

stato_attuale = STATO1;
...
if(stato_attuale == STATO1) %% (carattere_ricevuto == '$')

ma così fa più figo quando lo dici  smiley-mr-green




Logged

lucadentella.it

livorno
Offline Offline
Newbie
*
Karma: 0
Posts: 25
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

pensavo di capirci di più...

quindi il char rx_buffer[] con le posizioni da 0 a 20 sarebbe la mia stringa ?
avevo fatto una cosa simile con il Serial.read, ma il mio problema è che non riesco a infilare in un array ad esempio rx_buffer[da 0 a 20], e sono convinto che mi perdo veramente in un bicchiere d'acqua.

comunque proverò sia l'if che la macchina a stati
grazie poi ti faccio sapere se sono riuscito a pigiare il buffer nell'array  smiley-lol
paolo
Logged

Signori si nasce, io spero di esserlo diventato

Genova
Offline Offline
Faraday Member
**
Karma: 39
Posts: 3391
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

ciao non so cosa intendi per array di stringa ricevuta, forse intendi raccogliere tutto in una stringa

String readString;
void loop()
{
     while (Serial.available())
     {
       delay(1);
       if (Serial.available() >0)
            {
             char c = Serial.read();
             readString += c;      
            }

                  if (readString.endsWith('#'))
                  {
                    Serial.println(readString);
                   readString="";
                    break;      
                  }
      }

      readString="";   
}
 
in questo caso readString verrà compilato solo se il carattere terminale è #   if (readString.endsWith('#'))  altrimenti verrà svuotata readString="";
inoltre char c = Serial.read(); ti permette di leggere e analizzare un carattere alla volta potresti vedere così in che punto si trova la virgola e registrarlo.
readString += c; fa la concatenazione

che puoi anche sostituire con
readString .concat(char(Serial.read()));

non so se è quello che chiedi


Code:
String readString;
//String InputBuffer = String();
int xx=0;

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

// esempio di stringa    $GSUB,255,255,255,255#
void loop()
{
     xx=0;
     while (Serial.available())
     {
 delay(1);
   if (Serial.available() >0)
            {
     char c = Serial.read();
     readString += c;
              xx++;
                  if (c ==',')
                 {
                   Serial.print(String(xx));
                   Serial.print(";");
                 }
              
            }
                  if (readString.endsWith('#'))
                  {
                    Serial.println("");
                    Serial.println(readString);
           readString="";
                    break;      
                  }
      }

      readString="";
}

questo esempio ti da la posizione delle virgole che potresti usare
ad esempio con
     1a_virgola= readString.substring(0,char_posiz_a);
     2a_virgola= readString.substring(char_pos_a+1, char_posiz_b);
     3a_virgola= readString.substring(char_pos_b+1, char_posiz_c);

ottieni i valori numerici tra una virgola e l'altra ovviamente questo è un esempio di uso del substring le tue posizioni che saranno valori interi le puoi registrare in un array e andarle a riprendere con un for.

una volta ottenuta la stringa per intero cerca un argomento sui separatori, split di stringhe, parsing di stringhe ecc

_____________________________________________________________________________________________
un altro esempio:

#include <string.h>

char sz[] = "Here, is some, sample, 100, data, 1.414, 1020";
void setup()
{
 char *p = sz;
 char *str;
 Serial.begin(9600);
 while ((str = strtok_r(p, ",", &p)) != NULL) // delimiter is the semicolon
   Serial.println(str);
}

void loop(){}


Generando questa uscita

Here
is some
sample
100
data
1.414
1020

ciao

« Last Edit: January 29, 2012, 07:33:39 pm by pablos » Logged

no comment

0
Online Online
Faraday Member
**
Karma: 47
Posts: 5913
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

x iscrizione
Logged

- [Guida] IDE - http://goo.gl/ln6glr
- [Lib] ST7032i LCD I2C - http://goo.gl/GNojT6
- [Lib] PCF8574+HD44780 LCD I2C - http://goo.gl/r7CstH

livorno
Offline Offline
Newbie
*
Karma: 0
Posts: 25
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

buongiorno ragazzi,

@ pablos grazie,
ora ho un po' di materiale su cui studiare un po'...ero proprio bloccato e mi annodavo sui caratteri, virgole ecc.
ciao anche a te testato, anche se non ho capito cosa vuol dire x iscrizione
Logged

Signori si nasce, io spero di esserlo diventato

0
Online Online
Faraday Member
**
Karma: 47
Posts: 5913
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

serve per seguire il post.
quando si risponde ad un topic automaticamente si ci iscrive a seguire il thread.
ma quando il post e' interessante e non si ha nulla da rispondere ? in quel caso mi iscrivo scrivendo "x iscrizione"  smiley
Logged

- [Guida] IDE - http://goo.gl/ln6glr
- [Lib] ST7032i LCD I2C - http://goo.gl/GNojT6
- [Lib] PCF8574+HD44780 LCD I2C - http://goo.gl/r7CstH

0
Offline Offline
Newbie
*
Karma: 0
Posts: 17
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

signorbarro,

mi sembra di capire che tu voglia inviare singoli caratteri e valori da 0 a 255. Forse esiste un modo semplice per gestirli: usare i caratteri ASCII. In questo modo, invece di mandare ad esempio 123, mandi il carattere {
Quindi non ti devi preoccupare di separare i caratteri con ; ma mandi una stringa completa.
Tale stringa viene messa in un array e gestisci poi i singoli caratteri.

Questo il codice:

#include <SoftwareSerial.h>
SoftwareSerial mySerial(2, 3);
char myar[5];
int indice = 0;
void setup() 
{
  mySerial.begin(19200);
}
void loop()
{
  indice = 0;
  if (mySerial.available()>0){
     while (mySerial.available()){
        int serialIn = mySerial.read();
        delay(5);
        myar[indice] = serialIn;
        indice++;
      }
        delay(1500);}
}

Qui trovi informazioni su come usare SoftwareSerial bidirezionale:

http://arduino.cc/en/Reference/SoftwareSerial


Ciao
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 17
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

signorbarro,
naturalmente i caratteri ASCII vanno da 0 a 127, quindi per avere valori da 0 a 255 devi usarne 2 e poi sommarli.

Scusa per l'errore
Logged

Bergamo
Offline Offline
God Member
*****
Karma: 1
Posts: 663
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Aldo:

quando tu trasmetti (vedi ad esempio la funzione Serial.write() di Arduino) invii un BYTE, quindi un valore 0-255... che poi tu interpreti tale byte come carattere ASCII è solo una tua convenzione, comunque trasmetti UN BYTE, non hai alcun motivo per "sommare" due caratteri o altro se vuoi inviare un valore 0-255.
Logged

lucadentella.it

Genova
Offline Offline
Faraday Member
**
Karma: 39
Posts: 3391
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

State perdendo il filo, veramente il suo problema era separare i dati...... da una stringa fatta così
es:  $GSUB,255,255,255,255# lui vuole trovare i dati tra una virgola e l'altra smiley sapendo che $ è l'inizio stringa e # è il termine
« Last Edit: January 30, 2012, 06:03:43 pm by pablos » Logged

no comment

Bergamo
Offline Offline
God Member
*****
Karma: 1
Posts: 663
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Ciao

se il protocollo è "inventato", è inutile trasmettere un separatore tra byte e byte: in ricezione come indicavo prima ti basta salvare il "pacchetto" in un array per potervi accedere via indice e quindi estrarre il byte nella posizione che vuoi.
bye
Logged

lucadentella.it

Genova
Offline Offline
Faraday Member
**
Karma: 39
Posts: 3391
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

true smiley
bye
Logged

no comment

Pages: [1] 2 3   Go Up
Jump to: