I'm looking for some expert guidance on how to build a truly robust/reliable serial bluetooth channel for exchanging moderately large and varied data between two Arduino MEGA boards.
Over several (many!) years I've developed a large sketch running on a single MEGA that monitors a small electric vehicle, and displays and records the data as the vehicle moves around. The sketch compiles to around 60,000 bytes and is pretty reliable.
I'm working on a major revision to split the sketch between two MEGA boards connected by HC-05 serial bluetooth modules. I refer to these as the BASE and HEAD.
The BASE has all the sensors including GPS, voltage, current, temperature and air pressure.
The HEAD has an LCD display with keypad and microSD for data recording.
I've attached an example of the CSV data file that was recorded by the sketch prior to it being split. The data rate is moderate - one row is written to the CSV file every 200ms.
This same data will be recorded by the HEAD in the new dual MEGA with bluetooth design. I'm contemplating two alternatives for recording this data:
A) the BASE transmits each row of CSV data to the HEAD which then records each row to the SD card, and also breaks the data row up into constituent parts for display purposes, OR ...
B) the BASE transmits each piece of data (probably with a unique identifier for each type) to the HEAD which displays them, and also builds the data pieces into a row for recording in the CSV file.
My preference is Option A but either way I need the serial bluetooth channel between BASE and HEAD to be ultra robust i.e. no characters lost or dropped, ever!
I've have a prototype work-in-progress with the two MEGA boards and two HC-05 communicating "hearbeats" using typical serial code, like this:
const char CJ_ID[] = "BlueEcho.a";
/* Assumes HC-05 Bluetooth module connected to MEGA */
#include <Streaming.h>
#define bt Serial1 // MEGA: TX1/RX1 (pins 18,19)
#define bt_baud 38400
void setup() {
Serial.begin(115200);
Serial << '\n' << CJ_ID << " [bt:" << bt_baud << ']' << '\n';
Serial << "==> Echo BT strings to Serial Monitor ... " << '\n';
bt.begin(bt_baud); // if 38400 then compatible with AT command mode
}
void loop() {
processBTchars();
//ocessBTbytes();
delay(100); // small delay so we don't process faster than character/baud rate
}
void processBTchars(){
char readChar;
if (bt.available() > 0){
Serial << "RX> ";
while(bt.available() > 0){
readChar = bt.read();
//readChar = toupper(readChar); // convert lower case characters to upper case
if (readChar != '\r' && readChar != '\n'){ // ignore CR/LF (hex: A/D)
Serial << readChar;
}
}
Serial << '\n';
}
}
void processBTbytes(){
byte inByte; // = int inByte;
if (bt.available() > 0){
Serial << "RX> ";
while(bt.available() > 0){
inByte = bt.read();
if (inByte != '\r' && inByte != '\n'){ // ignore CR/LF (hex: A/D)
Serial << _HEX(inByte) << '|';
}
}
Serial << '\n';
}
}
So far this is working quite well. It doesn't seem to be dropping any characters, but it occasionally starts a new line before reaching the line terminator, as shown in the Serial Monitor screenshots attached. Playing with the short delay(100) can change the displayed line length, or at the extreme if I leave the delay out altogether it will print just one character per line. So it seems I'll have to load the characters one by one into a buffer and only process the buffer after the terminator is received.
I went back and had a careful read of the Arduino language reference for Serial. I see several possible commands that may offer a better way to do this, like Serial.readBytesUntil() ... maybe !? But I see lots of options there that I'm not familiar with, leaving me wondering which one I should choose.
So to my question: how best to build a really robust/reliable serial bluetooth channel.
I've posted this under Project Guidance because I'm not just asking a coding question, I'm also keen for any alternatives for doing this over bluetooth. e.g. perhaps there is a better way using interrupts?
TIA
SCOO8u.zip (5.48 KB)