Arduino-based BLE-Enabled Indoor Air Quality Monitor
Published on 2/11/2017 12:49:25 AM
Description
<style>.e_editor{font:14px/24px Arial,'microsoft yahei','Times New Roman','b8bf53';}.e_editor div,e_editor p,e_editor td,e_editor th,e_editor li{font-weight:inherit;font-size:inherit;font-style:inherit;font-family:inherit;}.e_editor ul{margin:-10px 0 20px;}.e_editor li{padding:5px 0;}.e_table{width:96%;border-collapse:collapse;empty-cells:show;}.e_table th,.e_table td{padding:5px;border:2px solid #eee;}.e_img{padding:10px 0;text-align:center;}.e_p{line-height:20px;padding:0 0 20px;text-indent:0em;}</style> <div class="e_editor"> <div class="e_p"> Like most folks, I sometimes wonder about the quality of the air I breathe. Naturally, I turned to the possibility of a project designed to measure the quality of the air in my own home. </div> <div class="e_p"> Indoor air quality is not a simple concept to quantify. I assumed that too much CO<sub>2</sub> (Carbon Dioxide) didn’t seem like a good idea. Furthermore, large concentrations of VOCs (volatile organic compounds) didn’t sound too pleasant either. So, I reasoned that these would be some important measures to have available. </div> <div class="e_p"> After further investigation, I found only a few ICs available to build such a project around. I settled on the iAQ-Core module from AMS. </div> <div class="e_p"> As I read more about measuring indoor air quality, I began to appreciate the complexity of the issue. The volatility of many compounds (the degree to which they vaporize into the air) depends, in part, on the temperature. Also, relative humidity can be a factor for some compounds. Thus, I decided to add temperature and relative humidity sensors to the project. </div> <div class="e_p"> Of course, I wanted to use a microcomputer with a display to read sensor output. As an additional feature, I decided to include BLE connectivity to allow remote monitoring. </div> <div class="e_p"> <strong>Let me state up front and without qualification (as in a complete disclaimer) that this project is an experiment driven by my curiosity. I don’t really know how meaningful it is as a decision tool for anything.</strong> </div> <div class="e_p"> <strong></strong> </div> <div class="e_p"> iAQ-Core Sensor Module </div> <div class="e_p"> The iAQ-Core indoor air quality sensor module is the heart of the project and is used to provide CO<sub>2</sub> and total volatile organic compounds (TVOC)equivalentpredictions. The sensing range from the datasheet is as follows: 450-2000 ppm CO<sub>2</sub> equivalents and 125-600 ppb TVOC equivalents. "Equivalents" are somewhat vague units and are not defined as well as I would have liked. </div> <div class="e_p"> From doing a little background reading, it seems like a CO<sub>2</sub> equivalent unit includes CO<sub>2</sub> and other "greenhouse" gasses, apparently scaled to a property of CO<sub>2</sub>. TVOC equivalent units also appears to be a somewhat vague measure. It seems that there are a number of compounds considered to be VOCs with particular relevance to indoor air quality and these are totaled and expressed as some standardized measure. </div> <div class="e_p"> In all fairness, I have seen the use of these "equivalent" units on several commercial indoor air monitors. Still, I would have liked to have seen a more rigorous definition. </div> <div class="e_p"> The device uses Micro-Electro-Mechanical Systems (MEMS) metal oxide sensor technology. It is a 3.3v device that supports an I<sup>2</sup>C interface, and it is available with either a continuous (-C) or pulsed (-P) operating mode. </div> <div class="e_p"> Interfacing the device is relatively easy. There are no commands to send. You do not write to the device's address at all, and the datasheet cautions that having the write bit set when addressing the chip can seriously interfere with its functionality. Instead, you simply read 9 bytes from the fixed I<sup>2</sup>C address. </div> <div class="e_p"> Within those 9 bytes, you have a status byte (0x0 = ok, 0x01 = busy, 0x10 = warming up, which takes ~5 min, and 0x80 = error), sensor resistance (ohms) and, of course, the CO<sub>2</sub> and TVOC equivalent values. The datasheet contains more details. </div> <div class="e_p"> HIH-6131 Humidity/Temperature Sensor </div> <div class="e_p"> To provide measurements for temperature and relative humidity, I chose the Honeywell HIH-6131. This SMT chip has a supply voltage range of 1.8v-5.5v, making it suitable for 3.3v operation. It also uses an I<sup>2</sup>C interface and the address can even be programmed, although I had no need for that feature. The chip has some alarm features, which I also did not need for this project. </div> <div class="e_p"> Using the chip is relatively easy and there are Arduino libraries and code samples around for your use (example here). For my specific application, I did not need a library as you can get the humidity and temperature values with only a few lines of code. </div> <div class="e_p"> Basically, after waking the chip up, you read 4 bytes of data. The first byte includes two status bits: 00 = normal, 01 = stale data (click here for the definition of "stale data"), 10 = in command mode, 11 = not used. All other bits in the four bytes are used to convey relative humidity and temperature data that can be easily converted to RH percentage and degrees Celsius (which I converted to Fahrenheit). </div> <div class="e_p"> Because it is an SMT IC, I used a small carrier board. With some careful soldering, it is not too difficult to manage and will allow you to mount header pins for easy access to the IC pins. </div> <div class="e_p"> LCD Display </div> <div class="e_p"> To display the sensor values, I decided to use a Grove RGB backlit LCD (available here and here). This I<sup>2</sup>C display has two particularly desirable features for the project. </div> <div class="e_p"> First, while the LCD is 5v, the I<sup>2</sup>C I/O is 3.3v/5v compatible, making it easy to use with the Arduino 101 which has 3.3v I/O. Second, the backlight is configurable and I wanted to use that feature to communicate certain conditions. That is, green for normal and blue when a central device has connected over BLE. <span style="font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;text-indent:0em;">I chose the Arduino 101 (USA) / Genuino 101 (outside of the USA) board for the microcomputer. This is a 3.3v board with the Intel Curie module, but also with a lot of Arduino familiarity and ease of use. Another feature is that it comes with BLE capabilities on the board and a CurieBLE library. In addition to the information links in the references section above, there is a dedicated forum for the board here.</span> </div> <div class="e_p"> <span style="font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;text-indent:0em;">It is straightforward and uses relatively few parts. Both sensors are attached to the Arduino's I</span><sup>2</sup><span style="font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;text-indent:0em;">C pins and I used 2.2K pull-up resistors on the I</span><sup>2</sup><span style="font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;text-indent:0em;">C bus, which is powered by the 3.3v line that is available on the Arduino header. The 3.3v line also powers the sensors. The LCD I/O is also on the 3.3v I</span><sup>2</sup><span style="font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;text-indent:0em;">C bus, but it is powered by the 5v line, which is also available on the Arduino header.</span> </div> <div class="e_p"> Add a few capacitors and the circuit is complete. Note that I used a 0.22 μF polarized capacitor for C1 because that's what I had on hand, but a (non-polarized) ceramic capacitor is the standard choice for power-supply decoupling. </div> <div class="e_p"> The iAQ-Core-C sensor module is available through several online suppliers including Mouser. The HIH-6131 sensor is also available from online sources including Digi-Key. I used a convenient case to enclose the project, and I also used this extension for the case. </div> <div class="e_p"> When you power up the air quality monitor, using either USB or through the Arduino external power connection (see specifications link), the display will light in a few seconds with a green backlight. From left to right and top to bottom, the diplay will show sensor output for: RH, Temperature (F), CO<sub>2</sub> equivalent, and TVOC equivalent values. </div> <div class="e_p"> As mentioned, normally, the iAQ Core chip takes a few minutes to warm up. During this time, you will see a warm-up code instead of the values. Similarly, if other errors occur with either sensor, the appropriate error code will be displayed instead of a value. </div> <div class="e_p"> If you exhale close to either sensor, you should see a jump in the RH value as well as the CO<sub>2</sub> equivalent value. If you place the monitor in various home environments, like the kitchen when cooking, you will get an idea of the range of values. </div> <div class="e_p"> Note also that iAQ values outside of the specified sensing range can be displayed, as is mentioned in the datasheet, and I preserved that characteristic in the software. The LCD values will refresh every two seconds, and that rate can be changed in the program code. </div> <div class="e_p"> An easy way to test the BLE connectivity is to use nRF Connect for mobile (previously called nRF Master Control Panel). This free software is an impressive tool. Install it on your device (I used one with an Android OS), run it, and scan for BLE devices. </div> <div class="e_p"> If you examine the program code, you will see where these variables are transmitted, as well as their type. For example, the second value, which is circled in red, is 0xc2, 0x01, 0x00, 0x00. This value is for the CO<sub>2</sub> measure which is a 16-bit integer. The first two bytes of the value represent this integer in "LSB, MSB" format. That is, the integer value is 0x01c2, which is decimal 450, which was the CO<sub>2</sub> reading on the LCD at the time of the screenshot. </div> <div class="e_p"> The TVOC variable is a long integer (32 bits), and RH and temperature are floating-point values—you could translate those as well. </div> <div class="e_p"> Examination of the code will also reveal the assignment of a universally unique identifier (UUID) for each characteristic. These are generated using random numbers and were the product of using an online generator. </div> <div class="e_p"> The nRF Connect app does not replace a custom app for the monitor which you could write for your device, but it is a very easy way to see what is going on and to verify the BLE functionality. </div> <div class="e_p"> Code </div> <div class="e_p"> Below, you can download the complete Arduino code for the Indoor Air Quality Monitor. It is straightforward and should not be too difficult for you to customize, if you are so inclined. </div> <div class="e_p"> For reference, this is the setup I used to write the code: </div> <ul> <li> Windows 7, 64 bit </li> <li> Arduino 1.6.7 </li> <li> Intel Curie Board 1.0.6 (as installed through the Arduino Board Manager) </li> <li> Samsung Galaxy Notepad Pro 12.2 (as a central BLE device) </li> </ul> </div>
101
comment
All comments
Unknown
2134
0
101
Rules about cashback: 1. Valid time: ALLPCB cashback activity will end on April 1st. 2. Capped amount: The capped amount of cashback for each account is $5,000. Each order can get a maximum of $2,000 cashback. That means every author can get $5,000 max. 3. Cashback range: The cashback activity only covers the corresponding PCB order. The order amount for other combined payment products will be invalid. 4. Clicking your own promotional link will be invalid. The same email address, shipping address, contact information, and phone number are all recognized as the same account. 5. ALLPCB has the final interpretation right of the cashback activity.
ALLPCB will donate 2% to the author for this promotion link.