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.
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
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:
while (Serial.available() < 32);
dovrebbe aspettare che siano stati ricevuti 32 byte, ma perchè non trattarli mano a mano che vengono ricevuti?
questo invece;
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
while (packetHeader[0] != 0xFF || packetHeader[1] != 0x55) ;
Hai ragione, meglio metterci un Serial.available();
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:
while (Serial.available() < 32);
dovrebbe aspettare che siano stati ricevuti 32 byte, ma perchè non trattarli mano a mano che vengono ricevuti?
questo invece;
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