Co2 sensor recommendations

boron
Tags: #<Tag:0x00007fe2260ddb20>

#1

Hi
I looking for a reliable CO2 sensor with available library to use with Gen3 Particle. Can be I2C or analog, just need to be able to have input voltage 3.3 or 5v. I look for a sensor with a cover like tube to be able to mount directly under an enclosure without extra cable. The range can be 2000, 5000 or 10 000ppm and budget max $100 for the sensor.

I see the MH-Z16 it’s look good but I never tested it. The MG-811 it’s also one I looked but I don’t know if I can fit in in my enclosure design. The sensor will using in a high humidity area ~80-85%

Thanks for your suggestions


#2

@steeves I’ve played around with a few. They’re combination TVOC/C02 sensors which are quite cheap. The one that I’ve found the most reliable is the CCS811.

Here’s some others that you can look into:

MICS-VZ-89TE
GY-MCU680V1
Senseair S8-0053
MH-Z14A
SGP30
BME680

These came from a long conversation I had with one of the members on another forum. The full thread is here.

I also did a comparison of some of the cheaper silicon based parts (CCS811, BME680 & SGP30) here.

Hopefully it will help save you some trouble in finding the best one for your application!


#3

Thanks @jaredwolff about the CCS811, it does provide PPM output ? It’s look like eCO2 with a range of 400 to 8192 ppm. Using a breakout sensor, I understand that I’ll need to put the sensor inside of my enclosure and drill some holes to have a good measurements instead of find a sensor like a probe. it’s correct ?


#4

Is a garbage sensor that drifts all over the place based on my and other experiences with it over time.

SGP30 senor is super stable from my testing over the last 6 months. Go with that one if you want to try one of these Voc/Co2 senors.


#5

@RWB first I look for 0-2000 or 0-5000 PPM sensor. SGP30 it’s output as PPM ? thanks


#6

I have the Co2 readings at 0-2500ppm.

https://app.losant.com/dashboards/599c9a05b36c040007c6e20c


#7

ok thanks.

and in the same orientation, temp-hum sensor, you propose which one ? My environment is very high humidity. SHT31-D ?


#8

Yes that’s the temp humidity sensor I use and it works great.


#9

Thank you, thread solved.


#10

Yes and yes. Without adequate airflow you’re not going to get accurate results.

@RWB how long ago did you use the CCS811? I’ve actually seen more variation with the SGP30. (In particular, temperature variance)

@steeves just remember that these devices estimate c02. Supposedly the IR based ones are more accurate. All depends on your application though!!

Also these sensors do depend on an external temperature sensor. I ended up using a Si7021 for my breakout board. All the code is open source.


#11

I used it for like 6 months, it was worthless even with trying different libraries and different sensors. @ScruffR had the same experience along with a few other guys in my search to fix it.

I have the SPG30 temp and humidity compensated via code. There is a great library on Hackster for the SPG30 that takes full advantage of the sensors features.


#12

Oy. That sucks that you guys had a hard time with it.

I’ve been away from home for almost 2 months. I’ve had several sensors running side by side (CCS811 with v2.0 firmware), SGP30 and BME680. The CCS811 readings seemed to be more reasonable.

Considering y’all have had such good luck with the SGP part. I’ll have to revisit my code. Could be something silly that I overlooked.


#13

@jaredwolff @steeves

Here is the library you want to use with the SGP30 for best results and to take advantage of all it’s features.


#14

@RWB I tested your code today with a sensor SHT20 instead of SHT31-D because I don’t have and all working great. Thanks


#15

Yea man the code works great!

If you ever see the VOC go peak out to the max reading due to getting the sensor wet by accident you can log into the Particle Console and reset the VOC baseline by sending 1 to the exposed Baseline variable.


#16

Got it thanks


#17

Hi @RWB just updated my VCode to 1.5.0 Workbench, Core and I can’t now compile your code. All working great before :frowning:

compiling code for argon
Targeting version: 1.2.1

Including:
    lib/SensirionSGP30/src/SensirionSGP30.h
    lib/sht20/src/DFRobot_SHT20.h
    lib/SensirionSGP30/examples/sgp30test/sgp30test.ino
    lib/sht20/examples/DFRobot_SHT20_test/DFRobot_SHT20_test.ino
    src/npx-gen3-air-quality-co2-temp-v1.ino
    lib/SensirionSGP30/src/SensirionSGP30.cpp
    lib/sht20/src/DFRobot_SHT20.cpp
    src/npx-gen3-air-quality-co2-temp-v1.cpp
    project.properties
attempting to compile firmware 

Processing  lib/SensirionSGP30/examples/sgp30test/sgp30test.ino
Processing  lib/sht20/examples/DFRobot_SHT20_test/DFRobot_SHT20_test.ino
Processing  src/npx-gen3-air-quality-co2-temp-v1.ino
Checking library SensirionSGP30...
Checking library sht20...
Installing library sht20 1.0.0 to lib/sht20 ...
Installing library SensirionSGP30 1.0.4 to lib/SensirionSGP30 ...
Library sht20 1.0.0 installed.
Library SensirionSGP30 1.0.4 installed.
make -C ../modules/argon/user-part all
make[1]: Entering directory '/firmware/modules/argon/user-part'

mkdir -p target/
make -f ../../../modules/shared/nRF52840/build_linker_script.mk PREBUILD=1
make[2]: Entering directory '/firmware/modules/argon/user-part'
Creating target/module_user_memory.ld ...
make[2]: Leaving directory '/firmware/modules/argon/user-part'

make -C ../../../user 
make[2]: Entering directory '/firmware/user'
Building cpp file: src/npx-gen3-air-quality-co2-temp-v1.cpp
Invoking: ARM GCC CPP Compiler
mkdir -p ../build/target/user/platform-12-msrc/
arm-none-eabi-gcc -DSTM32_DEVICE -DnRF52840 -DNRF52840_XXAA -DPLATFORM_THREADING=1 -DPLATFORM_ID=12 -DPLATFORM_NAME=argon -DUSBD_VID_SPARK=0x2B04 -DUSBD_PID_DFU=0xD00C -DUSBD_PID_CDC=0xC00C -DSPARK_PLATFORM -g3 -gdwarf-2 -Os -mcpu=cortex-m4 -mthumb -mabi=aapcs -mfloat-abi=hard -mfpu=fpv4-sp-d16 -DINCLUDE_PLATFORM=1 -DSOFTDEVICE_PRESENT=1 -DS140 -DPRODUCT_ID=12 -DPRODUCT_FIRMWARE_VERSION=65535 -DOPENTHREAD_PROJECT_CORE_CONFIG_FILE=\"openthread-config-project.h\" -DENABLE_FEM=1 -DNRF_802154_PROJECT_CONFIG=\"openthread-platform-config.h\" -DRAAL_SOFTDEVICE=1 -D_WIZCHIP_=W5500 -DUSE_STDPERIPH_DRIVER -DDFU_BUILD_ENABLE -DLFS_CONFIG=lfs_config.h -DSYSTEM_VERSION_STRING=1.2.1 -DRELEASE_BUILD -I./inc -I../wiring/inc -I../system/inc -I../third_party/miniz/miniz -I../services/inc -I../third_party/nanopb/nanopb -I../communication/src -I../hal/inc -I../hal/shared -I../hal/src/argon -I../hal/network/lwip/esp32 -I../hal/src/nRF52840 -I../hal/src/armv7 -I../hal/src/nRF52840 -I../hal/src/nRF52840/lwip -I../hal/src/nRF52840/freertos -I../hal/src/nRF52840/openthread -I../hal/src/nRF52840/mbedtls -I../hal/src/nRF52840/littlefs -I../hal/network/api -I../hal/network/lwip -I../hal/network/lwip/posix -I../hal/network/openthread -I../hal/network/lwip/wiznet -I../hal/network/ncp -I../hal/network/ncp/at_parser -I../third_party/lwip/lwip/src/include -I../third_party/freertos/freertos/FreeRTOS/Source/include -I../third_party/nrf5_sdk/nrf5_sdk/external/freertos/portable/GCC/nrf52 -I../third_party/nrf5_sdk/nrf5_sdk/external/freertos/portable/CMSIS/nrf52 -I../third_party/openthread/openthread/include -I../third_party/openthread/openthread/src/core -I../third_party/openthread/openthread/examples/platforms -I../third_party/openthread/openthread/third_party/NordicSemiconductor/drivers/radio -I../third_party/openthread/openthread/third_party/NordicSemiconductor/drivers/radio/hal -I../third_party/openthread/openthread/third_party/NordicSemiconductor/drivers/radio/rsch -I../third_party/openthread/openthread/third_party/NordicSemiconductor/drivers/radio/rsch/raal -I../third_party/openthread/openthread/third_party/NordicSemiconductor/drivers/radio/rsch/raal/softdevice -I../third_party/wiznet_driver/wiznet_driver/Ethernet -I../gsm0710muxer/gsm0710muxer/include -I../platform/shared/inc -I../third_party/nrf5_sdk -I../third_party/nrf5_sdk/nrf5_sdk/components/toolchain/cmsis/include -I../third_party/nrf5_sdk/nrf5_sdk/modules/nrfx -I../third_party/nrf5_sdk/nrf5_sdk/modules/nrfx/drivers -I../third_party/nrf5_sdk/nrf5_sdk/modules/nrfx/drivers/include -I../third_party/nrf5_sdk/nrf5_sdk/modules/nrfx/hal -I../third_party/nrf5_sdk/nrf5_sdk/modules/nrfx/mdk -I../third_party/nrf5_sdk/nrf5_sdk/modules/nrfx/hal -I../third_party/nrf5_sdk/nrf5_sdk/modules/nrfx/drivers/src/prs -I../third_party/nrf5_sdk/nrf5_sdk/components/libraries/util -I../third_party/nrf5_sdk/nrf5_sdk/components/softdevice/s140/headers -I../third_party/nrf5_sdk/nrf5_sdk/components/softdevice/s140/headers/nrf52 -I../third_party/nrf5_sdk/nrf5_sdk/components/softdevice/common -I../third_party/nrf5_sdk/nrf5_sdk/components/libraries/fstorage -I../third_party/nrf5_sdk/nrf5_sdk/components/libraries/experimental_section_vars -I../third_party/nrf5_sdk/nrf5_sdk/components/libraries/atomic -I../third_party/nrf5_sdk/nrf5_sdk/components/libraries/crc32 -I../third_party/nrf5_sdk/nrf5_sdk/integration/nrfx/legacy -I../third_party/nrf5_sdk/nrf5_sdk/components/libraries/delay -I../third_party/nrf5_sdk/nrf5_sdk/components/libraries/log -I../third_party/nrf5_sdk/nrf5_sdk/components/libraries/log -I../third_party/nrf5_sdk/nrf5_sdk/components/libraries/log/src -I../third_party/nrf5_sdk/nrf5_sdk/components/libraries/experimental_section_vars -I../third_party/nrf5_sdk/nrf5_sdk/components/libraries/atomic -I../third_party/nrf5_sdk/nrf5_sdk/components/libraries/delay -I../third_party/nrf5_sdk/nrf5_sdk/components/libraries/queue -I../third_party/nrf5_sdk/nrf5_sdk/components/softdevice/common -I../third_party/nrf5_sdk/nrf5_sdk/components/softdevice/mbr/nrf52840/headers -I../third_party/nrf5_sdk/nrf5_sdk/components/softdevice/s140 -I../third_party/nrf5_sdk/nrf5_sdk/components/softdevice/s140/headers -I../third_party/nrf5_sdk/nrf5_sdk/components/softdevice/s140/headers/nrf52 -I../third_party/nrf5_sdk/nrf5_sdk/components/libraries/fifo -I../third_party/nrf5_sdk/nrf5_sdk/components/libraries/atomic_fifo -I../third_party/nrf5_sdk/nrf5_sdk/components/libraries/strerror -I../third_party/nrf5_sdk/nrf5_sdk/components/libraries/fstorage -I../third_party/nrf5_sdk/nrf5_sdk/components/libraries/atomic_flags -I../third_party/nrf5_sdk/nrf5_sdk/components/libraries/usbd -I../third_party/nrf5_sdk/nrf5_sdk/components/libraries/usbd/class/cdc -I../third_party/nrf5_sdk/nrf5_sdk/components/libraries/usbd/class/cdc/acm -I../third_party/nrf5_sdk/nrf5_sdk/components/ble/common -I../third_party/nrf5_sdk/nrf5_sdk/components/ble/nrf_ble_gatt -I../third_party/nrf5_sdk/nrf5_sdk/components/ble/ble_advertising -I../third_party/nrf5_sdk/nrf5_sdk/external/nrf_cc310/include -I../third_party/nrf5_sdk/nrf5_sdk/external/utf_converter -I../third_party/littlefs/littlefs -I../platform/MCU/nRF52840/inc -I../dynalib/inc -Isrc -I./libraries -Ilib/sht20/src -Ilib/SensirionSGP30/src -I. -MD -MP -MF ../build/target/user/platform-12-msrc/npx-gen3-air-quality-co2-temp-v1.o.d -ffunction-sections -fdata-sections -Wall -Wno-switch -Wno-error=deprecated-declarations -fmessage-length=0 -fno-strict-aliasing -DSPARK=1 -DPARTICLE=1 -Wundef -DSTART_DFU_FLASHER_SERIAL_SPEED=14400 -DSTART_YMODEM_FLASHER_SERIAL_SPEED=28800 -DSPARK_PLATFORM_NET=ESP32 -fno-builtin-malloc -fno-builtin-free -fno-builtin-realloc  -DLOG_INCLUDE_SOURCE_INFO=1 -DPARTICLE_USER_MODULE -DUSER_FIRMWARE_IMAGE_SIZE=0x20000 -DUSER_FIRMWARE_IMAGE_LOCATION=0xD4000 -DMODULAR_FIRMWARE=1 -DMODULE_VERSION=6 -DMODULE_FUNCTION=5 -DMODULE_INDEX=1 -DMODULE_DEPENDENCY=4,1,1213 -DMODULE_DEPENDENCY2=0,0,0 -D_WINSOCK_H -D_GNU_SOURCE -DLOG_MODULE_CATEGORY="\"app\""  -fno-exceptions -fno-rtti -fcheck-new -std=gnu++14 -c -o ../build/target/user/platform-12-msrc/npx-gen3-air-quality-co2-temp-v1.o src/npx-gen3-air-quality-co2-temp-v1.cpp
src/npx-gen3-air-quality-co2-temp-v1.ino: In function 'void publishMeasurementData(const MeasurementData&)':
src/npx-gen3-air-quality-co2-temp-v1.ino:183:33: warning: 'memset' used with constant zero length parameter; this could be due to transposed parameters [-Wmemset-transposed-args]
     memset(data, sizeof(data), 0);
                                 ^
src/npx-gen3-air-quality-co2-temp-v1.ino: In function 'void setup()':
src/npx-gen3-air-quality-co2-temp-v1.ino:258:13: error: a function-definition is not allowed here before '{' token
 void loop() {
             ^
src/npx-gen3-air-quality-co2-temp-v1.ino:270:1: error: expected '}' at end of input
 }
 ^
../build/module.mk:277: recipe for target '../build/target/user/platform-12-msrc/npx-gen3-air-quality-co2-temp-v1.o' failed
make[2]: Leaving directory '/firmware/user'
make[2]: *** [../build/target/user/platform-12-msrc/npx-gen3-air-quality-co2-temp-v1.o] Error 1
../../../build/recurse.mk:11: recipe for target 'user' failed
make[1]: Leaving directory '/firmware/modules/argon/user-part'
	at makeError (/Users/steeves/.vscode/extensions/particle.particle-vscode-core-1.5.0/node_modules/execa/index.js:174:9)
	at module.exports.Promise.all.then.arr (/Users/steeves/.vscode/extensions/particle.particle-vscode-core-1.5.0/node_modules/execa/index.js:278:16)

- - - -

#18

I’ll have to rely on Master @ScruffR for help on this one.


#19

ok. While I’ll use my others laptop (not updated Core) :wink:


#20

Perhaps you’re missing a closing curly bracket?