Skip navigation
> RoadTest Reviews

Sensirion Environmental Sensor Shield - Review

Scoring

Product Performed to Expectations: 10
Specifications were sufficient to design with: 10
Demo Software was of good quality: 10
Product was easy to use: 10
Support materials were available: 10
The price to performance ratio was good: 9
TotalScore: 59 / 60
  • RoadTest: Sensirion Environmental Sensor Shield
  • Buy Now
  • Evaluation Type: Development Boards & Tools
  • Was everything in the box required?: Yes
  • Comparable Products/Other parts you considered: SHT35, MiCS5524, CCS811
  • What were the biggest problems encountered?: Support on SBC is not good, have to dig around to get proper library.

  • Detailed Review:

    Unboxing

     

    First Impression

    This development board looks pretty simple to work with, and it is indeed. It designed with Arduino Uno footprint to work directly stack on Arduino like a shield. But if you have other boards such as Raspberry Pi, Tinker board, Onion. It also provides 4 pin connector for easy 3~5V I2C connection.

     

     

    It has two environmental sensors, SHTC1 and SGP30. SHTC1 measures temperature and humidity, while SGP30 measures TVOCs and CO2 levels. Temperature and humidity are very common in the maker community. SGP30 is something new to me. It is metal oxide (MOX) gas sensor which measures TVOC and CO2.

     

     

    I drew a circuit diagram based on the board. Basically this shield equipped with two level shifter for I2C bus, it can covert the digital signal from 5V/3.3V to 1.8V and vice versa. It can work directly with Arduino Uno or boards with similar footprint. It also has 3 LEDS that can be controlled by Arduino PIN 9, 10, 11. See diagram below. I also attach the schematic at the end. After I drew this, official schematic is available here , but I still want to share my (reverse-engineered) drawing.

     

     

    Here is an overview of what this board offers:

    SGP30 Sensor, Data Sheet https://www.sensirion.com/file/datasheet_sgp30

     

    Key Parameters

    Typical Value

    VDD

    1.8V

    Measurement Current

    48.2mA

    Sleep current

    2µA

    Communication

    I2C

    I2C Address

    0x58

    TVOC Range

    0 ppb to 60000 ppb

    CO2

    400 ppm to 60000 ppm

     

    SHTC1, Data Sheet https://www.sensirion.com/file/datasheet_shtc1

     

    Key Parameters

    Typical Value

    VDD

    1.8V

    Measurement Current

    385µA

    Sleep current

    4.8µA

    Communication

    I2C

    I2C Address

    0x70

    Temperature Range

    -30 to +100°C

    Temperature Accuracy

    ±0.3°C

    Humidity Range

    0 to 100 %RH

    Humidity Accuracy

    ±3.0 %RH

     

     

    TVOC stands for Total Volatile Organic Compound. TVOC is a grouping of wide range of organic chemical compounds including benzene, fossil fuels, methylene chloride, etc. It is a good indicator of indoor air quality. There are several sources of TVOC such as indoor furnishings, new  construction materials, cleaning products. Excessive amount of TVOC may cause health issue for human bodies, such as allergies, asthma, dizziness, nausea and fatigue.

    Here is a chart to indicate the effect of different TVOC levels.

    Details can be found here. (https://www.wikiwand.com/en/Volatile_organic_compound)

     

                                                                                                  TVOC Level Reference

    TVOC [ppb]

    Level

    Recommendation

    Exposure Limit

    2200 – 5500

    5

    Unhealthy

    Use only if unavoidable /

    Intense ventilation necessary

    hours

    660 – 2200

    4

    Poor

    Intensified ventilation / airing necessary

    Search for sources

    < 1 month

    220 – 660

    3

    Moderate

    Intensified ventilation / airing necessary

    Search for sources

    < 12 months

    65 – 220

    2

    Good

    Ventilation / airing recommended

    no limit

    0 – 65

    1

    Excellent

    Target value

    no limit

    Source: TVOC guidelines issued by the German Federal Environmental Agency

     

    Carbon dioxide is a non-toxic and non-flammable gas, but excessive amount of CO2 still may do harm to people’s health, here is a chart for reference.

                                                           CO2 Level Reference

    CO2 [ppm]

    Level

    Effects

    >20%

    8

    Rapid unconsciousness, death

    >10%

    7

    Nausea, vomiting, unconsciousness

    3-8%

    6

    Increased respiration rate, headache

    6,000 – 30,000 ppm

    5

    Concern, short exposure only

    5,000 ppm

    4

    Average exposure limit over 8-hour period

    1,000 ppm

    3

    Tolerable indoor air quality

    600 – 800 ppm

    2

    Acceptable indoor air quality

    350 – 450 ppm

    1

    Typical atmospheric concentration

     

     

    Interfacing

     

    • Arduino

         Setup is pretty easy, basically plug and play.

         Here is my setup.

             

         Currently there are two libraries we can directly use.

             

              1. Official library https://github.com/Sensirion/arduino-ess

                

              Test Results: (Temperature (C), Humidity (%), TVOC (ppb), CO2 (ppm) )

              Note: TVOC and CO2 values are constant 0 and 400 in the first 15 seconds, that's SGP30's internal initialization state for measurement.

    SGP30 detected, running feature set version 32

    26.13 42.86 0.00 400.00

    26.16 42.83 0.00 400.00

    26.16 42.84 0.00 400.00

    26.18 42.83 0.00 400.00

    26.16 42.82 0.00 400.00

    26.17 42.86 0.00 400.00

    26.16 42.88 0.00 400.00

    26.16 42.90 0.00 400.00

    26.18 42.86 0.00 400.00

    26.13 42.82 0.00 400.00

    26.16 42.81 0.00 400.00

    26.16 42.81 0.00 400.00

    26.15 42.84 0.00 400.00

    26.19 42.91 0.00 400.00

    26.18 42.94 0.00 400.00

    26.16 42.99 0.00 400.00

    26.19 42.99 2.00 400.00

    26.18 43.04 5.00 400.00

    26.19 43.08 1.00 403.00

    26.18 43.08 0.00 406.00

    26.19 43.09 0.00 400.00

           2. Adafruit Library for SGP30 https://github.com/adafruit/Adafruit_SGP30

    Test Results: (Temperature (C), Humidity (%), TVOC (ppb), CO2 (ppm) )

    SGP30 test

    Found SGP30 serial #07AE4F3

    TVOC 0 ppb        eCO2 400 ppm

    TVOC 0 ppb        eCO2 400 ppm

    TVOC 0 ppb        eCO2 400 ppm

    TVOC 0 ppb        eCO2 400 ppm

    TVOC 0 ppb        eCO2 400 ppm

    TVOC 0 ppb        eCO2 400 ppm

    TVOC 0 ppb        eCO2 400 ppm

    TVOC 0 ppb        eCO2 400 ppm

    TVOC 0 ppb        eCO2 400 ppm

    TVOC 0 ppb        eCO2 400 ppm

    TVOC 0 ppb        eCO2 400 ppm

    TVOC 0 ppb        eCO2 400 ppm

    TVOC 0 ppb        eCO2 400 ppm

    TVOC 0 ppb        eCO2 400 ppm

    TVOC 0 ppb        eCO2 400 ppm

    TVOC 0 ppb        eCO2 400 ppm

    TVOC 3 ppb        eCO2 404 ppm

    TVOC 6 ppb        eCO2 407 ppm

    TVOC 3 ppb        eCO2 404 ppm

    TVOC 3 ppb        eCO2 400 ppm

    TVOC 5 ppb        eCO2 400 ppm

    TVOC 0 ppb        eCO2 405 ppm

     

    • Raspberry Pi (Circuit Python)

    Setup:

             Directly connect to the 3.3V, GND, SCL, SDA PINS on Raspberry Pi

        

    Use i2cdetect to check connection of the board, if you see 0x58, 0x70, the board is connected.

     

     

    Follow this guide to install circuit python on Raspberry Pi, https://learn.adafruit.com/circuitpython-on-raspberrypi-linux/installing-circuitpython-on-raspberry-pi

     

    By using the Adafruit Circuit Python SGP30 library, you can get this output, Notice first 15 seconds' data are constant 0 and 400 because of chip initialization.

     

    There is no available python library for SHTC1, I wrote a simple one for testing. You can expand to a full library easily using circuit python.

    import board
    import busio
    import time
    from adafruit_bus_device.i2c_device import I2CDevice
    
    i2c = busio.I2C(board.SCL, board.SDA)
    device = I2CDevice(i2c,0x70)
    
    
    
    def _get_data():
        with device:
            device.write(bytes([0x7C,0xA2]), stop=False)
            time.sleep(0.015)
            result = bytearray(6)
            device.readinto(result)
            temp_arr = [result[0],result[1]]
            val = int.from_bytes(temp_arr, byteorder='big', signed=False)
            temp = -45 + 175 * (val / 65535.0);
            hum_arr = [result[3], result[4]]
            val = int.from_bytes(hum_arr, byteorder='big', signed=False)
            hum = 100 * (val / 65535.0)
            return [temp, hum]
    
    while True:
        time.sleep(1)
        [t,h] = _get_data()
        print('temp={0:.3f}, humidity={1:.3f}'.format(t,h))

     

    Here is the ouput:

     

    Environmental Testing

         Setup:

    Sparkfun ESP8266 Thing board + 2000mAh Li-Ion battery + Sensirion ESS + Adafruit IO

    I use the box come with the sensor to create a mobile testing box, and cut two holes for two sensors to expose to the atmosphere. (ignore my bad cutting skill XD)

     

     

    Here is the code for remote monitoring / testing, it's based on Adafruit.io library publish example

    #include "config.h"
    #include <sensirion_ess.h>
    #include <Wire.h>
    
    
    SensirionESS ess;
    
    
    AdafruitIO_Feed *temp = io.feed("sensirion-ess-test.temp");
    AdafruitIO_Feed *hum = io.feed("sensirion-ess-test.hum");
    AdafruitIO_Feed *co2 = io.feed("sensirion-ess-test.co2");
    AdafruitIO_Feed *tvoc = io.feed("sensirion-ess-test.tvoc");
    
    
    int count = 0;
    
    
    void setup() {
    
    
      // start the serial connection
      Serial.begin(115200);
      delay(10000); // let console settle
      // wait for serial monitor to open
      while(! Serial);
    
    
      Serial.print("Connecting to Adafruit IO");
      // connect to io.adafruit.com
      io.connect();
    
    
      // wait for a connection
      while(io.status() < AIO_CONNECTED) {
        Serial.print(".");
        delay(500);
      }
    
    
      // we are connected
      Serial.println();
      Serial.println(io.statusText());
    
    
        if (ess.initSensors() != 0) {
          Serial.print("Error while initializing sensors: ");
          Serial.print(ess.getError());
          Serial.print("\n");
          while (1) { // loop forever
            delay(1000);
            Serial.println("error");
          }
      }
    
    
      int type = ess.getProductType();
      int fsVersion = ess.getFeatureSetVersion();
    
    
      Serial.print((type == SensirionESS::PRODUCT_TYPE_SGP30) ? "SGP30" : "SGPC3");
      Serial.print(" detected, running feature set version ");
      Serial.println(fsVersion);
    
    
    }
    
    
    void loop() {
    
    
      // io.run(); is required for all sketches.
      // it should always be present at the top of your loop
      // function. it keeps the client connected to
      // io.adafruit.com, and processes any incoming data.
      io.run();
    
    
       float temp_val, rh_val, tvoc_val, eco2_val = -1;
    
    
      // we'll start by triggering a measurement of the VOC/CO2 sensor;
      // it's important to do this first to make sure sleep timing is
      // correct. If the command succeeds, the local variables will
      // be set to the values we just read; if it fails, they'll be -1
      if (ess.measureIAQ() != 0) {
        Serial.print("Error while measuring IAQ: ");
        Serial.print(ess.getError());
        Serial.print("\n");
      } else {
        tvoc_val = ess.getTVOC();
        eco2_val = ess.getECO2(); // SGP30 only
      }
    
    
      // next, we'll trigger the humidity and temperature measurement
      if (ess.measureRHT() != 0) {
        Serial.print("Error while measuring RHT: ");
        Serial.print(ess.getError());
        Serial.print("\n");
      } else {
        temp_val = ess.getTemperature();
        rh_val = ess.getHumidity();
      }
    
    
      // finally, let's print those to the serial console
      Serial.print(temp_val);
      Serial.print(" ");
      Serial.print(rh_val);
      Serial.print(" ");
      Serial.print(tvoc_val);
      Serial.print(" ");
      if (ess.getProductType() == SensirionESS::PRODUCT_TYPE_SGP30) {
        Serial.print(eco2_val);
      }
    
    
      Serial.println();
      // and then, we'll use remainingWaitTimeMS() to ensure the correct
      // Measurement rate
      delay(ess.remainingWaitTimeMS());
    
    
      count++;
    
    
      if (count >= 60) {
        count = 0;  
        temp->save(temp_val);
        hum->save(rh_val);
        co2->save(eco2_val);
        tvoc->save(tvoc_val);
      }
      
    }

     

    I collect one full day of data for each environment. It's kind of surprise to see how bad our indoor air quality is.

     

         Bedroom

         Generally the sensor is sensitive enough to capture any changes in a enclosed environment. Whenever an event happens that can increase air circulation, the sensor is able to capture that, such as Opening window, close windows, AC running. So increasing indoor air circulation is the key to maintain a healthy indoor environment.

     

        Baby room

        

         The trend seems similar to the bedroom.

     

        Outdoor

         Outdoor data seems pretty smooth as expected, TVOC is less than 20 ppb most of the time and CO2 is around 400 ppm. A weried thing is that spike in the middle of the day. I guess it's a fly or bug stick on the sensor since it's not a single value that is way over range, it's a series of out-of-range values.

       The out-of-range data sets are like below. It seems like an actual bug than sensor firmware bugs.

    11:18 AM53426
    11:19 AM42406
    11:20 AM81477
    11:21 AM80456
    11:22 AM55412
    11:23 AM79457
    11:25 AM174934
    11:26 AM6175201
    11:27 AM313711169
    11:28 AM17723811
    11:29 AM10132031
    11:30 AM6801502
    11:31 AM4821011
    11:32 AM371856
    11:33 AM3861061
    11:35 AM333739
    11:36 AM233533
    11:37 AM284726
    11:38 AM219506

    Basement

        Our basement is not finished, it is a more or less enclosed environment. The data seems pretty smooth. It is more like a human indicator. When we are at home, the CO2 and TVOC level begin to climb slowly, when we left home, they began to drop.

    Mobile Environmental Testing Box

       I use a OLED from Amazon and this shield to build a simple environmental testing box, it can display current envriomental data readings and push the data to the cloud. (adafruit.io)

      Components:

         NodeMCU 1.0

         LiPo 1000mAh

         0.96" OLED Display

         Sensirion ESS

        

      Diagram:

            

     

    Code:

     

     

    #include "config.h"
    #include <sensirion_ess.h>
    #include <Wire.h>
    #include <Adafruit_GFX.h>
    #include <Adafruit_SSD1306.h>
    
    
    #define OLED_RESET LED_BUILTIN //4
    Adafruit_SSD1306 display(OLED_RESET);
    
    
    #define NUMFLAKES 10
    #define XPOS 0
    #define YPOS 1
    #define DELTAY 2
    
    
    
    
    #define LOGO16_GLCD_HEIGHT 16 
    #define LOGO16_GLCD_WIDTH  16 
    static const unsigned char PROGMEM logo16_glcd_bmp[] =
    { B00000000, B11000000,
      B00000001, B11000000,
      B00000001, B11000000,
      B00000011, B11100000,
      B11110011, B11100000,
      B11111110, B11111000,
      B01111110, B11111111,
      B00110011, B10011111,
      B00011111, B11111100,
      B00001101, B01110000,
      B00011011, B10100000,
      B00111111, B11100000,
      B00111111, B11110000,
      B01111100, B11110000,
      B01110000, B01110000,
      B00000000, B00110000 };
    
    
    #if (SSD1306_LCDHEIGHT != 64)
    #error("Height incorrect, please fix Adafruit_SSD1306.h!");
    #endif
    //  Create an instance of SensirionESS
    SensirionESS ess;
    /************************ Example Starts Here *******************************/
    
    
    // this int will hold the current count for our sketch
    
    
    // set up the 'counter' feed
    AdafruitIO_Feed *temp = io.feed("sensirion-ess-test.temp");
    AdafruitIO_Feed *hum = io.feed("sensirion-ess-test.hum");
    AdafruitIO_Feed *co2 = io.feed("sensirion-ess-test.co2");
    AdafruitIO_Feed *tvoc = io.feed("sensirion-ess-test.tvoc");
    
    
    int count = 0;
    
    
    void setup() {
    
    
      // start the serial connection
      Serial.begin(115200);
      delay(10000); // let console settle
      // wait for serial monitor to open
      while(! Serial);
    
    
      Serial.print("Connecting to Adafruit IO");
    
    
      display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  // initialize with the I2C addr 0x3D (for the 128x64)
    
    
      // connect to io.adafruit.com
      io.connect();
    
    
      // wait for a connection
      while(io.status() < AIO_CONNECTED) {
        Serial.print(".");
        delay(500);
      }
    
    
      // we are connected
      Serial.println();
      Serial.println(io.statusText());
    
    
        if (ess.initSensors() != 0) {
          Serial.print("Error while initializing sensors: ");
          Serial.print(ess.getError());
          Serial.print("\n");
          while (1) { // loop forever
            delay(1000);
            Serial.println("error");
          }
      }
    
    
      int type = ess.getProductType();
      int fsVersion = ess.getFeatureSetVersion();
    
    
      Serial.print((type == SensirionESS::PRODUCT_TYPE_SGP30) ? "SGP30" : "SGPC3");
      Serial.print(" detected, running feature set version ");
      Serial.println(fsVersion);
    
    
    }
    
    
    void display_on_oled(float t, float rh, float tvoc, float co2) {
      // Clear the buffer.
      display.clearDisplay();
      display.setTextSize(2);
      display.setTextColor(WHITE);
      display.setCursor(0,0);
      display.print("Temp:"); 
      display.println(t,2);
      display.print("Hum:");
      display.println(rh,2);
      display.setTextSize(2);
      display.setTextColor(WHITE);
      display.print("TVOC:"); 
      display.println(tvoc,2);
      display.print("CO2:");
      display.println(co2,2);
      display.display();
    }
    
    
    void loop() {
    
    
      // io.run(); is required for all sketches.
      // it should always be present at the top of your loop
      // function. it keeps the client connected to
      // io.adafruit.com, and processes any incoming data.
      io.run();
    
    
       float temp_val, rh_val, tvoc_val, eco2_val = -1;
    
    
      // we'll start by triggering a measurement of the VOC/CO2 sensor;
      // it's important to do this first to make sure sleep timing is
      // correct. If the command succeeds, the local variables will
      // be set to the values we just read; if it fails, they'll be -1
      if (ess.measureIAQ() != 0) {
        Serial.print("Error while measuring IAQ: ");
        Serial.print(ess.getError());
        Serial.print("\n");
      } else {
        tvoc_val = ess.getTVOC();
        eco2_val = ess.getECO2(); // SGP30 only
      }
    
    
      // next, we'll trigger the humidity and temperature measurement
      if (ess.measureRHT() != 0) {
        Serial.print("Error while measuring RHT: ");
        Serial.print(ess.getError());
        Serial.print("\n");
      } else {
        temp_val = ess.getTemperature();
        rh_val = ess.getHumidity();
      }
    
    
      // finally, let's print those to the serial console
      Serial.print(temp_val);
      Serial.print(" ");
      Serial.print(rh_val);
      Serial.print(" ");
      Serial.print(tvoc_val);
      Serial.print(" ");
      if (ess.getProductType() == SensirionESS::PRODUCT_TYPE_SGP30) {
        Serial.print(eco2_val);
      }
    
    
      display_on_oled(temp_val, rh_val, tvoc_val, eco2_val);
      
      Serial.println();
      // and then, we'll use remainingWaitTimeMS() to ensure the correct
      // Measurement rate
      delay(ess.remainingWaitTimeMS());
    
    
      count++;
    
    
      if (count >= 60) {
        count = 0;  
        temp->save(temp_val);
        hum->save(rh_val);
        co2->save(eco2_val);
        tvoc->save(tvoc_val);
      }
      
    }

     

       Build & Results:

        

    Summary

    I have tested Sensirion Environmental Sensor Shield on both MCUs (Arduino Uno and ESP8266) and SBC (Raspberry Pi). It is basically plug-and-play in Arduino Eco System, the library is capable of providing accurate results. When using ESP8266, make sure you remove LED controlling codes in the official library because they are not compatible as of now.

     

    While working on Linux, I need a bit of tinkering to get the board working correctly with the help of CircuitPython, but not too much pain. Thank you winkj for the Arduino ESS library and Adafruit IO for providing CircuitPython and SGP30 python library.

     

    I like the hardware design of the board because it provides on-board level shifter so everyone from the 3.3V / 5V world can talk to 1.8V sensors easily.

     

    For the sensors data testing, since I don't have other sensors for comparison, I test multiple locations around my house to see if the results make sense. It turns out it met my expectation. While there is a human activity, the TVOC and CO2 level will increase slightly. Air circulation will greatly help improving indoor air quality. I may perform a lab test for SHTC1 if I have a chance later. I will keep the results posted.

     

    Thanks for your time.

     

    Let me know if you have any questions or suggestions.


Comments

Also Enrolling

Enrollment Closes: Dec 19 
Enroll
Enrollment Closes: Dec 13 
Enroll
Enrollment Closes: Dec 27 
Enroll
Enrollment Closes: Dec 27 
Enroll
Enrollment Closes: Dec 26 
Enroll