TroubleshootingGravity

Gravity: Factory Calibrated Electrochemical Oxygen / O2 Sensor (0-25%Vol, I2C & UART)

userHead Mark.Chivers 2023-07-20 08:36:49 969 Views5 Replies

I have the sensor hooked up to a UART on a Pic32 microcontroller.  The sensor will send data for several hours and then just stop.  The only way to fix the problem is to power cycle the sensor.  I have looked at the data lines with an oscilloscope and can see that the pic is requesting data but there is no reply from the sensor.  Power cycle just the sensor and it starts working again.  Has anyone else had this problem?

 

Here is the code

 

void task_dfrobot_sensor(void *pvParameters){

 

/* skipping some initialization */       

 

while(1)

    {

   

 

        if (DFR_MODE == DFROBOT_SETTING_QA_MODE)

        {

            vTaskDelayUntil( &pxPreviousWakeTime, 1000 / portTICK_PERIOD_MS);

        } else {

            vTaskDelay( 600 / portTICK_PERIOD_MS);

        }

        if (DFR_INTERVAL == 0)  { continue; }

        switch (ro_state)

        {

            case RO_INIT:

                df_err = _open_driver(&df_handle, uart_num);

                df_handle.mode = DFR_MODE;

                if (df_err == DFROBOT_SUCCESS)

                {

                    ro_state = RO_MODE;

                }

                else

                {

                    _send_no_sensor(uart_num);

                }

                break;

            case RO_MODE:

                _send_info_msg(uart_num, "RO_MODE state"); /* debug code */

                _flush_uart(uart_num);

                df_err = DFROBOT_set_mode(&df_handle, DFR_MODE);

                if (df_err == DFROBOT_SUCCESS)

                {

                    ro_state = RO_SENS_TYPE;

                    missed_reading_cnt = 0;

                    break;

                }

                else if (df_err == DFROBOT_ERR_TIMEOUT)

                {

                    _send_no_sensor(uart_num);

                }

                else

                {

                    _send_err(uart_num, df_err);

                }

                if (_missed_cnt_over_max(&missed_reading_cnt))

                {

                    ro_state = RO_PWR_CYCL_SENS;

                }

                break;

            case RO_SENS_TYPE:

                _flush_uart(uart_num);

                if (DFR_MODE == DFROBOT_SETTING_ACTIVE_MODE) {

                    df_err = DFROBOT_read_gas_temp(&df_handle, &gas_type, &gas, &temp);

                } else {

                    df_err = DFROBOT_read_gas(&df_handle, &gas_type, &gas);

                }

                if (df_err == DFROBOT_SUCCESS)

                {

     /* different sensors can be set to different intervals */

                    itrvl_idx = _get_intrvl_indx(gas_type);

                    ro_state = RO_RUN;

                    missed_reading_cnt = 0;

                    break;

                }

                else if (df_err == DFROBOT_ERR_TIMEOUT)

                {

                    _send_no_sensor(uart_num);

                    DFROBOT_set_mode(&df_handle, DFR_MODE);

                }

                else

                {

                    _send_err(uart_num, df_err);

                }

                if (_missed_cnt_over_max(&missed_reading_cnt))

                {

                    ro_state = RO_PWR_CYCL_SENS;

                }

                break;

            case RO_RUN:

                _flush_uart(uart_num);

                if (DFR_MODE == DFROBOT_SETTING_ACTIVE_MODE) {

                    df_err = DFROBOT_read_gas_temp(&df_handle, &gas_type, &gas, &temp);

                } else {

                    df_err = DFROBOT_read_gas(&df_handle, &gas_type, &gas);

                }

                if (df_err)

                {

                    _send_err(uart_num, df_err);

                    if (df_err == DFROBOT_ERR_TIMEOUT)

                    {

                        _send_no_sensor(uart_num);

                    }

                   

                    if (_missed_cnt_over_max(&missed_reading_cnt))

                    {

                        ro_state = RO_PWR_CYCL_SENS;

                    }

                    break;

                } else {

                    /* Add reading to buffer for median filter */

                    avg_filter_push_float (&rbuff, gas);

                    missed_reading_cnt = 0;

                }

                    if ((next_send_time - xTaskGetTickCount()) <  DFR_INTERVAL)

                    {

                        break;

                    }

                    if( !avg_filt_get_median_float(&rbuff, &gas) ) /* filter out any outliers */

                    {

                        _send_gas(gas_type, gas);

                        _check_limits(gas_type, gas);

                    }

                    next_send_time = xTaskGetTickCount() + DFR_INTERVAL;

                break;

            case RO_PWR_CYCL_SENS:

                _send_info_msg(uart_num, "STATE - RO_PWR_CYCL_SENS");

                _ms_delay(100);

                _sens_pwr_cycl(uart_num);

                ro_state = RO_MODE;

                break;

            default:

                break;

        }

       

    }

 

}

 

DFROBOT_ERR DFROBOT_read_gas(DFROBOT_s *handle, int *gas_type, float *gas)

{

    DFROBOT_ERR err;

    uint8_t read_msg[DFROBOT_BUFF_LEN];

 

    /* if in QA mode then request the reading */

    err = _request_gas(handle);

    if (err != DFROBOT_SUCCESS)

    {

        return err;

    }

    handle->delay(50);

 

    // wait for response

    err = _read_and_verify(handle, read_msg, DFROBOT_BUFF_LEN);

    if (err != DFROBOT_SUCCESS)

    {

        return err;

    }

 

    // passive response

    // 0xFF, 0x86, gas high, gas low, gas type, decimal places, 0, 0, check sum

 

    // check command type

    if (read_msg[1] != 0x86)

    {

        return DFROBOT_ERR_SENSOR;

    }

 

    *gas_type = read_msg[4];

 

    float temp;

    /* reusing this.  temp will get set to 0.0 */

    err = _extract_gas_temp(read_msg, gas, &temp);

 

    if (err != DFROBOT_SUCCESS) return err;

 

    return DFROBOT_SUCCESS;

 

 

}

 

 

STATIC DFROBOT_ERR _request_gas(DFROBOT_s *handle)

{

    uint8_t buff[] = {0xFF, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

    buff[8] = _check_value(buff, DFROBOT_BUFF_LEN);

    return _write(handle, buff, DFROBOT_BUFF_LEN);

}

 

 

 

/**

* @brief Takes the full buffer of data returned from the sensor. From this

* the gas values and temperature value are calculated and returned.

*

 * Note: the temperature value has not been implemented.

*

 * @param buff

 * @param gas

 * @param temp - always 0.0

 * @return STATIC

 */

STATIC DFROBOT_ERR _extract_gas_temp(uint8_t *buff, float *gas, float *temp)

{

    uint8_t gas_high = buff[2];

    uint8_t gas_low = buff[3];

    uint8_t resolution = buff[5];

    *gas = _calc_gas(gas_high, gas_low, resolution);

    if (*gas == -555.5) /* calc_gas returns this exact value if there was an error */

    {

        return DFROBOT_ERR_SENSOR;

    }

 

    /* have not implemented the temperature calculation */

    *temp = 0.0;

    return DFROBOT_SUCCESS;

}

 

STATIC float _calc_gas(uint8_t gas_high, uint8_t gas_low, uint8_t resolution)

{

    uint16_t ugas = (gas_high << 8) | gas_low;

    float fgas = (float)ugas;

    float res = 0.0;

 

    switch (resolution)

    {

    case DFROBOT_GAS_1:

        res = 1.0f;

        break;

    case DFROBOT_GAS_0_1:

        res = 0.1f;

        break;

    case DFROBOT_GAS_0_01:

        res = 0.01;

        break;

    default:

        return -555.5;

        break;

    }

 

    return fgas * res;

}

 

 

/**

* @brief Takes the entire 9 byte buffer and calculates the checksum

*

 * @param buff

 * @param len

 * @return uint8_t  checksum

 */

STATIC uint8_t _check_value(uint8_t *buff, int len)

{

    int j;

    uint8_t tempq = 0;

    buff++;

    for (j=0; j<(len-3); j++)

    {

        tempq += *buff;

        buff++;

    }

    return (~tempq) + 1;

}

 

2024-02-22 13:34:59

Hi,

 

My sensor is not connecting.

 

I get NO Deivces !
NO Deivces !
NO Deivces !
NO Deivces !
NO Deivces !
NO Deivces !
NO Deivces !
 

I am using the code below:

 

#include "DFRobot_MultiGasSensor.h"

//Enabled by default, use IIC communication at this time. Use UART communication when disabled
#define I2C_COMMUNICATION

#ifdef  I2C_COMMUNICATION
#define I2C_ADDRESS    0x74
 DFRobot_GAS_I2C gas(&Wire ,I2C_ADDRESS);
#else
#if (!defined ARDUINO_ESP32_DEV) && (!defined __SAMD21G18A__)
/**
 UNO:pin_2-----RX
     pin_3-----TX
*/
 SoftwareSerial mySerial(22,21);
 DFRobot_GAS_SoftWareUart gas(&mySerial);
#else
/**
 ESP32:IO16-----RX
       IO17-----TX
*/
 DFRobot_GAS_HardWareUart gas(&Serial2); //ESP32HardwareSerial
#endif
#endif

void setup() {

 Serial.begin(115200);

 while(!gas.begin())
 {
   Serial.println("NO Devices !");
   delay(1000);
 }
 Serial.println("The device is connected successfully!");

 gas.changeAcquireMode(gas.PASSIVITY);
 delay(1000);

 gas.setTempCompensation(gas.OFF);
}

void loop() {

 Serial.print("Ambient ");
 Serial.print(gas.queryGasType());
 Serial.print(" concentration is: ");
 Serial.print(gas.readGasConcentrationPPM());
 Serial.println(" %vol");
 //The measurement unit will only be %vol when the sensor is SEN0465
 //Otherwise the unit will be PPM
 Serial.print("The board temperature is: ");
 Serial.print(gas.readTempC());
 Serial.println(" ℃");
 Serial.println();
 delay(1000);
}

 

My connectivity is:

      O2 sensor -> FireBeetle ESP32

      D/T ->  GPIO 21

      C/R ->  GPIO 22

      -      ->  GND

      +     ->  3.3V

userHeadPic dydmarco
2023-07-28 05:52:54

Hi, 

 

I am seeing a similar failure using IC2 ("QWIIC" Connect) on a Sparkfun Redboard (arduino uno), using the same (?) DF Robot O2 Sensor:

https://www.dfrobot.com/product-2052.html

 

The arduino is using 2 separate sensors: CO2 and O2, logging data to an SD Card.  

 

The O2 has been working, and then just stopped (returning zero always).

 

The CO2 sensor from Sensiron continues to work fine.

 

Wiring is straightforward in that both sensors are connected via I2C ("QWIIC") connections.

 

O2 was and has been working fine and now just reports zero values.

 

Error Detection in setup() (see below) does not indicate a failure to connect, so it seems things are connected ok.

 

// CODE BELOW

 

#include<SPI.h>#include "DFRobot_OxygenSensor.h" // for the O2 sensor#include "SdFat.h"#include <Wire.h> // for CO2 sensor#include "SparkFun_SCD30_Arduino_Library.h" // for CO2 sensor Click here to get the library: http://librarymanager/All#SparkFun_SCD30SCD30 co2Sensor; // a handle for CO2 sensor

/*** i2c slave Address, The default is ADDRESS_3.* ADDRESS_0 0x70 i2c device address.* ADDRESS_1 0x71* ADDRESS_2 0x72* ADDRESS_3 0x73*/

#define Oxygen_IICAddress ADDRESS_3

#define COLLECT_NUMBER 10 // collect number, the collection range is 1-100.

 

//

// GLOBALS

//

DFRobot_OxygenSensor oxygenSensor; // a handle for the O2 sensorunsigned short CO2Data;float humidityData;float airTemp;SdFat Sd;File dataFile;

 

 

//

// SETUP FUNCTION

//

void setup(){ Serial.begin(9600);

 

// SD SETUP while (!Sd.begin(8))  {   Serial.println("aaa");   delay(1); }

Serial.println(F("SD OK"));

 

 

// O2 SETUPwhile(oxygenSensor.begin(Oxygen_IICAddress) == false ) // keep checking while O2 is not responding{Serial.println("O2 Sensor Error");delay(1000); // pause for 1 sec before we try again}

 

// CO2 SETUPWire.begin();while (co2Sensor.begin() == false) // keep checking while CO2 is not responding{Serial.println("CO2 sensor Error.");delay(1000); // pause for 1 sec before we try again}

// OK - both sensors seem ok...

} // end setup()

 

 

//

// LOOP FUNCTION

//

void loop(void){ 

 if (co2Sensor.dataAvailable()) // if co2 sensor has data for us.... {   dataFile=Sd.open("datalog.csv", FILE_WRITE);   CO2Data=co2Sensor.getCO2();   airTemp=co2Sensor.getTemperature();   humidityData=co2Sensor.getHumidity();  //get and print CO2 ppm data, along with temp and humidity (from theSensirion CO2 sensor)   Serial.print("co2(ppm):");   Serial.print(CO2Data);   Serial.print(","); // add a comma so the serial plotter will display   Serial.print("temp(C):");   Serial.print(airTemp);   Serial.print(","); // add a comma so the serial plotter will display   Serial.print("humidity(%):");   Serial.print(humidityData);   Serial.print(","); // add a comma so the serial plotter will display   // now we can get the oxygen data (by volume)   float oxygenData = oxygenSensor.getOxygenData(COLLECT_NUMBER); // get O2 data by %volume   Serial.print("O2(%vol):"); // update for Serial Plotter

   Serial.println(oxygenData); // !!!!!! FAILURE OCCURS HERE: WE ONLY GET ZERO VALUES (ALWAYS) AFTER PRIOR CORRECT VALUES (~24%)

 

   dataFile.close();   } // end CO2 check (contains o2 check)

 

 delay(1000); // pause for 1 sec so sensors can sample again (increase to slow down sampling

} // end loop() function 

userHeadPic ubacca
jenna wrote:

Hi!

 

Will the two problematic sensors output normal values when they are powered on again? 

 

For SEN0322:

You can try recalibrating the sensor via the button on the sensor with the example code. (on the Arduino UNO)

 

 

 

 

 

 

 

2023-07-29 01:49:37
1 Replies
2023-07-24 03:04:41

There could be errors in the software code that interacts with the sensor, leading to communication issues. For instance, if the sensor and the microcontroller are not synchronized correctly, it might result in data loss or communication failures.

userHeadPic bidrohini.bidrohini
2023-07-20 18:12:26

Hi!

 

Sorry to hear this. 

 

What environment does the sensor work in? What is the sensor powered by? 

 

Thanks for more details.

userHeadPic jenna