Pontilhando sobre os sensores de gás da série MQ - compreensão profunda da folha de dados e do ajuste


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:

Rs=(Vref×RL)/UadcRL


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 é:

Ro=Rs/4.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ção
400…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:

f(x)=0.83x29.2x+25(0.3×HUM)



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 //     (4096 = 12 bit)
#define MQ4_REFERENCE_VOLTAGE 3.3f //  
#define MQ4_STATIC_RESISTOR 20000 //RL -     
#define MQ4_RO_DEF 13600 //Ro -   1000 ppm (RsRo=1),   
#define MQ4_HUM_WEIGHT 0.3f //     (  ) 
#define MQ4_AIR_RSRO 4.4f // RsRo    (   )
#endif /* MQ4_H_ */

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; //  .  . 1000 ppm
float mq4_calib_value;  //   RsRo
float mq4_calib_value2; //   RsRo (    )

extern int mq4_Ro; //   1000ppm 
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;} 
 //     -  9999 :
 else {ppm=9999;} 
 
 return (int)ppm;
}


Função de cálculo de ppm com compensação da temperatura e umidade atuais
int 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;} 
//     -  9999ppm:
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;  
//  (   - MQ4_HUM_WEIGHT*(hum_cal-33)          ): 
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 = 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 ADC
int 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ção
int 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;
//    1000 ppm (      RsRo 4.4  MQ-4):
Ro = Rs/MQ4_AIR_RSRO;
   return Ro;
 }


main.c


#include "main.h"
#include "adc.h"
#include "gpio.h"
#include "mq4.h"

int ppm_def;  //ppm  
int ppm_adv;  //ppm     
int ppm_full;  //ppm        

float mq4_temp_cal = 20; //    
float mq4_hum_cal = 33; //    
extern float mq4_calib_value; //   RsRo
extern float mq4_calib_value2; //   RsRo c   

int mq4_Ro = MQ4_RO_DEF; //   1000ppm   
extern int mq4_Rs;   //    
extern int mq4_adc_value; // 
extern float mq4_volts; //   
extern float  mq4_RsRo; //   .  . 1000 ppm

//  :
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


  1. , , . TGS2611 ( 15-20 MQ-4). header- ppm ( Graph 4.4.2).
  2. 1$ , .
  3. , , RsRo 0,5…0,8, ( ). ( 1000 ppm), .. , . , , – 4…5 RsRo .
  4. . , «» header- ( Y).
  5. , , . (20 , 33% ( 65% )).
  6. 3.8 RsRo. — 2.6, 1.2…1.5.
  7. , RL ( 20 , 10…47 ). High Precision Resistor.



All Articles