I'm trying to create an air quality sensor using a PMS5003 sensor and a Sensair L8 co2 sensor. Both of these devices use UART serial communication. Using SoftwareSerial for both of these devices doesn't seem to be working. Depending on the order that the devices are started in the code, one of the devices will either not connect or send garbled data.
Here's my code:
#include <SoftwareSerial.h>
#include "Adafruit_PM25AQI.h"
SoftwareSerial co2(7, 2); // RX, TX
byte readCO2[] = { 0xFE, 0X44, 0X00, 0X08, 0X02, 0X9F, 0X25 }; //Command packet to read Co2 (see app note)
byte response[] = { 0, 0, 0, 0, 0, 0, 0 }; //create an array to store the response
SoftwareSerial pmSerial(6, 3);
Adafruit_PM25AQI aqi = Adafruit_PM25AQI();
void setup() {
Serial.begin(9600);
//co2.begin(9600);
// Wait one second for sensor to boot up!
delay(1000);
pmSerial.begin(9600);
aqi.begin_UART(&pmSerial);
delay(1000);
}
void loop() {
co2.listen();
float co2 = getCO2(readCO2);
Serial.print("CO2 concentration: ");
Serial.println(co2);Serial.println();
delay(2000);
pmSerial.listen();
PM25_AQI_Data data;
if (aqi.read(&data)) {
Serial.print("PM 1.0: ");
Serial.println(data.pm10_standard);
Serial.print("PM 2.5: ");
Serial.println(data.pm25_standard);
Serial.print("PM 10: ");
Serial.println(data.pm100_standard);
}else{
Serial.println("PM ERROR");
}
Serial.println("--------------------------------------");
delay(1000);
}
float getCO2(byte packet[]) {
while (!co2.available()) //keep sending request until we start to get a response
{
co2.write(readCO2, 7);
delay(10);
}
int timeout = 0; //set a timeoute counter
while (co2.available() < 7) //Wait to get a 7 byte response
{
timeout++;
if (timeout > 10) //if it takes to long there was probably an error
{
while (co2.available()) //flush whatever we have
co2.read();
break; //exit and try again
}
delay(50);
}
for (int i = 0; i < 7; i++) {
response[i] = co2.read();
}
Serial.print("Response from sensor: ");
for (int i = 0; i < 7; i++) {
Serial.print(response[i], HEX);
Serial.print(" ");
}
Serial.println();
byte high = response[3]; //high byte for value is 4th byte in packet
byte low = response[4]; //low byte for value is 5th byte in packet
float val = (high * 256) + low; //Combine high byte and low byte with this formula to get value
return val;
}
I made a mistake, and I mislead you in my previous posting.
Serial2 (which is actually USART0 in the AT4809 data sheet) is not enabled in the Arduino megaavr core. I have been using MegaCoreX with the Nano Every, and that core supports Serial2. There are some other useful features of the MegaCoreX and you may want to try it.
You can add it from the Boards Manager https://github.com/MCUdude/MegaCoreX#boards-manager-installation
MegaCoreX defines the Serial2 Tx and Rx pins as follows. In my original posting I had the pins reversed.