[RISOLTO] Serial HW e SoftwareSerial compatibilità

Buongiorno e buona domenica a tutti,
sto provando a far comunicare un arduino (master) con altri 3 arduino (slave) mediante seriale. In pratica il master fa da smistatore dei dati che riceve sulla seriale hw (Pin 0 e 1) e le trasmette ai tre slave tramite SoftwareSerial (con altre 3 coppie di pin).
I 3 arduino slave ricevono sulla seriale hw. Ora credo che si perdano dei bytes durante la trasmissione.
Non sono compatibili tra loro USART e la seriale software?

Grazie e a presto.

BB

Per completezza inserisco il codice del master:

#include <SoftwareSerial..h>

SoftwareSerial mySerial(2,3);
int incomingByte[5];


void setup() {

mySerial.begin(9600);
Serial.begin(9600);
}

void loop() {

if (Serial.available() >= 5) {

for (i=0;i<5;i++) {

incomingByte[i] = Serial.read();

}

for (i=0;i<5;i++) {

mySerial.write((byte)incomingByte[i]);

}

}

}

e il codice dello slave:

int incomingByte[5];

void setup() {
Serial.begin(9600);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);
pinMode(11, OUTPUT);

}

void loop() {

if (Serial.available() >= 5) {

for (i=0;i<5;i++) {

incomingByte[i] = Serial.read();

}

digitalWrite(5, incomingByte[0]);
digitalWrite(6, incomingByte[1]);
digitalWrite(9, incomingByte[2]);
digitalWrite(10, incomingByte[3]);
digitalWrite(11, incomingByte[4]);


}
}

Il problema dovrebbe essere che non tutte le 3 Seriali Sw possano ascoltare nello stesso tempo.
Soluzioni:

  • Usa un arduino mega, quello ha 4 seriali (una collegata alla USB e altre 3 libere.
  • usa un protocollo richiesta dati. Il master chiede dati e lo slave chiamato risponde. cosí il devi ascoltare sempre solo una seriale SW.
  • se le distanze non sono troppo alte (1m) puoi usare l' I2C, con dei integrati di amplificazione puoi allungare la distanza I2C.
    Ciao Uwe

uwefed:
Il problema dovrebbe essere che non tutte le 3 Seriali Sw possano ascoltare nello stesso tempo.

Il problema è questo. Puoi istanziare molte seriali SW ma solo 1 può essere messa in ascolto:

Il problema non credo sia questo. Nel codice del master l'unica seriale in ascolto è quella hardware Serial, mentre nell'esempio pubblicato sopra la SotftwareSerial trasmette solamente.
La mia domanda è una SoftwareSerial può trasmettere senza problemi ad una Serial hardware?

Bartleboom:
La mia domanda è una SoftwareSerial può trasmettere senza problemi ad una Serial hardware?

Sì. Ovviamente impostando la stessa velocità di comunicazione ed incrociando le linee (RX/TX del master verso TX/RX dello slave).
Tu parli di "perdita di byte", a cosa ti riferisci esattamente?

leo72:
Sì. Ovviamente impostando la stessa velocità di comunicazione ed incrociando le linee (RX/TX del master verso TX/RX dello slave). ...

e coleghi le masse
Ciao Uwe

Buongiorno,
si la massa è in comune e ci arrivo ad incrociare il tx con l'rx... :stuck_out_tongue: (il baudrate è 9600)
Quello che intendo dire quando parlo di "perdita di byte" è che quando il master invia tramite mySerial.write((byte)incomingByte) l'int di incomingByte al Serial dello slave, questo qui (come si vede dal codice dello slave) non mi accende i LED che sono connessi ai pin di sopra (il valore di incomingByte può essere 0 se è spento e 255 se acceso).
Quando invece il master invia gli stessi dati tramite il Serial.write((byte)incomingByte*) tutto funziona alla perfezione.*
Ora dato che lo slave li riceve sul Serial hardware... credevo che ci fossero problemi di incompatibilità tra i due... Invece mi dite di no, quindi credo che sia qualcosa che mi perdo nella gestione dei byte... Però converrete con me che è alquanto strano che con Serial.write funziona mentre con mySerial.write no....

Non capisco una cosa.
Come hai collegato i 4 Arduino?
Tu dici:

Bartleboom:
sto provando a far comunicare un arduino (master) con altri 3 arduino (slave) mediante seriale. In pratica il master fa da smistatore dei dati che riceve sulla seriale hw (Pin 0 e 1) e le trasmette ai tre slave tramite SoftwareSerial (con altre 3 coppie di pin).
I 3 arduino slave ricevono sulla seriale hw.

Cioè? Hai collegato tutti gli slave alla stessa coppia RX/TX del master?

No... al momento c'è solo uno slave.... se non riesco a farne funzionare uno come posso metterne altri 2.... :slight_smile:

Bartleboom:
No... al momento c'è solo uno slave.... se non riesco a farne funzionare uno come posso metterne altri 2.... :slight_smile:

Era per capire, cercavo di escludere le possibili cause di problemi.

Altra cosa, nel codice master questa istruzione:

mySerial.write((byte)incomingByte[i]);

mi sembra ridondante. Fail cast esplicito a byte usando un array di int.
Converti l'array incomingByte in tipo byte e poi togli il casting.

int incomingByte[5]; --> byte incomingByte[5]
...
mySerial.write((byte)incomingByte[i]); --> mySerial.write(incomingByte[i]);

Su seriale viaggiano byte, parcheggiare i dati in un int non serve che a complicare il codice.

Ciao Leo,
ho provato a sostituire l'array di int con l'array di byte ma è esattamente la stessa cosa... Il primo LED non accende e gli altri invece si... poi quando tutto dovrebbe essere spento il primo accende...
Ho notato però che se sullo slave sostituisco la serial hw con la SoftwareSerial tutto funziona alla perfezione...
Ho provato anche a caricare la SoftwareSerial sui pin della serial HW ma non funziona...

E' quindi un problema di pin? Cmq per ora utilizzerò la SoftwareSerial sugli Slave... anche se resta da capire perché non funzionava sulla serial hw...

Grazie a tutti.

BB

La questione dei byte al posto degli int era più che altro per sistemare il codice.

Senti, ultima prova. Sullo slave usi la seriale HW, e questa non va. Potresti fare una prova?
Le prime righe del setup potresti trasformarle da così:

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

a così:

void setup() {
  delay(2000); //<-- aggiungi questa
  pinMode(0, OUTPUT); //<-- aggiungi questa
  Serial.begin(9600);

Aggiungi delay(2000) anche nel setup del master, subito prima dell'inizializzazione delle 2 seriali:

void setup() {
  delay(2000);  //<-- aggiungi questa
  mySerial.begin(9600);
  Serial.begin(9600);
}

Poi dimmi che succede

caro leo72.......... funziona!! E' bastato inserire il pinMode(0, OUTPUT);

Anche se non ho ben capito xkè... cmq grazie mille!

BB

Bartleboom:
caro leo72.......... funziona!! E' bastato inserire il pinMode(0, OUTPUT);

Anche se non ho ben capito xkè... cmq grazie mille!

BB

Prima di spiegartelo, volevo la conferma da parte tua.
Tu dicevi che lo slave in ricezione sulla seriale HW perdeva dati mentre con la seriale SW no. Mi è tornata allora a mente una discussione di un paio di mesi fa in cui un utente aveva manifestato dei problemi collegando un LED sul pin D0. Lo aveva trovato debolmente acceso.

Tale minima accensione dipende dal fatto che sull'Arduino le linee RX e TX della seriale HW (i pin D0 e D1) sono in comune con l'Atmega8/16U2 che è usato per programmare il chip. Sulle linee che dall'Atmega8/16U2 vanno all'Atmega328 ci sono in serie 2 R da 1K. E l'Atmega8/16U2 tiene pullata alta la linea RX (come ci spiegò astrobeed tempo fa, questa è la condizione standard di idle della linea RX della seriale).

Nei miei test mi accorsi che tale segnale di pull-up restava presente fino a quando non si impostava il pin come output, dopodiché il pilotaggio del pin fatto dal GPIO interno del micro annullava in pratica la debole corrente di quella resistenza. Il delay l'ho aggiunto per dar modo alle schede di stabilizzarsi dopo l'avvio.