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
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.