Skip to content

Instantly share code, notes, and snippets.

@ViliusKraujutis
Created March 28, 2017 13:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ViliusKraujutis/345b22564a35b616e3db016ecc7dc262 to your computer and use it in GitHub Desktop.
Save ViliusKraujutis/345b22564a35b616e3db016ecc7dc262 to your computer and use it in GitHub Desktop.
Air Sensor Arduino based air quality sensor Sensors used: DHT22 - temperature and humidity sensor MQ-2 - gas leakage detector. It is suitable for detecting H2, LPG, CH4, CO, Alcohol, Smoke or Propane MQ-3 - alcohol sensor is suitable for detecting alcohol concentration on your breath, just like your common breathalyzer. It has a high sensitivity…
/*
Air Sensor
Arduino based air quality sensor
Sensors used:
DHT22 - temperature and humidity sensor
MQ-2 - gas leakage detector. It is suitable for detecting H2, LPG, CH4, CO, Alcohol, Smoke or Propane
MQ-3 - alcohol sensor is suitable for detecting alcohol concentration on your breath, just like your common breathalyzer. It has a high sensitivity and fast response time
MQ-7 - Carbon Monoxide (CO) sensor
MQ-135 - detects NH3, NOx, alcohol, benzene, smoke, CO2
Photosensor - LDR photoresistor
Created at 25th November 2016
by Vilius Kraujutis
# Library dependencies
This project depends on these libraries, which needs to be imported into Arduino IDE:
- DHT22 - https://github.com/adafruit/DHT-sensor-library
- MQ2 - https://github.com/ViliusKraujutis/MQ-2-sensor-library
- MQ135 - https://github.com/ViliusKraujutis/MQ135/
- Adafruit GFX - https://github.com/adafruit/Adafruit-GFX-Library
- Nokia 5110 screen (PCD8544) - https://github.com/adafruit/Adafruit-PCD8544-Nokia-5110-LCD-library
- Adafruit Sensor - https://github.com/adafruit/Adafruit_Sensor
# HC-05 BLUETOOTH
Pairing with VILIAUS-HC-05 (98:D3:31:FC:17:D3) password is 54321
If you want to use AT COMMANDS to configure HC-05 bluetooth module,
you need to change BLUETOOTH_USE_AT_COMMANDS constant to true.
You need to bring HC-05 into AT commands mode like this:
- power off arduino
- press and hold little button on HC-05 module
- power on arduino (so it will power on BT module too)
- wait until red LED on BT module will start flashing every 2s
Serial should be in 9600 baud rate (although BTSerial will operate in 38400 baud rate).
Most useful AT commands are
AT : Ceck the connection.
AT+NAME : See default name
AT+ADDR : see default address
AT+VERSION : See version
AT+UART : See baudrate
AT+ROLE: See role of bt module(1=master/0=slave)
AT+RESET : Reset and exit AT mode
AT+ORGL : Restore factory settings
AT+PSWD: see default password
# CONNECTION Scheme
See PINS section below to see what actual constants mean
## Nokia's display connection scheme:
- GND - to ground pin
- LIGHT - to ground pin, if LCD backlight is needed
- VCC - to 5V pin
- CLK - to pin 8 - Serial clock out (SCLK)
- DIN - to pin 7 - Serial data out (DIN)
- DC - to pin 6 - Data/Command select (D/C)
- CE - to pin 5 - LCD chip select (CS)
- RST - to pin 4 - LCD reset (RST)
## BLUETOOTH
- Connect the HC-05 TX to Arduino pin PIN_BLUETOOTH_RX.
- Connect the HC-05 RX to Arduino pin PIN_BLUETOOTH_TX through a voltage divider.
## HEART BEAT LED
- Connect anode to PIN_HEART_BEAT_LED.
- Connect cathode to GROUND
## DHT22 - HUMIDITY AND TEMPERATURE
- Connect pin 1 (on the left) of the sensor to +5V
NOTE: If using a board with 3.3V logic like an Arduino Due connect pin 1
to 3.3V instead of 5V!
- Connect pin 2 of the sensor to whatever your PIN_DHT is
- Connect pin 4 (on the right) of the sensor to GROUND
- Connect a 10K resistor from pin 2 (data) to pin 1 (power) of the sensor
## MQ135 - GAS SENSOR
- Connect to PIN_MQ135
- detecting of NH3, NOx, alcohol, Benzene, smoke, CO2, etc
*/
// PINS
#define BLUETOOTH_USE_AT_COMMANDS false
#define PIN_BLUETOOTH_RX 2
#define PIN_BLUETOOTH_TX 3
#define PIN_HEART_BEAT_LED 13
#define PIN_BUTTON 9
#define PIN_DHT A5 // Temperature & humidity
#define PIN_MQ2 A4 // LPG
#define PIN_MQ7 A1 // CO
#define PIN_MQ3 A3 // Alcohol
#define PIN_MQ135 A2 // CO2
// INCLUDES
#include <SoftwareSerial.h>
#include "DHT.h"
#include <MQ2.h>
#include "MQ135.h"
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_PCD8544.h>
// CONSTANTS
#define LED_BLINK_TIME 300
#define CELSIUS_SYMBOL "°"
#define MAX_ANALOG_VALUE 1023
// VARIABLE INITIALIZATION
SoftwareSerial BTserial(PIN_BLUETOOTH_RX, PIN_BLUETOOTH_TX); // RX | TX // would be good to move to hardware RX/TX pins for better performance
DHT dht22(PIN_DHT, DHT22);
MQ2 mq2(PIN_MQ2);
MQ135 mq135_sensor = MQ135(PIN_MQ135);
// Nokia's display connection scheme:
// GND - to ground
// LIGHT - to ground if LCD backlight is needed
// VCC - to 5V
// CLK - to pin 8 - Serial clock out (SCLK)
// DIN - to pin 7 - Serial data out (DIN)
// DC - to pin 6 - Data/Command select (D/C)
// CE - to pin 5 - LCD chip select (CS)
// RST - to pin 4 - LCD reset (RST)
Adafruit_PCD8544 display = Adafruit_PCD8544(8, 7, 6, 5, 4);
// PRIMITIVE VARIABLES
boolean blinkLED = true;
boolean isButtonPressed = true;
// MEASUREMENTS
float dht22_humidity, dht22_temperature, dht22_heatIndex;
float mq2_lpg, mq2_co, mq2_smoke;
int mq7_co, mq3_alcohol;
float mq135_co2_corrected;
// SETUP
void setup() {
Serial.begin(9600);
Serial.println();
Serial.println("Arduino is ready");
Serial.println("Remember to select Both NL & CR in the serial monitor");
// BLUETOOTH - HC-05 default serial speed for AT mode is 38400
BTserial.begin(38400); // for AT commands
// PIN MODES
pinMode(PIN_HEART_BEAT_LED, OUTPUT);
pinMode(PIN_BUTTON, INPUT_PULLUP);
// DHT22
dht22.begin();
// MQ2
mq2.begin();
// DISPLAY
display.begin();
display.setContrast(60);
}
// PROGRAM LOOP
void loop() {
if (BLUETOOTH_USE_AT_COMMANDS) {
readFromBTserial();
writeToBTserial();
return;
}
readButtonValue();
heartBeatLED(true);
readDHT22();
printDHT22ValuesToSerial();
printDHT22ValuesToBT();
readFromMQ2();
printMQ2ValuesToSerial();
readFromMQ3();
printMQ3ValuesToSerial();
readFromMQ7();
printMQ7ValuesToSerial();
readFromMQ135();
printMQ135ValuesToSerial();
Serial.println();
updateDisplay();
heartBeatLED(false);
}
// MAIN METHODS
void readButtonValue() {
if (digitalRead(PIN_BUTTON) == LOW) {
isButtonPressed = true;
} else {
if (isButtonPressed) {
blinkLED = !blinkLED;
}
isButtonPressed = false;
}
}
void heartBeatLED(boolean light) {
if (light && !blinkLED || isButtonPressed) {
digitalWrite(PIN_HEART_BEAT_LED, HIGH);
} else {
digitalWrite(PIN_HEART_BEAT_LED, LOW);
}
delay(LED_BLINK_TIME);
}
void readFromBTserial() {
// Keep reading from HC-05 and send to Arduino Serial Monitor
if (BTserial.available()) {
Serial.write(BTserial.read());
}
}
void writeToBTserial() {
// Keep reading from Arduino Serial Monitor and send to HC-05
if (Serial.available()) {
BTserial.write(Serial.read());
}
}
String toPercentage(float value, float maxValue) {
float p = value / maxValue;
return String(p * 100) + "%";
}
// READ AND PRINT FROM SENSORS
void readDHT22() {
dht22_humidity = dht22.readHumidity();
dht22_temperature = dht22.readTemperature();
if (isnan(dht22_humidity) || isnan(dht22_temperature)) {
Serial.println("Failed to read from DHT22 sensor!");
return;
}
dht22_heatIndex = dht22.computeHeatIndex(dht22_temperature, dht22_humidity, false);
}
void printDHT22ValuesToSerial() {
Serial.print("DHT22 - Humidity: ");
Serial.print(dht22_humidity);
Serial.print("%\t DHT22 - Temperature: ");
Serial.print(dht22_temperature);
Serial.print(CELSIUS_SYMBOL);
Serial.print("C\t DHT22 - Heat index: ");
Serial.print(dht22_heatIndex);
Serial.print(CELSIUS_SYMBOL);
Serial.print("C\t ");
}
void printDHT22ValuesToBT() {
BTserial.print("DHT22 - Humidity: ");
BTserial.print(dht22_humidity);
BTserial.print("%\t DHT22 - Temperature: ");
BTserial.print(dht22_temperature);
BTserial.print(CELSIUS_SYMBOL);
BTserial.print("C\t DHT22 - Heat index: ");
BTserial.print(dht22_heatIndex);
BTserial.print(CELSIUS_SYMBOL);
BTserial.print("C\t ");
}
void readFromMQ2() {
/* Read the values from the sensor,
it returns
an array which contains 3 values.
1 = LPG in ppm
2 = CO in ppm
3 = SMOKE in ppm
*/
float* values = mq2.read(false); // don't print values to the Serial
mq2_lpg = mq2.readLPG();
mq2_co = mq2.readCO();
mq2_smoke = mq2.readSmoke();
}
void printMQ2ValuesToSerial() {
Serial.print("MQ2 - LPG: ");
Serial.print(mq2_lpg);
Serial.print("ppm\t MQ2 - CO: ");
Serial.print(mq2_co);
Serial.print("ppm\t MQ2 - Smoke: ");
Serial.print(mq2_smoke);
Serial.print("ppm\t ");
}
void readFromMQ3() {
mq3_alcohol = analogRead(PIN_MQ3);
}
void printMQ3ValuesToSerial() {
Serial.print("MQ3 - Alcohol: ");
Serial.print(toPercentage(mq3_alcohol, MAX_ANALOG_VALUE));
Serial.print("\t ");
}
void readFromMQ7() {
mq7_co = analogRead(PIN_MQ7);
}
void printMQ7ValuesToSerial() {
Serial.print("MQ7 - CO: ");
Serial.print(toPercentage(mq7_co, MAX_ANALOG_VALUE));
Serial.print("\t ");
}
void readFromMQ135() {
mq135_co2_corrected = mq135_sensor.getCorrectedPPM(dht22_temperature, dht22_humidity);
}
void printMQ135ValuesToSerial() {
Serial.print("MQ-135 C02+etc: ");
Serial.print(mq135_co2_corrected);
Serial.print("ppm\t ");
}
void updateDisplay() {
display.clearDisplay(); // clears the screen and buffer
display.setTextSize(0.5f);
display.setTextColor(BLACK);
display.setCursor(0, 0);
display.println("RH: " + String(dht22_humidity) + "%");
display.println("T: " + String(dht22_temperature) + "C");
display.println("Alc:" + String(mq3_alcohol) + "ppm");
display.println("CO2:" + String(mq135_co2_corrected) + "ppm");
display.println("LPG:" + String(mq2_lpg) + "ppm");
display.println("CO: " + String(mq2_co) + "ppm");
display.println("Smk:" + String(mq2_smoke) + "ppm");
display.println("MQ7:" + String(mq7_co) + "/1023"); // unclear value
display.display();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment