Close

Adding sensors: Air Quality

A project log for MakeTime

Arduino-compatible development platform whose primary function is a clock

mihai.cuciucmihai.cuciuc 10/23/2021 at 13:470 Comments

Adding a CCS811 sensor, in addition to the SHT31 MakeTime can indicate equivalent total VOC (eTVOC) levels.

Sensor readings are transformed to ug/m^3 and the full scale displayed reads from 0 to 1000 ug/m^3. The higher the reading, the more the display color shifts from green to red.

Arduino sketch

#include <Adafruit_NeoPixel.h>
#include <Wire.h>
#include "Adafruit_CCS811.h"
#include "Adafruit_SHT31.h"


#define LED_PIN    9
#define LED_COUNT 24

Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
Adafruit_CCS811 ccs;
Adafruit_SHT31 sht31 = Adafruit_SHT31();


void setup()
{
  Serial.begin(9600);

  strip.begin();
  strip.show();

  if (! sht31.begin(0x44))   // Set to 0x45 for alternate i2c addr
  {
    strip.setPixelColor(12, 0x00800000);
    strip.show();
    while (1) delay(1);
  }

  if(!ccs.begin())
  {
    strip.setPixelColor(12, 0x00008000);
    strip.show();
    while(1);
  }

  while(!ccs.available());
}

// https://help.atmotube.com/technical/13-atmotube-ppm-ug/
// https://myhealthyhome.info/assets/pdfs/TB531rev2TVOCInterpretation.pdf

void loop()
{
  float t = sht31.readTemperature();
  float h = sht31.readHumidity();
  float voc;
  uint32_t color, displayColor;
  uint8_t vocLevel, i;

  voc = 0;
  if(ccs.available())
  {
    if(!ccs.readData())
    {
      ccs.setEnvironmentalData(h, t);
      voc = ccs.getTVOC() * 100 * 0.0409; // [ug/m^3]
      Serial.print("TVOC [ug/m^3]: ");
      Serial.println(voc);
      vocLevel = round(voc / (1000.0/19));
      
      strip.clear();
      for (i = 0; i < 19; i++)
      {
        if (voc < 200) displayColor = 0x00003000;
        else if (voc < 300) displayColor = 0x00082800;
        else if (voc < 400) displayColor = 0x00102000;
        else if (voc < 500) displayColor = 0x00181800;
        else if (voc < 600) displayColor = 0x00201000;
        else if (voc < 700) displayColor = 0x00280800;
        else displayColor = 0x00300000;
        
        color = 0x00101010;
        if (vocLevel > i) color += displayColor;
        strip.setPixelColor((i + 15) % 24, color);
      }
      strip.show();
    }
  }

  delay(0.5);
}

Discussions