Go Down

Topic: "RISOLTO" trasferire un unsigned int via seriale (Read 1 time) previous topic - next topic

cepics

Oct 12, 2016, 05:44 pm Last Edit: Oct 14, 2016, 01:07 pm by cepics
salve a tutti.
 
Come faccio a trasferire il valore di un unsigned int tra due arduini via seriale?

ho un hc-sr04 collegato ad un arduino uno che mi tira fuori un tempo in millisecondi che viene messo in una unsigned int, e vorrei trasferire (per ora a cavo, poi con xbee) questo valore ad un altro arduino micro dove collegherò un display.

googolando mi sembra di aver capito di dovere mettere il dato in una striga, codificarla da una parte e decodificarla dall'altra ma non capisco come fare dato che il contenuto della variabile è un numero che può essere da una fino a sette cifre.

ho provato a fare cosi.. senza successo!

TX

Code: [Select]

#include <SoftwareSerial.h>
#include <NewPing.h>
 
#define trigger_Port 9
#define echo_Port 8

SoftwareSerial Seriale(4,7); //RX,TX

unsigned int durata;
NewPing sonar(trigger_Port, echo_Port);

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

void loop() {
 
   delay(100);
 
 durata = sonar.ping_median(5);
  //Seriale.print(durata);
  //Seriale.print(",");
 Seriale.write(durata);      // invia byte basso
 Seriale.write(durata>>8);   // invia byte alto
 
  Serial.println(durata);
  delay (1000);
}


RX

Code: [Select]



#include <SoftwareSerial.h>
SoftwareSerial Seriale(8,9); //RX,TX

int input;
void setup()
{
  Serial.begin(9600);
  Seriale.begin(9600);
}

void loop()
{
  if(Seriale.available())
  {
    //input=Seriale.read();
input = Seriale.read();          // riceve byte basso
input+= (int)Seriale.read()<<8;  // riceve byte alto
      Serial.println(input);

  }
}




ho usato Software Serial per debug e perchè una volta che riesco a vedere il valore della variabile nel monitor seriale del micro, vorrei invece collegare un serial 7seg display.

cosa sbaglio?

è giusto cominciare da qui se poi voglio arrivare alla trasmissione con gli xbee?

grazie

Mauro



gpb01

#1
Oct 12, 2016, 06:30 pm Last Edit: Oct 12, 2016, 06:34 pm by gpb01
Io modificherei le due write() così...

Code: [Select]
Seriale.write(lowByte(durata));  // trasmette il byte meno significativo
Seriale.write(highByte(durata)); // trasmette il byte più significativo

... le due funzioni lowByte ed highByte le trovi nel reference nella parte Bits and Bytes.

Ah ... un altra cosa, quando vai a leggere in ricezione, chi ti assicura che siano arrivati DUE bytes ? Magari fare:

if (Seriale.available() > 1) { ....... }

... ti assicura che almeno DUE byte ci sono, altrimente rischi, data la velocità della MCU, che tu vai a leggere un qualche cosa che NON è ancora arrivato. ;)

Guglielmo

Search is Your friend ... or I am Your enemy !

ExperimentUno

Della libreria Serial, ci sono diverse funzioni, non solo Serial.read(). Si può leggere anche valori stringa, float e byte.

Si potrebbe quindi usare la funzione readBytes() o readBytesUntil(). Nel secondo caso, si dovrebbe mettere un ulteriore byte per la terminazione della trasmissione oppure quanti bytes aspettare.

vbextreme

giusto così per farlo
Code: [Select]

void sex_write(void* s, size_t sz)
{
    uint8_t* b = (uint8_t*)s;
    while( sz-->0 ) Serial.write(*b++);
}

int sex_read(void* d, size_t sz)
{
    if (Serial.available() < sz ) return 0;
    uint8_t* b = (uint8_t*)d;
    while( sz-->0 ) *d++=Serial.read();
    return 1;
}

se funziona la userei per inviare così
Code: [Select]

...
int dato = 1234;
sex_write(&dato, sizeof dato);

e per ricevere
Code: [Select]

int recv;
if ( sex_read(&recv, sizeof recv) )
{
    ....
}

se si vuole ricevere in maniera bloccante
Code: [Select]

int recv;
while (!sex_read(&recv,sizeof recv));
...

ExperimentUno

Questa funzione è meglio. Dato che si può implementare anche con una SoftSerial. Solo che è hardcodato il tipo di seriale.

vbextreme

#5
Oct 12, 2016, 08:53 pm Last Edit: Oct 12, 2016, 08:56 pm by vbextreme
Code: [Select]


void sex_fwrite(Stream* f, void* s, size_t sz)
{
    uint8_t* b = (uint8_t*)s;
    while( sz-->0 ) f->write(*b++);
}

int sex_fread(Stream* f, void* d, size_t sz)
{
    if (f->available() < sz ) return 0;
    uint8_t* b = (uint8_t*)d;
    while( sz-->0 ) *d++=f->read();
    return 1;
}

Code: [Select]


...
int dato = 1234;
sex_write(&Serial, &dato, sizeof dato);

Code: [Select]


int recv;
if ( sex_read(&Serial, &recv, sizeof recv) )
{
    ....
}


dovrebbe andare

[edit]corretto[/edit]
[edit]tornato a correggere[/edit]

vbextreme

è comunque possibile non reinventare la ruota.
Code: [Select]

int dato=1234;
Serial.write((uint8_t*)&dato, sizeof dato);

Code: [Select]

int recv;
if ( Serial.available() >= sizeof recv)
{
    Serial.readBytes((uint8_t*)&recv, sizeof recv);
}

   

ExperimentUno

Bravo, con la Serial c'è. Ho notato che, invece, la SoftwareSerial  non ha le stesse funzioni della Serial, mio malgrado.

vbextreme

#8
Oct 12, 2016, 09:13 pm Last Edit: Oct 12, 2016, 09:13 pm by vbextreme
tutte le funzioni che ho usato fanno parte della classe Stream, di cui fanno parte sia Serial che la softwareSerial.

gpb01

#9
Oct 12, 2016, 09:38 pm Last Edit: Oct 13, 2016, 12:06 pm by gpb01
A volte mi viene da chiedervi ... MA CHE RAZZA DI RISPOSTE DATE ? ? ? :o :o :o

Ma l'avete letta la presentazione di chi ha posto la domanda ? ? ? :o

... mi piace smanettare per hobbie con elettronica e programmazione. le mie conoscenze sono praticamente pari allo zero ma realizzo semplici progetti seguendo tutorial, mescolando sketch e bruciando componenti.
e vi paiono i vostri post adatti alla preparazione di questa persona ? ? ?

Guglielmo
Search is Your friend ... or I am Your enemy !

cepics

grazie a tutti e soprattutto a Guglielmo!!!!   :)  :)  :)

sono riuscito a farli parlare la stessa lingua via cavo!!!

ora mi scontro con la trasmissione xbee, tra una settimana se non avrò fatto progressi mi troverò costretto ad importunarvi di nuovo.

una domandina così al volo gia che ci sono ce l'avrei, dato che sulla rete trovo pareri discordanti:

devo ridurre con delle resistenze il tx di arduino prima di entrare in din di xbee (no shield) e viceversa?

grazie ancora.

gpb01

Se ben ricordo gli Xbee lavorano a 3.3V ...
... devi controllare sulla documentazione del prodotto che hai acquistato, ma se è così, SI, devi assolutamente mettere un partitore resistivo sul collegamento  TX di Arduino ---> RX del Xbee in modo che al Xbee NON arrivino più di 3.3V.

Oppure puoi utilizzare dei "convertitori di livello" già belli che fatti che trovi sotto forma di piccole schedine.

Guglielmo


Search is Your friend ... or I am Your enemy !

cepics

RISOLTO!!! funziona anche con xbee

TX

Code: [Select]

#include <SoftwareSerial.h>
#include <NewPing.h>
 
#define trigger_Port 9
#define echo_Port 8

SoftwareSerial Seriale(4,7); //RX,TX

unsigned int durata;
NewPing sonar(trigger_Port, echo_Port);

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

void loop() {
 
   delay(100);
 
 durata = sonar.ping_median(5);
Seriale.write(lowByte(durata));  // trasmette il byte meno significativo
Seriale.write(highByte(durata)); // trasmette il byte più significativo
 
  Serial.println(durata);

}


RX

Code: [Select]

#include <SoftwareSerial.h>
SoftwareSerial Seriale(8,9); //RX,TX

int input;
void setup()
{
  Serial.begin(9600);
  Seriale.begin(9600);
}

void loop()
{
if (Seriale.available() > 1)
  {
input = Seriale.read();          // riceve byte basso
input+= (int)Seriale.read()<<8;  // riceve byte alto
      //Serial.println(input);

  }
  delay(100);
}


tutto ciò è bellissimo!!!

paulus1969

Bene, adesso, dopo averlo fatto così,
puoi anche dare un'occhiata qui: parseint

vbextreme

Bene, adesso, dopo averlo fatto così,
puoi anche dare un'occhiata qui: parseint
La parseInt si aspetta una stringa numerica, in questo caso viene inviato il numero "reale" senza la coversione a stringa.

Go Up