Wannabe (Customer) asked a question.

I2C Communication between P1AM-200 and Sensirion SCD30

Hello,

I am having a bit of an issue communicating over I2C with a Sensirion SCD30. When I run the example code provided with the Arduino library i get the following error: "Error trying to execute readFirmwareVersion(): Received NACK on transmit of data". I was able to isolate the error to the following code section.

  1. Serial.begin(115200);
  2. while (!Serial) {
  3. delay(100);
  4. }
  5. Wire.begin();
  6. sensor.begin(Wire, SCD30_I2C_ADDR_61);
  7.  
  8. sensor.stopPeriodicMeasurement();
  9. sensor.softReset();
  10. delay(2000);
  11. uint8_t major = 0;
  12. uint8_t minor = 0;
  13. error = sensor.readFirmwareVersion(major, minor);
  14. if (error != NO_ERROR) {
  15. Serial.print("Error trying to execute readFirmwareVersion(): ");
  16. errorToString(error, errorMessage, sizeof errorMessage);
  17. Serial.println(errorMessage);
  18. return;
  19. }

The error only happens if sensor.softReset(); is invoked. If I remove it the sensor behave has expected. The 2 second delay might seem strange, but it is part of I2C Protocol for this sensor. Attaching the section of interest of the sensor datasheet.

 

"Maximal I2C speed is 100 kHz and the master has to support clock stretching. Sensirion recommends to operate the SCD30 at a baud rate of 50 kHz or smaller. Clock stretching period in write- and read-frames is 30ms, however, due to internal calibration processes a maximal clock stretching of 150 ms may occur once per day. For detailed information to the I2C protocol, refer to NXP I2C-bus specification1 . SCD30 does not support repeated start condition. Clock stretching is necessary to start the microcontroller and might occur before every ACK. I2C master clock stretching needs to be implemented according to the NXP specification. The boot-up time is < 2 s. "

 

I have tried slowing down the I2C clock with "Wire.setClock(25000);", but it does not help.

 

For reference, my current P1AM configuration looks like this

P1-02AC -> P1AM-GPIO -> P1AM-ETH -> P1AM-Serial -> P1AM-200 -> 6x P1 Modules (Thermo Couple, Relay, ADC, Digital in)

 

Sensor VDD -> P1AM-GPIO Terminal Block 1 (VCC)

Sensor GND -> P1AM-GPIO Terminal Block 18 (GND)

Sensor TX/SCL -> P1AM-GPIO Terminal Block 15 (12)

Sensor RX/SDA -> P1AM-GPIO Terminal Block 14 (11)

 

I know I can circumvent the issue by removing the line, but I would like to make sure I understand why this is happening. During its operation we may need to do a software reset while keeping the rest of the system alive. Am I missing something obvious here?

 

Thank you in advance!

 


  • Wannabe (Customer)

    Hello Mike,

    I have found the solution to that problem. On line 97 in Adafruit_SCD30.cpp there is this little innocuous comment.

    1. // first I2C xfer after reset can fail, double tapping seems to get by it

    which gave me the idea to write the following

    1. sensor.stopPeriodicMeasurement();
    2. sensor.softReset();
    3. sensor.stopPeriodicMeasurement();
    4. delay(2000);

    And it turns out to work perfectly fine. I have reached out to Sensirion with the finding asking if they knew why it was happening.

    Thank you for all your help.

    Expand Post
    Selected as Best
  • FACTS_MikeSc (AutomationDirect)

    I'm not familiar with their library myself but my suggestion would be to dig into the libraries and do a some debugging of the code.

     

    If you take a look at the header file they have descriptions for each of the functions.

     

    It appears they also use error codes that can be looked up or printed that may need to be enabled to see the printouts. You can check for those in their dependency library. There's a source file called SensirionErrors.cpp.

     

    Hopefully that'll help out. Let me know if you figure it out.

    Expand Post
  • Wannabe (Customer)

    Hello Mike,

    I have also opened an issue on their github page. I already did some digging in their code, but nothing really came out of here.

    The closest I have come to it is a comment in Adafruit_SCD30 library.

    "// first I2C xfer after reset can fail, double tapping seems to get by it" If I send a command right after the softReset(), the sensor behaves as expected. I am still confused as to why this is happening. For the moment it is working even if the solution is a little hacky.

    Expand Post
  • FACTS_MikeSc (AutomationDirect)

    Oh sorry I just realized it is reporting the error message lol. "Received NACK on transmit of data". Might of been a timing thing. So you were able to get a firmware version?

     

    Other good news is there are other libraries that might work with that sensor if you are skeptical about using Sensirion's library.

     

    But I think as long as you do some testing and verify correct functionality, might not need to worry about reading the f/w all the time. You can add some logic in to retry the softReset() if it returns an error.

    Expand Post
  • Wannabe (Customer)

    Hello Mike,

    I have found the solution to that problem. On line 97 in Adafruit_SCD30.cpp there is this little innocuous comment.

    1. // first I2C xfer after reset can fail, double tapping seems to get by it

    which gave me the idea to write the following

    1. sensor.stopPeriodicMeasurement();
    2. sensor.softReset();
    3. sensor.stopPeriodicMeasurement();
    4. delay(2000);

    And it turns out to work perfectly fine. I have reached out to Sensirion with the finding asking if they knew why it was happening.

    Thank you for all your help.

    Expand Post
    Selected as Best
  • FACTS_MikeSc (AutomationDirect)

    It's always nice when you have libraries with good comments hehe :-). Thanks for the update and happy to hear you were able to find a solution.