Pages: [1]   Go Down
Author Topic: Comunicazione Seriale : Ricevere dati correttamente.  (Read 1593 times)
0 Members and 1 Guest are viewing this topic.
Italy
Offline Offline
Sr. Member
****
Karma: 0
Posts: 329
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ciao a tutti.
Sto usando L'ide0022 di arduino e la libreria NewSoftSerial per la comunicazione seriale tra due arduino.
Stavo provando a scambioare dati tra i due, e ci riesco, ma ho un problema a mettere  insieme i dati ricevuti.

Il codice che ho scritto è questo:
PER TX
Mi stampa continuamente interi da inviare all'altro arduino che ascolta in ricezione
Code:
#include <NewSoftSerial.h>

NewSoftSerial mySerial(2, 3);

void setup() 
{
  Serial.begin(115200);
  Serial.println("Inizio a trasmettere");
  mySerial.begin(115200);
}

void loop() {
          for (int i=0; i<100; i++) {
          delay (1000);       
                Serial.println(i);
                mySerial.print(i);
        }
        {

 if (Serial.available()) {
     mySerial.print((char)Serial.read());
  }
}
        }

PER RX
Code:
#include <NewSoftSerial.h>

NewSoftSerial mySerial(2, 3);
byte rx;    // variabile per contenere il carattere ricevuto
void setup() 
{
  Serial.begin(115200);
  Serial.println("Ricevo");
  mySerial.begin(115200);
  mySerial.flush();

}

void loop()       
{

  if (mySerial.available() >0) // Controllo se il buffer di ricezione contiene qualcosa
{
rx = mySerial.read(); // leggo il carattere ricevuto e lo memorizzo in rx
                Serial.println(rx);
                  }
                    }

Quando conta da 0  a 9 non ci sono problemi, quando deve mettere insieme 2 cifre (10,11,12 ... ecc) le separa trattandole  un valore alla volta.
così:
Code:
Ricevo:
0
1
2
3
4
5
6
7
8
9
1
0
1
1
1
2
1
3

Come posso fare a fare in modo che stampi qualsiasi valore come lo riceve, e non il byte separato?
Insomma come posso fare a sincronizzarlo in modo che capisca la parola che deve stampare?

Logged

0
Offline Offline
Faraday Member
**
Karma: 23
Posts: 2797
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Il motivo è legato al fatto che la seriale invia un byte per volta e riceve un byte per volta, il fatto che più byte composti a formare una stringa di senso compiuto per l'uomo è solo un caso per l'unità di calcolo, caso di cui non tiene conto. Da qui nascono i protocolli software, che permettono di ricomporre l'informazione comprensibile all'essere umano.

Come fare allora?
Io non ho mai provato, ma dovrebbe essere possibile incapsulare tutti i dati da inviare in una struttura o classe e anziche inviare il contenuto della classe si invia byte per byte tutta la memoria occupata dalla classe/struttura. Dall'altro lato la struttura/Classe viene ricomposta in una porzione di memoria capiente quanto basta ottenuta previo allocazione dinamica della memoria.

La cosa è possibile e viene chiamata serializzazione ma io ho avuto esperienza solo con la serializzazione delle strutture dati (struct), con le classi la cosa potrebbe essere molto più complessa fino a richiedere un metodo di classe specifico per la serializzazione.

Ciao.
Logged

AvrDudeQui front end per avrdude https://gitorious.org/avrdudequi/pages/Home

Offline Offline
Jr. Member
**
Karma: 0
Posts: 84
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Da quel che ho capito dalle numerose risposte da parte degli utenti del forum(gentilissimi) al riguardo, devi mettere un carattere che la tua applicazione non usa tra i valori e utilizzarlo per capire quando un valore inizia o finisce. Per esempio, io scelgo la virgola come separatore in modo che se io invio i seguenti byte:
Code:
,
1
2
3
,
arduino li metterà in un array chiamato ad esempio serialin ottenendo [,][1][2][3][,] e poi usando una funzione come explode divida l'array in modo da prendere solo 123 che è il numero inviato dalla seriale.
Tuttavia ti consiglio di aspettare qualcuno più esperto di me in quanto ogni volta che ho implementato questa funzione nei miei programmi essi sono diventati lunghi, incasinati e generalmente poco funzionanti.
Alessandro

EDIT: Dimenticavo di consigliarti di utilizzare il protocollo I2C che a mio parere a livello software è molto più semplice. (Se vuoi ho una ottima videoguida da condividere smiley-wink)
« Last Edit: July 21, 2012, 05:07:21 pm by aleale97 » Logged

0
Offline Offline
Faraday Member
**
Karma: 23
Posts: 2797
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
EDIT: Dimenticavo di consigliarti di utilizzare il protocollo I2C che a mio parere a livello software è molto più semplice. (Se vuoi ho una ottima videoguida da condividere smiley-wink)

Tra seriale e I2c è più affidabile la seriale e poi è più veloce, quindi io del parere totalmente contrario, si usa ic2 solo nel casi in cui si deve comunicare con più dispositivi e con I2c si posso mettere teoricamente fino a 127 dispositivi I2c su un bus bifilare (two wire) e farli dialogare tra di loro.

Per il reso è ok, quel carattere può essere chiamato separatore. Mentre nel caso il carattere venga messo prima ad una sequenza di byte e ne qualifica il senso/tipo/ecc il carattere viene detto "sentinella".
Es. @scacco#matto

@ nome utente
# password

Ciao.
Logged

AvrDudeQui front end per avrdude https://gitorious.org/avrdudequi/pages/Home

Italy
Offline Offline
Sr. Member
****
Karma: 0
Posts: 329
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Perfetto.. mi serviranno sia la sentinella che il separatore per distinguere tipo e dati....
Domani cercheró di implementare qualcosa. Mi preoccupa solamente la mole di lavoro a cui saranno sottoposti i microprocessori... vedremo!
Logged

Cagliari, Italy
Offline Offline
Tesla Member
***
Karma: 103
Posts: 6592
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Per trasferire dati tra arduini puoi usare la libreria EasyTransfer --> https://github.com/madsci1016/Arduino-EasyTransfer che, come anticipato da MauroTec, incapsula tutti i dati in una classe e li trasferisce in blocco. (più o meno  smiley-roll-blue)
Logged

Code fast. Code easy. Codebender --> http://codebender.cc/?referrer=PaoloP

Italy
Offline Offline
Sr. Member
****
Karma: 0
Posts: 329
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ho risolto con un mio protocollino che sembra funzionare.... A saperlo prima.... Ora sono con il cell. Quando ho il PC a disposizione mostreró quello che ho fatto.
--------------------
Ecco come promesso...
Ovviamente questo è solo un esempio e una parte di un codice molto più lungo e con altre funzioni.. ma la base è questa.
TX
Code:
#include <SoftwareSerial.h>
#include "leOS.h"

SoftwareSerial mySerial(2, 3);
leOS temperature;

void setup()  
  {
  Serial.begin(1200);
  Serial.println("Inizializzo seriale");
  mySerial.begin(1200);
  temperature.begin(); /
  temperature.addTask(temp, 3000);
 
}

void loop()
{

        }


 void temp() {
        val_t=val_t++;

         mySerial.print("t");  
         mySerial.print(val_t);
         mySerial.println(">");
}




RX
Code:
#include <SoftwareSerial.h>

SoftwareSerial mySerial(2, 3);
char temp[10];
int cont_t;
boolean inizio_t = false;
boolean fine_t = false;


void setup()  
{
  Serial.begin(1200);
  Serial.println("Ricevo");
  mySerial.begin(1200);
  mySerial.flush();

}

void loop()
{
  
   while(mySerial.available() > 0)
   {
     //char rx = mySerial.read();
     //Serial.println(rx);
     ottieni_dati();
    
     }
}

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

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

          if(rx == 't')
{
    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("Temperatura: ");
        Serial.println(tempInt);
 // Azzero tutto per la possima lettura
inizio_t = false;
fine_t = false;

cont_t = 0;
temp[cont_t] = '\0';
   }
  
}
« Last Edit: July 24, 2012, 06:15:27 am by dr4gone » Logged

Offline Offline
God Member
*****
Karma: 8
Posts: 691
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

ma non c'è qualche "barbatrucco"  tipo mettere i pin ad alta impedenza quando hanno finito di trasmettere,  o mettere 2 pin  trasmittenti  differenti sui trasmettitori   e mettere 2 pin riceventi sul ricevitore (anche se funziona un pin  per volta  è ok)
Logged


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

Pages: [1]   Go Up
Jump to: