Hello,
I am trying to find a better way to read about 68 bytes from 8192 baud serial. Currently I am doing this:
for (int i=0; i < dataStreamSize; i++) {
while (!Serial.available()) {}
dataStream[i] = Serial.read();
}
I would like to move to an interrupt based serial receive, or better alternative as Arduino already puts the Hardware serial into a ring buffer. As is, it takes about 83 milliseconds to receive 68 bytes. My loop is taking around 119 milliseconds. I would like to be doing calculations and other tasks, until all the data has come in.
Thank you in advance.
Complete (current) test code:
#include <NewSoftSerial.h>
NewSoftSerial mySerial(2, 3);
const int rxControl=5;
bool inSync=false;
bool inMode1=false;
int mdelay=3350;
const int dataStreamSize=69;
unsigned char dataStream[dataStreamSize];
#define Bit_Set(port,bit_num) (port = port | (0x01 << bit_num))
#define Bit_Clear(port,bit_num) (port = port & ~(0x01 << bit_num))
void setup() {
pinMode(rxControl,OUTPUT);
digitalWrite(rxControl,LOW);
mySerial.begin(57600);
Serial.begin(8192);
}
void loop() {
sendMode1();
displayDataStream();
}
int sendMode1(void) {
//Check if we are already synchronized. If not, wait for ecu to send 0xF0 probe
//The delay takes a little bit of working out.
//(@16MHz 3389 works for AVR C, 3353 works for Arduino Serial)
//
if (inSync == false) {
Bit_Clear(PORTD,rxControl);
while (Serial.read() != 0xF0) {}
Bit_Set(PORTD,rxControl);
delayMicroseconds(mdelay);
}
//Send commands to ECU for mode 1
Bit_Set(PORTD,rxControl);
Serial.print(0xF0,BYTE);
Serial.print(0x57,BYTE);
Serial.print(0x01,BYTE);
Serial.print(0x00,BYTE);
Serial.print(0xB8,BYTE);
Bit_Clear(PORTD,rxControl);
//Start Reading Data. To save time, only read first 5 bytes.
//If we are not in sync, we do not read the probe messages.
for (int i=0; i < 5; i++) {
while(!Serial.available()) {}
dataStream[i] = Serial.read();
}
//The ECU will send a 0xF0 and 0x95 and 0x01 to indicate it is in mode 1
//Different hardware moves this by a byte or two.
if (!((dataStream[1] == 0xF0 && dataStream[2] == 0x95) || (dataStream[2] == 0xF0 && dataStream[3] == 0x95))) {
Serial.flush();
inSync = false;
mdelay = mdelay + 1;
return 3;
}
//Read the rest of the data stream if the first 5 bytes are ok.
for (int i=5; i < dataStreamSize; i++) {
while (!Serial.available()) {}
dataStream[i] = Serial.read();
}
//check for 0xF0 and 0x95, this can probably be removed due to earlier check
if (dataStream[2] == 0xF0 && dataStream[3] == 0x95) {
inSync = true;
return 1;
} else {
if (inSync == false) {
mdelay = mdelay +1;
}
inSync = false;
return 0;
}
}
void displayDataStream(void) {
for (int j=2; j < dataStreamSize; j++) {
mySerial.print(dataStream[j],HEX);
}
mySerial.println();
mySerial.print(mdelay);
mySerial.print("\t");
if (inSync) {
mySerial.print("inSync\t");
byte a = calcCheckSum(2);
if (a != 0) {
mySerial.print(a,HEX);
mySerial.print("\t");
}
}
mySerial.println(millis());
}
byte calcCheckSum(int dss) {
//Pass the dataStreamStart(dss) as argument.
byte checkSum=0;
for (int cc=dss; cc < dataStreamSize; cc++) {
checkSum += dataStream[cc];
}
return checkSum;
}