Difficulties combining CO2 sensor and LoRa

Hello

We are 4 students electrical engineering working on a Covid-19 related project, however we have some difficulties working with Arduino as we have little to no experience with it (we do have experience with C/C++ however).

We’re supposed to design a wireless CO2-sensornetwork which could be used in a school for example. To read the CO2 values we use the SparkFun_SCD30_Arduino_Library. Then we want to send them via LoRa to our gateway. For this we use the Beelan-LoRaWAN library. Both work fine separately, but when we try to combine them, we encounter some problems with the Serial monitor. It’s basically as if the loop()-function only runs one time, because it only sends 1 packet with our CO2 value (and at the gateway we also only receive 1 packet). We’ve tried changing the baud rate or adding some delays here and there, but that doesn’t seem to work. However, if we uncomment the first line in the loop()-function which prints “loop”, all seems to work fine, but only for a while. Unfortunately, we cannot seem to find what causes this.

(I left out the ABP credentials for our LoRa device)

#include <lorawan.h>
#include <Wire.h>
#include <SparkFun_SCD30_Arduino_Library.h>

SCD30 scd30;

//ABP Credentials
const char *devAddr = "";
const char *nwkSKey = "";
const char *appSKey = "";

const unsigned long interval = 10000; 
unsigned long previousMillis = 0;  // will store last time message sent
char myStr[5];

const sRFM_pins RFM_pins = {
  .CS = 10,
  .RST = 7,
  .DIO0 = 6,
  .DIO1 = 8,
  .DIO2 = 5,
  .DIO5 = 9,
};

void setup() {
  Serial.begin(115200);
  while (!Serial);
  Wire.begin();

  // Setup loraid access
  if (!lora.init()) {
    Serial.println("RFM95 not detected");
    delay(5000);
    return;
  }

  // Set LoRaWAN Class change CLASS_A or CLASS_C
  lora.setDeviceClass(CLASS_A);

  // Set Data Rate
  lora.setDataRate(SF8BW125);

  // set channel to random
  lora.setChannel(MULTI);

  // Put ABP Key and DevAddress here
  lora.setNwkSKey(nwkSKey);
  lora.setAppSKey(appSKey);
  lora.setDevAddr(devAddr);

  // Setup CO2 sensor

  if (!scd30.begin()) {
    Serial.println("Failed to find SCD30 chip");
    while (1) {
      delay(10);
    }
  }

  Serial.println("SCD30 Found!");

  if (!scd30.setMeasurementInterval(10)) {
    Serial.println("Failed to set measurement interval");
    while (1) {
      delay(10);
    }
  }

}

void loop() {
  //Serial.println("loop");
  // Check interval overflow
  if (millis() - previousMillis > interval) {
    previousMillis = millis();

    if (scd30.dataAvailable()) {
      // Read CO2 value and cap at 9999
      uint16_t CO2 = min(scd30.getCO2(), 9999);
      // Convert to string as sendUplink() requires a string as input. Only use 4 (+1) characters to minimalise data throughput.
      snprintf(myStr, sizeof myStr, "%d", CO2);
      Serial.print("Sending: ");
      Serial.println(myStr);
      lora.sendUplink(myStr, strlen(myStr), 0, 1);
      
    } else {
      //Serial.println("No data");
    }
  }
  // Check Lora RX
  lora.update();
}

Hardware used:
Arduino Uno
SCD30 sensor
SX1276RF1JAS (LoRa)

Thanks in advance!

I expect the printing "loop" was causing blocking when it fills up the output buffer. How long does it run for when that line is commented out?

It would probably help if you post the two programs you combined to make this one.

This is the code for LoRa:

(I left out the credentials again)

#include <lorawan.h>

//ABP Credentials
const char *devAddr = "";
const char *nwkSKey = "";
const char *appSKey = "";

const unsigned long interval = 10000;    // 10 s interval to send message
unsigned long previousMillis = 0;  // will store last time message sent
unsigned int counter = 0;     // message counter

char myStr[50];

const sRFM_pins RFM_pins = {
  .CS = 10,
  .RST = 7,
  .DIO0 = 6,
  .DIO1 = 8,
  .DIO2 = 5,
  .DIO5 = 9,
};

void setup() {
  // Setup loraid access
  Serial.begin(9600);
  while (!Serial);
  if (!lora.init()) {
    Serial.println("RFM95 not detected");
    delay(5000);
    return;
  }

  // Set LoRaWAN Class change CLASS_A or CLASS_C
  lora.setDeviceClass(CLASS_A);

  // Set Data Rate
  lora.setDataRate(SF8BW125);

  // set channel to random
  lora.setChannel(MULTI);

  // Put ABP Key and DevAddress here
  lora.setNwkSKey(nwkSKey);
  lora.setAppSKey(appSKey);
  lora.setDevAddr(devAddr);
}

void loop() {
  // Check interval overflow
  if (millis() - previousMillis > interval) {
    previousMillis = millis();

    sprintf(myStr, "Counter-%d", counter);

    Serial.print("Sending: ");
    Serial.println(myStr);

    lora.sendUplink(myStr, strlen(myStr), 0, 1);
    counter++;
  }
  // Check Lora RX
  lora.update();
}

As expected, this sends a packet every 10 seconds which is received by our gateway.

This is the code for the CO2 sensor:

#include <Wire.h>

#include "SparkFun_SCD30_Arduino_Library.h"
SCD30 airSensor;

void setup()
{
  Serial.begin(115200);
  Serial.println("SCD30 Example");
  Wire.begin();

  if (airSensor.begin() == false)
  {
    Serial.println("Air sensor not detected. Please check wiring. Freezing...");
    while (1)
      ;
  }

  //The SCD30 has data ready every two seconds
}

void loop()
{
  if (airSensor.dataAvailable())
  {
    Serial.print("co2(ppm):");
    Serial.print(airSensor.getCO2());

    Serial.print(" temp(C):");
    Serial.print(airSensor.getTemperature(), 1);

    Serial.print(" humidity(%):");
    Serial.print(airSensor.getHumidity(), 1);

    Serial.println();
  }
  else
    Serial.println("Waiting for new data");

  delay(500);
}

As expected, this prints out the data every 2 seconds.

Both functions work separately (even when simultaneously connected to the Arduino Uno). As for the “loop”, it goes for a few times (4 or 5 times so 40-50 seconds) before also getting stuck. I just noticed that it also doesn’t actually send the packet (even though I’m sure it did yesterday). It prints “Sending: xxx” on the Serial, but nothing is received at the gateway so it’s likely that the update()-function at the end isn’t even reached. The Serial Monitor stops for a split second after the “Sending: xxx” line before it restarts completely (so “SCD30 found” is repeated which suggests the Arduino resets itself I suppose?). Also at the start it prints this message twice.

How is it all wired up?

SCD30 Arduino
Vin 5V
GND GND
SCL SCL
SDA SDA
SX1276RF1JAS Arduino
SCK 13
MOSI 11
MISO 12
NSS 10
NRESET 7
DIO0 6
DIO1 8
DIO2 5
DIO5 9
GND GND
VDD_RF 3.3V

In the attachment you’ll find the schematic of the SX1276RF1JAS. However, I don’t think there’s a problem with the wiring, as they work perfectly fine separately (while the wiring doesn’t change), but I might be wrong.

SX1276RF1JAS_e268v01a_sch.pdf (129 KB)

I was concerned that there might be a clash between the devices both using the same pin. Doesn’t look like it.

The length of Mystr makes me nervous, maybe make it a bit bigger, eight perhaps.

If that doesn’t work, you’re reduced to divide and conquer I think. Perhaps try a version that has the CO2 detector declared and initialized but don’t read it, just sending a constant string via LoRa and see if that’s stable.

I made the myStr longer (8) but it still doesn't work.

I now started from the LoRa code (with the only changes that myStr is 8 long and instead of sending a counter just sending "Hello"). This works fine. Now I added the line #include <SparkFun_SCD30_Arduino_Library.h> and weird things start happening in the Serial monitor (see image). This is for 6 packets, which strangely all arrive perfectly at our LoRa gateway (see image, indeed 48 65 6C 6C 6F corresponds to "Hello").

Here is the code:

#include <lorawan.h>
#include <SparkFun_SCD30_Arduino_Library.h>

//SCD30 scd30;

//ABP Credentials
const char *devAddr = "";
const char *nwkSKey = "";
const char *appSKey = "";

const unsigned long interval = 10000;
unsigned long previousMillis = 0;  // will store last time message sent
char myStr[8];

const sRFM_pins RFM_pins = {
  .CS = 10,
  .RST = 7,
  .DIO0 = 6,
  .DIO1 = 8,
  .DIO2 = 5,
  .DIO5 = 9,
};

void setup() {
  // Setup loraid access
  Serial.begin(9600);
  while (!Serial);
  if (!lora.init()) {
    Serial.println("RFM95 not detected");
    delay(5000);
    return;
  }

  // Set LoRaWAN Class change CLASS_A or CLASS_C
  lora.setDeviceClass(CLASS_A);

  // Set Data Rate
  lora.setDataRate(SF8BW125);

  // set channel to random
  lora.setChannel(MULTI);

  // Put ABP Key and DevAddress here
  lora.setNwkSKey(nwkSKey);
  lora.setAppSKey(appSKey);
  lora.setDevAddr(devAddr);
}

void loop() {
  // Check interval overflow
  if (millis() - previousMillis > interval) {
    previousMillis = millis();

    sprintf(myStr, "Hello");

    Serial.print("Sending: ");
    Serial.println(myStr);

    lora.sendUplink(myStr, strlen(myStr), 0, 1);
  }
  // Check Lora RX
  lora.update();
}

The StreamLine CO2 + Air Quality Sensor is a product line member of KCS’ advanced LoRaWan products, for indoor environment measurement.

get-vidmateapp.com
get-mobdroapk.com

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