Go Down

Topic: Arduino Pro-Mini e Software Serial (Read 326 times) previous topic - next topic

liso

Jun 07, 2018, 10:10 pm Last Edit: Jun 08, 2018, 10:30 am by liso
Dopo anni rieccomi qua a scrivere sul forum per un problema che mi blocca da 4 giorni.

Devo comunicare con un telefono (tramite Bluetooth) ed un altro dispositivo serialmente utilizzando un Arduino Pro-Mini a 3.3v, quindi 8Mhz

La comunicazione con il dispositivo deve essere fatta a 57600bps, mentre con il telefono sono libero di scegliere il baudrate con il quale parlare tramite una antenna RN42
.
Quello che ho fatto è stato utilizzare la seriale hardware per parlare con il dispositivo, ed una software serial per il bluetooth, con il risultato che il seguente codice non funziona correttamente.

Code: [Select]

SoftwareSerial BTSerial(13, 12);

void setup() {

  BTSerial.begin(9600);
  Serial.begin(57600); //Device serial

}

void loop(){
  byte packetHeader[] = {0x00, 0x00};
  int checksum = 0;
  do {
    byte b;
    b = Serial.read();
    packetHeader[0] = packetHeader[1];
    packetHeader[1] = b;
  }

  while (packetHeader[0] != 0xFF || packetHeader[1] != 0x55)  ;


  while (Serial.available() < 32);

  for (int i = 0; i < sizeof(received_data); i++) {
    received_data[i] = Serial.read();
  }

/* controllo il checksum */

 if(checksum_calcolato == checksum_ricevuto){
   for (int i = 0; i < sizeof(received_data); i++) {
     BTSerial.write(received_data[i]);
 }
}


Questo è un estratto del codice, nel loop non viene fatto niente più di quanto copiato qua...

In pratica devo ritrasmettere un pacchetto dalla dimensione di 34 byte. I primi 2 byte sono di intestazione, l'ultimo di checksum.

In questo modo non funziona, perdo alcuni byte.
Pare funzionare correttamente, se cambio il baudrate di trasmissione sulla softserial portandolo a 38400.
Pensavo che un baudrate più alto fosse peggiore...qui sembra migliorare, ma non riesco davvero a capire come mai, e non capisco se è un caso e cosa sto sbagliando

grazie mille come sempre

SukkoPera

#1
Jun 07, 2018, 11:40 pm Last Edit: Jun 07, 2018, 11:42 pm by SukkoPera
Una SoftwareSerial va al massimo a 9600 bps in maniera affidabile, su una Uno o simili.
Make your Sega MegaDrive/Genesis region-free with Arduino! https://goo.gl/X7zBcq

Guida rapida a ESP8266: https://goo.gl/kzh62E

liso

La cosa strana è con 9600, primo tentativo, andava peggio!
Forse è un caso che 38400 vada meglio.
Adesso provo 1200

gpb01

#3
Jun 08, 2018, 09:18 am Last Edit: Jun 08, 2018, 09:19 am by gpb01
Una SoftwareSerial va al massimo a 9600 bps in maniera affidabile, su una Uno o simili.
Occhio che sta usando un Pro Mini a 8MHz ... quindi la percentuale di errore in funzione del baud rate cambia rispetto ad Arduino a 16MHz ... ::)

>liso: Prova a vedere QUESTA libreria in sostituzione della classica SoftwareSerial ...

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

Standardoil

Sì, ma cosa fa?
La softserial non la usa mai
Legge e scrive sempre e solo su hw
Prima legge di Nelson (che sono io):
A parità di risultato
maggiore è il pensiero,
minore il lavoro.
Quindi prima di fare pensa!

liso

Sì, ma cosa fa?
La softserial non la usa mai
Legge e scrive sempre e solo su hw

Hai ragione, ho copiato male il codice. Adesso è corretto

Standardoil

Ma l'altro dispositivo trasmette di continuo?
Perché data la differente velocità delle due seriali DEVE esserci del tempo di attesa
Prima legge di Nelson (che sono io):
A parità di risultato
maggiore è il pensiero,
minore il lavoro.
Quindi prima di fare pensa!

liso

Ma l'altro dispositivo trasmette di continuo?
Perché data la differente velocità delle due seriali DEVE esserci del tempo di attesa
No, vengono trasmessi 34 byte una volta al secondo

Standardoil

Non so, non mi convince
questo pezzo:
Code: [Select]

  do {
    byte b;
    b = Serial.read();
    packetHeader[0] = packetHeader[1];
    packetHeader[1] = b;
  }

  while (packetHeader[0] != 0xFF || packetHeader[1] != 0x55)  ;

dovrebbe cominciare la lettura solo se riceve esattamente i byte 0xFF e 0x55
e va bene, ma perchè fare la serial read() anche se c'è c'è nulla in arrivo?
e questo pezzo:
Code: [Select]

while (Serial.available() < 32);

dovrebbe aspettare che siano stati ricevuti 32 byte, ma perchè non trattarli mano a mano che vengono ricevuti?
questo invece;
Code: [Select]

  for (int i = 0; i < sizeof(received_data); i++) {
    received_data[i] = Serial.read();
  }

carica un'array con 32 (sizeof spero restituisca 32) byte letti da seriale, ma non sarei sicuro che se ci fosse un errore di trasmissione non ci sia magari un nuovo start nei dati che ti aspetti essere solo dati
torno a dire che un trattamento byte a byte forse è meglio

Prima legge di Nelson (che sono io):
A parità di risultato
maggiore è il pensiero,
minore il lavoro.
Quindi prima di fare pensa!

liso

Non so, non mi convince
questo pezzo:
Code: [Select]

  do {
    byte b;
    b = Serial.read();
    packetHeader[0] = packetHeader[1];
    packetHeader[1] = b;
  }

  while (packetHeader[0] != 0xFF || packetHeader[1] != 0x55)  ;

Hai ragione, meglio metterci un Serial.available();
Quote
dovrebbe cominciare la lettura solo se riceve esattamente i byte 0xFF e 0x55
e va bene, ma perchè fare la serial read() anche se c'è c'è nulla in arrivo?
e questo pezzo:
Code: [Select]

while (Serial.available() < 32);

dovrebbe aspettare che siano stati ricevuti 32 byte, ma perchè non trattarli mano a mano che vengono ricevuti?
questo invece;
Code: [Select]

  for (int i = 0; i < sizeof(received_data); i++) {
    received_data[i] = Serial.read();
  }

carica un'array con 32 (sizeof spero restituisca 32) byte letti da seriale, ma non sarei sicuro che se ci fosse un errore di trasmissione non ci sia magari un nuovo start nei dati che ti aspetti essere solo dati
torno a dire che un trattamento byte a byte forse è meglio

Controllo il checksum del pacchetto, contenuto nell'ultimo byte

Il vero problema era la velocità dell'arduino Pro-mini  e l'incapacità di gestire una seriale a 57500, una softserial ed alcune print. Senza le print, con il Bluetooth sulla softserial a 9600 e nessuna print, funziona

Go Up