Hi.
I have two Mega2560 boards. One of them has Senseair S8 sensor for measuring CO2 level. Also one of them has Ethernet shield. Everything had been working great for several months till I wanted to connect the second board to the first one via Serial port.
So now I have this configuration: one board has connected Senseair via hardserial port. Another board requests data from the first one. I reduced my scatches to minimal reproducing form.
See below please:
Scetch of Mega with Senseair:
byte senseAirReadCO2Bytes[] = {0xFE, 0X44, 0X00, 0X08, 0X02, 0X9F, 0X25};
byte senseAirResponseBytes[] = {0, 0, 0, 0, 0, 0, 0};
const int senseAir_WAIT_REQUEST_STATE = 0;
const int senseAir_SEND_REQUEST_STATE = 1;
const int senseAir_RECEIVE_RESPONSE_STATE = 2;
int senseAirCurrentState = senseAir_SEND_REQUEST_STATE;
int senseAirReceiveTimeoutCount = 0;
String serial1SendingDataInputCommanString = "";
bool serial1SendingDataInputCommanStringComplete = false;
void setup() {
Serial.begin(9600);
while(!Serial); // time to get serial running
Serial.println(F("Initializing Serial1 (18, 19 pins)..."));
Serial1.begin(9600);
while(!Serial1);
Serial3.begin(9600);
while(!Serial3);
}
void loop() {
sendRequest(senseAirReadCO2Bytes);
unsigned long valCO2 = getValue(senseAirResponseBytes);
//valCO2 = 746;
Serial.print("Co2 ppm = ");
Serial.println(valCO2);
Serial1SendingDataWorker(valCO2);
delay(500);
}
void sendRequest(byte packet[]) {
if (!Serial3.available()) {
for (int i = 0; i < 7; i++)
{
Serial3.write(senseAirReadCO2Bytes[i]); // Push each char 1 by 1 on each loop pass
}
delay(50);
}
int timeout = 0;
while (Serial3.available() < 7 ) {
timeout++;
if (timeout > 10) {
while (Serial3.available())
Serial3.read();
break;
}
delay(50);
}
for (int i = 0; i < 7; i++) {
senseAirResponseBytes[i] = Serial3.read();
}
}
unsigned long getValue(byte packet[]) {
int high = packet[3];
int low = packet[4];
unsigned long val = high * 256 + low;
return val;
}
void Serial1SendingDataWorker(unsigned long val) {
while (Serial1.available()) {
char inChar = (char)Serial1.read();
if (inChar != '\n')
serial1SendingDataInputCommanString += inChar;
if (inChar == '\n' && serial1SendingDataInputCommanString.length() > 0) {
serial1SendingDataInputCommanStringComplete = true;
Serial.print(F("Serial1SendingDataWorker: received command = "));
Serial.println(serial1SendingDataInputCommanString);
Serial1SendingData_SendResponse(val);
return;
}
}
if (serial1SendingDataInputCommanStringComplete)
Serial1SendingData_SendResponse(val);
}
void Serial1SendingData_SendResponse(unsigned long val) {
Serial.println(F("Serial1SendingData_SendResponse"));
if (serial1SendingDataInputCommanString.equals("get")) {
String jsonStr = String(val);
for (int i = 0; i < jsonStr.length(); i++)
{
Serial1.print(jsonStr[i]); // Push each char 1 by 1 on each loop pass
Serial.print(jsonStr[i]);
}
}
Serial.println();
serial1SendingDataInputCommanString = "";
serial1SendingDataInputCommanStringComplete = false;
}
Scetch of the second Mega which requests data:
void setup() {
Serial.begin(9600);
while(!Serial); // time to get serial running
Serial.println(F("Initializing Serial2 (16, 17 pins)..."));
Serial1.begin(9600);
while(!Serial1);
}
void loop() {
SerialGettingDataWorker();
delay(2000);
}
void SerialGettingDataWorker() {
while (!Serial1.available()){
Serial.println("Sending Serial2GettingData request");
Serial1.write("get\n");
delay(500);
}
if (Serial1.available()) {
while(Serial1.available()){
char q = Serial1.read();
Serial.println(q);
delay(50);
}
Serial.println();
}
}
Initally I had big scatches which have a lot of data and sent then in JSON format. Now it's just example demostrating issue.
The problem is that requesting Mega gets numbers like 0 or 10000 or sometimes other figures and (what's very interesting for me) even symbols like "g" or "ge" or some corrupted symbol. I.e. it receives symbol from "get" that was sent to Mega with sensor!
At the same time if I uncomment
//valCO2 = 746;
line everything becomes perfect and the first controller gets 746 as it should be. Also I connected BME280 instead of Senseair and everything also worked perfect because BME280 does not user Serial.
So now I'm totally sure that problem is in using two Serials (actually even 3: Serial, Serial1 and Serial3) but I've spent already a lot of time and I don't know the nature of issue and how to resolve it.
P.S. Just in case. In Serial I see that I get correct values from Senseair (and when I used only requesting data via Ethernet everrything worked perfect - I was this correct CO2 value in JSON in my webbrowser). The more
Serial.print(jsonStr[i]);
shows that correct chars are sent. But on receiving side data is wrong.