
Wannabe (Customer) asked a question.
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.
- Serial.begin(115200);
- while (!Serial) {
- delay(100);
- }
- Wire.begin();
- sensor.begin(Wire, SCD30_I2C_ADDR_61);
-
- sensor.stopPeriodicMeasurement();
- sensor.softReset();
- delay(2000);
- uint8_t major = 0;
- uint8_t minor = 0;
- error = sensor.readFirmwareVersion(major, minor);
- if (error != NO_ERROR) {
- Serial.print("Error trying to execute readFirmwareVersion(): ");
- errorToString(error, errorMessage, sizeof errorMessage);
- Serial.println(errorMessage);
- return;
- }
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!
Hello Mike,
I have found the solution to that problem. On line 97 in Adafruit_SCD30.cpp there is this little innocuous comment.
which gave me the idea to write the following
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.