CO2Cube warns about exhaled air and opens a window
The portable cube with a CO2 sensor that opens a window when an air in the room is exhaled
Components and supplies
1
Arduino Nano
Project description
Code
OLEDDisplay
arduino
To operate OLED display
1 2/* 3 * OLED display 128x32 4 * SDA - pin A4 5 * SCK - pin A5 6 * VCC - 3V-5V 7 */ 8 9#include <SPI.h> 10#include <Wire.h> 11#include <Adafruit_GFX.h> 12#include <Adafruit_SSD1306.h> 13 14#define SCREEN_WIDTH 128 // OLED display width, in pixels 15#define SCREEN_HEIGHT 32 // OLED display height, in pixels 16 17#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin) 18Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); 19 20void InitializeOledDisplay() { 21 if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { 22 PlayError(); 23 while(1); 24 } 25 display.dim(true); // set contrast to 31 (reduces consumption to half) 26 DisplayIntro(); 27 //SleepTime(1); 28} 29 30#define shift 55 31#define vertical 12 32 33void DisplayValues(int tempVal, int CO2Val) { 34 display.clearDisplay(); 35 display.setTextColor(WHITE); 36 37 display.setCursor(0,0); //temperature 38 display.setTextSize(1); 39 display.print("Temp:"); 40 display.setCursor(0,vertical); 41 display.setTextSize(2); 42 display.print(tempVal); 43 display.setTextSize(1); 44 display.print("O"); 45 display.setTextSize(2); 46 display.print("C"); 47 48 display.setCursor(shift,0); //CO2 49 display.setTextSize(1); 50 display.print("CO2:"); 51 display.setCursor(shift,vertical); 52 display.setTextSize(3); 53 display.print(CO2Val); 54 55 display.display(); 56} 57 58void DisplayIntro() { 59 display.clearDisplay(); 60 display.setTextColor(WHITE); 61 display.setCursor(0,8); 62 display.setTextSize(2); 63 display.println(" MyCO2Cube"); 64 display.setTextSize(1); 65 display.print(" by Viliam"); 66 display.display(); 67} 68 69void DisplayText(char* text) { 70 display.clearDisplay(); 71 display.setTextColor(WHITE); 72 display.setCursor(0,0); 73 display.setTextSize(1); 74 display.print(text); 75 display.display(); 76 TurnDisplayON(); 77} 78 79void TurnDisplayOFF() { 80 display.ssd1306_command(SSD1306_DISPLAYOFF); 81} 82 83void TurnDisplayON() { 84 display.ssd1306_command(SSD1306_DISPLAYON); 85}
CO2Cube
arduino
Main loop
1/* 2 * 300-400 ppm /v mestách aj viac/ koncentrácia CO2 vo vonkajšom prostredí 3 * do 1000 ppm zdravotne akceptovateľná koncentrácia CO2 4 * 1000-1200 ppm maximálna akceptovateľná úroveň CO2 v interiéri 5 * 1200-1500 ppm pocit vydýchaného vzduchu, začínajú ťažkosti /únava/ 6 * 1500-2000 ppm znížená koncentrácia, únava, ospalosť 7 * 2000-5000 ppm strata pozornosti, zvýšená srdcová frekvencia, bolesti hlavy 8 * nad 25000 ppm začína hroziť smrť udusením 9*/ 10 11#define buttonPin 2 12#define acceptedCO2 1100 13#define stopAirCO2 800 14#define maxTransmitAttempts 5 15#define cycle30mins 225 //30min x 60sec / 8sec sleep = 225x cycle 16#define cycle20hours 9000 //20h x 60min x 60sec / 8sec sleep = 9000x cycle 17 18int CO2Value[3] = {0, 0, 0}; 19int minCO2Value, maxCO2Value; 20int tempValue, prevTempValue, tempCount = 5; 21int getCO2; 22byte countCO2Value = 0; 23volatile bool buttonPushed = false; 24bool start = false, openWindow = false; 25bool transmitFailed = false; 26char transmitText[10]; 27byte transmitAttempt = maxTransmitAttempts; 28long cycle = 0; 29 30void setup() { 31 InitializeLowPower(); 32 InitializeCO2Cube(); 33 InitializeSpeaker(); 34 InitializeOledDisplay(); 35 InitializeTemperature(); 36 InitializeCO2Sensor(); 37 InitializeTransmitter(); 38 InitializeEEPROM(); 39 PlayWarn(); 40} 41 42void InitializeCO2Cube() { 43 pinMode(10, OUTPUT); 44 pinMode(buttonPin, INPUT_PULLUP); 45 attachInterrupt(digitalPinToInterrupt(buttonPin), PushButton, LOW); 46} 47 48void loop() { 49 if (buttonPushed) { 50 detachInterrupt(digitalPinToInterrupt(buttonPin)); 51 DisplayValues(tempValue, CO2Value[countCO2Value]); 52 TurnDisplayON(); 53 TransmitText(String(CO2Value[countCO2Value]).c_str()); 54 SleepTime(1); 55 if (!start) TurnDisplayOFF(); 56 buttonPushed = false; 57 attachInterrupt(digitalPinToInterrupt(buttonPin), PushButton, LOW); 58 } 59 60 tempCount++; 61 if (tempCount > 5) { //saves some energy not to get the temp every time 62 tempValue = GetTemperature(); 63 if (tempValue != prevTempValue) SetTemp(tempValue); 64 tempCount = 0; 65 } 66 67 getCO2 = GetCO2Value(); 68 if (getCO2 > 0) { 69 countCO2Value++; if (countCO2Value > 2) countCO2Value = 0; 70 CO2Value[countCO2Value] = getCO2; 71 72 minCO2Value = min(CO2Value[0], CO2Value[1]); 73 minCO2Value = min(minCO2Value, CO2Value[2]); 74 75 maxCO2Value = max(CO2Value[0], CO2Value[1]); 76 maxCO2Value = max(maxCO2Value, CO2Value[2]); 77 } 78 79 if (!start && (minCO2Value > acceptedCO2)) { //initializes to show high values of CO2 80 start = true; 81 DisplayValues(tempValue, CO2Value[countCO2Value]); 82 TurnDisplayON(); 83 PlayWarn(); 84 OpenWindow(true); 85 } 86 87 if (start && (maxCO2Value > acceptedCO2)) { //shows high values of CO2 88 DisplayValues(tempValue, CO2Value[countCO2Value]); 89 } 90 else { //if values of CO2 are acceptable 91 start = false; 92 TurnDisplayOFF(); 93 } 94 95 if (openWindow && (maxCO2Value < stopAirCO2)) OpenWindow(false); 96 97 if (transmitFailed && (transmitAttempt < maxTransmitAttempts)) { 98 transmitFailed = !TransmitText(transmitText); 99 transmitAttempt++; 100 } 101 102 cycle++; 103 if (cycle > cycle20hours) { //cycle30mins, cycle20hours 104 105 //Use this part after 20 hours when the baseline was already set for the first time 106 cycle = 0; 107 DisplayText("Setting baseline"); 108 PlayWarn(); 109 WriteBaselineToEEPROM(); 110 ResetCO2Sensor(); 111 OpenWindow(false); 112 113 /* 114 //Use this part for the first set of the baseline after 30 minutes on the fresh air 115 cycle = 0; 116 WriteBaselineToEEPROM(); 117 DisplayText("Baseline set"); 118 PlayWarn(); 119 while(1); 120 */ 121 } 122 123 if (!buttonPushed) SleepTime(8); 124} 125 126void OpenWindow(bool b) { 127 openWindow = b; 128 strcpy(transmitText, b? "open" : "close"); 129 transmitFailed = true; 130 transmitAttempt = 0; 131} 132 133void PushButton() { 134 buttonPushed = true; 135}
LOWPower
arduino
Low Power sheet for decreasing consumption
1 2#include <LowPower.h> 3 4/* 5enum period_t { 6 SLEEP_15MS, SLEEP_30MS, SLEEP_60MS, SLEEP_120MS, SLEEP_250MS, SLEEP_500MS, SLEEP_1S, SLEEP_2S, SLEEP_4S, SLEEP_8S, SLEEP_FOREVER}; 7*/ 8 9void InitializeLowPower() { 10 SetClockTo8MHz(); //decrease the consumption of Arduino 11} 12 13void SleepTime(byte sleep) { //puts Arduino into sleep mode 14 switch(sleep) { 15 case 2: 16 LowPower.powerDown(SLEEP_2S, ADC_OFF, BOD_OFF); 17 break; 18 case 4: 19 LowPower.powerDown(SLEEP_4S, ADC_OFF, BOD_OFF); 20 break; 21 case 8: 22 LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF); 23 break; 24 default: 25 LowPower.powerDown(SLEEP_1S, ADC_OFF, BOD_OFF); 26 break; 27 } 28} 29 30void SetClockTo8MHz() { 31 noInterrupts(); 32 CLKPR = 0x80; // (1000 0000) enable change in clock frequency 33 CLKPR = 0x01; // (0000 0001) use clock division factor 2 to reduce the frequency from 16 MHz to 8 MHz, 0x02 is to 4 Mhz, ... 34 interrupts(); 35}
Transmitter
arduino
Serves nRF24L01 transmitter
1/* 2 * nRF24L01 3 */ 4 5#include <SPI.h> 6#include <nRF24L01.h> 7#include <RF24.h> 8 9RF24 transmitter(7, 6); // CE, CSN 10const byte address[6] = "openw"; //address through which two modules communicate. It can be any text of 6 chars 11 12/* 13 * You can try a few software tricks to improve range as well, referenced in the setup function of both Arduino code examples. Power levels are defined by the radio.setPALevel(), and vary between RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH, and RF24_PA_max. 14 151. Set the data rates with the radio.setDataRate() function. RF24_250KBPS signifies 250 kbps, which is the slowest speed available and it offers the longest range of data transmission. RF24_1MBPS signifies 1Mbps and RF24_2MBPS signifies 2 Mbps, giving a higher transfer speed, but less range. 16 172. You can also set the channel of your radio between 2.400 and 2.524 GHz using the radio.setChannel(). At that reading, values of 0-124 correspond to 2.4 GHz plus the channel number in units of MHz. So radio.setChannel(21). Your radio will therefore communicate at 2.421 GHz. While this is a bit more nebulous speed-wise, different channels will certainly give better performance depending on your surrounding environment. Note that 2.483.5 GHz is normally the top legal limit for this type of transmission, so be sure to keep that in mind. 18 */ 19 20void InitializeTransmitter() { 21 transmitter.begin(); 22 23 transmitter.setPALevel(RF24_PA_MIN); //RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH, and RF24_PA_max 24 transmitter.setDataRate(RF24_250KBPS); //RF24_250KBPS, RF24_1MBPS, RF24_2MBPS 25 //transmitter.setChannel(0); //max 80 26 27 transmitter.openWritingPipe(address); 28 transmitter.stopListening(); //Set module as transmitter 29 TransmitText("Hello"); 30} 31 32bool TransmitText(char msg[10]) { 33 bool succesfull = false; 34 byte count = 0; 35 36 transmitter.powerUp(); 37 while (!succesfull && (count < 5)) { 38 succesfull = transmitter.write(msg, strlen(msg)); 39 count++; 40 if (!succesfull) delay(100); 41 } 42 transmitter.powerDown(); 43 return succesfull; 44}
CO2Sensor
arduino
To operate CCS811 sensor
1 2/* 3 * CCS811 sensor 4 * SDA - pin A4 5 * SCK - pin A5 6 * VCC - 3.3V 7 * WAKE - GND or D5 to control SLEEP MODE 8 */ 9 10#include <Adafruit_CCS811.h> 11 12/* 13enum {CCS811_DRIVE_MODE_IDLE = 0x00, CCS811_DRIVE_MODE_1SEC = 0x01, CCS811_DRIVE_MODE_10SEC = 0x02, CCS811_DRIVE_MODE_60SEC = 0x03, CCS811_DRIVE_MODE_250MS = 0x04 }; 14*/ 15 16#define pinCO2Wake 5 17 18Adafruit_CCS811 ccs; 19 20void InitializeCO2Sensor() { 21 pinMode(pinCO2Wake, OUTPUT); 22 digitalWrite(pinCO2Wake, LOW); 23 if (!ccs.begin()) { 24 DisplayText("Failed start CO2 sensor"); 25 PlayError(); 26 while(1); 27 } 28 while(!ccs.available()); 29 //calculate internal temperature 30 float temp = ccs.calculateTemperature(); 31 ccs.setTempOffset(temp - 25.0); 32 33 int i = ReadBaselineFromEEPROM(); 34 ccs.setBaseline(i); 35 36 ccs.setDriveMode(CCS811_DRIVE_MODE_10SEC); 37} 38 39void WakeUpCO2Sensor() { 40 digitalWrite(pinCO2Wake, LOW); 41 delay(10); 42} 43 44void SleepCO2Sensor() { 45 digitalWrite(pinCO2Wake, HIGH); 46} 47 48int GetCO2Value() { 49 int value = 0; 50 WakeUpCO2Sensor(); 51 while ((value == 0) && !buttonPushed) { //wait till sensor gives value 52 if (ccs.available()) { 53 if(!ccs.readData()) value = ccs.geteCO2(); 54 } 55 } 56 SleepCO2Sensor(); 57 return value; 58} 59 60void SetTemp(int tempVal) { 61 WakeUpCO2Sensor(); 62 while (!ccs.available() && !buttonPushed); 63 ccs.setEnvironmentalData(50, tempVal); //humidity + temperature 64 prevTempValue = tempVal; 65 SleepCO2Sensor(); 66} 67 68int ReadCO2Baseline() { 69 return ccs.getBaseline(); 70} 71 72void ResetCO2Sensor() { 73 ccs.SWReset(); 74 InitializeCO2Sensor(); 75 DisplayText("Baseline set"); 76 PlayWarn(); 77}
Temperature
arduino
To operate the temperature sensor
1 2/* 3 * Temperature module KY-001 4 */ 5 6#include <OneWire.h> 7#include <DallasTemperature.h> 8 9#define tempPin 8 10 11OneWire oneWire(tempPin); 12DallasTemperature tempSensor(&oneWire); 13 14void InitializeTemperature() { 15 tempSensor.begin(); 16} 17 18float GetTemperature() { 19 tempSensor.requestTemperatures(); // Send the command to get temperatures 20 return tempSensor.getTempCByIndex(0); //originaly float 21}
Temperature
arduino
To operate the temperature sensor
1 2/* 3 * Temperature module KY-001 4 */ 5 6#include <OneWire.h> 7#include <DallasTemperature.h> 8 9#define tempPin 8 10 11OneWire oneWire(tempPin); 12DallasTemperature tempSensor(&oneWire); 13 14void InitializeTemperature() { 15 tempSensor.begin(); 16} 17 18float GetTemperature() { 19 tempSensor.requestTemperatures(); // Send the command to get temperatures 20 return tempSensor.getTempCByIndex(0); //originaly float 21}
PIN_scheme
arduino
1 2/* CO2Cube 3 * PIN 0 4 * PIN 1 5 * PIN 2 - (INPUT) PushButton wakes up Arduino 6 * PIN 3 7 * PIN 4 8 * PIN 5 - (OUTPUT) Wakes up CCS811 sensor 9 * PIN 6 10 * PIN 7 11 * PIN 8 - Temperature sensor KY-001 12 * PIN 9 - (OUTPUT) Speaker 13 * PIN 10 14 * PIN 11 15 * PIN 12 16 * PIN 13 17 * PIN A0 18 * PIN A1 19 * PIN A2 20 * PIN A3 21 * 22 * PIN A4 - (SDA) CCS811 sensor, OLED display 23 * PIN A5 - (SCL) CCS811 sensor, OLED display 24 * 25 * PIN A6 26 * PIN A7 27 * 28 * GND - battery, Arduino, KY-001, CCS811, Speaker, PushButton 29 * VCC 3.3 - battery, switch, Arduino, KY-001, CCS811 30 */
EEPROM
arduino
Saves CO2 baseline
1 2#include <EEPROM.h> 3 4#define baselineAddress 100 5 6void InitializeEEPROM() { 7} 8 9void WriteBaselineToEEPROM() { 10 int baseline = ReadCO2Baseline(); 11 EEPROM.update(baselineAddress, baseline >> 8); 12 EEPROM.update(baselineAddress + 1, baseline && 0xFF); 13} 14 15int ReadBaselineFromEEPROM() { 16 return (EEPROM.read(baselineAddress) << 8) + EEPROM.read(baselineAddress + 1); 17}
OLEDDisplay
arduino
To operate OLED display
1 2/* 3 * OLED display 128x32 4 * SDA - pin A4 5 * SCK - pin A5 6 7 * VCC - 3V-5V 8 */ 9 10#include <SPI.h> 11#include <Wire.h> 12#include <Adafruit_GFX.h> 13#include 14 <Adafruit_SSD1306.h> 15 16#define SCREEN_WIDTH 128 // OLED display width, in pixels 17#define 18 SCREEN_HEIGHT 32 // OLED display height, in pixels 19 20#define OLED_RESET -1 21 // Reset pin # (or -1 if sharing Arduino reset pin) 22Adafruit_SSD1306 display(SCREEN_WIDTH, 23 SCREEN_HEIGHT, &Wire, OLED_RESET); 24 25void InitializeOledDisplay() { 26 if(!display.begin(SSD1306_SWITCHCAPVCC, 27 0x3C)) { 28 PlayError(); 29 while(1); 30 } 31 display.dim(true); // 32 set contrast to 31 (reduces consumption to half) 33 DisplayIntro(); 34 //SleepTime(1); 35} 36 37#define 38 shift 55 39#define vertical 12 40 41void DisplayValues(int tempVal, int CO2Val) 42 { 43 display.clearDisplay(); 44 display.setTextColor(WHITE); 45 46 display.setCursor(0,0); 47 //temperature 48 display.setTextSize(1); 49 display.print("Temp:"); 50 51 display.setCursor(0,vertical); 52 display.setTextSize(2); 53 display.print(tempVal); 54 55 display.setTextSize(1); 56 display.print("O"); 57 display.setTextSize(2); 58 59 display.print("C"); 60 61 display.setCursor(shift,0); //CO2 62 display.setTextSize(1); 63 64 display.print("CO2:"); 65 display.setCursor(shift,vertical); 66 display.setTextSize(3); 67 68 display.print(CO2Val); 69 70 display.display(); 71} 72 73void DisplayIntro() 74 { 75 display.clearDisplay(); 76 display.setTextColor(WHITE); 77 display.setCursor(0,8); 78 79 display.setTextSize(2); 80 display.println(" MyCO2Cube"); 81 display.setTextSize(1); 82 83 display.print(" by Viliam"); 84 display.display(); 85} 86 87void 88 DisplayText(char* text) { 89 display.clearDisplay(); 90 display.setTextColor(WHITE); 91 92 display.setCursor(0,0); 93 display.setTextSize(1); 94 display.print(text); 95 96 display.display(); 97 TurnDisplayON(); 98} 99 100void TurnDisplayOFF() { 101 102 display.ssd1306_command(SSD1306_DISPLAYOFF); 103} 104 105void TurnDisplayON() 106 { 107 display.ssd1306_command(SSD1306_DISPLAYON); 108}
Speaker
arduino
To operate a speaker
1 2#define speakerPin 9 3#define toneDelay 40 4#define pauseDelay 50 5 6void InitializeSpeaker() { 7 pinMode(speakerPin, OUTPUT); 8} 9 10void Play(int sound) { 11 tone(speakerPin, sound, toneDelay); 12 delay(pauseDelay); 13} 14 15void PlayError() { 16 Play(500); 17 Play(700); 18 Play(500); 19 Play(700); 20 Play(500); 21 Play(700); 22 Play(500); 23 Play(700); 24 Play(500); 25} 26 27void PlayWarn() { 28 Play(1600); 29 Play(800); 30 Play(2400); 31 Play(3000); 32 Play(3500); 33}
CO2Cube
arduino
Main loop
1/* 2 * 300-400 ppm /v mestách aj viac/ koncentrácia CO2 vo vonkajšom 3 prostredí 4 * do 1000 ppm zdravotne akceptovateľná koncentrácia CO2 5 * 1000-1200 6 ppm maximálna akceptovateľná úroveň CO2 v interiéri 7 * 1200-1500 ppm pocit 8 vydýchaného vzduchu, začínajú ťažkosti /únava/ 9 * 1500-2000 ppm znížená koncentrácia, 10 únava, ospalosť 11 * 2000-5000 ppm strata pozornosti, zvýšená srdcová frekvencia, 12 bolesti hlavy 13 * nad 25000 ppm začína hroziť smrť udusením 14*/ 15 16#define 17 buttonPin 2 18#define acceptedCO2 1100 19#define stopAirCO2 800 20#define maxTransmitAttempts 21 5 22#define cycle30mins 225 //30min x 60sec / 8sec sleep = 225x cycle 23#define 24 cycle20hours 9000 //20h x 60min x 60sec / 8sec sleep = 9000x cycle 25 26int 27 CO2Value[3] = {0, 0, 0}; 28int minCO2Value, maxCO2Value; 29int tempValue, prevTempValue, 30 tempCount = 5; 31int getCO2; 32byte countCO2Value = 0; 33volatile bool buttonPushed 34 = false; 35bool start = false, openWindow = false; 36bool transmitFailed = false; 37char 38 transmitText[10]; 39byte transmitAttempt = maxTransmitAttempts; 40long cycle = 41 0; 42 43void setup() { 44 InitializeLowPower(); 45 InitializeCO2Cube(); 46 47 InitializeSpeaker(); 48 InitializeOledDisplay(); 49 InitializeTemperature(); 50 51 InitializeCO2Sensor(); 52 InitializeTransmitter(); 53 InitializeEEPROM(); 54 55 PlayWarn(); 56} 57 58void InitializeCO2Cube() { 59 pinMode(10, OUTPUT); 60 61 pinMode(buttonPin, INPUT_PULLUP); 62 attachInterrupt(digitalPinToInterrupt(buttonPin), 63 PushButton, LOW); 64} 65 66void loop() { 67 if (buttonPushed) { 68 detachInterrupt(digitalPinToInterrupt(buttonPin)); 69 70 DisplayValues(tempValue, CO2Value[countCO2Value]); 71 TurnDisplayON(); 72 73 TransmitText(String(CO2Value[countCO2Value]).c_str()); 74 SleepTime(1); 75 76 if (!start) TurnDisplayOFF(); 77 buttonPushed = false; 78 attachInterrupt(digitalPinToInterrupt(buttonPin), 79 PushButton, LOW); 80 } 81 82 tempCount++; 83 if (tempCount > 5) { //saves 84 some energy not to get the temp every time 85 tempValue = GetTemperature(); 86 87 if (tempValue != prevTempValue) SetTemp(tempValue); 88 tempCount = 0; 89 90 } 91 92 getCO2 = GetCO2Value(); 93 if (getCO2 > 0) { 94 countCO2Value++; 95 if (countCO2Value > 2) countCO2Value = 0; 96 CO2Value[countCO2Value] = getCO2; 97 98 99 minCO2Value = min(CO2Value[0], CO2Value[1]); 100 minCO2Value = 101 min(minCO2Value, CO2Value[2]); 102 103 maxCO2Value = max(CO2Value[0], CO2Value[1]); 104 105 maxCO2Value = max(maxCO2Value, CO2Value[2]); 106 } 107 108 if (!start && 109 (minCO2Value > acceptedCO2)) { //initializes to show high values of CO2 110 start 111 = true; 112 DisplayValues(tempValue, CO2Value[countCO2Value]); 113 TurnDisplayON(); 114 115 PlayWarn(); 116 OpenWindow(true); 117 } 118 119 if (start && (maxCO2Value 120 > acceptedCO2)) { //shows high values of CO2 121 DisplayValues(tempValue, CO2Value[countCO2Value]); 122 123 } 124 else { //if values of CO2 are acceptable 125 start = false; 126 127 TurnDisplayOFF(); 128 } 129 130 if (openWindow && (maxCO2Value < stopAirCO2)) 131 OpenWindow(false); 132 133 if (transmitFailed && (transmitAttempt < maxTransmitAttempts)) 134 { 135 transmitFailed = !TransmitText(transmitText); 136 transmitAttempt++; 137 138 } 139 140 cycle++; 141 if (cycle > cycle20hours) { //cycle30mins, cycle20hours 142 143 144 //Use this part after 20 hours when the baseline was already set for 145 the first time 146 cycle = 0; 147 DisplayText("Setting baseline"); 148 PlayWarn(); 149 150 WriteBaselineToEEPROM(); 151 ResetCO2Sensor(); 152 OpenWindow(false); 153 154 155 /* 156 //Use this part for the first set of the baseline after 30 minutes 157 on the fresh air 158 cycle = 0; 159 WriteBaselineToEEPROM(); 160 DisplayText("Baseline 161 set"); 162 PlayWarn(); 163 while(1); 164 */ 165 } 166 167 if (!buttonPushed) 168 SleepTime(8); 169} 170 171void OpenWindow(bool b) { 172 openWindow = b; 173 strcpy(transmitText, 174 b? "open" : "close"); 175 transmitFailed = true; 176 transmitAttempt = 0; 177} 178 179void 180 PushButton() { 181 buttonPushed = true; 182}
LOWPower
arduino
Low Power sheet for decreasing consumption
1 2#include <LowPower.h> 3 4/* 5enum period_t { 6 SLEEP_15MS, 7 SLEEP_30MS, SLEEP_60MS, SLEEP_120MS, SLEEP_250MS, SLEEP_500MS, SLEEP_1S, SLEEP_2S, 8 SLEEP_4S, SLEEP_8S, SLEEP_FOREVER}; 9*/ 10 11void InitializeLowPower() { 12 13 SetClockTo8MHz(); //decrease the consumption of Arduino 14} 15 16void SleepTime(byte 17 sleep) { //puts Arduino into sleep mode 18 switch(sleep) { 19 case 2: 20 21 LowPower.powerDown(SLEEP_2S, ADC_OFF, BOD_OFF); 22 break; 23 case 24 4: 25 LowPower.powerDown(SLEEP_4S, ADC_OFF, BOD_OFF); 26 break; 27 28 case 8: 29 LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF); 30 break; 31 32 default: 33 LowPower.powerDown(SLEEP_1S, ADC_OFF, BOD_OFF); 34 break; 35 36 } 37} 38 39void SetClockTo8MHz() { 40 noInterrupts(); 41 CLKPR = 0x80; 42 // (1000 0000) enable change in clock frequency 43 CLKPR = 0x01; // (0000 0001) 44 use clock division factor 2 to reduce the frequency from 16 MHz to 8 MHz, 0x02 is 45 to 4 Mhz, ... 46 interrupts(); 47}
PIN_scheme
arduino
1 2/* CO2Cube 3 * PIN 0 4 * PIN 1 5 * PIN 2 - (INPUT) PushButton wakes up Arduino 6 * PIN 3 7 * PIN 4 8 * PIN 5 - (OUTPUT) Wakes up CCS811 sensor 9 * PIN 6 - CSN nRF24L01 10 * PIN 7 - CE nRF24L01 11 * PIN 8 - Temperature sensor KY-001 12 * PIN 9 - (OUTPUT) Speaker 13 * PIN 10 14 * PIN 11 - MOSI nRF24L01 15 * PIN 12 - MISO nRF24L01 16 * PIN 13 - SCK nRF24L01 17 * PIN A0 18 * PIN A1 19 * PIN A2 20 * PIN A3 21 * 22 * PIN A4 - (SDA) CCS811 sensor, OLED display 23 * PIN A5 - (SCL) CCS811 sensor, OLED display 24 * 25 * PIN A6 26 * PIN A7 27 * 28 * GND - battery, Arduino, KY-001, CCS811, Speaker, PushButton, nRF24L01 29 * VCC 3.3 - battery, switch, Arduino, CCS811, nRF24L01, KY-001 30 */
CO2Sensor
arduino
To operate CCS811 sensor
1 2/* 3 * CCS811 sensor 4 * SDA - pin A4 5 * SCK - pin A5 6 * 7 VCC - 3.3V 8 * WAKE - GND or D5 to control SLEEP MODE 9 */ 10 11#include 12 <Adafruit_CCS811.h> 13 14/* 15enum {CCS811_DRIVE_MODE_IDLE = 0x00, CCS811_DRIVE_MODE_1SEC 16 = 0x01, CCS811_DRIVE_MODE_10SEC = 0x02, CCS811_DRIVE_MODE_60SEC = 0x03, CCS811_DRIVE_MODE_250MS 17 = 0x04 }; 18*/ 19 20#define pinCO2Wake 5 21 22Adafruit_CCS811 ccs; 23 24void 25 InitializeCO2Sensor() { 26 pinMode(pinCO2Wake, OUTPUT); 27 digitalWrite(pinCO2Wake, 28 LOW); 29 if (!ccs.begin()) { 30 DisplayText("Failed start CO2 sensor"); 31 32 PlayError(); 33 while(1); 34 } 35 while(!ccs.available()); 36 //calculate 37 internal temperature 38 float temp = ccs.calculateTemperature(); 39 ccs.setTempOffset(temp 40 - 25.0); 41 42 int i = ReadBaselineFromEEPROM(); 43 ccs.setBaseline(i); 44 45 46 ccs.setDriveMode(CCS811_DRIVE_MODE_10SEC); 47} 48 49void WakeUpCO2Sensor() 50 { 51 digitalWrite(pinCO2Wake, LOW); 52 delay(10); 53} 54 55void SleepCO2Sensor() 56 { 57 digitalWrite(pinCO2Wake, HIGH); 58} 59 60int GetCO2Value() { 61 int 62 value = 0; 63 WakeUpCO2Sensor(); 64 while ((value == 0) && !buttonPushed) { 65 //wait till sensor gives value 66 if (ccs.available()) { 67 if(!ccs.readData()) 68 value = ccs.geteCO2(); 69 } 70 } 71 SleepCO2Sensor(); 72 return value; 73} 74 75void 76 SetTemp(int tempVal) { 77 WakeUpCO2Sensor(); 78 while (!ccs.available() && !buttonPushed); 79 80 ccs.setEnvironmentalData(50, tempVal); //humidity + temperature 81 prevTempValue 82 = tempVal; 83 SleepCO2Sensor(); 84} 85 86int ReadCO2Baseline() { 87 return 88 ccs.getBaseline(); 89} 90 91void ResetCO2Sensor() { 92 ccs.SWReset(); 93 InitializeCO2Sensor(); 94 95 DisplayText("Baseline set"); 96 PlayWarn(); 97}
Comments
Only logged in users can leave comments