in Arduino Spiegato Facile, Sensori Arduino

Sensori Arduino: sensore di gas MQ-5

Dopo aver introdotto il sensore di gas e il suo principio di funzionamento, andiamo a utilizzarlo realizzando un semplice circuito e codice.

Realizzazione circuitale

La preparazione di uno schema circuitale da collegare ad Arduino è abbastanza semplice e può essere trasposto a qualsiasi altra scheda di prototipazione. Decidiamo di voler acquisire il segnale in analogico, per avere maggiori informazioni sulla variazione di concentrazione di gas.

Assumendo per semplicità il sensore come una semplice resistenza RS e la resistenza dovuta al trimmer con RL, il circuito può essere declinato come segue:

Si tratta di un semplice partitore di tensione, la cui uscita verrà direttamente letta da un pin analogico dei microcontrollore. Ovviamente i valori assunti dai resistori varieranno, per cui la caratteristica non sarà univocamente determinata. Assumeremo, per semplicità, fissata la resistenza RL. Ricaviamo l’espressione di RS in funzione dei parametri circuitali, di cui conosciamo il valore:

V={ V }_{ RS }+{ V }_{ RL }=I\cdot \left( { R }_{ S }+{ R }_{ L } \right) =I\cdot { R }_{ S }+I\cdot { R }_{ L }=
=\frac { V\cdot { R }_{ S } }{ { R }_{ S }+{ R }_{ L } } +{ V }_{ OUT }
V-{ V }_{ OUT }=\frac { { R }_{ S } }{ { R }_{ S }+{ R }_{ L } } \cdot V
\left( V-{ V }_{ OUT } \right) \cdot \left( { R }_{ S }+{ R }_{ L } \right) ={ V\cdot R }_{ S }
{ V }_{ OUT }\cdot { R }_{ S }=V\cdot { R }_{ L }-{ V }_{ OUT }\cdot { R }_{ L }
{ R }_{ S }=\frac { \left( V-{ V }_{ OUT } \right)  }{ { V }_{ OUT } } \cdot { R }_{ L }

Ricavata l’espressione, analizziamo il datasheet relativo al sensore di gas MQ-5 ed in particolare alla caratteristica RS/R0, dove R0 indica la resistenza del sensore in presenza di 1000ppm (parti per milione) di H2, come visibile nel seguente grafico:

Il grafico mostra il legame tra il valore RS/R0 e la concentrazione, espressa in ppm (parti per milione) dei gas a cui il sensore reagisce. Si può notare la presenza, nello stesso grafico, di diverse caratteristiche in base al gas rilevato. L’aria pulita si pone in alto a 6.5 ed assume una caratteristica costante, mentre più in basso sono presenti gas come alcool, monossido di carbonio e GPL.  Sebbene gli andamenti sembrino lineari, c’è da evidenziare il fatto che il grafico è logaritmico, per cui l’andamento in scala lineare risulta differente.

Realizziamo un semplice sistema di prova, usando un Arduino UNO e il sensore di gas MQ-5, come in figura:

In questo semplice circuito abbiamo connesso l’alimentazione del sensore direttamente alla 5V dell’Arduino: è consigliabile utilizzare una alimentazione dedicata per il sensore, in quanto può assorbire (a causa del riscaldatore) correnti non indifferenti. Completiamo i collegamenti con il GND e il terminale analogico su A0 dell’Arduino.

 

Calibrazione del sensore di gas MQ-5

Al fine di ottenere delle acquisizioni quanto più accurate e veritiere possibile, è necessario procedere ad una prima fase di calibrazione del sensore: dovremo infatti ricavarci il valore di Rin condizioni di aria pulita.

Poniamo quindi il circuito realizzato in un ambiente con aria pulita e garantiamo un ricambio dell’aria costante. Se si utilizza per la prima volta il sensore, è buona norma mantenerlo alimentato per almeno 24 ore prima dell’uso. Inoltre, ad ogni avvio è necessario attendere 10 minuti circa per portare il sistema a regime termico.

Questo processo è comunque suscettibile di imprecisioni e non è ripetibile: teoricamente si dovrebbe procedere in ambiente isolato, conoscendone temperatura e umidità, introducendo una concentrazione di gas nota e calibrare il sistema su di essa. Ma per valutazioni nel nostro campo di interesse l’approccio qui seguito è comunque accettabile. 

Ecco il codice di esempio per la calibrazione, che potete scaricare facilmente anche da qui:

#define MQ5_pin A0

float Vout;
float RS_air; //  Valore di RS in aria pulita 
float R0;  
float sensorValue = 0;
int i = 0;
float Vin = 5; //bisogna garantire 5 Volt stabili
int RL = 10000; //10k
int campioni = 1000;

void setup() {
  Serial.begin(9600);
}

void loop() {
  for (i = 0 ; i < campioni ; i++) {
    sensorValue += analogRead(MQ5_pin);
    delay(1);
  }
  sensorValue = sensorValue / campioni;

  Vout = sensorValue / 1024 * Vin;
  RS_air = (Vin - Vout) * RL / Vout;
  R0 = RS_air / 6.5;

  Serial.print("Vout \t \t");                 Serial.print("RS_air \t \t");   Serial.print("R0 \t \t");   Serial.println("RS_air/R0 \t");
  Serial.print(Vout); Serial.print("V \t \t"); Serial.print(RS_air);  Serial.print("\t");       Serial.print(R0);    Serial.print("\t \t");    Serial.println(RS_air / R0);
}

Un diagramma di flusso del codice di calibrazione è illustrato di seguito:

Analizziamo il codice: inizialmente viene definito il pin al quale abbiamo collegato il sensore MQ-5, oltre che alcune variabili utili ai nostri fini.  Inizializzata e impostata la velocità della seriale, si entra subito nel loop nel quale viene effettuata una media su 1000 campioni del segnale in ingresso. Una volta mediato, tale valore viene scalato in base alla risoluzione del microcontrollore e al suo livello logico: i pin analogici lavorano a 10 bit (1024 valori) con logica a 5 Volt.

In questo modo abbiamo ottenuto una misura della tensione Vout dovuta al partitore, precedentemente analizzato. Applicando la formula ricavata, siamo in grado di acquisire il valore di resistenza assunta dal sensore. 

Caricato il codice sul microcontrollore, assicuriamoci di porre il sensore in un luogo arieggiato e pulito. Garantito ciò, è possibile visualizzare i dati tramite il Monitor Seriale, come in figura:

Noterete che con il tempo si riscalderà e emetterà uno strano odore: è tutto normale, per come abbiamo visto il suo principio di funzionamento ci dovremmo meravigliare del contrario!

Dai risultati, possiamo già notare che i valori della tensione Vout e della resistenza Rs rientrano nei range attesi. Annotiamo il valore R0 ottenuto, in quanto sarà utile per la valutazione delle concentrazioni di gas.

 

Letture dal sensore di gas MQ-5

Ricavato il valore di R0  dalla fase di calibrazione, procediamo con l’utilizzo effettivo del sensore e quindi con le acquisizioni delle misure. Il circuito rimarrà lo stesso.

Riprendendo il grafico delle caratteristiche al variare della concentrazione, abbiamo detto che quell’andamento lineare in realtà è dovuto alla scala logaritmica utilizzata per la rappresentazione. Estrapolandone i dati e riportandoli su scala lineare, otterremo il seguente grafico:

dal quale è evidente che l’andamento non è affatto lineare (a meno dell’aria, che si mantiene costante).

Invertendo ascisse e ordinate, è possibile ottenere la concentrazione in ppm in funzione del rapporto RS/R0.

Da quest’ultimo grafico possiamo notare che il valore di RS/R0 in “aria pulita” si discosta nettamente da quello in presenza, seppur minima (200 ppm di CO è la prima concentrazione di gas rilevata), dei gas rilevati. Ciò può essere molto utile per apprezzare di quanto l’ambiente si discosti dal valore “ottimale” ed eventualmente utilizzare una soglia per avvertire quando ci si è allontanati troppo.

Questo utilizzo approssimativo del sensore non è da scartare, ricordando il suo punto debole: l’alterazione della misura in presenza di più gas e l’impossibilità di identificarne la presenza.

Calcolando il logaritmo dei valori riportati nel primo grafico, otteniamo esattamente l’andamento fornito nel datasheet, come riprova e conferma dei passi effettati.

Tutti i grafici qui riportati sono stati realizzati in Excel, che permette di ricavare anche l’equazione che meglio approssima l’andamento delle caratteristiche, come visibile nella figura sopra. In particolare, è stata usata una linea di tendenza lineare, la cui espressione analitica è, appunto, lineare, del tipo:

y = mx+q

I valori di m (slope, pendenza o coefficiente angolare) e q (intercetta) ci saranno utili in seguito per il calcolo delle concentrazioni per i diversi gas.

Trovate il codice di esempio per la lettura qui, mentre di seguito il diagramma di flusso: 

Analizziamo di seguito alcune porzioni di codice:

float CO[2] =      { -0.1547, 0.9143};    //data format:{ m, q};
float Alcohol[2] = { -0.2617, 1.113};     //data format:{ m, q};
float H2[2] =      { -0.2428, 0.7474};    //data format:{ m, q};
float Metano[2] =  { -0.3958, 0.8973};    //data format:{ m, q};
float GPL[2] =     { -0.4132, 0.7928};    //data format:{ m, q};
String GAS[6] = {"undefined", "CO", "Alcohol", "H2", "Metano", "GPL"};

Nella dichiarazione delle variabili, oltre a quelle già incontrate per la calibrazione, sono presenti questi array, a cui sono associati i valori di m e q per ciascun gas, ricavati precedentemente in Excel. L’ultimo array serve semplicemente per etichettare i diversi gas.

void conversione(float ratio, float m, float q) {
  Serial.println("-------------------------------------------------------------------------------");
  String wGas = GAS[j];
  ppm_log = (log10(ratio) - q) / m;
  ppm = pow(10, ppm_log);
  percentuale = ppm / 10000; // *100 / 1 milione

  Serial.print("GAS = ");
  Serial.println(wGas);

  if (ppm > 1000) {
    Serial.print(" Attenzione, "); Serial.print(wGas); Serial.println(" in eccesso!!!");
  }

  Serial.print("ppm_log = "); Serial.print("\t"); Serial.print(ppm_log); Serial.print("\t");
  Serial.print("ppm = "); Serial.print("\t"); Serial.print(ppm); Serial.print("\t");
  Serial.print("percentuale = "); Serial.print("\t"); Serial.print(percentuale); Serial.print("\t"); Serial.print("%");

  j++;
}

Questa funzione ci permette di calcolare la concentrazione in ppm di un generico gas e la sua percentuale conoscendo il valore di RS/R0 calcolato esternamente e successivamente fornito. Inoltre controlla se la concentrazione supera il valore di 1000 ppm, valore per il quale la presenza di gas, generalmente, non può più essere trascurata. Questa funzione viene richiamata nel loop() per ogni gas, come sotto riportato, per cui si avranno letture diverse dovute alla diversa caratteristica dei diversi  gas. come abbiamo visto dai grafici precedenti.

  j = 1;
  conversione(ratio, CO[0], CO[1]); Serial.println(" CO");
  conversione(ratio, Alcohol[0], Alcohol[1]); Serial.println(" Alcohol");
  conversione(ratio, H2[0], H2[1]); Serial.println(" H2");
  conversione(ratio, Metano[0], Metano[1]); Serial.println(" Metano");
  conversione(ratio, GPL[0], GPL[1]); Serial.println(" GPL");
  j = 0;

Infine, la variabile j viene aumentata ogni volta che la funzione conversione() viene chiamata, per identificare il gas successivo nell’array GAS[] e riportato a zero quando è finito.


Per questo articolo è tutto.

Per dubbi, errori o semplicemente ringraziamenti, puoi contattarci attraverso i nostri contatti social.

Puoi seguirci sul sito: www.antima.it
su Instagram: https://www.instagram.com/antima.it/
su Facebook: https://www.facebook.com/Antima.it/
su Youtube: https://www.youtube.com/channel/UC-D8OGdMdveQILJeQvh8atQ

Scrivi un commento

Commento