Natural Gas (methane) is widely used fuel in residential, commercial and industrial facilities. Indoor leakage of natural gas poses explosion and fire hazard in household kitchens, restaurants and factories/power plants.
This project demonstrates a prototype for gas leakage detection system with warning and take-action features. During any gas leakage incident, it will warn the user with a voice message warning repeatedly until someone acknowledges. While doing so, the system will try to vent out gas-air mixture from the confined space with a ventilation fan. By actively ventilating leaked gas from kitchen/restaurant /factory during any unattended leakage incident, this device can reduce the chance of fire/explosion hazard and ensuring safety of life and assets. It will not only work for methane but also for propane and butane.
The system is programmed with Ada, which is selectively used for coding safety critical applications
DemonstrationHere is a quick demonstration of this project :-
Hardware BuildI am using BBC Micro:bit development board as the brain of this project. It's very easy to use this board with Ada programming because there is official driver support written by Fabien Chouteau.
Parts list
Here is a short description of the list of hardware used in this project :-
- BBCMicro:bit : Microbit runs the firmware written in ADA for the system. I had to modify it to breakout the extra I/O pins needed for this project.
- LED bar graph display: It will show gas leakage level, has 7 LEDs -3 Green, 2 Yellow, 2 Red.
- MQ-5: Natural gas sensor for sensing gas leakage, it has analog output which increases more gas is present. The analog output of the sensor is around 660 mV when no natural gas is present in the surrounding. As the natural gas level goes up the sensor output max out at 3.2 volts.
- Speaker: Sound transducer for voice message output, driven by ISD1820 chip which is triggered from Microbit.
- Potentiometer : 20k variable resistor to adjust gas detection sensitivity, goes to one of the ADC input of Microbit. Sensitivity is adjusted in the software.
- Push button: This button will take setup & fault acknowledgement input from user, connected to button B of Microbit in parallel.
Everything is put together inside a cardboard box with necessary cuts according to the size of the parts on the front face like this -
Relay Module: The relay used in this project is a latching relay, which is different from normal relay. Latching relay can hold its contacts without the need of continuous energization of its coils. There are 2 electromagnetic coils inside this latching relay which are driven through 2 NPN transistors. Both transistors are controlled with 2 I/O pins of microbit alternatively with short pulses to latch or unlatch the relay contacts. This is how the ventilation fan is powered on and off through relay contacts from AC mains supply.
- Voice Record/Playback Module: The voice recording and playback module is a single chip solution for audio messages based on ISD1820 IC. It has internal EEPROM to store few seconds ( 8 sec to 16 sec depending on sampling frequency ) of audio message and built-in speaker driver to play the message through a speaker without the need of additional amplifier. Recording is done by pulling up the REC (Red button in my custom module) pin of ISD1820 chip to Vcc. To record message, audio stream is fed through MIC and MIC_REF pins with a 3.5mm audio jack from computer headphone port. Playback is triggered with a falling edge on PLEY_E pin of the chip with an output pin of microbit. Using a lipo battery to power the ISD1820 chip will help better audio recording.
You can use any text-to-speech converter (MS TTS or free online TTS reader) to produce the voice message for recording to this module, or use the microphone record your own voice.
- Power Supplies: 5V adapter with 2 USB outlets will power the microbit and gas sensor. Microbit onboard regulator will generate 3V rail.
- Ventilation Fan: AC powered exhaust fan used to remove leaked gas when detected.
- Plastic Cup: It will help to accumulate leaked gas and make the detection easier. I salvaged this from an empty aerosol insecticide spray
Schematic
All the components are connected according to following schematic -
What's inside the box !
Inside a cardboard box, everything is hot-glued like this and interconnected with jumper wires -
After connecting the whole circuit, it's time to put some 'Dark Magic' with Ada programming !
Preparation for Ada programming
- GNAT IDE: download and install GNAT Studio
- ARM Driver: download and install ARM Elf Driver
- Example Codes : https://github.com/AdaCore/Ada_Drivers_Library
Install all of these in the same directory.
GNAT Programming Studio
: GPS
After downloading and installing GNAT IDE, arm driver into the same directory, open example code from :
C:\GNAT\2019\share\gps\templates\microbit_example
Open one of the examples (i.e. digital_out.gpr) for Microbit according to following steps and edit example project code as needed.
- Step 1: Run GPS (GNAT Programming Studio)
- Step 2: Select and open the digital_out.gpr example project
- Step 3: Copy this project's code attached below and replace the example code in main.adb file
Before I explain the whole code in details, check this simple ada skeleton code to understand what goes where:-
-- License information
-- package inclusion goes here
procedure Main is
-- variable declaration goes here
begin
-- initialization or one time executable code goes here
loop
-- body of recurring or looping code goes here
end loop;
end Main;
; (semicolon) is the end of a loop or procedure.
-- (double dash) is used to write comments
Following files are the most important files when working with GNAT Studio: -
.gpr file is the GNAT project file for a project
.adb file is the file where Ada code resides (src folder)
.ads files is where the definitions and declarations goes
Inside the Main.adb file of this project :-
The code starts with the 'with' clause which will include Microbit I/O, timing and button support. The 'use' clause will make the content of these Microbit packages visible/usable in the main code.
with MicroBit.IOs;use MicroBit.IOs;
with MicroBit.Time;
with MicroBit.Buttons; use MicroBit.Buttons;
"with MicroBit.IOs" includes microbit GPIO control support to main.adb code. But including "use MicroBit.IOs" will enable to use variable types from MicroBit.IOs package.
Then the Main subroutine starts with 'procedure' clause/keyword. Ada procedures is a subroutine but does not return any value. Next, there are Boolean variables, constants, integers declared which will be used in the code:-
procedure Main is
Detected : Boolean := False;
Sensor_Min : constant Integer := 220; -- gas sensor ADC val when no gas
Range_Step : constant Integer := 15; -- detection steps in a given range
Sensitivity : MicroBit.IOs.Analog_Value; -- potentiometer ADC value
Gas_Sensor : MicroBit.IOs.Analog_Value; -- gas sensor ADC value
Vref : MicroBit.IOs.Analog_Value; -- 2.5V external refernec for ADC
Threshold : Integer; -- gas sensor sensing threshold
Level : Integer; -- user selectable sensivity level
Next, GPIO pins are associated with suitable names to their respective pins which will trigger Audio message, relay and bargraph LEDs :-
-- Audio MSG enable pin
Aud : constant MicroBit.IOs.Pin_Id := 15;
-- latching relay control pins
Latch : constant MicroBit.IOs.Pin_Id := 13;
Unlatch : constant MicroBit.IOs.Pin_Id := 14;
-- LEDs on bar graph Driving I/O pins
R7 :constant MicroBit.IOs.Pin_Id := 7;
R6 :constant MicroBit.IOs.Pin_Id := 10;
Y5 :constant MicroBit.IOs.Pin_Id := 6;
Y4 :constant MicroBit.IOs.Pin_Id := 0;
G3 :constant MicroBit.IOs.Pin_Id := 8;
G2 :constant MicroBit.IOs.Pin_Id := 20;
G1 :constant MicroBit.IOs.Pin_Id := 19;
Set_Bargraph procedure will drive the bargraph LEDs depending on the parameter value (any Integer between 0 to 7) passed to it when call :-
-- LED bargraph driver
procedure Set_Bargraph(I:Integer);
procedure Set_Bargraph(I:Integer) is
begin
if I >= 7 then
MicroBit.IOs.Set(R7,False);MicroBit.IOs.Set(R6,False);
MicroBit.IOs.Set(Y5,False);MicroBit.IOs.Set(Y4,False);
MicroBit.IOs.Set(G3,False);MicroBit.IOs.Set(G2,False);
MicroBit.IOs.Set(G1,False);
elsif I = 6 then
MicroBit.IOs.Set(R7,True);MicroBit.IOs.Set(R6,False);
MicroBit.IOs.Set(Y5,False);MicroBit.IOs.Set(Y4,False);
MicroBit.IOs.Set(G3,False);MicroBit.IOs.Set(G2,False);
MicroBit.IOs.Set(G1,False);
elsif I = 5 then
MicroBit.IOs.Set(R7,True);MicroBit.IOs.Set(R6,True);
MicroBit.IOs.Set(Y5,False);MicroBit.IOs.Set(Y4,False);
MicroBit.IOs.Set(G3,False);MicroBit.IOs.Set(G2,False);
MicroBit.IOs.Set(G1,False);
elsif I = 4 then
MicroBit.IOs.Set(R7,True);MicroBit.IOs.Set(R6,True);
MicroBit.IOs.Set(Y5,True);MicroBit.IOs.Set(Y4,False);
MicroBit.IOs.Set(G3,False);MicroBit.IOs.Set(G2,False);
MicroBit.IOs.Set(G1,False);
elsif I = 3 then
MicroBit.IOs.Set(R7,True);MicroBit.IOs.Set(R6,True);
MicroBit.IOs.Set(Y5,True);MicroBit.IOs.Set(Y4,True);
MicroBit.IOs.Set(G3,False);MicroBit.IOs.Set(G2,False);
MicroBit.IOs.Set(G1,False);
elsif I = 2 then
MicroBit.IOs.Set(R7,True);MicroBit.IOs.Set(R6,True);
MicroBit.IOs.Set(Y5,True);MicroBit.IOs.Set(Y4,True);
MicroBit.IOs.Set(G3,True);MicroBit.IOs.Set(G2,False);
MicroBit.IOs.Set(G1,False);
elsif I = 1 then
MicroBit.IOs.Set(R7,True);MicroBit.IOs.Set(R6,True);
MicroBit.IOs.Set(Y5,True);MicroBit.IOs.Set(Y4,True);
MicroBit.IOs.Set(G3,True);MicroBit.IOs.Set(G2,True);
MicroBit.IOs.Set(G1,False);
elsif I <= 0 then
MicroBit.IOs.Set(R7,True);MicroBit.IOs.Set(R6,True);
MicroBit.IOs.Set(Y5,True);MicroBit.IOs.Set(Y4,True);
MicroBit.IOs.Set(G3,True);MicroBit.IOs.Set(G2,True);
MicroBit.IOs.Set(G1,True);
end if;
MicroBit.Time.Delay_Ms (100);
end Set_Bargraph;
Fan_Control procedure will latch or unlatch the relay to turn on/off the ventilation fan:-
-- Fan control
procedure Fan_Control(I:Integer);
procedure Fan_Control(I:Integer) is
begin
if I = 1 then
MicroBit.IOs.Set(Latch,False); MicroBit.IOs.Set(Unlatch,False);
MicroBit.IOs.Set(Latch,True); MicroBit.Time.Delay_Ms (200);
MicroBit.IOs.Set(Latch,False);
elsif I = 0 then
MicroBit.IOs.Set(Latch,False); MicroBit.IOs.Set(Unlatch,False);
MicroBit.IOs.Set(Unlatch,True); MicroBit.Time.Delay_Ms (200);
MicroBit.IOs.Set(Unlatch,False);
end if;
end Fan_Control;
In Ada, 'begin' keyword is the beginning of the body from the element (i.e. if, elsif, for loop, while loop) to which it pertains.
Following code block will run only once (single iteration) to make sure the ventilation fan is turned off. The LED bargraph display will glow each bar for 100 ms as a startup test.
begin
-- keep fan off during startup
Fan_Control(0);
-- test bar graph display
for I in 0 .. 7 loop
Set_Bargraph(I);
MicroBit.Time.Delay_Ms (100);
end loop;
-- turn off bar graph
Set_Bargraph(0);
This while loop will take user input through potentiometer and push button B. Here, user can adjust the sensitivity of the device with the potentiometer. As user adjusts the potentiometer, more sensitive will lit up more LEDs on the bargraph. Once the gas detection sensitivity is adjusted, user needs to press button B to break this loop
loop
-- take user input for detection sensitivity
while MicroBit.Buttons.State (Button_B) = Released loop
Sensitivity := MicroBit.IOs.Analog (2);
Vref := MicroBit.IOs.Analog (3); -- 2.5 V reference, reads about 880
Level := Integer(Vref/Sensitivity);
Set_Bargraph(Level);
end loop;
-- acknowledge user input been taken with blink
for I in 0 .. 3 loop
Set_Bargraph(7);
MicroBit.Time.Delay_Ms (100);
Set_Bargraph(0);
MicroBit.Time.Delay_Ms (100);
end loop;
Finally the infinite while loop starts, which will repeated sense for gas leakage according to the user set threshold. If gas leakage is detected, it will trigger the I/O pins to play voice message and keep the ventilation fan running.
-- loop forever
while True loop
-- frequently check for gas leakage
Gas_Sensor := MicroBit.IOs.Analog(1);
Threshold := (Integer(Gas_Sensor)-Sensor_Min)/((8-Level)*Range_Step);
Set_Bargraph(Threshold);
-- if gas leakage detected
if Threshold >= 7 then
Detected := True;
-- turn on vent fan
Fan_Control(1);
-- play voice warning repeatedly until user acknowledges
while MicroBit.Buttons.State (Button_B) = Released loop
MicroBit.IOs.Set(Aud,True);
MicroBit.IOs.Set(R7,False);MicroBit.IOs.Set(R6,False);
MicroBit.Time.Delay_Ms (150);
MicroBit.IOs.Set(R7,True);MicroBit.IOs.Set(R6,True);
MicroBit.IOs.Set(Aud,False);
MicroBit.Time.Delay_Ms (150);
end loop;
end if;
-- turn off vent fan only if leaked gas is vented out
-- keep vent fan running if there is gas,
if Threshold <= 1 and Detected then
Fan_Control(0); Detected := False;
end if;
end loop;
User needs to press B button to acknowledge the fault to stop the voice message playback. The fan will turn off only when the leakage gas level goes below the threshold. Then, the device will keep sensing for gas leakage again.
Uploading FirmwareOnce the editing of the code is done, connect Microbit to computer with USB cable.
Then click : Build > Bareboard > Flash to Board > main.adb to flash firmware to Microbit from GNAT Studio.
- Ada Driver Library and Example code for Microbit on GitHub
- Ada for the C++ or Java Developer
- Ada Keywords
- GNAT IDE and Drivers
- ISD1820 Module
- MS Office Text-to-Speech
This project is very simple and easy to build, intended for beginners with Ada programming. Yet, it's a practical solution to potential gas leakage hazards. The hardware build of this project is a quick prototype. But for everyday use one must develop a PCB solution with solid connections between components. Not to mention all the extensive testing that is required to find the time delay for detection, sensor placement/positioning and reliability. One other important matter is to use the right size and positioning of ventilation fan. As, Methane is slightly lighter than air but Propane/Butane is heavier than air, placement of ventilation fan (near ceiling or near floor) is very important. Relay and all the electronics must sealed, not to become the source of ignition with a spark !
Comments