In this multi part series, I will be taking you through building, breaking and re-making of a rugged (dust and water proof) and reliable (firmware, power, and connectivity) with Hornbill series of ESP32 dev boards. The aim is show the process of building, documenting the failure as well as the working! So in this first part we will try and build a quick prototype and show that it is possible. At the end of it we will ask some fundamental questions and re-visit the design and see what can be improved.

0 iaq esp32.jpeg

Why do it?

Air pollution is on rise in all major Indian cities. Indoor Air Pollution at times is worse than outdoors. In my opinion it is important to measure it. We may not be able to control it with this project but as the saying goes "If You Can't Measure It, You Can't Improve It. "

Poll.png

So I had a poll with a fellow makers and they believe it is important to measure it.

Measuring Indoor Air Quality (IAQ)

Although measuring Indoor Air Quality is important, basic research suggest that it is a complex task. The end goal would be to provide a simple indication to showing the air the quality. In this example let us concentrate on getting the data from chosen sensors provides. Air quality deteriorates due to CO2, volatile organic compounds (VOCs) in conjunction with temperature and relative humidity. The sensor AMS iAQCore provide C02 equivalents and TVOC. The combination of these parameters should be able to provide a basic indication of air quality. Figure below shows how these combination of factors affects Air Quality and it could be detected with our setup. IaqCorePlot.png In the subsequent articles in the series, we will try and make sense of the data, go through the available standards and figure out a metric for normal, good and bad air.

So we will be measuring the following

  • Temperature in degree Celsius
  • Humidity in Percentage
  • Carbon Dioxide(CO2) equivalents in Parts per Million ppm
  • Total Volatile Organic Componds (TVOC) in Parts per Billion ppb

Schematic

Iaq schematic.png

Parts

  • Hornbill ESP32 Dev Board
  • Hornbill ESP32 Proto Board
  • AMS iAQCore
  • Other passive components

Code

Well giving it shot should be fun enough!

/*
* Indoor Air Quality v0.1
*
* Demo sketch to log Indoor Air Quality to thingspeak.com
*
* Temperature, humidity, TVOC and C02 are measured and logged.
* The data is also printed on the terminal and displayed on OLED
*
* More details visit:
*
* https://exploreembedded.com/wiki/Building_a_reliable_and_rugged_Air_Quality_Logger_with_Hornbill_ESP32_PART-1
*
*/
// Libraries
#include <WiFi.h>
#include <Adafruit_SHT31.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include "iAQ-MOD1023.h"
//Display
#define OLED_RESET 4
#define OLED_address 0x3c
Adafruit_SSD1306 display(OLED_RESET);
//Wifi Thingspeak data logging
WiFiClient client;
String apiKey = "things_speak_api_key";
char ssid[20] = "your_wifi_ssid";
char password[20] = "yourWifiPassword";
const char* server = "api.thingspeak.com";
//Temperature humidity Sensor
#define SHT_ADDRESS 0x44
Adafruit_SHT31 sht31 = Adafruit_SHT31();
//Global Variables
float temperature,humidity;
unsigned int co2,tvoc;
void setup()
{
Serial.begin(115200);
display.begin(SSD1306_SWITCHCAPVCC, OLED_address);
display.clearDisplay();
display.setCursor(0,20);
display.print("Connecting to:");
display.setCursor(0,40);
display.print(ssid);
// Setup the Internet
WiFi.begin(ssid, password);
int pos = 0;
int dot = 20;
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
pos++;
dot++;
display.setCursor(dot,40);
display.print(".");
}
// sendStrXY("connected", 5, 0);
display.clearDisplay();
delay(100);
}
void loop()
{
iaqUpdate();
readSensors();
updateDisplay();
printData();
logData();
}
//Update and print data from iAQ
void iaqUpdate()
{
Wire.begin();
iaq.readRegisters();
co2 = iaq.getPrediction();
tvoc = iaq.getTVOC();
}
void readSensors()
{
if (! sht31.begin(SHT_ADDRESS))
{
Serial.println("Couldn't find SHT31");
while (1) delay(1);
}
temperature = sht31.readTemperature();
humidity = sht31.readHumidity();
}
void updateDisplay()
{
display.setTextSize(1);
display.setTextColor(WHITE);
display.clearDisplay();
display.setCursor(0,0);
display.print(" Indoor Air Quality ");
display.setCursor(0,20);
display.print("Temp :");
display.setCursor(70,20);
display.print(temperature);
display.setCursor(100,20);
display.print(" C");
display.setCursor(0,30);
display.print("Humidity :");
display.setCursor(70,30);
display.println(humidity);
display.setCursor(100,30);
display.print(" %");
display.setCursor(0,40);
display.print("co2 Val :");
display.setCursor(70,40);
display.print(co2);
display.setCursor(100,40);
display.print(" ppm");
display.setCursor(0,50);
display.print("TVOC :");
display.setCursor(70,50);
display.print(tvoc);
display.setCursor(100,50);
display.print(" ppb");
display.display();
}
void logData()
{
if (client.connect(server,80))
{
String postStr = apiKey;
postStr +="&field1=";
postStr += String(temperature);
postStr +="&field2=";
postStr += String(humidity);
postStr +="&field3=";
postStr += String(co2);
postStr +="&field4=";
postStr += String(tvoc);
postStr += "\r\n\r\n";
client.print("POST /update HTTP/1.1\n");
client.print("Host: api.thingspeak.com\n");
client.print("Connection: close\n");
client.print("X-THINGSPEAKAPIKEY: "+apiKey+"\n");
client.print("Content-Type: application/x-www-form-urlencoded\n");
client.print("Content-Length: ");
client.print(postStr.length());
client.print("\n\n");
client.print(postStr);
}
client.stop();
Serial.println("****Next data log after 20 seconds*****");
// thingspeak needs minimum 15 sec delay between updates
delay(20000);
}
//prints data to the terminal, can be removed later
void printData()
{
Serial.println("****Indoor Air Quality Values******");
Serial.print("Temperature: ");
Serial.print(temperature);
Serial.println(" *C ");
Serial.print("Humidity");
Serial.print(humidity);
Serial.println("%");
Serial.print("TVOC:");
Serial.print(tvoc);
Serial.println("ppb");
Serial.print("Corbon Dioxide: ");
Serial.print(co2);
Serial.println("ppm");
}
view raw IAQ_v_0_1.ino hosted with ❤ by GitHub

The Data Plots

The data is sent to thingspeak over http. This could be improved further to use https.

Logging data to the blynk app was simple enough. Blynk allows displays data on smartphones with nice widgets and controls.
Blynk IAQ.png

Downloads

Going further

There are some essential questions that we need to ask at this point, so that the design can be improved further.

  • Data Logging Frequency: We are logging data every 20 seconds. We need to arrive at a logical time interval which is much higher. This will help us save power.
  • Can Power modes be configured to put the system is sleep mode when logging?
  • Can local (SD card) data storing and logging once in a while make more sense?
  • How can the data be interpreted to indicate Air Quality in a Simpler way?
  • Should we measure the power as a parameter?
  • Can the code be re-written in 'C' for lower power consumption?

We will explore all of this and more in the future articles.

References