Last active
February 9, 2021 13:39
-
-
Save brian-lc/ebadbecc0f98b8f90918 to your computer and use it in GitHub Desktop.
CO2 Sensor Code
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #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