Scd30 in combination with teensy 3.2 problems

Status
Not open for further replies.

EmielcpNL

Active member
Hallo,

I'm using the SCD30 in combination with a Teensy 3.2 through I2C with the example code.

When I upload the code and check the serial monitor it's giving me no data. However, when I unplug the SCD30 and plug it back in it works perfectly... The SCD30 sensor works fine on an Arduino Uno. Also connected other i2c sensors to my Teensy and they all work fine.

I tried an 10uF decoupling capacitor between + and -. Also tried 4,7k pull-up resistors on the i2c lines, no succes... Any suggestions?

Edit: it got something to do with the SDA i2c line not getting pulled-up to 3.3v, when I hold a resisitor between SDA and 3v3 (also works between SDA and GND) it start working. However, when I solder the resistor permanently it's still doesn't work...

Code:

Code:
#include <Wire.h>

//Click here to get the library: http://librarymanager/All#SparkFun_SCD30
#include "SparkFun_SCD30_Arduino_Library.h"

SCD30 airSensor;

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

  airSensor.begin(); //This will cause readings to occur every two seconds

  airSensor.setMeasurementInterval(4); //Change number of seconds between measurements: 2 to 1800 (30 minutes)

  //My desk is ~1600m above sealevel
  airSensor.setAltitudeCompensation(1); //Set altitude of the sensor in m

  //Pressure in Boulder, CO is 24.65inHg or 834.74mBar
  airSensor.setAmbientPressure(835); //Current ambient pressure in mBar: 700 to 1200
}

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.print(".");
  delay(1000);
}
 
Last edited:
Not seeing ANY output it either dies on Wire.begin - or raced past it all too quickly. The general answer relates to Teensy startup speed - it is running in 300 to 400 ms before the computer can get USB Serial connected and the i2c device may not be ready to .begin that fast from a cold start ...

Try this perhaps:
Code:
void setup()
{
  Serial.begin(9600);
  while ( !Serial && millis() < 2000 ); // this allows 2 seconds for SerMon to be connected
  Serial.println("SCD30 Example");
  delay( 1000 );  // optional and adjustable downward to where it still works … if it works …
  Wire.begin();
  Serial.println("SCD30 Example - ready to run");
  // … ready to continue

If nothing else the first print should always show, and then the second 'ready' if the .begin() completes okay
 
Not seeing ANY output it either dies on Wire.begin - or raced past it all too quickly. The general answer relates to Teensy startup speed - it is running in 300 to 400 ms before the computer can get USB Serial connected and the i2c device may not be ready to .begin that fast from a cold start ...

Try this perhaps:
Code:
void setup()
{
  Serial.begin(9600);
  while ( !Serial && millis() < 2000 ); // this allows 2 seconds for SerMon to be connected
  Serial.println("SCD30 Example");
  delay( 1000 );  // optional and adjustable downward to where it still works … if it works …
  Wire.begin();
  Serial.println("SCD30 Example - ready to run");
  // … ready to continue

If nothing else the first print should always show, and then the second 'ready' if the .begin() completes okay

Thank you for the reply :) unfortunately it didn't work
 
Well the wiring is easy (checked everything a couple of times):

3v3 --> VCC
GND --> GND
SDA PIN 18 --> SDA
SCL PIN 19 --> SCL

I have multiple I2C sensors on my print and they all work except the SCD30, also when I connect the SCD30 alone without any other divices on the I2C bus. Ehm so weird...
 
Well the wiring is easy (checked everything a couple of times):

Yes, but can you show us photos anyway?

Over and over on this forum, we see problems like this. About half the time, when we finally see photos we're able to spot the problem. What have you got to lose, other than the several seconds it takes to snap a photo and put it into a message?

Yeah, it's also possible (but unlikely) the problem could be some sort of obscure software issue. But the Wire library is very mature, used by many thousands of people successfully.

The early days of Teensy 3.0, before we had a 0.4 delay in the default startup code (lately only 0.3 seconds), we would also see issues with sensors that take time to "boot up". Arduino boards all take much longer before your code runs. So if it's working on Arduino and not Teensy, maybe try adding delay before you start the sensor's library.

But since you've said it works wired one way, and when you hold the resistor, but not when connected another way.... seems most likely this is some sort of wiring issue. You really should let us try to help by showing photos.
 
Also, on Teensy 3.x boards, real pullup resistors are absolutely required. I know you already said you're using them in msg #1. But no mention of resistors in msg #6.

Be aware, the resistors are *NOT* optional with Teensy 3.x. This absolutely will not work, as it does with Arduino Uno, if you omit the resistors.
 
Thank you for the reply :) unfortunately it didn't work

That put in a delay and should have resulted in SerMon output, ideally a line after Wire.begin() - please say more than "it didn't work" - did anything change. Indication before was there was no SerMon output when there was a problem - this should have resulted in at least one and perhaps two SerMon strings printing to give some feedback on what is happening.

Also as noted the added PullUps are essential to work with Teensy.
 
@PaulStoffregen Pics coming :) There are pull-up resistors on the sensor, don't know which value though :( Let me explain the situation when it does work: I run the code on the Teensy and open the SerialMonitor it starts and gives me dots (no data). When i connect a resistor between SDA (DATA I2C) and 3v3 OR Ground and than disconnect it again it start working...

@defragster Yes it give results in SerMon, but exacly the same as before just with a delay. It just give dots in the SerMon, that means there is no data.

@manitou tried it (did I do it correctly?), still the same :( Code library:

Code:
/*
  This is a library written for the SCD30
  SparkFun sells these at its website: www.sparkfun.com
  Do you like this library? Help support SparkFun. Buy a board!
  https://www.sparkfun.com/products/14751

  Written by Nathan Seidle @ SparkFun Electronics, May 22nd, 2018

  The SCD30 measures CO2 with accuracy of +/- 30ppm.

  This library handles the initialization of the SCD30 and outputs
  CO2 levels, relative humidty, and temperature.

  https://github.com/sparkfun/SparkFun_SCD30_Arduino_Library

  Development environment specifics:
  Arduino IDE 1.8.5

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "SparkFun_SCD30_Arduino_Library.h"

SCD30::SCD30(void)
{
  // Constructor
}

//Initialize the Serial port
boolean SCD30::begin(TwoWire &wirePort)
{
  _i2cPort = &wirePort; //Grab which port the user wants us to use

  //We expect caller to begin their I2C port, with the speed of their choice external to the library
  //But if they forget, we start the hardware here.
  _i2cPort->begin();
  
  /* Especially during obtaining the ACK BIT after a byte sent the SCD30 is using clock stretching  (but NOT only there)!
   * The need for clock stretching is described in the Sensirion_CO2_Sensors_SCD30_Interface_Description.pdf
   *
   * The default clock stretch (maximum wait time) on the ESP8266-library (2.4.2) is 230us which is set during _i2cPort->begin();
   * In the current implementation of the ESP8266 I2C driver there is NO error message when this time expired, while
   * the clock stretch is still happening, causing uncontrolled behaviour of the hardware combination.
   *
   * To set ClockStretchlimit() a check for ESP8266 boards has been added in the driver.
   *
   * With setting to 20000, we set a max timeout of 20mS (> 20x the maximum measured) basically disabling the time-out 
   * and now wait for clock stretch to be controlled by the client.
   */

   #if defined(ARDUINO_ARCH_ESP8266)
   	_i2cPort->setClockStretchLimit(200000);
   #endif

  //Check for device to respond correctly
  if(beginMeasuring() == true) //Start continuous measurements
  {
	setMeasurementInterval(2); //2 seconds between measurements
	setAutoSelfCalibration(true); //Enable auto-self-calibration
	
	return (true);
  }

  return (false); //Something went wrong
}

//Returns the latest available CO2 level
//If the current level has already been reported, trigger a new read
uint16_t SCD30::getCO2(void)
{
  if (co2HasBeenReported == true) //Trigger a new read
    readMeasurement(); //Pull in new co2, humidity, and temp into global vars

  co2HasBeenReported = true;

  return (uint16_t)co2; //Cut off decimal as co2 is 0 to 10,000
}

//Returns the latest available humidity
//If the current level has already been reported, trigger a new read
float SCD30::getHumidity(void)
{
  if (humidityHasBeenReported == true) //Trigger a new read
    readMeasurement(); //Pull in new co2, humidity, and temp into global vars

  humidityHasBeenReported = true;

  return humidity;
}

//Returns the latest available temperature
//If the current level has already been reported, trigger a new read
float SCD30::getTemperature(void)
{
  if (temperatureHasBeenReported == true) //Trigger a new read
    readMeasurement(); //Pull in new co2, humidity, and temp into global vars

  temperatureHasBeenReported = true;

  return temperature;
}

//Enables or disables the ASC
void SCD30::setAutoSelfCalibration(boolean enable)
{
  if (enable)
    sendCommand(COMMAND_AUTOMATIC_SELF_CALIBRATION, 1); //Activate continuous ASC
  else
    sendCommand(COMMAND_AUTOMATIC_SELF_CALIBRATION, 0); //Deactivate continuous ASC
}

//Set the forced recalibration factor. See 1.3.7.
//The reference CO2 concentration has to be within the range 400 ppm ≤ cref(CO2) ≤ 2000 ppm.
void SCD30::setForcedRecalibrationFactor(uint16_t concentration)
{
  if(concentration < 400 || concentration > 2000) return; //Error check.
  sendCommand(COMMAND_SET_FORCED_RECALIBRATION_FACTOR, concentration);
}

//Set the temperature offset. See 1.3.8.
void SCD30::setTemperatureOffset(float tempOffset)
{
  int16_t tickOffset = tempOffset * 100;
  sendCommand(COMMAND_SET_TEMPERATURE_OFFSET, tickOffset);
}

//Set the altitude compenstation. See 1.3.9.
void SCD30::setAltitudeCompensation(uint16_t altitude)
{
  sendCommand(COMMAND_SET_ALTITUDE_COMPENSATION, altitude);
}

//Set the pressure compenstation. This is passed during measurement startup.
//mbar can be 700 to 1200
void SCD30::setAmbientPressure(uint16_t pressure_mbar)
{
  if(pressure_mbar < 700 || pressure_mbar > 1200) pressure_mbar = 0; //Error check
  sendCommand(COMMAND_CONTINUOUS_MEASUREMENT, pressure_mbar);
}

//Begins continuous measurements
//Continuous measurement status is saved in non-volatile memory. When the sensor
//is powered down while continuous measurement mode is active SCD30 will measure
//continuously after repowering without sending the measurement command.
//Returns true if successful
boolean SCD30::beginMeasuring(uint16_t pressureOffset)
{
  return(sendCommand(COMMAND_CONTINUOUS_MEASUREMENT, pressureOffset));
}

//Overload - no pressureOffset
boolean SCD30::beginMeasuring(void)
{
  return(beginMeasuring(0));
}

//Sets interval between measurements
//2 seconds to 1800 seconds (30 minutes)
void SCD30::setMeasurementInterval(uint16_t interval)
{
  sendCommand(COMMAND_SET_MEASUREMENT_INTERVAL, interval);
}

//Returns true when data is available
boolean SCD30::dataAvailable()
{
  uint16_t response = readRegister(COMMAND_GET_DATA_READY);

  if (response == 1) return (true);
  return (false);
}

//Get 18 bytes from SCD30
//Updates global variables with floats
//Returns true if success
boolean SCD30::readMeasurement()
{
  //Verify we have data from the sensor
  if (dataAvailable() == false)
    return (false);

  uint32_t tempCO2 = 0;
  uint32_t tempHumidity = 0;
  uint32_t tempTemperature = 0;

  _i2cPort->beginTransmission(SCD30_ADDRESS);
  _i2cPort->write(COMMAND_READ_MEASUREMENT >> 8); //MSB
  _i2cPort->write(COMMAND_READ_MEASUREMENT & 0xFF); //LSB
  if (_i2cPort->endTransmission() != 0)
    return (0); //Sensor did not ACK

delay(1); // Test , delay(1) before every requestFrom ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  _i2cPort->requestFrom((uint8_t)SCD30_ADDRESS, (uint8_t)18);
  if (_i2cPort->available())
  {
    for (byte x = 0 ; x < 18 ; x++)
    {
      byte incoming = _i2cPort->read();

      switch (x)
      {
        case 0:
        case 1:
        case 3:
        case 4:
          tempCO2 <<= 8;
          tempCO2 |= incoming;
          break;
        case 6:
        case 7:
        case 9:
        case 10:
          tempTemperature <<= 8;
          tempTemperature |= incoming;
          break;
        case 12:
        case 13:
        case 15:
        case 16:
          tempHumidity <<= 8;
          tempHumidity |= incoming;
          break;
        default:
          //Do nothing with the CRC bytes
          break;
      }
    }
  }

  //Now copy the uint32s into their associated floats
  memcpy(&co2, &tempCO2, sizeof(co2));
  memcpy(&temperature, &tempTemperature, sizeof(temperature));
  memcpy(&humidity, &tempHumidity, sizeof(humidity));

  //Mark our global variables as fresh
  co2HasBeenReported = false;
  humidityHasBeenReported = false;
  temperatureHasBeenReported = false;

  return (true); //Success! New data available in globals.
}

//Gets two bytes from SCD30
uint16_t SCD30::readRegister(uint16_t registerAddress)
{
  _i2cPort->beginTransmission(SCD30_ADDRESS);
  _i2cPort->write(registerAddress >> 8); //MSB
  _i2cPort->write(registerAddress & 0xFF); //LSB
  if (_i2cPort->endTransmission() != 0)
    return (0); //Sensor did not ACK

delay(1); // Test, delay(1) before every requestFrom ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  _i2cPort->requestFrom((uint8_t)SCD30_ADDRESS, (uint8_t)2);
  if (_i2cPort->available())
  {
    uint8_t msb = _i2cPort->read();
    uint8_t lsb = _i2cPort->read();
    return ((uint16_t)msb << 8 | lsb);
  }
  return (0); //Sensor did not respond
}

//Sends a command along with arguments and CRC
boolean SCD30::sendCommand(uint16_t command, uint16_t arguments)
{
  uint8_t data[2];
  data[0] = arguments >> 8;
  data[1] = arguments & 0xFF;
  uint8_t crc = computeCRC8(data, 2); //Calc CRC on the arguments only, not the command

  _i2cPort->beginTransmission(SCD30_ADDRESS);
  _i2cPort->write(command >> 8); //MSB
  _i2cPort->write(command & 0xFF); //LSB
  _i2cPort->write(arguments >> 8); //MSB
  _i2cPort->write(arguments & 0xFF); //LSB
  _i2cPort->write(crc);
  if (_i2cPort->endTransmission() != 0)
    return (false); //Sensor did not ACK

  return (true);
}

//Sends just a command, no arguments, no CRC
boolean SCD30::sendCommand(uint16_t command)
{
  _i2cPort->beginTransmission(SCD30_ADDRESS);
  _i2cPort->write(command >> 8); //MSB
  _i2cPort->write(command & 0xFF); //LSB
  if (_i2cPort->endTransmission() != 0)
    return (false); //Sensor did not ACK

  return (true);
}

//Given an array and a number of bytes, this calculate CRC8 for those bytes
//CRC is only calc'd on the data portion (two bytes) of the four bytes being sent
//From: http://www.sunshine2k.de/articles/coding/crc/understanding_crc.html
//Tested with: http://www.sunshine2k.de/coding/javascript/crc/crc_js.html
//x^8+x^5+x^4+1 = 0x31
uint8_t SCD30::computeCRC8(uint8_t data[], uint8_t len)
{
  uint8_t crc = 0xFF; //Init with 0xFF

  for (uint8_t x = 0 ; x < len ; x++)
  {
    crc ^= data[x]; // XOR-in the next input byte

    for (uint8_t i = 0 ; i < 8 ; i++)
    {
      if ((crc & 0x80) != 0)
        crc = (uint8_t)((crc << 1) ^ 0x31);
      else
        crc <<= 1;
    }
  }

  return crc; //No output reflection
}
 
Last edited:
Read this "When I upload the code and check the serial monitor it's giving me no data." seemed to be saying that nothing is printing - suggesting it was hung in setup. Was looking for confirmation the line added to setup completed. Knowing it is printing dots but not showing data is informative.
 
Read this "When I upload the code and check the serial monitor it's giving me no data." seemed to be saying that nothing is printing - suggesting it was hung in setup. Was looking for confirmation the line added to setup completed. Knowing it is printing dots but not showing data is informative.

I understand, sorry for that. So yes, the code is running fine but no data is coming from the sensor
 
See pic, upperleft is the Teensy with 3v3, GND, SDA and SCL to the SCD30 left to right: SDA, SCL, GND, 3v3. It's hard to see because all of the other components. Measured all the connections, no short circuit and everything is wired correctly.

Knipsel.jpg

20190704_124355Copy.jpg
 

Attachments

  • 20190704_124355.jpg
    20190704_124355.jpg
    99.3 KB · Views: 66
Wow, that's a lot of components! Do you have a scope? Observing I2C SCL and SDA in action might be enlightening.

you also might try the i2c_t3 lib in place of Wire lib. It has a Wire.resetBus() that you could add after Wire.begin(). resetBus() sort of does what you have been doing with I2C wires when jumpering to GND and/or 3v3. The lib is installed with Teensyduino.

https://github.com/nox771/i2c_t3

Both Wire and i2c_t3 libs have an I2Cscanner example. Does the scanner example see the I2C device?
 
Last edited:
Is anything else on that i2c bus with the Teensy? If so does anything already have the lines pulled up?

I went to github.com/sparkfun/SparkFun_SCD30_Arduino_Library/ … /Example3_WireOptions.ino#L19
It indicates: Note: 100kHz I2C is fine, but according to the datasheet 400kHz I2C is not supported by the SCD30
Not sure if 100 or 400 Khz is the default? Might try adding: setClock( 100000 );

Yes, i've seen that before and tried the Wire.setClock (100000);

No succes though.
 
Wow, that's a lot of components! Do you have a scope? Observing I2C SCL and SDA in action might be enlightening.

you also might try the i2c_t3 lib in place of Wire lib. It has a Wire.resetBus() that you could add after Wire.begin(). resetBus() sort of does what you have been doing with I2C wires when jumpering to GND and/or 3v3. The lib is installed with Teensyduino.

https://github.com/nox771/i2c_t3

Both Wire and i2c_t3 libs have an I2Cscanner example. Does the scanner example see the I2C device?

Found all my devices with the scanner:

I2C.PNG

Measured the SDA line and it doesn't pull up to 3v3. So there's the problem I guess

I want to try the i2c_t3 library with the SCD30 because the reset makes sense but I don't know how. I replace all the Wire.h for ic2_t3.h but I'm getting this error (what should I change in the library?):

Arduino:1.8.9 (Windows 10), TD: 1.46, Board:"Teensy 3.2 / 3.1, Serial, 96 MHz (overclock), Faster, US English"

In file included from C:\Users\Afstuderen\OneDrive\Arduino\Teensy\Losse sensoren\Sensirion_Co2_sensor__i2c_t3\Sensirion_Co2_sensor__i2c_t3.ino:6:0:

C:\Users\Afstuderen\Documents\Arduino\libraries\SparkFun_SCD30_Arduino_Library\src/SparkFun_SCD30_Arduino_Library.h:59:19: error: 'TwoWire' has not been declared

boolean begin(TwoWire &wirePort = Wire); //By default use Wire port

^

C:\Users\Afstuderen\Documents\Arduino\libraries\SparkFun_SCD30_Arduino_Library\src/SparkFun_SCD30_Arduino_Library.h:87:5: error: 'TwoWire' does not name a type

TwoWire *_i2cPort; //The generic connection to user's chosen I2C hardware

^

C:\Users\Afstuderen\Documents\Arduino\libraries\SparkFun_SCD30_Arduino_Library\src/SparkFun_SCD30_Arduino_Library.h:59:39: error: could not convert 'Wire' from 'i2c_t3' to 'int&'

boolean begin(TwoWire &wirePort = Wire); //By default use Wire port

^

Sensirion_Co2_sensor__i2c_t3: In function 'void setup()':
Sensirion_Co2_sensor__i2c_t3:21: error: invalid initialization of reference of type 'int&' from expression of type 'i2c_t3'
airSensor.begin(); //This will cause readings to occur every two seconds

^

In file included from C:\Users\Afstuderen\OneDrive\Arduino\Teensy\Losse sensoren\Sensirion_Co2_sensor__i2c_t3\Sensirion_Co2_sensor__i2c_t3.ino:6:0:

C:\Users\Afstuderen\Documents\Arduino\libraries\SparkFun_SCD30_Arduino_Library\src/SparkFun_SCD30_Arduino_Library.h:59:13: note: in passing argument 1 of 'boolean SCD30::begin(int&)'

boolean begin(TwoWire &wirePort = Wire); //By default use Wire port

^

invalid initialization of reference of type 'int&' from expression of type 'i2c_t3'


Code:
Code:
#include <i2c_t3.h>

//Click here to get the library: http://librarymanager/All#SparkFun_SCD30
#include "SparkFun_SCD30_Arduino_Library.h"

SCD30 airSensor;

void setup()
{
  Wire.begin(I2C_MASTER, 0x00, I2C_PINS_18_19, I2C_PULLUP_EXT, 100000);
  Wire.setDefaultTimeout(10000); // 10ms
  
  Serial.begin(9600);
  Serial.println("SCD30 Example");

  //Wire.begin();
  //Wire.setClock(100000);

  airSensor.begin(); //This will cause readings to occur every two seconds

  airSensor.setMeasurementInterval(4); //Change number of seconds between measurements: 2 to 1800 (30 minutes)

  //My desk is ~1600m above sealevel
  airSensor.setAltitudeCompensation(1); //Set altitude of the sensor in m

  //Pressure in Boulder, CO is 24.65inHg or 834.74mBar
  airSensor.setAmbientPressure(835); //Current ambient pressure in mBar: 700 to 1200

}

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.print(".");
  delay(1000);
}
 
Found all my devices with the scanner:

View attachment 16938

Measured the SDA line and it doesn't pull up to 3v3. So there's the problem I guess

If you're not seeing 3v3 on SDA, then you need to check your wiring/soldering. Or maybe one of your I2C devices is misbehaving. Can you disconnect each I2C device to identify the faulty device?

As for i2c_t3 compile errors, you need to change ALL #include <Wire.h> to <i2c_t3.h> -- in your sketch and in the Sparkfun lib .cpp and .h files. And in the Sparkfun lib .cpp and .h files, change all TwoWire to i2c_t3
 
Last edited:
If you're not seeing 3v3 on SDA, then you need to check your wiring/soldering. Or maybe one of your I2C devices is misbehaving. Can you disconnect each I2C device to identify the faulty device?

As for i2c_t3 compile errors. You need to change ALL #include <Wire.h> to <i2c_t3.h> -- in your sketch and in the Sparkfun lib .cpp and .h files. And in the Sparkfun lib .cpp and .h files, change all TwoWire to i2c_t3


Wiring is correct, checked it so many times haha.

The i2c_t3 with the reset did it! Thank you sir <3
 
Could you please post the final code/changes in the library you did?

Thanks a lot

Here you go (Code for the SCD30) :) change every <Wire.h> to <i2c_t3.h> and TwoWire to i2C_t3 in the library :)

Code:
#include <i2c_t3.h>

//Click here to get the library: http://librarymanager/All#SparkFun_SCD30
#include "SparkFun_SCD30_Arduino_Library.h"

SCD30 airSensor;

void setup()
{
  Wire.begin(I2C_MASTER, 0x00, I2C_PINS_18_19, I2C_PULLUP_EXT, 100000);
  Wire.setDefaultTimeout(10000); // 10ms
  
  Serial.begin(9600);
  Serial.println("SCD30 Example");

  airSensor.begin(); //This will cause readings to occur every two seconds

  airSensor.setMeasurementInterval(4); //Change number of seconds between measurements: 2 to 1800 (30 minutes)

  //My desk is ~1600m above sealevel
  airSensor.setAltitudeCompensation(1); //Set altitude of the sensor in m

  //Pressure in Boulder, CO is 24.65inHg or 834.74mBar
  airSensor.setAmbientPressure(835); //Current ambient pressure in mBar: 700 to 1200

}

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.print(".");
    Wire.resetBus();
  }
  delay(2000);
}
 
I just wanted to let people know that the sparkfun library has been modified so that only 1 line needs uncommenting. No need to replace the wire.h with i2c_t3.h .
I also wanted to point out that there is a RDY pin on the SCD30 that can be used for sync. Use it to trigger a reading and you "should" be better off all around with the data collection.
 
Status
Not open for further replies.
Back
Top