Skip to content

Instantly share code, notes, and snippets.

@brian-lc
Last active February 9, 2021 13:39
Show Gist options
  • Select an option

  • Save brian-lc/ebadbecc0f98b8f90918 to your computer and use it in GitHub Desktop.

Select an option

Save brian-lc/ebadbecc0f98b8f90918 to your computer and use it in GitHub Desktop.
CO2 Sensor Code
#include <Wire.h>
#include "Adafruit_LEDBackpack.h"
#include "Adafruit_GFX.h"
#include <SPI.h>
#include <Adafruit_BLE_UART.h>
#include "DHT.h"
#define ADAFRUITBLE_REQ 10
#define ADAFRUITBLE_RDY 3
#define ADAFRUITBLE_RST 9
#define DHTPIN 8
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
Adafruit_BLE_UART BTLEserial = Adafruit_BLE_UART(ADAFRUITBLE_REQ, ADAFRUITBLE_RDY, ADAFRUITBLE_RST);
Adafruit_24bargraph bar = Adafruit_24bargraph();
int barAddr = 0x70;
int co2Addr = 0x68;
double co2Level = 0;
double prevCO2Level = 300;
double humidity = 0;
double temp = 0;
void setup() {
Wire.begin();
bar.begin(barAddr); // pass in the address
barBands();
delay(5000);
allBarsOff();
BTLEserial.setDeviceName("CO2 v2A"); /* 7 characters max! */
BTLEserial.begin();
dht.begin();
}
aci_evt_opcode_t laststatus = ACI_EVT_DISCONNECTED;
void loop(){
// Tell the nRF8001 to do whatever it should be working on.
BTLEserial.pollACI();
// Ask what is our current status
aci_evt_opcode_t status = BTLEserial.getState();
// Getting the CO2
co2Level = getCO2();
// Reading temperature or humidity takes about 250 milliseconds!
// Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
humidity = dht.readHumidity();
// Read temperature as Celsius
temp = dht.readTemperature(true);
// Transmitting to BLE if available
if (status == ACI_EVT_CONNECTED){
sendCO2OverBLE();
}
if (co2Level > 0){
prevCO2Level = co2Level;
co2Bars(prevCO2Level);
}else{
// sometimes the C02 sensor is busy and returns -1 for readings
// in that case, display last known reading
co2Bars(prevCO2Level);
}
delay(5000); //sleep for a few seconds
}
void sendCO2OverBLE(){
String s = String("C:" + String((int) co2Level) + " T:" + String(temp) + " H:" + String((int) humidity) + "\r");
uint8_t sendbuffer[20];
s.getBytes(sendbuffer, 20);
char sendbuffersize = min(20, s.length());
// write the data
BTLEserial.write(sendbuffer, sendbuffersize);
}
void barBands(){
for (uint8_t b=0; b<24; b++ ){
if (b >= 16) bar.setBar(b, LED_RED);
if ((b >= 8) && (b < 16)) bar.setBar(b, LED_YELLOW);
if (b < 8) bar.setBar(b, LED_GREEN);
}
bar.writeDisplay();
}
void co2Bars(double ppms){
int bmax = 0;
int co2Base = 300; //one green
int co2Max = 2700; //full red 2,400 ppm spread over 24 segments
int barLevel = (int)((ppms - co2Base) / 100);
if (barLevel > 24){
// alert
}
else{
for(uint8_t b=0; b < barLevel; b++){
// Setting color bands of green, yellow, red as CO2 climbs
if (b <= 8){
bar.setBar(b, LED_GREEN);
}
else if(b > 8 && b <= 16){
bar.setBar(b, LED_YELLOW);
}
else if(b > 16) {
bar.setBar(b, LED_RED);
}
}
for(uint8_t b=barLevel; b < 24; b++){
bar.setBar(b, LED_OFF);
}
bar.writeDisplay();
delay(50); //built-in time to settle
}
}
void allBarsOff(){
for (uint8_t b=0; b<24; b++) {
bar.setBar(b, LED_OFF);
bar.writeDisplay();
}
}
double getCO2(){
int co2_value = 0;
Wire.beginTransmission(co2Addr); //0xD0 is Sensor address and read/write bit. 0x68 shifted one bit to left and R/W bit is 0 (Write)
Wire.write(0x22); //0x22 is command number 2 (ReadRAM), and 2 bytes to read
Wire.write(0x00);
Wire.write(0x08);
Wire.write(0x2A); //Checksum 0x2A is calculated as sum of byte 2, 3 and 4
Wire.endTransmission();
delay(20);
Wire.requestFrom(co2Addr,4);
byte i = 0;
byte buffer[4] = {0, 0, 0, 0};
while(Wire.available()) {
buffer[i] = Wire.read();
i++;
}
co2_value = 0;
co2_value |= buffer[1] & 0xFF;
co2_value = co2_value << 8;
co2_value |= buffer[2] & 0xFF;
byte sum = 0; //Checksum Byte
sum = buffer[0] + buffer[1] + buffer[2]; //Byte addition utilizes overflow
if(sum == buffer[3]) {
// Success!
return ((double) co2_value / (double) 1);
}
else{
return (double) -1;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment