Setting up the hardware
As just stated, all devices are connected with the BeagleBone Black, which is the real core of the system, as shown in the following screenshot:
The data flow is from the sensors to the alarm actuators (LED, buzzer, and GSM module) and the user will be able to send commands to the system, or check the system status and the collected data, by using the system console.
Connecting the gas sensors
The gas sensors are used to monitor the environment and we can choose different kinds of such devices. I decided to use the ones shown in the following screenshot due to the fact they act as a variable resistor according to the gas concentration, so they can be easily read with a normal ADC:
In the prototype presented here, the gas sensors are actually four, but the ones named MQ-2 (smoke detector), MQ-4 (methane detector), and MQ-7 (LPG detector) look very similar to each other (except the label on each sensor), so I reported only one of them in the preceding screenshot, while the carbon monoxide detector is the red device labeled with MQ-7.
Note
The devices can be purchased at the following links (or by surfing the Internet):
The following are the URLs where we can get the datasheet for each GAS sensor:
Looking carefully at the datasheet of the gas sensors, we can see exactly how these sensors' class varies their internal resistance according to the gas concentration (in reality, it depends on environment humidity and temperature too; but for an indoor functioning, we can consider these values as constants). So, if we put it in series with a resistor and apply a constant voltage). We can get an output voltage that is proportional to the actual gas concentration.
The following diagram shows a possible schematics where the gas sensor is connected to 5V power supply and the RL resistor is formed by two resistors (R1 & R2) due to the fact we cannot put more than 1.8V at a BeagleBone Black's ADC pin. So, by choosing these two resistors in such a way that R1 ≥ 2*R2, we can be sure we have no more than 5.0V/3 ≈ 1.67V at the ADC input pin on every possible functioning condition, even if the sensor's internal resistance is shorted. However, to be completely sure we can add a Zener diode (Z) with a reverse threshold on 1.8V (but I didn't use it on my prototype).
The following diagram shows the circuitry I used to connect each sensor:
Tip
Note that the GAS sensors have six pins labeled in pairs as A, B, and H; while the A and B pair pins are shortened, the H labeled pairs must be connected at one end to the input voltage (5V in our case) and the other end to the GND (see the datasheet for further information).
Another important issue regarding these sensors is the calibration we should perform before using them. This last adjustment is very important; as reported in the MQ-2 datasheet, we read the following recommendation:
We recommend that you calibrate the detector for 1000 ppm liquefied petroleum gas (LPG), or 1000ppm iso-butane (i-C4H10) concentration in air and use value of load resistance that (RL) about 20K (5K to 47K).
This step can be done by replacing resistors R1 or R2 with a varistor and then fine tuning its resistance. However, I decided to use normal resistors (R1 = 15KΩ, R2 = 6.8KΩ in such a way that RL = R1 + R2 ≈ 20KΩ, as suggested by the datasheet) and then implemented a little translation in software (see the following section), that is, we can translate raw data from the ADCs into a ppm (part-per-million) value in such a way the user can work with physic data.
This translation can be done using a gain and an offset value in the following formula for each sensor:
- ppm = raw * gain + offset
During the calibration procedure, we just need to use two known points (ppm1 and ppm2), read the corresponding raw data (raw1 and raw2), and then apply the following formulas:
- gain = (ppm1 – ppm2) / (raw1 – raw2)
- offset = ppm1 – raw1 * gain
Of course, we need four gain/offset couples, one per sensor (the calibration procedure is quite long!)
Once we have fixed the input circuits, we simply have to connect each Vout to the BeagleBone Black's ADC input pins. Our board has 8 ADCs inputs, so we can use the following connections:
Pin |
Gas sensor |
---|---|
P9.39 - AIN0 |
Vout @MQ-2 |
P9.37 - AIN2 |
Vout @MQ-4 |
P9.35 - AIN6 |
Vout @MQ-5 |
P9.33 - AIN4 |
Vout @MQ-7 |
To enable them, we use the following command:
root@beaglebone:~# echo cape-bone-iio > /sys/devices/bone_capemgr.9/slots
If everything works well, we should get the following kernel messages:
part_number 'cape-bone-iio', version 'N/A' slot #7: generic override bone: Using override eeprom data at slot 7 slot #7: 'Override Board Name,00A0,Override Manuf,cape-bone-iio' slot #7: Requesting part number/version based 'cape-bone-iio-00A0.dtbo slot #7: Requesting firmware 'cape-bone-iio-00A0.dtbo' for board-name 'Override Board Name', version '00A0' slot #7: dtbo 'cape-bone-iio-00A0.dtbo' loaded; converting to live tree slot #7: #1 overlays helper.12: ready slot #7: Applied #1 overlays.
Then, the files AIN0
, AIN1
, …, AIN7
should become available as follows:
root@beaglebone:~# find /sys -name '*AIN*' /sys/devices/ocp.3/helper.12/AIN0 /sys/devices/ocp.3/helper.12/AIN1 /sys/devices/ocp.3/helper.12/AIN2 /sys/devices/ocp.3/helper.12/AIN3 /sys/devices/ocp.3/helper.12/AIN4 /sys/devices/ocp.3/helper.12/AIN5 /sys/devices/ocp.3/helper.12/AIN6 /sys/devices/ocp.3/helper.12/AIN7
Note
These settings can be done using the bin/load_firmware.sh
script in the book's example code repository, as follows:
root@beaglebone:~# ./load_firmware.sh adc
Then, we can read the input data by using the cat
command:
root@beaglebone:~# cat /sys/devices/ocp.3/helper.12/AIN0 1716
Tip
Note that the ADC can also be read by using other files still into the sysfs filesystem. The following command, for instance, reads from AIN0 input pin:
root@beaglebone:~# cat /sys/bus/iio/devices/iio:device0/in_voltage0_raw
Connecting the alarm actuators
Now, we have to connect the alarm actuators in such a way the user can have a visual and acoustic feedback of any possible dangerous gas concentration. Also, we have to connect the GSM module to a serial port to communicate with it.
LED and buzzer
The LED and buzzer connections are very simple. The LEDs can be directly connected (with a resistor) with the BeagleBone Black's GPIO pins without problems, while the buzzer needs a little more work due to the fact that it needs a higher current than the LED to work. However, we can resolve the problem by using a transistor as shown in the following diagram to manage the buzzer with a higher current.
Tip
Note that the buzzer can't be a simple piezo without an internal oscillator, otherwise an external oscillator circuit or a PWM signal must be used!
In my circuitry, I used an R (470Ω) resistor for the LED (L), an R (2KΩ), Rd (4.7KΩ) resistors for the buzzer, and a BC546 transistor (T). Note that, regarding the LEDs, an R = 100Ω resistor can result in a higher brightness, so you may change it according to the LED color to have different results.
Note also that the resistor Rd in the buzzer circuitry is needed to pull-down the GPIO during the boot. In fact, during this stage it is set as input, and even in such configuration the current that flows out from the pin can turn on the buzzer!
The BeagleBone Black has a lot of GPIOs lines, so we can use the following connections:
Pin |
Actuator |
---|---|
P8.9 - GPIO69 |
R @LED |
P8.10 - GPIO68 |
R @Buzzer |
Now, to test the connections, we can set up the GPIOs by exporting them and then setting these lines as outputs with the following commands:
root@beaglebone:~# echo 68 > /sys/class/gpio/export root@beaglebone:~# echo out > /sys/class/gpio/gpio68/direction root@beaglebone:~# echo 0 > /sys/class/gpio/gpio68/value root@beaglebone:~# echo 69 > /sys/class/gpio/export root@beaglebone:~# echo out > /sys/class/gpio/gpio69/direction root@beaglebone:~# echo 0 > /sys/class/gpio/gpio69/value
Note
Note that it will be a good idea to use blinking LEDs to do this job. However, for this first chapter I'm going to use normal GPIO lines, leaving this topic for the following chapters.
Now, to turn on and off both the LED and the buzzer, we simply write 1
or 0
into the proper files, as follows:
root@beaglebone:~# echo 1 > /sys/class/gpio/gpio68/value root@beaglebone:~# echo 0 > /sys/class/gpio/gpio68/value root@beaglebone:~# echo 1 > /sys/class/gpio/gpio69/value root@beaglebone:~# echo 0 > /sys/class/gpio/gpio69/value
Note
These settings can be done by using the bin/gpio_set.sh
script in the book's example code repository, as follows:
root@beaglebone:~# ./gpio_set 68 out root@beaglebone:~# ./gpio_set 69 out
GSM module
As stated in the introduction of this chapter, we wish to add a GSM module to be able to alert the user remotely too. In order to do this, we can connect this device with a normal serial port with TTL level signals. In this case, we have only to choose one of the serial ports available on our BeagleBone Black.
The following screenshot shows the GSM module I decided to use:
Note
The device can be purchased at the following link (or by surfing the Internet):
http://www.cosino.io/product/serial-gsmgprs-module
The user manual con be retrieved at http://www.mikroe.com/downloads/get/1921/gsm_click_manual_v101c.pdf.
The BeagleBone Black has four available serial ports. By deciding to use the device /dev/ttyO1
, we can use the following connections:
Pin |
GSM module |
---|---|
P9.24 - TX-O1 |
RX |
P9.26 - RX-O1 |
TX |
P9.1 - GND |
GND |
P9.3 - 3.3V |
3.3V |
P9.5 - 3.3V |
5V |
To enable the serial port, we have to use the following command:
root@beaglebone:~# echo BB-UART1 > /sys/devices/bone_capemgr.9/slots
If everything works well, we should get the following kernel messages:
part_number 'BB-UART1', version 'N/A' slot #8: generic override bone: Using override eeprom data at slot 8 slot #8: 'Override Board Name,00A0,Override Manuf,BB-UART1' slot #8: Requesting part number/version based 'BB-UART1-00A0.dtbo slot #8: Requesting firmware 'BB-UART1-00A0.dtbo' for board-name 'Override Board Name', version '00A0' slot #8: dtbo 'BB-UART1-00A0.dtbo' loaded; converting to live tree slot #8: #2 overlays 48022000.serial: ttyO1 at MMIO 0x48022000 (irq = 73) is a OMAP UART1 slot #8: Applied #2 overlays.
The device file /dev/ttyO1
should now become available.
Note
These settings can be done by using the bin/load_firmware.sh
script in the book's example code repository, as follows:
root@beaglebone:~# ./load_firmware.sh ttyO1
To verify that the new device is ready, we can use the ls
command as follows:
root@beaglebone:~# ls -l /dev/ttyO1 crw-rw---T 1 root dialout 248, 1 Apr 23 22:25 /dev/ttyO1
Note
The reader can take a look at the book BeagleBone Essentials, Packt Publishing, which was written by the author of this book, in order to have more information regarding how to activate and use the GPIO lines and the serial ports available on the system.
Now, we can test whether we actually talk with the modem by using the screen
command as follows:
root@beaglebone:~# screen /dev/ttyO1 115200
Note
The screen
command can be installed by using the aptitude
command as follows:
root@beaglebone:~# aptitude install screen
After pressing the ENTER key, you should get a blank terminal where, if you enter the ATZ
string, you should get the string OK
as answer, as shown in the following code:
ATZ OK
It's the GSM module that answers that it's okay and fully functional. To quit from the screen
command, you have to enter the CTRL + A + \ keys sequence and then answer yes by pressing the y key when the program asks you to Really quit and kill all your windows [y/n]
.
The final picture
Well, now we have to put it all together! The following image shows the prototype I made to implement this project and to test the software:
Note that we need an external power supplier due to the fact that the external circuitry (and especially the GSM module) needs the 5V power supply.