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

rigrazie a tutti per la partecipazione,

@testato, grazie per ritenere il topic interessante

@ aldo, no non era un problema di trasmissione o caratteri ascii (come ha precisato pablos)

@luca, ho messo le virgole come separatore perche ho supposto che il dato trasmesso potesse avere 1, 2 o tre cifre (valore da 0 a 255), quindi non mi volevo legare a cercare i byte nel buffer con la posizione
detto terra terra volevo prendere la stringa inviata e sbatterla ad esempio in:
array []={stringa ricevuta con le variabili separate da virgole};
array[1]= prima variabile inviata
array[2]=seconda variabile inviata
ecc.
ma mi sembra di capire che non è immediato come pensavo
(devo essere sincero che per casini col lavoro non ho ancora ne provato ne ragionato sulla tua soluzione, ma lo farò presto ..la macchina a stati mi intriga anche come cultura)

@pablos penso che tu abbia "decifrato" la mia domanda probabilmente era posta in termini poco tecnici, ma sono comunque contento che abbia incuriosito tanta gente (anche il tuo suggerimento sarà seguito presto, quando avrò il tempo di agganciare l'arduino sul pc).

ciao di nuovo a tutti





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

per fare lo split di una stringa o ti scrivi tu la funzione utilizzando i metodi che l'oggetto String ti mette a disposizione (indexOf, subString...) oppure puoi usare la funzione strtok_r che non è delle librerie Arduino ma è nativa del compilatore ed è sicuramente più complessa da usare:

http://www.nongnu.org/avr-libc/user-manual/group__avr__string.html#gac0dbc25e8b202114031a4aa2a7c5177b
Logged

lucadentella.it

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

non esistono risposte sbagliate,ma domande fatte male!

allora ieri sera mi sono un po' sbizzarrito con i consigli di pablos, ed era perfetta per ottenere la stringa che inviavo io.
la mia idea era di ottenere però i valori numerici come int quindi non funzica in quanto sono parte di stringa.
io ho pensato:
- soluzione tipo luca, butto nel buffer di rx e estrapolo dalla "," in poi i byte come variabile int provvedendo a catalogarli come unità, decine e centinaia, in modo da riottenere una variabile int da 0 a 255.
- soluzione da valutare ho visto l'esistenza della funzione atoi per convertire stringa in int... sapete dove posso trovare la libreria "stdlib.h"?
in pratica io con i valori che "spedisco con la stinga vorrei comandare 4 motori

non voglio logorare nessuno, e non voglio codici già fatti, ma un aiuto mi farebbe guadagnare ore di sonno  smiley-lol

ciao a tutti
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

la funzione atoi() è già disponibile in Arduino senza necessità di aggiungere librerie.
Se ti serve trasmettere un valore 0-255 ti basta un byte, non serve convertirlo o dividere unità-decine... quando ricevi il singolo byte, ecco quello è già il valore!
bye
Logged

lucadentella.it

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

sei un mago!
allora se io mi prendo ciò che viene letto dopo le virgole mi da già i valori che voglio!
e posso dare il fine stringa per dare lo stop
giusto per finire di approfittarmi di voi..allora le virgole sono inutili e incasinanti?

lo sapevo che mi stavo complicando la vita ma era tutta una cavolata risolverlo

stanotte ritento!
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

esatto, secondo me ti basta inviare un pacchetto in cui definisci:

byte di start
byte(s) di dati
byte di stop

ogni byte di dati ti rappresenta un valore 0-255

facci sapere!

Logged

lucadentella.it

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

cari tutti,
vi faccio vedere come con il vostro aiuto ho risolto la questione.
un grazie particolare a luca che mi ha illuminato sul fatto che da 0 a 255 mi basta un byte

et voilà

// esempio stringa   $GSUB,37,100,255,1#
// che coincide con  $GSUB,%,d, ,☺#

int c = 0;
int a = 0;
int var = 0;
int variabile[] ={0,0,0,0};

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

void loop(){
   if (Serial.available()>0){
     c= Serial.read();
     
     
     if (c == '$'){//con questo blocchetto mi leggo il caso 1 se la stringa parte $GSUB
       if (c == 'G'){
         if (c== 'S'){
           if (c== 'U'){
             if (c == 'B'){
               var =1;
               }
             }     
           }   
         }//
       }
       
     if (c == ','){//con questo blocchetto mi leggo il caso 2 se trovo una virgola
       var =2;
       }

     if (c == '#'){//con questo blocchetto mi leggo il caso 3 se trovo il #
       var =3;
       }
     switch (var) {
       
       case 1:
       
       delay (10);
       //di questa forse ne potrei fare a meno, ma fa tanta compagnia
       a = 0;
       break;
       
       case 2:
       
       delay (10);
       
       //incomincio a "infilare" le mie variabili famose nell'array
       variabile[a] = Serial.read();
       a++;
       break;
       
       case 3://se la stringa viene chiusa con # mi comincio a leggere le mie variabili
             
       //giusto per vedere se le mie variabili sono corrette
       Serial.println(variabile[0]);
       Serial.println(variabile[1]);
       Serial.println(variabile[2]);
       Serial.println(variabile[3]);
       
       //riporto le mie variabili al valore di partenza
       a = 0;
       c = 0;
       var = 0;
       break;
       
       //default:
       // if nothing else matches, do the default
       // default is optional
       }
     }
   }

magari non è fine, ma sono sempre in tempo a sgrezzare e sembra che funzioni
Logged

Signori si nasce, io spero di esserlo diventato

0
Offline Offline
Faraday Member
**
Karma: 49
Posts: 6023
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

scusa ma non puoi fare direttamente:
Code:
if (c == '$GSUB')

evitandoti 5 if ?

p.s. quando vuoi allegare un codice usa l'iconcina # in modo da renderlo piu' leggibile
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

posso?
non è che c mi legge un byte alla volta?
ah comunque ho parlato troppo presto, in quanto arduino:
da 0 a 32 non mi da nulla (un quadratino)
il 10 mi da ovviamente "invio"
da 127 a 160, solito quadratino bastardo
e tanti caratteri non coincidono con quelli classici

finche non posso provare con un altro arduino non so se è un problema di serial monitor
quasi quasi provo con Software.Serial e gli paro i dati in nel pin rx e controllo se arriva quello che voglio io
cioè mando es (9,BYTE) e guardo se riceve 9

secondo voi?
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

anche perché ho dei dubbi sui 5 if concatenati... praticamente stai dicendo ad Arduino

- prendi il carattere in ingresso
- se il carattere è uguale a $
- se poi è anche uguale a G
- ...

come farà ad essere uguale a tutti contemporaneamente?
$GSUB per te è un codice ASCII (es. il codice 26 che equivale a 'SUB') o trasmetti la sequenza di caratteri?
Logged

lucadentella.it

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

ok, vero

il risultato tornava solo perchè in case 1 io in pratica non do nessun ordine dato che riporto a = 0 in case 3.
io quando trasmetto simulo l'invo di variabili, ad esempio per avere 125 mando }.
pensavo di mandare il carattere ascii corrispondente al numero della variabile es invece che 97 mando (97,BYTE)...per provare la ricezione scrivo nel serial monitor "a"
es: $GSUB,a,b,c,d# mi da in l'array variabile [3]={97,98,99,100} che è quello che voglio io!
potrebbe andar bene per me, se non fosse che la tabella "Classica" di codice ascii  (http://www.oppo.it/tabelle/tabella_ascii.htm)non è la stessa interpretata da arduino (provare per credere)
Code:
int a = 0;

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

void loop(){

  Serial.print("valore ASCII ");
  Serial.print(a);
  Serial.print(":   ");
  Serial.println(a,BYTE);
  a++;
  delay (100);
  if (a == 255){
    a ==0;
    Serial.println("Riavvio lettura dati");
       
  }
}

magari ora tramite software serial provo ad inviare la stringa con il tx nel rx e vedere se mi legge quello che voglio io

ah buonanotte
Logged

Signori si nasce, io spero di esserlo diventato

BG (I)
Offline Offline
Full Member
***
Karma: 0
Posts: 202
Usus plura docet
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Topic molto interessante, mi sembra di tornare indietro di 25 anni , quando in Basic per lavoro ho dovuto affrontare questo problema per inviare e ricevere dati su seriale via modem a 300bps.
Con il Basic si avevano a disposizione delle istruzioni per elaborare le stringhe di dati più evolute, ma i concetti sono sempre gli stessi.
Ciao Luca, scusate l'OT.
Logged

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

Ciao

tornando un po' alle origini vediamo di affrontare la questione iniziale: trasmettere un pacchetto di dati, di lunghezza variabile e non nota a priori.

Il problema si risolve così:

- definisci un byte di TESTA e uno di CODA, con la sicurezza che tali valori non potranno essere usati anche come byte di dati (una soluzione classica è quella di riservare due valori, che so 0 e 255 come testa e coda e garantire che i dati siano sempre 1-254)

- in ricezione fai un loop così:

* aspetti la testa
* salvi i dati ricevuti in un vettore controllando che non siano il byte di coda
* in questo caso pacchetto completo e torni ad attendere la testa


PS: Ciao Mario  smiley
Logged

lucadentella.it

Guidonia
Offline Offline
Full Member
***
Karma: 0
Posts: 214
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

visto il ritorno alle origini, mi intrometto con un semi OT smiley-wink

è possibile creare una funzione che restituisca un'array?

es.
Code:
float Pitagora[2](int a,int b,int c) {
 Pitagora[1]=(-b+(sqrt((B^2)-4*a*c)))/2*a;
 Pitagora[0]=(-b-(sqrt((B^2)-4*a*c)))/2*a;
 return Pitagora[];
}


ho cercato googlando, ma i risultati per me non sono pienamente convincenti.
Logged

Offline Offline
God Member
*****
Karma: 0
Posts: 589
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ok, provo a dare un aiuto, anche se quasi sicuramente sarà offtopic smiley
Marbi vuole inviare dei dati via seriale, fin tanto che questi dati sono archiviabili in una variabile... perché non usi la libreria EasyTransfer?
Io ho messo su il trasferimento via seriale tra due arduini, di 10 variabili miste (float, int, unsigned long) in 10 minuti.
La libreria è molto leggera e poco invasiva in termini di ram, non fa altro che ricomporre i dati smiley
Vedi un po' se ti aiuta...
https://github.com/madsci1016/Arduino-EasyTransfer
Logged

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