Arduino Nano Every SoftwareSerial Issues

Hey all,

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;
}

Thanks for the help!

This thread may be of interest.

Plus many more with an internet search for "SoftwareSerial Issues nano every".

Why do you need a SoftwareSerial on Nano Every, which has up to 4 hardware serial ports?

I tried using the hardware ports, but nothing happend. Maybe I had them configured wrong?

Serial.begin(baud rate); //usb serial
Serial1.begin(baud rate); //RX1 D1   Tx1 D0
Serial2.begin(baud rate); //RX2 D2  TX2 D7

There are alternative pin configurations as well.

Whenever I try this Serial2.available(); returns false.

Thanks! I'll look into that thread, and not being able to find anything on google is what lead me here.

What is the point of Nano Every? - Nano Family / Nano Every - Arduino Forum

Given that ─ probably easier to go with SoftwareSerial.

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.

#define PIN_HWSERIAL2_TX                PIN_PA0  2
#define PIN_HWSERIAL2_RX                PIN_PA1  7

If you do not want to use MegaCoreX but stay with the megaavr core, you can make the following changes to the pins_arduino file located at

AppData\Local\Arduino15\packages\arduino\hardware\megaavr\1.8.8\variants\nona4809\pins_arduino

You may want to save a copy of the original file to a different location before making the changes in order to make it easier to go back.

I think at line 82 you will find this where Serial2 is disabled.
#define HWSERIAL2_MUX (PORTMUX_USART0_NONE_gc)

Comment it out
//#define HWSERIAL2_MUX (PORTMUX_USART0_NONE_gc)

Then add these lines and save the file. Serial2 should be enabled in the megaavr core at Tx 2 and Rx 7

//#define HWSERIAL2_MUX (PORTMUX_USART0_NONE_gc)

// Nano Every USART (Serial2)
// USART0 on mega4809
// Maps to default pins by default
// Mapped to HWSERIAL2 in Serial library
#define HWSERIAL2                       &USART0
#define HWSERIAL2_DRE_VECTOR            USART0_DRE_vect
#define HWSERIAL2_DRE_VECTOR_NUM        USART0_DRE_vect_num
#define HWSERIAL2_RXC_VECTOR            USART0_RXC_vect
#define HWSERIAL2_MUX                   PORTMUX_USART0_DEFAULT_gc
#define HWSERIAL2_MUX_PINSWAP_1         PORTMUX_USART0_ALT1_gc
#define PIN_WIRE_HWSERIAL2_TX           (2)
#define PIN_WIRE_HWSERIAL2_RX           (7)

MagaCoreX ...

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.