Appendix3

docx

School

Sheridan College *

*We aren’t endorsed by this school

Course

10734

Subject

Mechanical Engineering

Date

Apr 3, 2024

Type

docx

Pages

13

Uploaded by andso90

Report
1 MQ131 Sensor
2 Table of Contents 1 Abstract ................................................................................................................................................ 3 2 Introduction to the Project ................................................................................................................... 3 2.1 Introduction to AirMonitor app .................................................................................................... 3 2.2 Introduction to the sensors ........................................................................................................... 3 2.3 Introduction to the MQ131 ........................................................................................................... 4 3 Proposal ............................................................................................................................................... 4 3.1 Summary ...................................................................................................................................... 4 3.2 Conclusion ................................................................................................................................... 4 4 Introduction to CPU and Schematic ..................................................................................................... 5 5 Testing Procedures ............................................................................................................................... 7 6 Github Link .......................................................................................................................................... 7 7 Testing and troubleshooting ................................................................................................................. 7 8 References ........................................................................................................................................... 9 9 Appendix ............................................................................................................................................. 9 9.1 Mq.py ........................................................................................................................................... 9 9.2 MCP3008.py .............................................................................................................................. 12 9.3 Example.py ................................................................................................................................ 13
3 1 Abstract The project my group and I are creating is an Air Quality app that monitors the air quality in the environment it is in, whether that is a house, warehouse, or outside. The sensors will be held inside a device that consumers can buy and set up wherever they want. The consumer can then use the devices code only unique to theirs or use a QR code to connect the device to the mobile app. The mobile app has many quality-of-life features that are useful for the consumer. The front page provides the readings of the sensors which can read many gases and air particles such as, carbon monoxide, temperature, humidity, volatile organic compounds, and the ozone. The second page has extra readings that might be important for the consumer in their environment. 2 Introduction to the Project 2.1 Introduction to AirMonitor app This project consists of 4 sensors, MQ131, BME680, MiCS5524, and the . These sensors are used to create an air monitoring device that can be set up in buildings to then track the air quality in the environment. The device connects to the app, AirMonitor, through a QR code or a serial number that is found on the device. The app consists of a few pages that are user friendly and easy to navigate. 2.2 Introduction to the sensors The MQ131 sensor is a low concentration sensor that detects natural gases in the air such as ozone, carbon monoxide, liquefied petroleum gas, etc. This sensor is primarily being used for its ability to detect the ozone. The BME680 sensor detects the temperature, humidity, and
Your preview ends here
Eager to read complete document? Join bartleby learn and gain access to the full version
  • Access to all documents
  • Unlimited textbook solutions
  • 24/7 expert homework help
4 pressure. The MiCS5524 detects carbon monoxide, alcohol, and volatile organic compounds (VOC). 2.3 Introduction to the MQ131 The sensor that I’ve been assigned to is the MQ131 low concentration ozone sensor. The low concentration model has lower conductivity in clean air. When ozone gas is present, the sensors conductivity gets lower while the gas concentration rises. Although the MQ131 ozone gas sensor has high sensitivity to ozone, it also has sensitivity to oxides such as chlorine, nitrogen dioxide, carbon monoxide, etc. The MQ131 sensor has a long lifespan, comes to a low cost, and is widely used in portable ozone concentration detectors and alarms. 3 Proposal 3.1 Summary Plan to use the MQ131 gas sensor with a Raspberry Pi, to do this I need to get a MCP3008 ADC and an BSS138 bi-directional logic-level-converter to then implement the values the sensor gets to the AirMonitor app that is designed by my group and me. I need to connect the MQ131 to the ADC since the MQ131 uses an analog output and then connect the MCP3008 to the logic- level-converter to convert the 5V needed to supply the MQ131 gas sensor to a 3.3V power supply to safely connect to the Raspberry Pi. 3.2 Conclusion The conclusion is to use this PCB design of the MQ131 and connect it to my other groups sensors PCB designs to create the device used to output data to the AirMonitor app. The device can be sold to consumers and commercial buildings/warehouses, and the sensors will pick up on
5 the air particles and gases and constantly send updates to the app where users can be informed if the values get too high. 4 Introduction to CPU and Schematic This schematic is the final schematic for the MQ131 sensor alone. On the very right we see “MQ BREAKOUT” which is the sensor, the MQ131 uses AO which is the sensors analog output, and the 5V that is the voltage being supplied to the sensor. Connected to the sensor we have the MCP3008 or the ADC (Analog-to-Digital converter) and provides the MQ131 with an SPI (Serial Peripheral Interface) interface, the MQ131 is connected to the first channel (CH0) but it is possible to connect 8 devices to the MCP3008 since it has 8 channels. From top to bottom, we have the Vdd which is the power supply for the MCP3008 it uses 5V. The Vref is the reference voltage which is connected to the same 5V power supply. AGND is the analog ground. CLK is the serial clock, the serial clock is user to initiate a conversion and clock out each bit of
6 conversion as it takes place. The Dout and Din is the serial data out and data in, used to load and unload channel configuration data into the device. CS is the chip select, its used to start and end a communication with the device. Finally, the DGND is the digital ground. To the right of the MCP3008, we have the BSS138 bi-directional logic-level-converter. Since the Raspberry Pi can only be powered on with a 3.3V power supply and the MQ131 requires a 5V power supply, it is important to convert the power level to safely use the sensor on the Pi and not do any damage to the device itself. The 5V supply goes into the HV pin while the serial clock (CLK), Dout (digital out), Din (digital in), and the CS (chip select) is connected to the B pins. The voltage is then converted to 3.3V which is shown as the LV pin, the serial clock and chip select is converted. The MISO and MOSI pins stand for “Master in, slave out” and “Master out, slave in”, which are data lines. MOSI sends out data from the main while MISO sends out data to the main. Lastly, we have the Raspberry Pi itself, the Pi has specific GPIO pins for the SPI outputs from the MCP3008 and BSS138 logic-level-converter. The MOSI goes into GPIO10, the MISO in the GPIO9, both pins are specific to SPI MOSI and MISO. The serial clock (SCLK) also has a GPIO pin specifically for SPI serial clock which is the pin under MISO, GPIO11. The chip select (CS) is assigned to GPIO8 and is the first channel (or channel 0) of the chip enables GPIO pins. GPIO24 is connect to an LED circuit with 2 resistors, one being 330 ohms and the other 2.2k ohms which helps limit the current in the circuit and a transistor that is used like a switch, allowing additional amplification to the circuit.
Your preview ends here
Eager to read complete document? Join bartleby learn and gain access to the full version
  • Access to all documents
  • Unlimited textbook solutions
  • 24/7 expert homework help
7 5 Testing Procedures The testing procedures were to follow and completely understand the sensor and the other components so that, this is especially important with the components I have since we are dealing with supplying the sensor with 5V and converting it to 3.3V so that the Raspberry Pi can safely be used. If this was not done correctly then there is potential of not only damaging the components but the Raspberry Pi itself. Testing and designing the PCB was tedious work because if a single wire crossed it would’ve meant that the connection being crossed would become unusable and potentially cause harm to the circuit. 6 Github Link https://github.com/jacobStephens0088/AirMonitor 7 Testing and troubleshooting All the troubleshooting that was done was researching the curve values of the MQ131 sensor, the sensitivity curve reads the concentration in parts per billion (ppb) and the resistance ratio of the MQ131 (Rs/R0).
8 This graph shows the difference of resistance ration of MQ131 between air and O3. Rs means resistance of sensor in target gas with different concentration and R0 means resistance of sensor in clean air. This graph shows the Rs/R0 specifically for O3 alone, the y index shows the part per billion. From here I took two different values, (x = 10, y = 1.12) and (x = 1000, y = 7.5), I did
9 this to find the “real” values using the ten logarithms. To find the slope I used two-point form, (log10(7.5) – log10(1.12)) / (log10(1000) – log10(10)) = 0.41. The carbon monoxide and smoke curve values were given to me when cloning the github Raspberry-Pi-Gas-Sensor-MQ. 8 References MQ131 Datasheet . (n.d.). [Dataset]. Sparkfun. https://cdn.sparkfun.com/assets/9/9/6/e/4/mq131- datasheet-low.pdf BSS138 . (n.d.). [Dataset]. Adafruit. https://cdn-shop.adafruit.com/datasheets/BSS138.pdf MCP3008 Database . (n.d.). [Dataset]. Adafruit. https://cdn-shop.adafruit.com/datasheets/MCP3008.pdf RPi, tut. (2016, October 10). TUTRPI/raspberry-pi-gas-sensor-MQ: Raspberry Pi Library for several MQ gas sensors (MQ-2, MQ-3, etc..) . GitHub. Retrieved December 16, 2022, from https://github.com/tutRPi/Raspberry-Pi-Gas-Sensor-MQ 9 Appendix 9.1 Mq.py import time import math from MCP3008 import MCP3008 class MQ(): ######################### Hardware Related Macros ######################### MQ_PIN = 0 # define which analog input channel you are going to use (MCP3008) RL_VALUE = 5 # define the load resistance on the board, in kilo ohms RO_CLEAN_AIR_FACTOR = 9.83 # RO_CLEAR_AIR_FACTOR=(Sensor resistance in clean air)/RO, # which is derived from the chart in datasheet
Your preview ends here
Eager to read complete document? Join bartleby learn and gain access to the full version
  • Access to all documents
  • Unlimited textbook solutions
  • 24/7 expert homework help
10 ######################### Software Related Macros ######################### CALIBARAION_SAMPLE_TIMES = 50 # define how many samples you are going to take in the calibration phase CALIBRATION_SAMPLE_INTERVAL = 500 # define the time interval(in milisecond) between each samples in the # cablibration phase READ_SAMPLE_INTERVAL = 50 # define the time interval(in milisecond) between each samples in READ_SAMPLE_TIMES = 5 # define how many samples you are going to take in normal operation # normal operation ######################### Application Related Macros ###################### GAS_OZ = 0 GAS_CO = 1 GAS_SMOKE = 2 def init (self, Ro=10, analogPin=0): self.Ro = Ro self.MQ_PIN = analogPin self.adc = MCP3008() self.OZCurve = [1.0,0.049,0.41] # two points are taken from the curve. # with these two points, a line is formed which is "approximately equivalent" # to the original curve. # data format:{ x, y, slope}; point1: (lg200, 0.21), point2: (lg10000, - 0.59) self.COCurve = [2.3,0.72,-0.34] # two points are taken from the curve. # with these two points, a line is formed which is "approximately equivalent" # to the original curve. # data format:[ x, y, slope]; point1: (lg200, 0.72), point2: (lg10000, 0.15) self.SmokeCurve =[2.3,0.53,-0.44] # two points are taken from the curve. # with these two points, a line is formed which is "approximately equivalent" # to the original curve. # data format:[ x, y, slope]; point1: (lg200, 0.53), point2: (lg10000, -0.22) print("Calibrating...") self.Ro = self.MQCalibration(self.MQ_PIN) print("Calibration is done...\n") print("Ro= %f kohm" % self.Ro) def MQPercentage(self): val = {} read = self.MQRead(self.MQ_PIN) val["GAS_OZ"] = self.MQGetGasPercentage(read/self.Ro, self.GAS_OZ) val["CO"] = self.MQGetGasPercentage(read/self.Ro, self.GAS_CO) val["SMOKE"] = self.MQGetGasPercentage(read/self.Ro, self.GAS_SMOKE) return val ######################### MQResistanceCalculation #########################
11 # Input: raw_adc - raw value read from adc, which represents the voltage # Output: the calculated sensor resistance # Remarks: The sensor and the load resistor forms a voltage divider. Given the voltage # across the load resistor and its resistance, the resistance of the sensor # could be derived. ############################################################################ def MQResistanceCalculation(self, raw_adc): return float(self.RL_VALUE*(1023.0-raw_adc)/float(raw_adc)); ######################### MQCalibration #################################### # Input: mq_pin - analog channel # Output: Ro of the sensor # Remarks: This function assumes that the sensor is in clean air. It use # MQResistanceCalculation to calculates the sensor resistance in clean air # and then divides it with RO_CLEAN_AIR_FACTOR. RO_CLEAN_AIR_FACTOR is about #10, which differs slightly between different sensors. ############################################################################ def MQCalibration(self, mq_pin): val = 0.0 for i in range(self.CALIBARAION_SAMPLE_TIMES): # take multiple samples val += self.MQResistanceCalculation(self.adc.read(mq_pin)) time.sleep(self.CALIBRATION_SAMPLE_INTERVAL/1000.0) val = val/self.CALIBARAION_SAMPLE_TIMES # calculate the average value val = val/self.RO_CLEAN_AIR_FACTOR # divided by RO_CLEAN_AIR_FACTOR yields the Ro # according to the chart in the datasheet return val; ######################### MQRead ########################################## # Input: mq_pin - analog channel # Output: Rs of the sensor # Remarks: This function use MQResistanceCalculation to caculate the sensor resistenc (Rs). # The Rs changes as the sensor is in the different consentration of the target # gas. The sample times and the time interval between samples could be configured #by changing the definition of the macros. ############################################################################ def MQRead(self, mq_pin): rs = 0.0 for i in range(self.READ_SAMPLE_TIMES): rs += self.MQResistanceCalculation(self.adc.read(mq_pin)) time.sleep(self.READ_SAMPLE_INTERVAL/1000.0) rs = rs/self.READ_SAMPLE_TIMES
12 return rs ######################### MQGetGasPercentage ############################## # Input: rs_ro_ratio - Rs divided by Ro # gas_id - target gas type # Output: ppm of the target gas # Remarks: This function passes different curves to the MQGetPercentage function which # calculates the ppm (parts per million) of the target gas. ############################################################################ def MQGetGasPercentage(self, rs_ro_ratio, gas_id): if ( gas_id == self.GAS_OZ ): return self.MQGetPercentage(rs_ro_ratio, self.OZCurve) elif ( gas_id == self.GAS_CO ): return self.MQGetPercentage(rs_ro_ratio, self.COCurve) elif ( gas_id == self.GAS_SMOKE ): return self.MQGetPercentage(rs_ro_ratio, self.SmokeCurve) return 0 ######################### MQGetPercentage ################################# # Input: rs_ro_ratio - Rs divided by Ro # pcurve - pointer to the curve of the target gas # Output: ppm of the target gas # Remarks: By using the slope and a point of the line. The x(logarithmic value of ppm) #of the line could be derived if y(rs_ro_ratio) is provided. As it is a # logarithmic coordinate, power of 10 is used to convert the result to non- logarithmic # value. ############################################################################ def MQGetPercentage(self, rs_ro_ratio, pcurve): return (math.pow(10,( ((math.log(rs_ro_ratio)-pcurve[1])/ pcurve[2]) + pcurve[0]))) 9.2 MCP3008.py from spidev import SpiDev class MCP3008: def init (self, bus = 0, device = 0): self.bus, self.device = bus, device self.spi = SpiDev() self.open() self.spi.max_speed_hz = 1000000 # 1MHz def open(self): self.spi.open(self.bus, self.device) self.spi.max_speed_hz = 1000000 # 1MHz def read(self, channel = 0): cmd1 = 4 | 2 | (( channel & 4) >> 2) cmd2 = (channel & 3) << 6
Your preview ends here
Eager to read complete document? Join bartleby learn and gain access to the full version
  • Access to all documents
  • Unlimited textbook solutions
  • 24/7 expert homework help
13 adc = self.spi.xfer2([cmd1, cmd2, 0]) data = ((adc[1] & 15) << 8) + adc[2] return data def close(self): self.spi.close() 9.3 Example.py from mq import * import RPi.GPIO as GPIO import sys, time LED_PIN = 24 GPIO.setwarnings(False) GPIO.setmode(GPIO.BCM) GPIO.setup(GPIO.OUT) try: print("Press CTRL+C to abort.") mq = MQ(); while True: GPIO.output(LED_PIN, GPIO.HIGH) sleep(1) GPIO.output(LED_PIN, GPIO.LOW) sleep(1) perc = mq.MQPercentage() sys.stdout.write("\r") sys.stdout.write("\033[K") sys.stdout.write("O3: %g ppm, CO: %g ppm, Smoke: %g ppm" % (perc["GAS_OZ"], perc["CO"], perc["SMOKE"])) sys.stdout.flush() time.sleep(0.1) except: print("\nAbort by user")