Last active
June 2, 2017 13:46
-
-
Save tomtor/d63fb0eef60ed15d5c67d220e524acdc to your computer and use it in GitHub Desktop.
CCS811 low power Arduino sketch
This file contains 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
/*************************************************** | |
This is an example for the CCS811 digital TVOC/eCO2 Sensor by CCMOSS/AMS | |
http://www.ccmoss.com/gas-sensors#CCS811 | |
Updated: March 28, 2017 | |
The sensor uses I2C protocol to communicate, and requires 2 pins - SDA and SCL | |
Another GPIO is also required to assert the WAKE pin for communication. this | |
pin is passed by an argument in the begin function. | |
A breakout board is available: https://github.com/AKstudios/CCS811-Breakout | |
The ADDR pin on the sensor can be connected to VCC to set the address as 0x5A. | |
The ADDR pin on the sensor can be connected to GND to set the address as 0x5B. | |
Written by Akram Ali from AKstudios (www.akstudios.com) | |
GitHub: https://github.com/AKstudios/ | |
STM32 Sleep and low power code by Tom Vijlbrief | |
****************************************************/ | |
#include <CCS811.h> | |
#define ADDR 0x5A | |
//#define ADDR 0x5B | |
#define WAKE_PIN PB12 | |
// Defined for power and sleep functions pwr.h and scb.h | |
#include <libmaple/pwr.h> | |
#include <libmaple/scb.h> | |
#include <RTClock.h> | |
RTClock rt(RTCSEL_LSI, 39); // 1 milli second alarm | |
void sleepMode(bool deepSleepFlag) | |
{ | |
// Clear PDDS and LPDS bits | |
PWR_BASE->CR &= PWR_CR_LPDS | PWR_CR_PDDS | PWR_CR_CWUF; | |
// Set PDDS and LPDS bits for standby mode, and set Clear WUF flag (required per datasheet): | |
PWR_BASE->CR |= PWR_CR_CWUF; | |
// Enable wakeup pin bit. | |
PWR_BASE->CR |= PWR_CSR_EWUP; | |
SCB_BASE->SCR |= SCB_SCR_SLEEPDEEP; | |
// System Control Register Bits. See... | |
// http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0497a/Cihhjgdh.html | |
if (deepSleepFlag) { | |
// Set Power down deepsleep bit. | |
PWR_BASE->CR |= PWR_CR_PDDS; | |
// Unset Low-power deepsleep. | |
PWR_BASE->CR &= ~PWR_CR_LPDS; | |
} else { | |
adc_disable(ADC1); | |
adc_disable(ADC2); | |
#if STM32_HAVE_DAC | |
dac_disable_channel(DAC, 1); | |
dac_disable_channel(DAC, 2); | |
#endif | |
// Unset Power down deepsleep bit. | |
PWR_BASE->CR &= ~PWR_CR_PDDS; | |
// set Low-power deepsleep. | |
PWR_BASE->CR |= PWR_CR_LPDS; | |
} | |
// Now go into stop mode, wake up on interrupt | |
asm(" wfi"); | |
// Clear SLEEPDEEP bit so we can use SLEEP mode | |
SCB_BASE->SCR &= ~SCB_SCR_SLEEPDEEP; | |
} | |
void setSpeed() | |
{ | |
#if F_CPU == 8000000UL | |
// nothing to do, using about 8 mA | |
#elif F_CPU == 16000000UL | |
rcc_clk_init(RCC_CLKSRC_HSI, RCC_PLLSRC_HSE , RCC_PLLMUL_2); | |
#elif F_CPU == 48000000UL | |
rcc_clk_init(RCC_CLKSRC_HSI, RCC_PLLSRC_HSE , RCC_PLLMUL_6); | |
#elif F_CPU == 72000000UL | |
rcc_clk_init(RCC_CLKSRC_HSI, RCC_PLLSRC_HSE , RCC_PLLMUL_9); | |
#else | |
#error "Unknown F_CPU!?" | |
#endif | |
} | |
int sleepTime; | |
void AlarmFunction () { | |
// We always wake up with the 8Mhz HSI clock! | |
// So adjust the clock if needed... | |
setSpeed(); | |
extern volatile uint32 systick_uptime_millis; | |
systick_uptime_millis += sleepTime; | |
} | |
void mdelay(int n, bool mode = false) | |
{ | |
sleepTime = n; | |
const int interval = 10000; | |
while (n > 0) { | |
//iwdg_feed(); | |
time_t nextAlarm = rt.getTime() + (n > interval ? interval : n); // Calculate from time now. | |
rt.createAlarm(&AlarmFunction, nextAlarm); | |
sleepMode(mode); | |
n -= interval; | |
} | |
} | |
void msleep(uint32_t ms) | |
{ | |
uint32_t start = rt.getTime(); | |
while (rt.getTime() - start < ms) { | |
asm(" wfi"); | |
} | |
} | |
void allInput() | |
{ | |
adc_disable(ADC1); | |
adc_disable(ADC2); | |
pinMode(PA0, INPUT_ANALOG); | |
pinMode(PA1, INPUT_ANALOG); | |
pinMode(PA2, INPUT_ANALOG); | |
pinMode(PA3, INPUT_ANALOG); | |
pinMode(PA4, INPUT_ANALOG); | |
pinMode(PA5, INPUT_ANALOG); | |
pinMode(PA6, INPUT_ANALOG); | |
pinMode(PA7, INPUT_ANALOG); | |
pinMode(PA8, INPUT_ANALOG); | |
pinMode(PA9, INPUT_ANALOG); | |
pinMode(PA10, INPUT_ANALOG); | |
pinMode(PA11, INPUT_ANALOG); | |
pinMode(PA12, INPUT_ANALOG); | |
pinMode(PA13, INPUT_ANALOG); | |
pinMode(PA14, INPUT_ANALOG); | |
pinMode(PA15, INPUT_ANALOG); | |
pinMode(PB0, INPUT_ANALOG); | |
pinMode(PB1, INPUT_ANALOG); | |
pinMode(PB2, INPUT_ANALOG); | |
pinMode(PB3, INPUT_ANALOG); | |
pinMode(PB4, INPUT_ANALOG); | |
pinMode(PB5, INPUT_ANALOG); | |
pinMode(PB6, INPUT_ANALOG); | |
pinMode(PB7, INPUT_ANALOG); | |
pinMode(PB8, INPUT_ANALOG); | |
pinMode(PB9, INPUT_ANALOG); | |
pinMode(PB10, INPUT_ANALOG); | |
pinMode(PB11, INPUT_ANALOG); | |
pinMode(PB12, INPUT_ANALOG); | |
pinMode(PB13, INPUT_ANALOG); | |
pinMode(PB14, INPUT_ANALOG); | |
pinMode(PB15, INPUT_ANALOG); | |
} | |
void blinkN(int n, int d = 400, int t = 800) | |
{ | |
pinMode(LED_BUILTIN, OUTPUT); | |
for (int i = 0; i < n; i++) { | |
digitalWrite(LED_BUILTIN, 0); | |
mdelay(5); | |
digitalWrite(LED_BUILTIN, 1); | |
mdelay(d); | |
} | |
pinMode(LED_BUILTIN, INPUT_ANALOG); | |
mdelay(t); | |
} | |
CCS811 sensor; | |
void setup() | |
{ | |
allInput(); | |
Serial.begin(115200); | |
delay(1000); | |
Serial.println("CCS811 test"); | |
if (!sensor.begin(uint8_t(ADDR), uint8_t(WAKE_PIN))) { | |
Serial.println("Initialization failed."); | |
while (1) | |
; | |
} | |
} | |
void loop() | |
{ | |
static int loop; | |
static int co2; | |
static int tvoc; | |
//pinMode(LED_BUILTIN, OUTPUT); | |
//digitalWrite(LED_BUILTIN, 0); | |
byte status = sensor.readStatus(); | |
//Serial.println(status, HEX); | |
if (status == 0x98) { | |
sensor.compensate(22, 50.73); // replace with t and rh values from sensor | |
sensor.getData(); | |
Serial.println(); | |
co2= sensor.readCO2(); | |
tvoc= sensor.readTVOC(); | |
Serial.print("CO2 concentration : "); Serial.print(co2); Serial.println(" ppm"); | |
Serial.print("TVOC concentration : "); Serial.print(tvoc); Serial.println(" ppb"); | |
} | |
Serial.print(++loop); Serial.print(' '); | |
Serial.flush(); | |
//digitalWrite(LED_BUILTIN, 1); | |
blinkN(co2 ? (co2+50) / 100 : 2); | |
blinkN((tvoc + 5) / 10); | |
mdelay(10000); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment