Depois de comprar um detector de vazamento de gás, havia um desejo de desmontar tudo nas prateleiras e descobrir o que estava acontecendo lá dentro. Há muitas informações e artigos sobre sensores, mas a maioria está limitada à pinagem do módulo chinês padrão, às vezes aos princípios de operação. Sobre a determinação relativamente precisa dos valores absolutos das informações lá. Olhando para o futuro, direi que tentaremos extrair tudo da folha de dados, incluindo: as funções exatas de determinar "papagaios", correção de temperatura e umidade e algumas possibilidades de seleção.Por exemplo, um sensor de gás combustível (principalmente metano) MQ-4. Em resumo, o elemento sensor, devido às suas propriedades químicas, altera a resistência em diferentes concentrações de gás e atua como um resistor do divisor de tensão a partir do qual obtemos o valor da tensão através do ADC. Essas propriedades se manifestam a uma certa temperatura do elemento para o qual o sensor deve ser aquecido.Acima está uma representação esquemática de um sensor e um circuito divisor, onde H é uma bobina de aquecimento (33 Ohms - cerca de 150 mA, as correntes são grandes demais para trabalhos com controladores; isso deve ser levado em consideração ao projetar um circuito de potência), AV são as saídas de um elemento sensível com resistência intercambiável, dependendo da concentração de gás , RL é o segundo resistor divisor recomendado pela ficha de dados - 20 kOhm.Comentário sobre a escolha de uma tensão de referência ADC (Vref)Hanwei Vc = 5 , Winsen – Vc < 24 . , 3.3 , , . 5 .
Converter ADC para ppm
Nas saídas do divisor ADC, tomamos o valor de tensão (Uadc) com base no qual podemos calcular a resistência do sensor Rs (sabendo o valor do segundo resistor do divisor RL), ou seja, determine o que exatamente o sensor nos transmite:
Com o valor de Rs, já podemos determinar a concentração de gás de acordo com o gráfico da folha de dados. Uma simples relação Rs / Ro é usada para determinar a concentração. Ro, neste caso, é a resistência do elemento sensor a uma concentração de gás de detecção de 1000 ppm.Comentário sobre pontos de partida nos cálculos,
«Ro: sensor resistance at 1000ppm of CH4 in the clean air»
, 1000 ppm. «» . , « » , , 1800 ppb ( 1.8 ppm, 1000 ppm). , 4.4 Rs/Ro.
Nesta fase, graças ao ADC e à fórmula, sabemos apenas o valor da resistência atual (Rs) da qual iremos repelir. Assumiremos que a medimos em ar limpo (a partir de gases detectados), em temperatura e umidade de calibração (pela folha de dados 20, 65%). Um pouco mais tarde, haverá um comentário interessante sobre a umidade em que a calibração é realizada.Assim, o valor de referência Ro para o sensor MQ-4 é:
Comentar sobre a seleção de fumaça, , Rs/Ro – 1.8…0.43, – 3.8…2.6. . , , «» . . RsRo 2.8, «» :
O cálculo da concentração real de gás é um pouco complicado pela curvatura do gráfico e pela falta de pontos de controle distintos pelos quais esse gráfico pode ser ajustado. Além disso, o problema está na baixa expansão da imagem, pelo que é necessário determinar os pontos de controle pixel por pixel.Para esclarecer os cálculos, os valores mais óbvios são espaçados em uma grade de coordenadas. Os pontos de controle determinaram a função da dependência de ppm em Rs / Ro:Comentar limites de medição400…10000 ppm. (Winsen/Hanwei) 200 400 ppm, 400. ppm Rs/Ro, x = ppm/1000; y= (Rs/Ro)*10:
O gráfico construído corresponde à função:Assim, o número de "papagaios" é reconhecido pela fórmula:Um pouco sobre a compensação de temperatura
Com base no seguinte gráfico de dados, sabe-se que, dependendo do ambiente em que o sensor é usado, as leituras se desviam das reais:
Comentário sobre a umidade típica do ambiente de medição, = 65%. RsRo/ppm ( ppm) RsRo/Temp ( ). Rs/Ro = 1 ppm=1000 20, : 33% 65%. . , , 33%. .
Para determinar com mais precisão a dependência dos indicadores no ambiente, também foi construído um gráfico de funções, o sensor é limitado a uma faixa de temperatura de -10 ° C ... +50 ° C (x = TEMP / 10; y = RsRo (erro) * 100):O gráfico corresponde à função:
A base é um gráfico com uma umidade de 33% (a julgar pela interseção 1, é uma calibração). Se você prestar atenção à umidade, a umidade de 1% muda o gráfico em 0,3 Y (em valores reais do ajuste RsRo será dividido por 100 - o coeficiente é usado no gráfico para maior clareza). "+25" muda a posição do gráfico em Y para umidade "zero"; "0,3 x HUM" retorna a posição Y para a umidade real. Alguma mudança no “peso” de 1% de umidade a temperaturas extremas é de pouca importância e não é levada em consideração.Nota importante: tudo isso se aplica se a calibração for realizada em ar limpo a uma umidade de 33% e a uma temperatura de 20 graus.O valor de correção RsRo (erro), que precisará ser adicionado aos valores de RsRo para compensar o impacto ambiental, pode ser calculado pela fórmula:A tarefa "com um asterisco" é esclarecer a compensação durante a calibração em um ambiente não padrão, (20/33%), RsRo(error) :
Y – . X: . , , .
, , , .
, — .
Para calcular um valor já compensado:Transferimos a teoria para o microcontrolador
Para testar o sensor, foram utilizados o microcontrolador STM32F407VET e a biblioteca HAL, os valores para correção foram recebidos do sensor BME280. No arquivo de cabeçalho, definimos alguns valores constantes para nossa configuração.mq4.h
#ifndef MQ4_H_
#define MQ4_H_
int mq4_default_work (void);
int mq4_advanced_work (float temp, float hum);
int mq4_full_work (float temp, float hum, float temp_cal, float hum_cal);
int mq4_calib_Ro(void);
int mq4_get_adc (void);
#define MQ4_ADC hadc1
#define MQ4_ADC_PRECISION 4096
#define MQ4_REFERENCE_VOLTAGE 3.3f
#define MQ4_STATIC_RESISTOR 20000
#define MQ4_RO_DEF 13600
#define MQ4_HUM_WEIGHT 0.3f
#define MQ4_AIR_RSRO 4.4f
#endif
mq4.c
mq4.c
#include "mq4.h"
#include "adc.h"
#include "math.h"
int mq4_Rs;
int mq4_adc_value;
float mq4_volts;
float mq4_RsRo;
float mq4_calib_value;
float mq4_calib_value2;
extern int mq4_Ro;
extern int mq4_temp_cal;
extern int mq4_hum_cal;
Função de cálculo de ppm (sem correções)int mq4_default_work (void)
{
int ppm;
int mq4_adc;
float volts;
int Rs;
float RsRo;
mq4_adc = mq4_get_adc();
volts = mq4_adc/(MQ4_ADC_PRECISION/MQ4_REFERENCE_VOLTAGE);
Rs = ((MQ4_REFERENCE_VOLTAGE * MQ4_STATIC_RESISTOR)/volts)- MQ4_STATIC_RESISTOR;
RsRo = (float)Rs / (float)mq4_Ro;
mq4_RsRo = RsRo;
mq4_adc_value = mq4_adc;
mq4_volts = volts;
if (RsRo>0.437)
{ppm = (pow((10/(RsRo*10)),(1/0.36152689)))*1000;}
else {ppm=9999;}
return (int)ppm;
}
Função de cálculo de ppm com compensação da temperatura e umidade atuaisint mq4_advanced_work (float temp, float hum)
{
int ppm;
int mq4_adc;
float volts;
int Rs;
float RsRo;
float K;
mq4_adc = mq4_get_adc();
volts = mq4_adc/(MQ4_ADC_PRECISION/MQ4_REFERENCE_VOLTAGE);
Rs = ((MQ4_REFERENCE_VOLTAGE * MQ4_STATIC_RESISTOR)/volts)- MQ4_STATIC_RESISTOR;
RsRo = (float)Rs / (float)mq4_Ro;
K = ((0.83*(pow((temp/10),2)))-(9.2*(temp/10))+ 25 - (hum*MQ4_HUM_WEIGHT))/100;
RsRo = RsRo - K;
if (RsRo>0.437)
{ppm = (pow((10/(RsRo*10)),(1/0.36152689)))*1000;}
else {ppm=9999;}
mq4_RsRo = RsRo;
mq4_calib_value = K;
mq4_adc_value = mq4_adc;
mq4_Rs = Rs;
return ppm;
}
Função de cálculo de ppm (com compensação de temperatura / umidade e correção para o meio de calibração)int mq4_full_work (float temp, float hum, float temp_cal, float hum_cal)
{
int ppm;
int mq4_adc;
float volts;
int Rs;
float RsRo;
float K;
temp = temp + (20 - temp_cal);
mq4_adc = mq4_get_adc();
volts = mq4_adc/(MQ4_ADC_PRECISION/MQ4_REFERENCE_VOLTAGE);
Rs = ((MQ4_REFERENCE_VOLTAGE * MQ4_STATIC_RESISTOR)/volts)- MQ4_STATIC_RESISTOR;
RsRo = (float)Rs / (float)mq4_Ro;
K = ((0.83*(pow((temp/10),2)))-(9.2*(temp/10))+ 25 - (hum*MQ4_HUM_WEIGHT)+(MQ4_HUM_WEIGHT*(hum_cal-33)))/100;
RsRo = RsRo - K;
if (RsRo>0.437) ppm = (pow((10/(RsRo*10)),(1/0.36152689)))*1000;
else {ppm=9999;}
mq4_RsRo = RsRo;
mq4_calib_value2 = K;
mq4_adc_value = mq4_adc;
mq4_Rs = Rs;
return ppm;
}
Valor ADCint mq4_get_adc (void)
{
int mq4_adc_bits;
HAL_ADC_Start(&MQ4_ADC);
HAL_ADC_PollForConversion(&MQ4_ADC,100);
mq4_adc_bits = HAL_ADC_GetValue(&MQ4_ADC);
HAL_ADC_Stop(&MQ4_ADC);
return mq4_adc_bits;
}
Calibraçãoint mq4_calib_Ro(void)
{
float mq4_adc_volts;
int Rs;
int Ro;
int mq4_adc;
mq4_adc = mq4_get_adc();
mq4_adc_volts = (float)mq4_adc/((float)MQ4_ADC_PRECISION/MQ4_REFERENCE_VOLTAGE);
Rs = (((float)MQ4_REFERENCE_VOLTAGE * (float)MQ4_STATIC_RESISTOR)/mq4_adc_volts)- (float)MQ4_STATIC_RESISTOR;
Ro = Rs/MQ4_AIR_RSRO;
return Ro;
}
main.c
#include "main.h"
#include "adc.h"
#include "gpio.h"
#include "mq4.h"
int ppm_def;
int ppm_adv;
int ppm_full;
float mq4_temp_cal = 20;
float mq4_hum_cal = 33;
extern float mq4_calib_value;
extern float mq4_calib_value2;
int mq4_Ro = MQ4_RO_DEF;
extern int mq4_Rs;
extern int mq4_adc_value;
extern float mq4_volts;
extern float mq4_RsRo;
float tf = 0.0f, hf = 0.0f;
int main(void)
{
HAL_Init();
MX_GPIO_Init();
MX_ADC1_Init();
}
while (1)
{
ppm_def = mq4_default_work();
ppm_adv = mq4_advanced_work(tf,hf);
ppm_full= mq4_full_work(tf,hf,mq4_temp_cal,mq4_hum_cal);
if(HAL_GPIO_ReadPin(KEY_1_GPIO_Port, KEY_1_Pin)==GPIO_PIN_RESET)
{
mq4_Ro = mq4_calib_Ro();
mq4_temp_cal = tf;
mq4_hum_cal = hf;
}
}
Exemplos de uso
Determinando o valor de ppm:A função do cálculo da compensação de temperatura (neste caso, com a mesma umidade):Correção de valores durante a calibração em condições fora do padrão:Conclusão
- , , . TGS2611 ( 15-20 MQ-4). header- ppm ( Graph 4.4.2).
- 1$ , .
- , , RsRo 0,5…0,8, ( ). ( 1000 ppm), .. , . , , – 4…5 RsRo .
- . , «» header- ( Y).
- , , . (20 , 33% ( 65% )).
- 3.8 RsRo. — 2.6, 1.2…1.5.
- , RL ( 20 , 10…47 ). High Precision Resistor.