Boron UART Sensor Problem

Hi Everyone,

I am not sure if this is the place to turn to because this is more of a sensor issue than a boron issue. I have scoured the web for information and can’t find anything that actually works.

I am trying to use a Senseaire S8 CO2 sensor. There is a decent amount of code for this sensor in the Arduino world, which is great. I thought I could port this code over to the Boron LTE and get it to work. I got it to work with a caveat. The boron transmits the data exactly how I expect it to, verified using a logic analyzer. However, the S8 sensor refuses to transmit any data back.

I am lost at this point. I have poured over the sensors datasheet, quadruple checked my connections, tried a second S8 sensor, and so on. I just not seem to want to work for me.

Any help or guidance would be greatly appreciated.

//Read Sequence from Modbus data sheet (pg.13)
byte CO2_read[8] = {0xFE, 0X04, 0X00, 0X00, 0X00, 0X01, 0X25, 0XC5}; 
byte response[] = {0, 0, 0, 0, 0, 0, 0};

void setup() {

	Serial.begin(9600);
	Serial1.begin(9600);
}

void loop() {
        
    getCO2();
    unsigned long CO2 = CO2count();
        
    //delay(2000);

}
void getCO2(){
    
    while(!Serial1.available())
    {
        Serial1.write(CO2_read,8);
        delay(50);
    }
    int timeout = 0;
    
    while(Serial1.available() < 6 ){
        
        timeout++;
        if (timeout > 10){
            
            while(Serial1.available())
                Serial1.read();
            break;
        }
        delay(50);
    }
    for (int i = 0; i < 6; i++){
        response[i] = Serial1.read();
    }
}


unsigned long CO2count()
{
  int high = response[3];
  int low = response[4];
  unsigned long val = high * 256 + low;
  return val * 1; // S8 = 1. K-30 3% = 3, K-33 ICB = 10
}

Data Sheets:
Sensaire S8 Data Sheet
Senseair S8 Modbus Data Sheet

Hi SpicyGator-

Can you double check what power the sensor accepts? It looks like the sensor is using a 5V logic levels, and the Boron use a 3V3 logic levels. I think that the main problem could be a hardware issue related to the logical level of communication in the UART port.

Will work perfect when you will use a modbus master lib. I’m gonna make some example “how_to” for you, but I’m so f… busy as we moving :see_no_evil:

I have already looked at that. The sensor data sheet says it is powered via 5 V, but uses 3.3 V logic logic levels with the UART communication. I have my setup configured as such.

I had no idea a modbus library existed. I will have to check that out. And no worries, I will see what I can do in the mean time. Thanks!

Hi, sorry for a late response, finally I got some free time :slight_smile:
You could try this: Particle Web IDE
and let’s see if will read correctly according to Senseair Modbus should read status and CO2 at once senseair_st_and_co2

Best,
Arek

Hi Arek,

I apologize for not responding yesterday, but I finally figured out the issue I was having yesterday evening.

It turns out that the CO2 sensor uses half-duplex in the UART transmission. So, the sensor can read or write data but not simultaneously. I was trying to write to the sensor too quickly and did not give the sensor enough time to respond.

I added a longer delay, and the sensor started responding with data.

I appreciate your help and will refer to your code to see what you did as well.

Thanks,
Dominic

1 Like

Hi Dominic

I am trying a similar setup as yours, only using a photon in stead of a Boron. Which delay did you increase?
I have tried your code but I cannot seem to get a value from the S8 sensor.
I’m had a problem getting the serial to display anything, so I tried the Particle.variable instead.
This just returns “0”

//Read Sequence from Modbus data sheet (pg.13)
byte CO2_read[8] = {0xFE, 0X04, 0X00, 0X00, 0X00, 0X01, 0X25, 0XC5}; 
byte response[] = {0, 0, 0, 0, 0, 0, 0};
unsigned long CO2;


void setup() {

	Serial.begin(9600);
	Serial1.begin(9600);
	Particle.variable("CO2", CO2);
	
}

void loop() {
        
    getCO2();
    CO2 = CO2count();
       
    delay(5000);

}
void getCO2(){
    
    while(!Serial1.available())
    {
        Serial1.write(CO2_read,8);
        delay(50);
    }
    int timeout = 0;
    
    while(Serial1.available() < 6 ){
        
        timeout++;
        if (timeout > 10){
            
            while(Serial1.available())
                Serial1.read();
            break;
        }
        delay(5000);
    }
    for (int i = 0; i < 6; i++){
        response[i] = Serial1.read();
    }
}


unsigned long CO2count()
{
  int high = response[3];
  int low = response[4];
  unsigned long val = high * 256 + low;
  return val * 1; // S8 = 1. K-30 3% = 3, K-33 ICB = 10
}
 

Any ideas?