The project so far:
Blog One – In the Air Tonight Project Start
Blog Two– In the Air Tonight, unboxing, connecting and first try outs
Blog Three– In the Air Tonight, Design, Parameters and a Plan!
Blog Four– In the Air Tonight, The Build
Coming next: blog 5 - extending and stretch objectives
A few hours of design in Fusion 360, much much longer on the 3D printer and then even longer in Arduino IDE and rage quit with FTDI drivers and WIndows 10 update
Front view with slight right angle skew to admire the profile of the Canary in the Coal Mine.
Front of lower section, 4 MQ gas sensors.
Top of lower section, RGB LCD displaying messages on startup, heating and AQ measure
Front view with left right angle skew to admire the profile of the Canary in the Coal Mine.
Front of lower section, 4 MQ gas sensors.
Wiring harness to Arduino Uno Grove Shield. Note: the VCC + GND lines are disconnected. For why I hear you cry. I am seperately powering the MQ gas sensors which want 5v and .5amp from my bench power supply.
Minimal wasted energy breaks out into 4 GND and 4 VCC lines which hook up the MQ sensors.
Now this is the point at which Dr Frankenstein would cry out, its aliiiiiive. However I am not going to say that for I do not wish for Frankensteins monster to ultimately seek to kill its creator.
Instead I present the wired up but not yet tidy, In the Air Tonight, Summer of Sensors Bench AQ monitoring system:
From power on the intial display reads "Summer of Sensors", "In the AIr Tonight" across the two line RGB LCD display. The RGB screen has a green back light on for turning ON - green, good. all ok.
From here the LCD backlight turns orange and tells you that the Sensors are now heating. The heating process before measurement takes around 20 seconds. Thats long for a bid old delay(20000), but has robustly worked for me.
Once powered on, warmed up, the LCD now changes to a nice Green and reads OK air, no fuss, no drama, zip.
Green would not be the colour nor message however in the event of the AQ sensors picking up something which exceeds the thresholds (I have crudely defined) first for Mal Air and secondly for BAD air, which turns the screen Amber and Red respectively along with displaying a message on screen. In addition, the sensor screeches a high pitched tone and the tiny tiny tiny servo for ants at the back, tips the "canary" from his upright position into the dead parrot position, as such:
(this one is for dougw )
Now you might notice that the "passing of the Canary" is a very terminal looking thing, this is by design I assure you! The intent of this was to have a manual indicator that at some point the air quality inside my office had falling below, good accceptable breathing air standards - and whilst it is fine now, it was not. I can resetm resusitate said canary by tipping back onto upright position, and once again fine and well.
With the rapidly rising costs of electricity I have become increasingly conscious of minimising waste, so everything in my office come the end of the working day is turned off, no standby or sleep, off unless its in use. One think I had not considered as part of the original design process was the power control, so for now, this will be powered from my uber USB socket once set on the desk, this will let me easily turn on in the morning and off again when I am done. I will later add a data route from Arduino, serial to Raspberry Pi, ingest and data flow using Node Red to connect into Postgresql and display with Grafana. A potential home hub intergration is also under consideration :)
Code Bit
This is my confirmed, 100% working, could be tidier and no doubt as I get better at these things, will look back on and see the errors of my ways. Until then, this is the basic, working, uses all functions code for the Arduino Uno soluttion.
Schematic to follow up.
#include <Servo.h> #include <Wire.h> #include "rgb_lcd.h" #include <Servo.h> rgb_lcd lcd; Servo twitcher; // create servo object to control a servo const int colorR = 0; const int colorG = 255; const int colorB = 0; // MQ Gas Sensors - Analog Pins #define MQ2_pin (A0) #define MQ6_pin (A1) #define MQ9_pin (A2) #define MQ135_pin (8) // Assign variables to store gas sensor values int MQ2_value; // assign variable to store sensor value int MQ6_value; // assign variable to store sensor value int MQ9_value; // assign variable to store sensor value int MQ135_value; // assign variable to store sensor value // Relative AQ Thresholds int ok_threshold = 800; // Currently arbitrary threshold levesl that's in the range of MQ gas sensors int notok_threshold = 2000; // Currently arbitrary threshold levesl that's in the range of MQ gas sensors int reallynotok_threshold = 5000; // Currently arbitrary threshold levesl that's in the range of MQ gas sensors // Dust sensor variables int pin = 4; unsigned long duration; unsigned long starttime; unsigned long sampletime_ms = 20000; unsigned long lowpulseoccupancy = 0; float ratio = 0; int concentration = 0; // Create the servo object int pos = 0; // variable to store the servo position void setup() { // put your setup code here, to run once: //Init serial port Serial.begin(9600); twitcher.attach(5); //Init RGB LCD lcd.begin(16, 2); //Set initial colour RGB - Green, then message, two line lcd.setRGB(colorR, colorG, colorB); lcd.setCursor(0, 0); lcd.print("SummerofSensors"); lcd.setCursor(0, 1); lcd.print("InTheAirTonight"); delay(4000); //Clear the LCD, set orange and let it warm up for c.20 seconds. lcd.clear(); lcd.setRGB(255, 79, 0); lcd.setCursor(0, 0); lcd.print("Sensors Warming"); lcd.setCursor(0, 1); lcd.print("Up ..... :D."); delay(20000); Serial.println("Ready"); // Dust PM sensor pinMode(4, INPUT); //cheeper beeper pinMode(6, OUTPUT); starttime = millis(); delay(20000); // initialization of serial communication and wait for 20 seconds to allow the MQ2 sensor to warm up } void loop() { // put your main code here, to run repeatedly: duration = pulseIn(pin, LOW); lowpulseoccupancy = lowpulseoccupancy + duration; if ((millis() - starttime) >= sampletime_ms) //if the sample time = = 30s { MQ2_value = analogRead(MQ2_pin); // read analogue input pin 0 MQ6_value = analogRead(MQ6_pin); // read analogue input pin 0 MQ9_value = analogRead(MQ9_pin); // read analogue input pin 0 MQ135_value = analogRead(MQ135_pin); // read analogue input pin 0 ratio = lowpulseoccupancy / (sampletime_ms * 10.0); concentration = 1.1 * pow(ratio, 3) - 3.8 * pow(ratio, 2) + 520 * ratio + 0.62; Serial.print(MQ2_value); Serial.print(", "); Serial.print(MQ6_value); Serial.print(", "); Serial.print(MQ9_value); Serial.print(", "); Serial.print(MQ135_value); Serial.print(", "); Serial.print(concentration); Serial.println(); lowpulseoccupancy = 0; starttime = millis(); lcd.clear(); //lcd.print(MQ2_value); //lcd.print(","); //lcd.print(MQ6_value); //lcd.print(","); //lcd.print(MQ9_value); //lcd.print(","); //lcd.print(MQ135_value); } //coloured(); lcd.clear(); setscreen(); } void setscreen() { //Threshold check for Air Quality. If below threshold, OK Air if ((MQ2_value <= ok_threshold) || (MQ6_value <= ok_threshold) || (MQ9_value <= ok_threshold) || (MQ135_value <= ok_threshold)) { Serial.print("clean air message"); lcd.clear(); lcd.setRGB(0, 255, 10); lcd.print("OK Air"); } //Second Threshold check for Air Quality. If above threshold, OK if below threshold, OK Air if ((MQ2_value >= ok_threshold) || (MQ6_value >= ok_threshold) || (MQ9_value >= ok_threshold) || (MQ135_value >= ok_threshold)) { Serial.print("mal air message"); lcd.clear(); lcd.setRGB(255, 79, 0); lcd.print("Mal Air"); //make some attention grabbing noise digitalWrite(6, HIGH); delay(1000); digitalWrite(6, LOW); delay(1000); for (pos = 0; pos <= 180; pos += 1) { // goes from 0 degrees to 180 degrees // in steps of 1 degree twitcher.write(pos); // tell servo to go to position in variable 'pos' delay(15); // waits 15ms for the servo to reach the position } for (pos = 180; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees twitcher.write(pos); // tell servo to go to position in variable 'pos' delay(15); // waits 15ms for the servo to reach the position } } //Third Threshold check for Air Quality. If below threshold, Malair if above threshold, BAD Air if ((MQ2_value >= notok_threshold) || (MQ6_value >= notok_threshold) || (MQ9_value >= notok_threshold) || (MQ135_value >= notok_threshold)) { Serial.print("BAD air message"); lcd.clear(); lcd.setRGB(255, 0, 0); lcd.print("BAD Air"); } }
This is the trying to be more clever than I am version, where by the sensors go through a calibration stage before they provide first readings. There is just enough room, space and memory for this to run, however it made my Arduino Uno very warm, if not HOT and unstable after being left on for a while.
// I do not suggest using this code.
The Assembly Bit
With the designed elements which were then 3D printed, I am not a big fan of having to glue things and so like a good friction fit. With the exception of the Canary and the Canary perch, the assembly is happy with an frictional fit. (results with vary depending on how calibrated your printer is)
The lower assembly piece contains the build of the electronics. To the front, 4 counter sunk holes for the selected 4 MQ air sensors. I have gone with a counter sunk / bevelled edge to these as the sensors do get hot. This minimises the metal - PLA contact here. To the left, the dust sensor.
Top Comments