This tutorial shows how to use the AVNET Azure Sphere Kit to:
- read Air Quality data (CO2/VOC) from CCS811 sensor
- read temperature and humidity from BME280 sensor
- control RGB led diode with PCA9685 controller
These I2C modules don't have a public software drivers for Azure Sphere, so we will develope libraries based on Arduino libraries.
As part of assembly all things together, we will build own microBUS compatible Air Quality Module.
We will send the data to the Azure Cloud. Anyway I will not go into details about setting up Azure Sphere device and connecting it with Azure IoT Central, because there are already here great tutorials to follow:
* Connecting Azure Sphere to Azure IoT Central
* Azure Sphere and Mikroe Air Quality Sending to IoT Central
And last but not least - we will put whole project to baby friendly case.. :)
1. ComponentsI have some experiences with cheap I2C arudino modules, so I wanted to try them with Azure Sphere board. For Indoor Air Quality monitoring device I will use CCS811 sensor and BME280 sensor. For controlling RGB LED module I will use PCA9685 controller. The LED indicator will be an easy way to show actual indoor air quality level. There will be 3 levels.
1.1 CCS811 Sensor ModuleThe CCS811 is an ultra-low power digital gas sensor solution which integrates a metal oxide (MOX) gas sensor to detect a wide range of Volatile Organic Compounds (VOCs) for indoor air quality monitoring with a microcontroller unit (MCU), which includes an Analog-to-Digital converter (ADC), and an I2C interface.
CCS811 supports intelligent algorithms to process raw sensor measurements to output equivalent total VOC (eTVOC) and equivalent CO2 (eCO2) values, where the main cause of VOCs is from humans.
eCO2 The equivalent CO2 (eCO2) output range for CCS811 is from 400ppm up to 29206ppm. The equivalent Total Volatile Organic Compound (eTVOC) output range for CCS811 is from 0ppb up to 32768ppb.
CCS811 supports compensation due to temperature and humidity changes. For temperature and humidity detection we will use BME280 Sensor module.
More info on: CCS811 datasheet
Cheap breakout module, that we can buy on eBay, looks like that:
Connecting to Azure Sphere is easy:
- sensor I2C SDA <------> mikroBUS I2C SDA
- sensor I2C SCL <------> mikroBUS I2C SCL
- sensor GND <------> mikroBUS GND
- sensor WAK <------> mikroBUS GND [CCS811 sensor will be always ON]
- sensor VCC <------> mikroBUS 3.3V
The BME280 is an combined digital temperature, humidity, and barometric pressure sensor. It provides both I2C and SPI interfaces.
- Temperature Range: -40 to +85°C
- Humidity Range: 0% to 100% rel. humidity
- Pressure Range: 300hPa to 1100hPa
More info on: BME datasheet
Cheap breakout module, that you can buy on eBay, looks like that:
Connecting to Azure Sphere is easy:
- sensor I2C SDA <------> mikroBUS I2C SDA
- sensor I2C SCL <------> mikroBUS I2C SCL
- sensor GND <------> mikroBUS GND
- sensor VCC<------> mikroBUS 3.3V
The PCA9685 is an I²C-bus controlled 16-channel LED controller optimized for Red/Green/Blue/Amber (RGBA) color backlighting applications. Each LED output has its own 12-bit resolution (4096 steps) fixed frequency individual PWM controller that operates at a programmable frequency from a typical of 24 Hz to 1526 Hz with a duty cycle that is adjustable from 0 % to 100 % to allow the LED to be set to a specific brightness value. All outputs are set to the same PWM frequency. Each LED output can be off or on (no PWM control) or set at its individual PWM controller value.
More info on: PCA9685 datasheet
Cheap breakout module, that you can buy on eBay or Aliexpress looks like that:
- sensor I2C SDA <------> mikroBUS I2C SDA
- sensor I2C SCL <------> mikroBUS I2C SCL
- sensor GND <------> mikroBUS GND
- sensor VCC <------> mikroBUS 3.3V
- sensor V+ <------> mikroBUS 3.3V
The module uses the 5050 full-color super highlight LED and has current limiting resistors to prevent burning LED. LED drive mode can: common cathode (-) drive or common anode (+) drive.
More information about using Common Cathode / Common Anode RGB LED you can find here.
1.5 Homemade mikroBUS Air Quality ModuleOk, I can wire I2C modules with Azure Sphere with dupont wires directly, but what about make own "mikroBUS" like board? We are hacksters, so let's make it. I only need universal PCB, single row male breakable pin headers, wires, soldering wire and soldering iron.
MicroBUS pinout:
Soldering is easy, I just connected SDA, SCL, +3.3V and GND with breakout modules. I also connect GND to CCS811's WAK pin. Be sure to grind the low right corner for correct module orientation.
Result:
For housing I will use Children Lamp from IKEA.
I attached boards with screws, but you can use zip ties or glue as well. The result looks like that:
The RGB LED module I we will attach to cover within “window” area.
2. SoftwareThese I2C modules don't have a public software drivers for Azure Sphere, so I’ve to develope libraries. First of all, to understand how sensors works, I’ve studied specs sheets. But why to discover everything again from zero!? I can create own libraries based on Arduino libs for CCS811/BME280/PCA9685.
2.1 CCS811 DriverMy driver for Azure Sphere has few public functions:
bool ccs811_begin(void);
for sensor initialization
uint8_t ccs811_readData(void);
for reading measurements (it reads eCO2 and eTVOC at the same time, for getting values, I have other functions.
uint16_t ccs811_geteCO2(void);
get eCO2. output range is from 400ppm up to 29206ppm.
uint16_t ccs811_geteTVOC(void);
get eTVOC. output range is from 0ppb up to 32768ppb.
void css811_setEnvironmentalData(double humidity, double temperature);
Set environmental data for due to temperature and humidity changes. Used for compensation.
2.2 BME280 DriverMy driver for Azure Sphere has few public functions:
bool bme280_begin(void);
for sensor initialization.
double bme280_readTemperature(void);
double bme280_readPressure(void);
double bme280_readHumidity(void);
Get temperature, pressure and humidity.
2.3 PCA9685 Drivervoid pca9685_begin(void);
for sensor initialization.
void pca9685_setPWM(uint8_t num, uint16_t on, uint16_t off);
Sets the PWM output of one of the PCA9685 pins (0 to 15) - at what point in the 4096-part cycle to turn the PWM output ON and OFF.
2.4 Connecting Azure Sphere to Azure IoT CentralGreat tutorial about connecting to Azure Sphere IoT central is here.
I did it the same way, only modified telemetry json message in i2c.c to:
snprintf(pjsonBuffer, JSON_BUFFER_SIZE, "{\"temperature\": \"%.2f\", \"pressure\": \"%.2f\", \"humidity\": \"%.2f\", \"eco2\": \"%d\", \"etvoc\": \"%d\"}", temperature, pressure, humidity, eCO2, eTVOC);
2.5 ApplicationFor this project, the demo code provided by Avnet is great start point:
https://github.com/Avnet/AvnetAzureSphereStarterKitReferenceDesign
I made my own modifications to the main.c, i2c.c and added drivers for sensors (sensor_ccs280.c, sensor_ccs280.h, sensor_bme280.c, sensor_bme280.h, sensor_pca9685.c and sensor_pca9685.h).
In main. there is change to control RGB LED based on actual eCO2 value:
/* LED color based on eCO2 */
airQuality = geteCO2();
if (airQuality > 0 && airQuality < 800) {
// blue
GPIO_SetValue(userLedRedFd, GPIO_Value_High);
GPIO_SetValue(userLedGreenFd, GPIO_Value_High);
GPIO_SetValue(userLedBlueFd, GPIO_Value_Low);
pca9685_setPWM(0, 0, 4095); // red off
pca9685_setPWM(1, 0, 4095); // green off
pca9685_setPWM(2, 0, 0); // blue on (common anode)
}
else if (airQuality >= 800 && airQuality < 1200) {
// green
GPIO_SetValue(userLedRedFd, GPIO_Value_High);
GPIO_SetValue(userLedGreenFd, GPIO_Value_Low);
GPIO_SetValue(userLedBlueFd, GPIO_Value_High);
pca9685_setPWM(0, 0, 4095); // red off
pca9685_setPWM(1, 0, 0); // green on (common anode)
pca9685_setPWM(2, 0, 4095); // blue off
}
else if (airQuality >= 1200) {
// red
GPIO_SetValue(userLedRedFd, GPIO_Value_Low);
GPIO_SetValue(userLedGreenFd, GPIO_Value_High);
GPIO_SetValue(userLedBlueFd, GPIO_Value_High);
pca9685_setPWM(0, 0, 0); // red (common anode)
pca9685_setPWM(1, 0, 4095); // green
pca9685_setPWM(2, 0, 4095); // blue
}
else {
GPIO_SetValue(userLedRedFd, GPIO_Value_High);
GPIO_SetValue(userLedGreenFd, GPIO_Value_High);
GPIO_SetValue(userLedBlueFd, GPIO_Value_High);
// no measurement yet
pca9685_setPWM(0, 0, 4095); // red off
pca9685_setPWM(1, 0, 4095); // green off
pca9685_setPWM(2, 0, 4095); // blue off
}
and in i2c.c threre is code, that reads values from sensors and send values to Azure IoT Central.
The final code is available at GitHub.
Comments