Sensores de gas MQ leer y calcular ppm
En este caso no se trata de un único sensor sino de toda una gama de ellos. Los que voy a usar son MQ2, MQ3, MQ4, MQ5, MQ7, MQ8, MQ9 y MQ135. También había adquirido un MQ6, pero este me llegó defectuoso.
Muchos de los sensores comparten la medición del mismo gas, pero en total mide los siguiente gases: propano, humo, benceno, acetona, tolueno, hidrogeno, metano, GPL, alcohol y monóxido de carbono al que nos dirigiremos de ahora en adelante como CO
Estos sensores no son de precisión ni profesionales. Son simplemente para uso didactico por lo que tampoco hay que prestarle mucha atención a los resultados que nos arroja.
Teoría
Cada sensor MQ es sensible a uno o varios tipos de gases. Si el sensor es sensible a varios tipos de gases al detectar uno en gran cantidad el resto de gases del mismo sensor también los leerá más alto, más adelante en este apartado explico por qué, así que teniendo toda una red de sensores podemos determinar de una forma más eficaz que gas tiene realmente una alta concentración.
Los sensores MQ contienen una resistencia variable en su interior la cual reacciona con X gas haciendo que pase más voltaje a través de la resistencia. Lo que mido realmente de los sensores es el voltaje de la salida analógica por lo que al detectar un aumento del voltaje sé que ha aumentado la concentración de uno de los gases que lee el sensor
Para leer este voltaje de salida usaremos los ADC como lo hemos hecho en la lectura de la veleta. El ADC funciona a 3.3 voltios mientras que los sensores MQ funcionan a 5 voltios. Según la ficha técnica del fabricante de los ADC modelo ADS1115 se puede conectar tanto a 3.3 como a 5 voltios y puede soportar hasta 2 voltios más de los que tiene de entrada. Por lo que si uso 3.3 voltios el conversor aguanta hasta 5.3 voltios.
Aviso: He usado voltaje de 3.3 en los ADC debido a que con una alimentación de 5 voltios generaba inestabilidad en los canales SDA y SCL por lo que podían dejar de funcionar las comunicaciones de todos los sensores con las Raspberry Pi.
Los sensores MQ tiene un pequeño quemador de hasta 0.8 amperios para catalizar las reacciones químicas ocurridas en el interior de su malla y obtener una buena lectura de estos. Debido al consumo eléctrico que tienen he tenido que usar un alimentador externo de 10A y 5V para poder suplir el consumo energético. El alimentador usado es el S-50-5 de Leadstar. Si intentas conectar todos los sensores MQ a la raspberry Pi puede que esta no te arranque o que se ropa debido a la cantidad de energía que se le está pidiendo.
Los sensores se han tenido encendidos entre 24 y 48 horas antes de su uso como recomienda el fabricante para eliminar posibles residuos que se hayan quedado adheridos a la resistencia generados en la producción de los sensores.
Cableado
Antes de cablear los sensores de gas tenemos que cablear los ADC para poder leer las señales analógicas.
- Pin VDD: se conecta a un pin 3.3V de la placa.
- Pin GND: se conecta a un pin GND de la placa y al negativo del alimentador para que los sensores MQ puedan tener un circuito cerrado y así recibir datos del pin analógico.
- Pin SCL: se conecta al pin SCL de la placa.
- Pin SCA: se conecta al pin SCA de la placa.
Como ya hemos visto en el caso del SHT31 al tener varios chips I2C del mismo modelo por lo que tenemos que cambiar la ruta de comunicación de estos para que cada uno pueda comunicarse independientemente con la Raspberry Pi. El ADC de la veleta usa la ruta 0x48 por lo que ahora usaremos la ruta 0x49 para el primer ADC que se consigue conectando el pin address del chip un cable con 3.3 voltios de entrada. Le asignamos la ruta 0x4a para el segundo ADC conectando su pin address al pin SDA.
Todos los sensores MQ tienen cuatro pines. Todos los pines VCC se conectar al alimentador externo de 5V y los GND al negativo del alimentador externo. En cuanto a los pines de salida digital se conecta cada uno a un pin GPIO de la placa y los pines de salida analógica cada uno a un canal diferente de entrada. Las conexiones son las siguientes:
MQ2 | MQ3 | MQ4 | MQ5 | MQ7 | MQ8 | MQ9 | MQ135 | |
---|---|---|---|---|---|---|---|---|
Pin digital | GPIO 14 | GPIO 15 | GPIO 23 | GPIO 24 | GPIO 25 | GPIO 17 | GPIO 27 | GPIO 22 |
Pin analógico | 0x49 canal 0 | 0x49 canal 1 | 0x49 canal 2 | 0x49 canal 3 | 0x4a canal 0 | 0x4a canal 1 | 0x4a canal 2 | 0x4a canal 3 |
Como el esque es algo complejo vamos a comentar para qué se ha usado cada color de los cables y así tener más claro el esquema:
- Rojo: Es el positivo. Proporciona tanto la enegía de 3.3v como la de 5v. (No se juntan nunga los dos voltajes)
- Negro: El negativo/tierra. Aquí si que están conectado tanto los ADC de 3.3v como los sensores MQ de 5v a la misma línea.
- Azul: Es el canal SCL.
- Naranja: Es el canal SDA.
- Morado: Son los canales digitales de los sensores mq que lanza una señal de alarma cuando la concentración de gas es algo.
Una vez visto esto dejo la representación gráfica de como está conectado todo.

Y si quieres ver el esquema que puede que para algunas conexiones sea más facil de ver como está conectado lo muestro tambien:
Calculos - Calibración
Cómo lo que recibimos de los sensores de gas son únicamente voltajes tenemos que mirar las fichas técnicas de cada sensor para poder determinar su sensibilidad a cada gas y de esta forma sacar su concentración en PPM.
Antes de nedada tenemos que calcular la resistencia inicial que tiene cada sensor. Usaremos los siguientes datos para calcularlo:
- Las resistencia del PCB que mostraré para calcular R0 se obtiene mirando el sensor por la parte trasera y fijándote en el número de la resistencia central. En mi caso todos los sensores tienen la resistencia 102 que es una resistencia de 1 kΩ.
- El voltaje de entrada es el voltaje con el que se alimenta el sensor de gas. Suele ser 5V aunque en mi caso midiendolo le llegan 4.9V.
- El voltaje inicial es aquel que nos da el sensor en el pin de salida en un entorno concentración nula del gas que mide a 20ºC y 65% de humedad. Cada sensor dará un voltaje diferente. Es crucial dejar el sensor MQ encendido durante varios dias para quemar los residuos que pueda tener la resistencia y así obtener unos voltajes estables.
- Resistencia al aire. En las tablas que pondré para calcular cada gas veremos que siembre hay una línea que en la leyenda pone "air" hay poner el valor de esta linea como resistencia al aire. Los números exactos de la resistencia al aire ya los he sacado con y se pueden ver en los calculos de cada sensor de gas por lo que no es necesario que midas la tabla para obtener el valor.
La fórmula para obtener la resistencia inicial de un sensor al aire es la siguiente:
Lo segundo que vamos a calcular son las curvas de concentración de gases que tiene cada sensor. Como las fichas técnicas de las que tenemos que sacar los datos para las curvas de concentración y la resistencia al aire de cada sensor no nos lo pone de forma numérica he tenido que sacar estos datos de los gráficos logarítmicos de base 10 que mostraré a continuación mediante una plantilla de Excel y midiendo la distancia de los puntos entre su margen superior e inferior para obtener los datos.
Para obtener la trayectoria de cada gas necesitamos un punto inicial de la gráfica en logaritmo de base 10. En mi caso siempre he cogido el punto de menor concentración de cada gas en cada tabla como punto inicial. Ahora que tenemos un punto de la gráfica tenemos que saber la curvatura que tiene determinado gas en determinado sensor. De esta forma teniendo el eje X e Y más la curva del gas podemos conocer la concentración del gas en todas las situaciones con bastante veracidad.
Nota: La curva no es necesario que la calcules, ya la he calculado yo y siempre va ha ser la misma. Por lo que si no te intera calcula solo la resistencia inicial y saltas a la parte del código directamente que ya está puesto las curvaturas de cada sensor para cada gas.
MQ2
Cálculos de R0:
- Resistencia al aire: 9,7 RS/R0
- Voltaje entrada: 4,9 V
- Voltaje inicial: 0,114 V
- Resistencia PCB: 1 kΩ

Cálculos para el punto de referencia y curvatura para los distintos gases:
GPL
- Punto inicial: X = 200 PPM, Y = 1.7 RS/R0
- Punto final: X = 10000 PPM, Y = 0.26 RS/R0
X referencia = log10(200) = 2,301030
Y referencia = log10(1.7) = 0.230449
PROPANO
- Punto inicial: X = 200 PPM, Y = 1.78 RS/R0
- Punto final: X = 10000 PPM, Y = 0.28 RS/R0
X referencia = log10(200) = 2,301030
Y referencia = log10(1.78) = 0.250420
HIDÓGENO
- Punto inicial: X = 200 PPM, Y = 2.1 RS/R0
- Punto final: X = 10000 PPM, Y = 0.33 RS/R0
X referencia = log10(200) = 2,301030
Y referencia = log10(2.1) = 0.322219
ALCOHOL
- Punto inicial: X = 200 PPM, Y = 2.89 RS/R0
- Punto final: X = 10000 PPM, Y = 0.65 RS/R0
X referencia = log10(200) = 2,301030
Y referencia = log10(2.89) = 0.460898
HUMO
- Punto inicial: X = 200 PPM, Y = 3.43 RS/R0
- Punto final: X = 10000 PPM, Y = 0.61 RS/R0
X referencia = log10(200) = 2,301030
Y referencia = log10(3.43) = 0.535294
METANO
- Punto inicial: X = 200 PPM, Y = 3.05 RS/R0
- Punto final: X = 10000 PPM, Y = 0.69 RS/R0
X referencia = log10(200) = 2,301030
Y referencia = log10(3.05) = 0.484300
Los datos de calibración a ingresar en el futuro programa es que el sensor MQ2 tiene una R0 = 4.328 y la tabla con el punto de referencia de cada gas y su respectiva curva.
Eje X | Eje Y | Curva | |
---|---|---|---|
GPL | 2.301030 | 0.230449 | -0.479982 |
PROPANO | 2.301030 | 0.250420 | -0.472793 |
HIDRÓGENO | 2.301030 | 0.322219 | -0.473054 |
ALCOHOL | 2.301030 | 0.460898 | -0.381398 |
HUMO | 2.301030 | 0.535294 | -0.441422 |
METANO | 2.301030 | 0.4842300 | -0.379907 |
MQ3
Cálculos de R0:
- Resistencia al aire: 60 RS/R0
- Voltaje entrada: 4,9 V
- Voltaje inicial: 0,300 V
- Resistencia PCB: 1 kΩ

Cálculos para el punto de referencia y curvatura para los distintos gases:
ALCOHOL
- Punto inicial: X = 0.1 PPM, Y = 2.28 RS/R0
- Punto final: X = 10 PPM, Y = 0.26 RS/R0
X referencia = log10(0.1) = -1
Y referencia = log10(2.28) = 0.357935
BENCENO
- Punto inicial: X = 0.1 PPM, Y = 4.49 RS/R0
- Punto final: X = 10 PPM, Y = 0.8 RS/R0
X referencia = log10(0.1) = -1
Y referencia = log10(4.49) = 0.652246
Los datos de calibración a ingresar en el futuro programa es que el sensor MQ3 tiene una R0 = 0.255 y la tabla con el punto de referencia de cada gas y su respectiva curva.
Eje X | Eje Y | Curva | |
---|---|---|---|
ALCOHOL | -1 | 0.357935 | -0.471481 |
BENCENO | 2.301030 | 0.652246 | -0.374578 |
MQ4
Cálculos de R0:
- Resistencia al aire: 4.45 RS/R0
- Voltaje entrada: 4,9 V
- Voltaje inicial: 1,150 V
- Resistencia PCB: 1 kΩ

Cálculos para el punto de referencia y curvatura para los distintos gases:
METANO
- Punto inicial: X = 200 PPM, Y = 1.8 RS/R0
- Punto final: X = 10000 PPM, Y = 0.44 RS/R0
X referencia = log10(200) = 2.301030
Y referencia = log10(1.8) = 0.255273
GPL
- Punto inicial: X = 200 PPM, Y = 2.6 RS/R0
- Punto final: X = 10000 PPM, Y = 0.73 RS/R0
X referencia = log10(200) = 2.301030
Y referencia = log10(2.6) = 0.414973
Los datos de calibración a ingresar en el futuro programa es que el sensor MQ4 tiene una R0 = 0.733 y la tabla con el punto de referencia de cada gas y su respectiva curva.
Eje X | Eje Y | Curva | |
---|---|---|---|
METANO | 2.301030 | 0.255273 | -0.360112 |
GPL | 2.301030 | 0.414973 | -0.324697 |
MQ5
Cálculos de R0:
- Resistencia al aire: 6.5 RS/R0
- Voltaje entrada: 4,9 V
- Voltaje inicial: 0.848 V
- Resistencia PCB: 1 kΩ

Cálculos para el punto de referencia y curvatura para los distintos gases:
GPL
- Punto inicial: X = 200 PPM, Y = 0.7 RS/R0
- Punto final: X = 10000 PPM, Y = 0.155 RS/R0
X referencia = log10(200) = 2.301030
Y referencia = log10(0.7) = -0.154902
METANO
- Punto inicial: X = 200 PPM, Y = 0.94 RS/R0
- Punto final: X = 10000 PPM, Y = 0.207 RS/R0
X referencia = log10(200) = 2.301030
Y referencia = log10(0.94) = -0.026872
Los datos de calibración a ingresar en el futuro programa es que el sensor MQ5 tiene una R0 = 0.735 y la tabla con el punto de referencia de cada gas y su respectiva curva.
Eje X | Eje Y | Curva | |
---|---|---|---|
GPL | 2.301030 | -0.154902 | -0.358375 |
METANO | 2.301030 | -0.026872 | -0.386798 |
MQ7
Cálculos de R0:
- Resistencia al aire: 26.75 RS/R0
- Voltaje entrada: 4,9 V
- Voltaje inicial: 0.626 V
- Resistencia PCB: 1 kΩ

Cálculos para el punto de referencia y curvatura para los distintos gases:
HIDRÓGENO
- Punto inicial: X = 50 PPM, Y = 1.36 RS/R0
- Punto final: X = 4000 PPM, Y = 0.09 RS/R0
X referencia = log10(50) = 1.698970
Y referencia = log10(1.36) = 0.133539
CO (Monóxido de carbono)
- Punto inicial: X = 50 PPM, Y = 1.66 RS/R0
- Punto final: X = 4000 PPM, Y = 0.052 RS/R0
X referencia = log10(50) = 1.698970
Y referencia = log10(1.36) = -0.220108
Los datos de calibración a ingresar en el futuro programa es que el sensor MQ7 tiene una R0 = 0.255 y la tabla con el punto de referencia de cada gas y su respectiva curva.
Eje X | Eje Y | Curva | |
---|---|---|---|
HIDRÓGENO | 1.698970 | 0.133539 | -0.619674 |
CO | 1.698970 | 0.220108 | -0.790349 |
MQ8
Cálculos de R0:
- Resistencia al aire: 70 RS/R0
- Voltaje entrada: 4,9 V
- Voltaje inicial: 1.072 V
- Resistencia PCB: 1 kΩ

Cálculos para el punto de referencia y curvatura para los distintos gases:
HIDRÓGENO
- Punto inicial: X = 200 PPM, Y = 8.56 RS/R0
- Punto final: X = 10000 PPM, Y = 0.029 RS/R0
X referencia = log10(200) = 2.301030
Y referencia = log10(8.56) = 0.932474
Los datos de calibración a ingresar en el futuro programa es que el sensor MQ8 tiene una R0 = 0.051 y la tabla con el punto de referencia de cada gas y su respectiva curva.
Eje X | Eje Y | Curva | |
---|---|---|---|
HIDRÓGENO | 2.301030 | 0.932474 | -1.453867 |
MQ9
Cálculos de R0:
- Resistencia al aire: 9.9 RS/R0
- Voltaje entrada: 4,9 V
- Voltaje inicial: 0.474 V
- Resistencia PCB: 1 kΩ

Cálculos para el punto de referencia y curvatura para los distintos gases:
CO (Monóxido de carbono)
- Punto inicial: X = 200 PPM, Y = 1.69 RS/R0
- Punto final: X = 1000 PPM, Y = 0.782 RS/R0
X referencia = log10(200) = 2.301030
Y referencia = log10(1.69) = 0.227886
GPL
- Punto inicial: X = 200 PPM, Y = 2.11 RS/R0
- Punto final: X = 10000 PPM, Y = 0.333 RS/R0
X referencia = log10(200) = 2.301030
Y referencia = log10(2.11) = 0.324282
Los datos de calibración a ingresar en el futuro programa es que el sensor MQ9 tiene una R0 = 0.943 y la tabla con el punto de referencia de cada gas y su respectiva curva.
Eje X | Eje Y | Curva | |
---|---|---|---|
CO | 2.301030 | 0.227886 | -0.478819 |
GPL | 2.301030 | 0.324282 | -0.471955 |
MQ135
Cálculos de R0:
- Resistencia al aire: 3.65 RS/R0
- Voltaje entrada: 4,9 V
- Voltaje inicial: 0.748 V
- Resistencia PCB: 1 kΩ

Cálculos para el punto de referencia y curvatura para los distintos gases:
ACETONA
- Punto inicial: X = 10 PPM, Y = 1.51 RS/R0
- Punto final: X = 200 PPM, Y = 0.579 RS/R0
X referencia = log10(10) = 1
Y referencia = log10(1.51) = 0.319976
TOLUENO
- Punto inicial: X = 10 PPM, Y = 1.62 RS/R0
- Punto final: X = 200 PPM, Y = 0.635 RS/R0
X referencia = log10(10) = 1
Y referencia = log10(1.62) = 0.209515
TOLUENO
- Punto inicial: X = 10 PPM, Y = 1.92 RS/R0
- Punto final: X = 200 PPM, Y = 0.733 RS/R0
X referencia = log10(10) = 1
Y referencia = log10(1.92) = 0.293301
Los datos de calibración a ingresar en el futuro programa es que el sensor MQ9 tiene una R0 = 0.943 y la tabla con el punto de referencia de cada gas y su respectiva curva.
Eje X | Eje Y | Curva | |
---|---|---|---|
ACETONA | 1 | 0.178977 | -0.319976 |
TOLUENO | 1 | 0.209515 | -0.312630 |
ALCOHOL | 1 | 0.283301 | -0.321435 |
Calculos - PPM
Con los cálculos previos hechos e ingresados en el programa ahora explicaré que cálculos se hacen en el interior del programa para determinar la concentración de un gas.
- Cálculo de resistencia:
RS =R pcb * (V entrada - V inicial) V inicial
- Cáculo ratio:
Ratio =Rs R0
- Cáculo concentración:
Gas ppm = 10^(ln Ration - GasEjeY GasCurva) + GasEjeX
Como es complicado verlo sin un ejemplo voy hacer un cálculo práctico cogiendo los datos del gas hidrógeno en el sensor MQ2.
Los parámetros a introducir son la resistencia de la PCB del sensor que en MQ2 es de 1K Ohms, voltaje de entrada que son 4,9 V y el voltaje de la salida analógica que imáginemos que son 0.150 V.
Para calcular el ratio necesitamos dividir el resultado obtenido antes por la R0 de sensor MQ2 que como hemos calculado previamente es 4.328
Para saber la concentración de determinado gas en PPM tenemos que calcular el exponente de la base 10. Este exponente tiene varios cálculos en su interior.
- El primer calculo que tenemos que hacer es la resta del logaritmo natural del ratio conseguido anteriormente menos la constante del eje Y para el gas a calcular, en este caso el hidrógeno del MQ2 con el valor calculado 0.322. La resta se ve así:
ln(7.317) - 0,322 = 1.668
- En segundo lugar, hay que dividir el resultado obtenido entre la curvatura calculada del gas, siendo esta curvatura para el hidrógeno en el sensor MQ2 de -0,473 quedando el cálculo de la siguiente forma:
1.668 -0.473= -3,526
- El tercer paso y con el que terminaremos de calcular el exponente es sumarle el valor de la constante del X que es 2,301:
-3.526 - 2.301 = -1,225
- Por último, teniendo el exponente ya calculado que es -0,923 simplemente tenemos que calcular 10^(-1,225)=0,059 PPM de hidrógeno leído por el sensor MQ2.
Funcionamiento
Cada sensor MQ tiene su propia clase para almacenar sus calibraciones de gases, R0, inicio de hilo de lectura propio, variables de resultados de gases, alarma y ruta I2C y GPIO usadas para la trasmisión de datos digitales y analógicos.
Como la medición es continua también dispone de un contador de ciclos de lectura y el sumatorio de voltajes leídos. El intervalo de lectura es de 5 segundos.
Como todos los sensores de gases tienen que hacer los mismos cálculos estos están en una clase a parte para evitar redundancia. Los cálculos se hacen por cada gas en cada sensor.
En el caso de que el ADC falle y no se puedan leer los gases la clase eliminará su propio hilo de ejecución para dejar de generar errores de lectura y marcará como False la variable funcionamiento para que el programa principal sepa que ese sensor no funciona. El programa principal volverá a intentar leer el sensor en el siguiente ciclo.
Código
Como se ha comentado anteriormente hay una clase por cada sensor. A parte de estas clases tenemos una clase con los métodos que usan todos los gases para calcular las PPM y otra clase que estará en la carpeta test que vamos a mostar primero.
Test
Es un script lo más sencillo posible para validar que el sensor funciona y ver su voltaje para poder calibrar los sensores. En la variable ADDRESS y PIN tendremos que poner los valores que vimos en la tabla del cableado de los sensores.
# nativas de Python
import time
# I2C comunicación
import board
import busio
# librerías del ADC ADS1115
import adafruit_ads1x15.ads1115 as ads1115
from adafruit_ads1x15.analog_in import AnalogIn
# lectura digital
from gpiozero import Button
# direccion I2C del ADS11115
ADDRESS = 0x4a # address conectado a VDD
PIN = 3 # canal analógico del chip
convertor = ads1115.ADS1115
i2c = busio.I2C(board.SCL, board.SDA)
adc = convertor(i2c=i2c, address=ADDRESS)
channel = AnalogIn(adc, PIN)
while True:
print(channel.voltage)
time.sleep(1)
Calculos PPM
Esta es la clase general que usan todos los sensores MQ para determinar su concentración de gas. Aquí llevamos a la práctica los calculos hechos en la sección de calculos.
# calculos_gas.py
import math
import logging
class Calculos:
'''Tiene los métodos necesarios para calculas las
PPM de cualquier sensor MQ'''
@classmethod
def calcular_voltaje(cls, voltaje_acumulado, cantidad_muestras):
''' Calcula el voltaje de media leido en un intervalo de tiempo'''
voltaje = 0
if (cantidad_muestras != 0):
voltaje = voltaje_acumulado / cantidad_muestras
# en el caso de que el sensor no funcione te ponemos un valor
# artificial en el voltaje para que el programa pueda seguir
# funcionando.
if(voltaje <= 0):
voltaje = 0.001
logging.error('Sensor de gas inutilizado')
return voltaje
@classmethod
def calcular_resistencia(cls, voltaje, resistencia):
'''Con el voltaje y la resistencia del PCB del sensor podemos calcular
la resistentencia que te tendrá el sensor. Esta resistencia se
representa como Rs.'''
resultado = 0
if (voltaje != 0):
resultado = float(
resistencia * (4.9 - float(voltaje)) / float(voltaje))
return resultado
@classmethod
def calcular_ppm(cls, ratio, curva_gas):
'''Mediante calculos logaritmicos nos devuelve los ppm de un gas
en particular.'''
concentracion = math.pow(
10,
((math.log(ratio) - curva_gas[1]) / curva_gas[2]) + curva_gas[0]
)
return str(round(concentracion, 3))
Clases MQ
Cada sensor tiene su propia clase ya que cada uno tiene sus propios datos.
MQ2
# sensor_mq2.py
# I2C comunicación
import board
import busio
# librerías del ADC ADS1115
import adafruit_ads1x15.ads1115 as ads1115
from adafruit_ads1x15.analog_in import AnalogIn
# lectura digital
from gpiozero import Button
# Medición por intervalos
from apscheduler.schedulers.background import BackgroundScheduler
# Calcular PPM
from calculos_gas import Calculos
# para registro de errores
import logging
# direccion I2C del ADS11115
ADDRESS = 0x49 # pin address conectado a VDD
PIN = 0 # canal analógico del chip
alarma_mq2 = 0
class MQ2:
"""Detector de gas MQ2"""
# resistencia del sensor
LOAD_RESISTANCE = 1
# pin salida digital
DOutput = Button(14)
# Ro value of the sensor
ro = 4.328
# Curva logaritmica con base 10
HIDROGENO_CURVA = [2.301030, 0.322219, -0.473054]
METANO_CURVA = [2.301030, 0.484300, -0.379901]
GPL_CURVA = [2.301030, 0.230449, -0.479982]
PROPANO_CURVA = [2.301030, 0.250420, -0.472794]
ALCOHOL_CURVA = [2.301030, 0.460898, -0.381398]
HUMO_CURVA = [2.301030, 0.535294, -0.441423]
# gas en ppm
hidrogeno_ppm = 0
metano_ppm = 0
gpl_ppm = 0
propano_ppm = 0
alcohol_ppm = 0
humo_ppm = 0
voltaje = 0
funcionamiento = True
# Contadores
voltaje_acumulado = 0
cantidad_muestras = 0
def __init__(self, convertor=ads1115.ADS1115, pin=PIN, address=ADDRESS):
'''Inicia con la lectura periodica de gases del sensor MQ2'''
# Permique que el resto del programa sigua funcionando aunque el ADC no funcione
try:
i2c = busio.I2C(board.SCL, board.SDA)
adc = convertor(i2c=i2c, address=address)
self.channel = AnalogIn(adc, pin)
self.sched_mq2 = BackgroundScheduler()
self.sched_mq2.add_job(self.leer_voltaje, 'interval',
seconds=5, id="sched_mq2")
self.sched_mq2.start()
except (ValueError, OSError):
self.funcionamiento = False
logging.error('El ADC del MQ2 ha dejado de funcionar.')
def leer_voltaje(self):
'''leerá el voltaje cada cierto tiempo y lo irá acumulando, además
lleva la cuenta de cuantos ciclos de lectura lleva.'''
# Evita que se rompa el programa en caso de que el ADC deje de funcionar a mitad
# de una lectura de voltaje.
try:
self.voltaje_acumulado += self.channel.voltage
self.cantidad_muestras += 1
except (ValueError, OSError):
self.funcionamiento = False
logging.error('El ADC del MQ2 ha dejado de funcionar.')
self.sched_mq2.remove_job("sched_mq2")
def finalizar_ciclo(self):
'''Llama a las funciones necesarias para finalizar el ciclo de lectura
de datos y empezar uno nuevo'''
self.calcular_concentracion()
self.reiniciar_contadores()
def calcular_concentracion(self):
'''Hace los calculos necesarios para obtener las concentraciones
de los gases en ppm'''
calculos = Calculos()
self.voltaje = calculos.calcular_voltaje(
self.voltaje_acumulado, self.cantidad_muestras)
rs = calculos.calcular_resistencia(self.voltaje, self.LOAD_RESISTANCE)
ratio = rs / self.ro
self.hidrogeno_ppm = calculos.calcular_ppm(ratio, self.HIDROGENO_CURVA)
self.metano_ppm = calculos.calcular_ppm(ratio, self.METANO_CURVA)
self.gpl_ppm = calculos.calcular_ppm(ratio, self.GPL_CURVA)
self.propano_ppm = calculos.calcular_ppm(ratio, self.PROPANO_CURVA)
self.alcohol_ppm = calculos.calcular_ppm(ratio, self.ALCOHOL_CURVA)
self.humo_ppm = calculos.calcular_ppm(ratio, self.HUMO_CURVA)
def activar_alarma(self):
'''Pasa la variable alarma a True en el caso de que el pin digital
envien una señal.'''
global alarma_mq2
alarma_mq2 = 1
def reiniciar_contadores(self):
'''Reinicia los valores de los contadores para tomar nuevas lecturas.'''
global alarma_mq2
self.voltaje_acumulado = 0
self.cantidad_muestras = 0
alarma_mq2 = 0
def get_hidrogeno(self):
'''Devuelve un string de la variable hidrogeno_ppm con tres decimales'''
return self.hidrogeno_ppm
def get_metano(self):
'''Devuelve un string de la variable metano_ppm con tres decimales'''
return self.metano_ppm
def get_gpl(self):
'''Devuelve un string de la variable gpl_ppm con tres decimales'''
return self.gpl_ppm
def get_propano(self):
'''Devuelve un string de la variable propano_ppm con tres decimales'''
return self.propano_ppm
def get_alcohol(self):
'''Devuelve un string de la variable alcohol_ppm con tres decimales'''
return self.alcohol_ppm
def get_humo(self):
'''Devuelve un string de la variable humo_ppm con tres decimales'''
return self.humo_ppm
def get_alarma(self):
'''Devuelve un String de la variable alarma'''
global alarma_mq2
return str(alarma_mq2)
def get_voltaje(self):
'''Devuelve un String de la variable voltaje'''
return str(self.voltaje)
def get_funcionamiento(self):
'''Nos dice mediante un boolean si el sensor funciona. En el caso de True
es que el sensor funciona'''
return self.funcionamiento
# cuando el sensor detecte una concentración peligrosa lanzará una alarma
DOutput.when_pressed = activar_alarma
MQ3
# sensor_mq3.py
# I2C comunicación
import board
import busio
# librerías del ADC ADS1115
import adafruit_ads1x15.ads1115 as ads1115
from adafruit_ads1x15.analog_in import AnalogIn
# lectura digital
from gpiozero import Button
# Medición por intervalos
from apscheduler.schedulers.background import BackgroundScheduler
# Calcular PPM
from calculos_gas import Calculos
# para registro de errores
import logging
# direccion I2C del ADS11115
ADDRESS = 0x49 # pin address conectado a VDD
PIN = 1 # canal analógico del chip
alarma_mq3 = 0
class MQ3:
"""Detector de gas MQ3"""
# resistencia del sensor
LOAD_RESISTANCE = 1
# pin salida digital
DOutput = Button(15)
# Ro value of the sensor
ro = 0.255
# Curva logaritmica con base 10
ALCOHOL_CURVA = [-1, 0.357935, -0.471481]
BENCENO_CURVA = [-1, 0.652246, -0.374582]
# gas en ppm
alcohol_ppm = 0
benceno_ppm = 0
voltaje = 0
funcionamiento = True
# Contadores
voltaje_acumulado = 0
cantidad_muestras = 0
def __init__(self, convertor=ads1115.ADS1115, pin=PIN, address=ADDRESS):
'''Inicia con la lectura periodica de gases del sensor MQ3'''
# Permique que el resto del programa sigua funcionando aunque el ADC no funcione
try:
i2c = busio.I2C(board.SCL, board.SDA)
adc = convertor(i2c=i2c, address=address)
self.channel = AnalogIn(adc, pin)
self.sched_mq3 = BackgroundScheduler()
self.sched_mq3.add_job(self.leer_voltaje, 'interval',
seconds=5, id="sched_mq3")
self.sched_mq3.start()
except (ValueError, OSError):
self.funcionamiento = False
logging.error('El ADC del MQ3 ha dejado de funcionar.')
def leer_voltaje(self):
'''leerá el voltaje cada cierto tiempo y lo irá acumulando, además
lleva la cuenta de cuantos ciclos de lectura lleva.'''
# Evita que se rompa el programa en caso de que el ADC deje de funcionar a mitad
# de una lectura de voltaje.
try:
self.voltaje_acumulado += self.channel.voltage
self.cantidad_muestras += 1
except (ValueError, OSError):
self.funcionamiento = False
logging.error('El ADC del MQ3 ha dejado de funcionar.')
self.sched_mq3.remove_job("sched_mq3")
def finalizar_ciclo(self):
'''Llama a las funciones necesarias para finalizar el ciclo de lectura
de datos y empezar uno nuevo'''
self.calcular_concentracion()
self.reiniciar_contadores()
def calcular_concentracion(self):
'''Hace los calculos necesarios para obtener las concentraciones
de los gases en ppm'''
calculos = Calculos()
self.voltaje = calculos.calcular_voltaje(
self.voltaje_acumulado, self.cantidad_muestras)
rs = calculos.calcular_resistencia(self.voltaje, self.LOAD_RESISTANCE)
ratio = rs / self.ro
self.alcohol_ppm = calculos.calcular_ppm(ratio, self.ALCOHOL_CURVA)
self.benceno_ppm = calculos.calcular_ppm(ratio, self.BENCENO_CURVA)
def activar_alarma(self):
'''Pasa la variable alarma a True en el caso de que el pin digital
envien una señal.'''
global alarma_mq3
alarma_mq3 = 1
def reiniciar_contadores(self):
'''Reinicia los valores de los contadores para tomar nuevas lecturas.'''
global alarma_mq3
self.voltaje_acumulado = 0
self.cantidad_muestras = 0
alarma_mq3 = 0
def get_alcohol(self):
'''Devuelve un string de la variable alcohol_ppm con tres decimales'''
return self.alcohol_ppm
def get_benceno(self):
'''Devuelve un string de la variable benceno_ppm con tres decimales'''
return self.benceno_ppm
def get_alarma(self):
'''Devuelve un String de la variable alarma'''
global alarma_mq3
return str(alarma_mq3)
def get_voltaje(self):
'''Devuelve un String de la variable alarma'''
return str(self.voltaje)
def get_funcionamiento(self):
'''Nos dice mediante un boolean si el sensor funciona. En el caso de True
es que el sensor funciona'''
return self.funcionamiento
# cuando el sensor detecte una concentración peligrosa lanzará una alarma
DOutput.when_pressed = activar_alarma
MQ4
# sensor_mq4.py
# I2C comunicación
import board
import busio
# librerías del ADC ADS1115
import adafruit_ads1x15.ads1115 as ads1115
from adafruit_ads1x15.analog_in import AnalogIn
# lectura digital
from gpiozero import Button
# Medición por intervalos
from apscheduler.schedulers.background import BackgroundScheduler
# Calcular PPM
from calculos_gas import Calculos
# para registro de errores
import logging
# direccion I2C del ADS11115
ADDRESS = 0x49 # pin address conectado a VDD
PIN = 2 # canal analógico del chip
alarma_mq4 = 0
class MQ4:
"""Detector de gas MQ4"""
# resistencia del sensor
LOAD_RESISTANCE = 1
# pin salida digital
DOutput = Button(23)
# Constante de resistencia inicial
ro = 0.733
# Curva logaritmica con base 10
METANO_CURVA = [2.301030, 0.255273, -0.385390]
GPL_CURVA = [2.301030, 0.414973, -0.386798]
# gas en ppm
metano_ppm = 0
gpl_ppm = 0
voltaje = 0
funcionamiento = True
# Contadores
voltaje_acumulado = 0
cantidad_muestras = 0
def __init__(self, convertor=ads1115.ADS1115, pin=PIN, address=ADDRESS):
'''Inicia con la lectura periodica de gases del sensor MQ4'''
# Permique que el resto del programa sigua funcionando aunque el ADC no funcione
try:
i2c = busio.I2C(board.SCL, board.SDA)
adc = convertor(i2c=i2c, address=address)
self.channel = AnalogIn(adc, pin)
self.sched_mq4 = BackgroundScheduler()
self.sched_mq4.add_job(self.leer_voltaje, 'interval',
seconds=5, id="sched_mq4")
self.sched_mq4.start()
except (ValueError, OSError):
self.funcionamiento = False
logging.error('El ADC del MQ4 ha dejado de funcionar.')
def leer_voltaje(self):
'''leerá el voltaje cada cierto tiempo y lo irá acumulando, además
lleva la cuenta de cuantos ciclos de lectura lleva.'''
# Evita que se rompa el programa en caso de que el ADC deje de funcionar a mitad
# de una lectura de voltaje.
try:
self.voltaje_acumulado += self.channel.voltage
self.cantidad_muestras += 1
print(str(self.voltaje_acumulado) +
" || " + str(self.cantidad_muestras))
except (ValueError, OSError):
self.funcionamiento = False
logging.error('El ADC del MQ4 ha dejado de funcionar.')
self.sched_mq4.remove_job("sched_mq4")
def finalizar_ciclo(self):
'''Llama a las funciones necesarias para finalizar el ciclo de lectura
de datos y empezar uno nuevo'''
self.calcular_concentracion()
self.reiniciar_contadores()
def calcular_concentracion(self):
'''Hace los calculos necesarios para obtener las concentraciones
de los gases en ppm'''
calculos = Calculos()
self.voltaje = calculos.calcular_voltaje(
self.voltaje_acumulado, self.cantidad_muestras)
rs = calculos.calcular_resistencia(self.voltaje, self.LOAD_RESISTANCE)
ratio = rs / self.ro
self.metano_ppm = calculos.calcular_ppm(ratio, self.METANO_CURVA)
self.gpl_ppm = calculos.calcular_ppm(ratio, self.GPL_CURVA)
def activar_alarma(self):
'''Pasa la variable alarma a True en el caso de que el pin digital
envien una señal.'''
global alarma_mq4
alarma_mq4 = 1
def reiniciar_contadores(self):
'''Reinicia los valores de los contadores para tomar nuevas lecturas.'''
global alarma_mq4
self.voltaje_acumulado = 0
self.cantidad_muestras = 0
alarma_mq4 = 0
def get_metano(self):
'''Devuelve un string de la variable metano_ppm con tres decimales'''
return self.metano_ppm
def get_gpl(self):
'''Devuelve un string de la variable gpl_ppm con tres decimales'''
return self.gpl_ppm
def get_alarma(self):
'''Devuelve un String de la variable alarma'''
global alarma_mq4
return str(alarma_mq4)
def get_voltaje(self):
'''Devuelve un String de la variable voltaje'''
return str(self.voltaje)
def get_funcionamiento(self):
'''Nos dice mediante un boolean si el sensor funciona. En el caso de True
es que el sensor funciona'''
return self.funcionamiento
# cuando el sensor detecte una concentración peligrosa lanzará una alarma
DOutput.when_pressed = activar_alarma
MQ5
# sensor_mq5.py
# I2C comunicación
import board
import busio
# librerías del ADC ADS1115
import adafruit_ads1x15.ads1115 as ads1115
from adafruit_ads1x15.analog_in import AnalogIn
# lectura digital
from gpiozero import Button
# Medición por intervalos
from apscheduler.schedulers.background import BackgroundScheduler
# Calcular PPM
from calculos_gas import Calculos
# para registro de errores
import logging
# direccion I2C del ADS11115
ADDRESS = 0x49 # pin address conectado a VDD
PIN = 3 # canal analógico del chip
alarma_mq5 = 0
class MQ5:
"""Detector de gas MQ5"""
# resistencia del sensor
LOAD_RESISTANCE = 1
# pin salida digital
DOutput = Button(24)
# Ro value of the sensor
ro = 0.735
# Curva logaritmica con base 10
GPL_CURVA = [2.301030, -0.154902, -0.385390]
METANO_CURVA = [2.301030, 0.026872, -0.386798]
# gas en ppm
gpl_ppm = 0
metano_ppm = 0
voltaje = 0
funcionamiento = True
# Contadores
voltaje_acumulado = 0
cantidad_muestras = 0
def __init__(self, convertor=ads1115.ADS1115, pin=PIN, address=ADDRESS):
'''Inicia con la lectura periodica de gases del sensor MQ5'''
# Permique que el resto del programa sigua funcionando aunque el ADC no funcione
try:
i2c = busio.I2C(board.SCL, board.SDA)
adc = convertor(i2c=i2c, address=address)
self.channel = AnalogIn(adc, pin)
self.sched_mq5 = BackgroundScheduler()
self.sched_mq5.add_job(self.leer_voltaje, 'interval',
seconds=5, id="sched_mq5")
self.sched_mq5.start()
except (ValueError, OSError):
self.funcionamiento = False
logging.error('El ADC del MQ5 ha dejado de funcionar.')
def leer_voltaje(self):
'''leerá el voltaje cada cierto tiempo y lo irá acumulando, además
lleva la cuenta de cuantos ciclos de lectura lleva.'''
# Evita que se rompa el programa en caso de que el ADC deje de funcionar a mitad
# de una lectura de voltaje.
try:
self.voltaje_acumulado += self.channel.voltage
self.cantidad_muestras += 1
except (ValueError, OSError):
self.funcionamiento = False
logging.error('El ADC del MQ5 ha dejado de funcionar.')
self.sched_mq5.remove_job("sched_mq5")
def finalizar_ciclo(self):
'''Llama a las funciones necesarias para finalizar el ciclo de lectura
de datos y empezar uno nuevo'''
self.calcular_concentracion()
self.reiniciar_contadores()
def calcular_concentracion(self):
'''Hace los calculos necesarios para obtener las concentraciones
de los gases en ppm'''
calculos = Calculos()
self.voltaje = calculos.calcular_voltaje(
self.voltaje_acumulado, self.cantidad_muestras)
rs = calculos.calcular_resistencia(self.voltaje, self.LOAD_RESISTANCE)
ratio = rs / self.ro
self.gpl_ppm = calculos.calcular_ppm(ratio, self.GPL_CURVA)
self.metano_ppm = calculos.calcular_ppm(ratio, self.METANO_CURVA)
def activar_alarma(self):
'''Pasa la variable alarma a True en el caso de que el pin digital
envien una señal.'''
global alarma_mq5
alarma_mq5 = 1
def reiniciar_contadores(self):
'''Reinicia los valores de los contadores para tomar nuevas lecturas.'''
global alarma_mq5
self.voltaje_acumulado = 0
self.cantidad_muestras = 0
alarma_mq5 = 0
def get_gpl(self):
'''Devuelve un string de la variable gpl_ppm con tres decimales'''
return self.gpl_ppm
def get_metano(self):
'''Devuelve un string de la variable metano_ppm con tres decimales'''
return self.metano_ppm
def get_alarma(self):
'''Devuelve un String de la variable alarma'''
global alarma_mq5
return str(alarma_mq5)
def get_voltaje(self):
'''Devuelve un String de la variable voltaje'''
return str(self.voltaje)
def get_funcionamiento(self):
'''Nos dice mediante un boolean si el sensor funciona. En el caso de True
es que el sensor funciona'''
return self.funcionamiento
# cuando el sensor detecte una concentración peligrosa lanzará una alarma
DOutput.when_pressed = activar_alarma
MQ7
# sensor_mq7.py
# I2C comunicación
import board
import busio
# librerías del ADC ADS1115
import adafruit_ads1x15.ads1115 as ads1115
from adafruit_ads1x15.analog_in import AnalogIn
# lectura digital
from gpiozero import Button
# Medición por intervalos
from apscheduler.schedulers.background import BackgroundScheduler
# Calcular PPM
from calculos_gas import Calculos
# para registro de errores
import logging
# direccion I2C del ADS11115
ADDRESS = 0x4a # pin address conectado a VDD
PIN = 0 # canal analógico del chip
alarma_mq7 = 0
class MQ7:
"""Detector de gas MQ7"""
# resistencia del sensor
LOAD_RESISTANCE = 1
# pin salida digital
DOutput = Button(25)
# Ro value of the sensor
ro = 0.255
# Curva logaritmica con base 10
HIDROGENO_CURVA = [1.698970, 0.133539, -0.619674]
CO_CURVA = [1.698970, 0.220108, -0.790349]
# gas en ppm
hidrogeno_ppm = 0
co_ppm = 0
voltaje = 0
funcionamiento = True
# Contadores
voltaje_acumulado = 0
cantidad_muestras = 0
def __init__(self, convertor=ads1115.ADS1115, pin=PIN, address=ADDRESS):
'''Inicia con la lectura periodica de gases del sensor MQ7'''
# Permique que el resto del programa sigua funcionando aunque el ADC no funcione
try:
i2c = busio.I2C(board.SCL, board.SDA)
adc = convertor(i2c=i2c, address=address)
self.channel = AnalogIn(adc, pin)
self.sched_mq7 = BackgroundScheduler()
self.sched_mq7.add_job(self.leer_voltaje, 'interval',
seconds=5, id="sched_mq7")
self.sched_mq7.start()
except (ValueError, OSError):
self.funcionamiento = False
logging.error('El ADC del MQ7 ha dejado de funcionar.')
def leer_voltaje(self):
'''leerá el voltaje cada cierto tiempo y lo irá acumulando, además
lleva la cuenta de cuantos ciclos de lectura lleva.'''
# Evita que se rompa el programa en caso de que el ADC deje de funcionar a mitad
# de una lectura de voltaje.
try:
self.voltaje_acumulado += self.channel.voltage
self.cantidad_muestras += 1
except (ValueError, OSError):
self.funcionamiento = False
logging.error('El ADC del MQ7 ha dejado de funcionar.')
self.sched_mq7.remove_job("sched_mq7")
def finalizar_ciclo(self):
'''Llama a las funciones necesarias para finalizar el ciclo de lectura
de datos y empezar uno nuevo'''
self.calcular_concentracion()
self.reiniciar_contadores()
def calcular_concentracion(self):
'''Hace los calculos necesarios para obtener las concentraciones
de los gases en ppm'''
calculos = Calculos()
self.voltaje = calculos.calcular_voltaje(
self.voltaje_acumulado, self.cantidad_muestras)
rs = calculos.calcular_resistencia(self.voltaje, self.LOAD_RESISTANCE)
ratio = rs / self.ro
self.hidrogeno_ppm = calculos.calcular_ppm(ratio, self.HIDROGENO_CURVA)
self.co_ppm = calculos.calcular_ppm(ratio, self.CO_CURVA)
def activar_alarma(self):
'''Pasa la variable alarma a True en el caso de que el pin digital
envien una señal.'''
global alarma_mq7
alarma_mq7 = 1
def reiniciar_contadores(self):
'''Reinicia los valores de los contadores para tomar nuevas lecturas.'''
global alarma_mq7
self.voltaje_acumulado = 0
self.cantidad_muestras = 0
alarma_mq7 = 0
def get_hidrogeno(self):
'''Devuelve un string de la variable hidrogeno_ppm con tres decimales'''
return self.hidrogeno_ppm
def get_co(self):
'''Devuelve un string de la variable co_ppm con tres decimales'''
return self.co_ppm
def get_alarma(self):
'''Devuelve un String de la variable alarma'''
global alarma_mq7
return str(alarma_mq7)
def get_voltaje(self):
'''Devuelve un String de la variable voltaje'''
return str(self.voltaje)
def get_funcionamiento(self):
'''Nos dice mediante un boolean si el sensor funciona. En el caso de True
es que el sensor funciona'''
return self.funcionamiento
# cuando el sensor detecte una concentración peligrosa lanzará una alarma
DOutput.when_pressed = activar_alarma
MQ8
# sensor_mq8.py
# I2C comunicación
import board
import busio
# librerías del ADC ADS1115
import adafruit_ads1x15.ads1115 as ads1115
from adafruit_ads1x15.analog_in import AnalogIn
# lectura digital
from gpiozero import Button
# Medición por intervalos
from apscheduler.schedulers.background import BackgroundScheduler
# Calcular PPM
from calculos_gas import Calculos
# para registro de errores
import logging
# direccion I2C del ADS11115
ADDRESS = 0x4a # pin address conectado a VDD
PIN = 1 # canal analógico del chip
alarma_mq8 = 0
class MQ8:
"""Detector de gas MQ8"""
# resistencia del sensor
LOAD_RESISTANCE = 1
# pin salida digital
DOutput = Button(17)
# Ro value of the sensor
ro = 0.051
# Curva logaritmica con base 10
HIDROGENO_CURVA = [2.301030, 0.932474, -1.453867]
# gas en ppm
hidrogeno_ppm = 0
voltaje = 0
funcionamiento = True
# Contadores
voltaje_acumulado = 0
cantidad_muestras = 0
def __init__(self, convertor=ads1115.ADS1115, pin=PIN, address=ADDRESS):
'''Inicia con la lectura periodica de gases del sensor MQ8'''
# Permique que el resto del programa sigua funcionando aunque el ADC no funcione
try:
i2c = busio.I2C(board.SCL, board.SDA)
adc = convertor(i2c=i2c, address=address)
self.channel = AnalogIn(adc, pin)
self.sched_mq8 = BackgroundScheduler()
self.sched_mq8.add_job(self.leer_voltaje, 'interval',
seconds=5, id="sched_mq8")
self.sched_mq8.start()
except (ValueError, OSError):
self.funcionamiento = False
logging.error('El ADC del MQ8 ha dejado de funcionar.')
def leer_voltaje(self):
'''leerá el voltaje cada cierto tiempo y lo irá acumulando, además
lleva la cuenta de cuantos ciclos de lectura lleva.'''
# Evita que se rompa el programa en caso de que el ADC deje de funcionar a mitad
# de una lectura de voltaje.
try:
self.voltaje_acumulado += self.channel.voltage
self.cantidad_muestras += 1
except (ValueError, OSError):
self.funcionamiento = False
logging.error('El ADC del MQ8 ha dejado de funcionar.')
self.sched_mq8.remove_job("sched_mq8")
def finalizar_ciclo(self):
'''Llama a las funciones necesarias para finalizar el ciclo de lectura
de datos y empezar uno nuevo'''
self.calcular_concentracion()
self.reiniciar_contadores()
def calcular_concentracion(self):
'''Hace los calculos necesarios para obtener las concentraciones
de los gases en ppm'''
calculos = Calculos()
self.voltaje = calculos.calcular_voltaje(
self.voltaje_acumulado, self.cantidad_muestras)
rs = calculos.calcular_resistencia(self.voltaje, self.LOAD_RESISTANCE)
ratio = rs / self.ro
self.hidrogeno_ppm = calculos.calcular_ppm(ratio, self.HIDROGENO_CURVA)
def activar_alarma(self):
'''Pasa la variable alarma a True en el caso de que el pin digital
envien una señal.'''
global alarma_mq8
alarma_mq8 = 1
def reiniciar_contadores(self):
'''Reinicia los valores de los contadores para tomar nuevas lecturas.'''
global alarma_mq8
self.voltaje_acumulado = 0
self.cantidad_muestras = 0
alarma_mq8 = 0
def get_hidrogeno(self):
'''Devuelve un string de la variable hidrogeno_ppm con tres decimales'''
return self.hidrogeno_ppm
def get_alarma(self):
'''Devuelve un String de la variable alarma'''
global alarma_mq8
return str(alarma_mq8)
def get_voltaje(self):
'''Devuelve un String de la variable voltaje'''
return str(self.voltaje)
def get_funcionamiento(self):
'''Nos dice mediante un boolean si el sensor funciona. En el caso de True
es que el sensor funciona'''
return self.funcionamiento
# cuando el sensor detecte una concentración peligrosa lanzará una alarma
DOutput.when_pressed = activar_alarma
MQ9
# sensor_mq9.py
# I2C comunicación
import board
import busio
# librerías del ADC ADS1115
import adafruit_ads1x15.ads1115 as ads1115
from adafruit_ads1x15.analog_in import AnalogIn
# lectura digital
from gpiozero import Button
# Medición por intervalos
from apscheduler.schedulers.background import BackgroundScheduler
# Calcular PPM
from calculos_gas import Calculos
# para registro de errores
import logging
# direccion I2C del ADS11115
ADDRESS = 0x4a # pin address conectado a VDD
PIN = 2 # canal analógico del chip
alarma_mq9 = 0
class MQ9:
"""Detector de gas MQ9"""
# resistencia del sensor
LOAD_RESISTANCE = 1
# pin salida digital
DOutput = Button(27)
# Ro value of the sensor
ro = 0.943
# Curva logaritmica con base 10
CO_CURVA = [2.301030, 0.227887, -0.478819]
GPL_CURVA = [2.301030, 0.324282, -0.471955]
# gas en ppm
co_ppm = 0
gpl_ppm = 0
voltaje = 0
funcionamiento = True
# Contadores
voltaje_acumulado = 0
cantidad_muestras = 0
def __init__(self, convertor=ads1115.ADS1115, pin=PIN, address=ADDRESS):
'''Inicia con la lectura periodica de gases del sensor MQ9'''
# Permique que el resto del programa sigua funcionando aunque el ADC no funcione
try:
i2c = busio.I2C(board.SCL, board.SDA)
adc = convertor(i2c=i2c, address=address)
self.channel = AnalogIn(adc, pin)
self.sched_mq9 = BackgroundScheduler()
self.sched_mq9.add_job(self.leer_voltaje, 'interval',
seconds=5, id="sched_mq9")
self.sched_mq9.start()
except (ValueError, OSError):
self.funcionamiento = False
logging.error('El ADC del MQ9 ha dejado de funcionar.')
def leer_voltaje(self):
'''leerá el voltaje cada cierto tiempo y lo irá acumulando, además
lleva la cuenta de cuantos ciclos de lectura lleva.'''
# Evita que se rompa el programa en caso de que el ADC deje de funcionar a mitad
# de una lectura de voltaje.
try:
self.voltaje_acumulado += self.channel.voltage
self.cantidad_muestras += 1
except (ValueError, OSError):
self.funcionamiento = False
logging.error('El ADC del MQ9 ha dejado de funcionar.')
self.sched_mq9.remove_job("sched_mq9")
def finalizar_ciclo(self):
'''Llama a las funciones necesarias para finalizar el ciclo de lectura
de datos y empezar uno nuevo'''
self.calcular_concentracion()
self.reiniciar_contadores()
def calcular_concentracion(self):
'''Hace los calculos necesarios para obtener las concentraciones
de los gases en ppm'''
calculos = Calculos()
self.voltaje = calculos.calcular_voltaje(
self.voltaje_acumulado, self.cantidad_muestras)
rs = calculos.calcular_resistencia(self.voltaje, self.LOAD_RESISTANCE)
ratio = rs / self.ro
self.co_ppm = calculos.calcular_ppm(ratio, self.CO_CURVA)
self.gpl_ppm = calculos.calcular_ppm(ratio, self.GPL_CURVA)
def activar_alarma(self):
'''Pasa la variable alarma a True en el caso de que el pin digital
envien una señal.'''
global alarma_mq9
alarma_mq9 = 1
def reiniciar_contadores(self):
'''Reinicia los valores de los contadores para tomar nuevas lecturas.'''
global alarma_mq9
self.voltaje_acumulado = 0
self.cantidad_muestras = 0
alarma_mq9 = 0
def get_co(self):
'''Devuelve un string de la variable co_ppm con tres decimales'''
return self.co_ppm
def get_gpl(self):
'''Devuelve un string de la variable gpl_ppm con tres decimales'''
return self.gpl_ppm
def get_alarma(self):
'''Devuelve un String de la variable alarma'''
global alarma_mq9
return str(alarma_mq9)
def get_voltaje(self):
'''Devuelve un String de la variable voltaje'''
return str(self.voltaje)
def get_funcionamiento(self):
'''Nos dice mediante un boolean si el sensor funciona. En el caso de True
es que el sensor funciona'''
return self.funcionamiento
# cuando el sensor detecte una concentración peligrosa lanzará una alarma
DOutput.when_pressed = activar_alarma
MQ135
# sensor_mq135.py
# I2C comunicación
import board
import busio
# librerías del ADC ADS1115
import adafruit_ads1x15.ads1115 as ads1115
from adafruit_ads1x15.analog_in import AnalogIn
# lectura digital
from gpiozero import Button
# Medición por intervalos
from apscheduler.schedulers.background import BackgroundScheduler
# Calcular PPM
from calculos_gas import Calculos
# para registro de errores
import logging
# direccion I2C del ADS11115
ADDRESS = 0x4a # pin address conectado a VDD
PIN = 3 # canal analógico del chip
alarma_mq135 = 0
class MQ135:
"""Detector de gas MQ135"""
# resistencia del sensor
LOAD_RESISTANCE = 1
# pin salida digital
DOutput = Button(22)
# Ro value of the sensor
ro = 1.521
# Curva logaritmica con base 10
ACETONA_CURVA = [1, 0.178977, -0.319976]
TOLUENO_CURVA = [1, 0.209515, -0.312630]
ALCOHOL_CURVA = [1, 0.283301, -0.321436]
# gas en ppm
acetona_ppm = 0
tolueno_ppm = 0
alcohol_ppm = 0
voltaje = 0
funcionamiento = True
# Contadores
voltaje_acumulado = 0
cantidad_muestras = 0
def __init__(self, convertor=ads1115.ADS1115, pin=PIN, address=ADDRESS):
'''Inicia con la lectura periodica de gases del sensor MQ135'''
# Permique que el resto del programa sigua funcionando aunque el ADC no funcione
try:
i2c = busio.I2C(board.SCL, board.SDA)
adc = convertor(i2c=i2c, address=address)
self.channel = AnalogIn(adc, pin)
self.sched_mq135 = BackgroundScheduler()
self.sched_mq135.add_job(self.leer_voltaje, 'interval',
seconds=5, id="sched_mq135")
self.sched_mq135.start()
except (ValueError, OSError):
self.funcionamiento = False
logging.error('El ADC del MQ135 ha dejado de funcionar.')
def leer_voltaje(self):
'''leerá el voltaje cada cierto tiempo y lo irá acumulando, además
lleva la cuenta de cuantos ciclos de lectura lleva.'''
# Evita que se rompa el programa en caso de que el ADC deje de funcionar a mitad
# de una lectura de voltaje.
try:
self.voltaje_acumulado += self.channel.voltage
self.cantidad_muestras += 1
except (ValueError, OSError):
self.funcionamiento = False
logging.error('El ADC del MQ135 ha dejado de funcionar.')
self.sched_mq135.remove_job("sched_mq135")
def finalizar_ciclo(self):
'''Llama a las funciones necesarias para finalizar el ciclo de lectura
de datos y empezar uno nuevo'''
self.calcular_concentracion()
self.reiniciar_contadores()
def calcular_concentracion(self):
'''Hace los calculos necesarios para obtener las concentraciones
de los gases en ppm'''
calculos = Calculos()
self.voltaje = calculos.calcular_voltaje(
self.voltaje_acumulado, self.cantidad_muestras)
rs = calculos.calcular_resistencia(self.voltaje, self.LOAD_RESISTANCE)
ratio = rs / self.ro
self.acetona_ppm = calculos.calcular_ppm(ratio, self.ACETONA_CURVA)
self.tolueno_ppm = calculos.calcular_ppm(ratio, self.TOLUENO_CURVA)
self.alcohol_ppm = calculos.calcular_ppm(ratio, self.ALCOHOL_CURVA)
def activar_alarma(self):
'''Pasa la variable alarma a True en el caso de que el pin digital
envien una señal.'''
global alarma_mq135
alarma_mq135 = 1
def reiniciar_contadores(self):
'''Reinicia los valores de los contadores para tomar nuevas lecturas.'''
global alarma_mq135
self.voltaje_acumulado = 0
self.cantidad_muestras = 0
alarma_mq135 = 0
def get_acetona(self):
'''Devuelve un string de la variable acetona_ppm con tres decimales'''
return self.acetona_ppm
def get_tolueno(self):
'''Devuelve un string de la variable tolueno_ppm con tres decimales'''
return self.tolueno_ppm
def get_alcohol(self):
'''Devuelve un string de la variable alcohol_ppm con tres decimales'''
return self.alcohol_ppm
def get_alarma(self):
'''Devuelve un String de la variable alarma'''
global alarma_mq135
return str(alarma_mq135)
def get_voltaje(self):
'''Devuelve un String de la variable voltaje'''
return str(self.voltaje)
def get_funcionamiento(self):
'''Nos dice mediante un boolean si el sensor funciona. En el caso de True
es que el sensor funciona'''
return self.funcionamiento
# cuando el sensor detecte una concentración peligrosa lanzará una alarma
DOutput.when_pressed = activar_alarma