Luftkvalitet i klassen

Der findes helt utrolig mange forskellig sensorer til Arduino. Jeg har for tiden kastet min kjærlighed på en CO2-gas specifik sensor.

En CO2-sensor kan bruges til at undersøge mange ting. Bl.a.:
* Udåndingsluft (afslører om man forbrænder fedt eller kulhydrat)
* Fotosyntese
* Respiration i jord
* Drivhus-effekt
* Luftkvalitet i klassen

Vernier sælger en sensor, men til omkring 3000,- pr. styk, har vi kun råd til nogle få.

Efter at have kæmpet noget tid uden held med CO2-sensoren MG811, faldt jeg over sensoren MH-Z14, som koster omkring 20 US dollars (ca. 150,- kr.):

Som ses kan den give output på flere måder. Jeg har været nødt til at vælge den ringeste: Analogt output, fordi mit board (Wemos D1) af en eller anden grund ikke kan arbejde med PWM (Arduino Uno kan godt). Men det analoge output, som er et tal typisk mellem 0 og 1023, har fungeret nogenlunde.

Den pin med det analoge output forbindes simpelthen til A0 på Wemos D1 (eller Arduino). Denne vejledning har hjulpet mig meget.

Den virker ved IR-absorption (NDIR) ved en bølgelængde på 426 nm. Her er det stort set kun CO2, som absorberer, hvorfor vi undgår signal fra andre gasser bl.a. vand, N2 m.m. Det er smart.

efter CC BY-SA 3.0, Link

Kalibrering:
Jeg kender kun tre blandinger med kendt CO2-indhold eller signal:
1) en CO2-fri blanding, opnås fx vha. gas fra en flaske helium eller bedre N2.
2) frisk luft. CO2-indhold = 400 ppm
3) sensoren kan max registrere 5000 ppm. Her over vil det analoge signal være max.
Ifølge dokumentationen er der en linær sammenhæng ml. signal og CO2-indhold.

Frisk luft giver et signal på ca. 170, som svarer til 400 ppm.
Mætning med CO2 (fra udånding) giver signal på ca. 420, som burde svare til 5000 ppm.
Så følsomheden er ikke så stor. 1 enhed svarer til et skift på ca. 20 ppm.

Jeg har brugt en “map” funktion til at omregne det analoge signal til ppm. Men det kan eleverne lige så godt selv gøre.

De fleste IR-sensorer er følsomme for større lys-spredende partikler fx vanddråber. Fx har jeg oplevet nogle pudsige målinger, som jeg tilskriver dug. Temperatur kan også have en betydning, og bør holdes konstant.

Resultaterne sendes via wifi til Thingspeak.com serveren, så de kan tilgås fra alle enheder og når som helst. (se koden nederst)

Eksempler:
CO2 målt i et klasseværelse over et par dage:

CO2 målt i en lukket beholder med en plante på en solrig formiddag m.v.:

Det sidste fald i CO2-indhold ud på natten, kan jeg ikke helt forklare. Under opvarmningen midt på dagen, blev der dannet en del kondens, idet jorden ved planten var gennemvædet. Kondensen har måske påvirket sensoren i de kølige nattetimer? Normalt ville jeg forvente at kondens fik signalet til at stige.

Til prisen virker det som en super sensor. Enkelt, specifik og tilstrækkelig følsom. Jeg har bestilt fem styks 🙂

#include <ESP8266WiFi.h>

/*
Wemos D1 -- MH-Z14
5V -- VCC
GND -- GND
A0 -- Analog output
*/

// replace with your channel’s thingspeak API key and your SSID and password
String apiKey = ""; //kode fra thingspeak.com
const char* ssid = ""; //netværk navn
const char* password = ""; //netværk kode
const char* server = "api.thingspeak.com";
WiFiClient client;

//const int PWM=3;
long co2ppm;
long co2volt;


void setup()
{
  Serial.begin(115200);
//Serial.println (" CO2 PWM program is running ..");
  pinMode(D4, OUTPUT);
Serial.println("begyndelse");
delay(10);
Serial.println("WIFI begin");
delay(1000); 
Serial.println();
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
delay(1000); 
while (WiFi.status() != WL_CONNECTED) 
{
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
 }

void loop()
{
/*
while (digitalRead(PWM) == LOW); {}
  long startTime = micros();
  while (digitalRead(PWM) == HIGH);
  {
  long duration = micros() - startTime;
  //from datasheet
  //CO2 ppm = 5000 * (Th - 2ms) / (Th + Tl - 4ms)
  //  given Tl + Th = 1004
  //        Tl = 1004 - Th
  //        = 5000 * (Th - 2ms) / (Th + 1004 - Th -4ms)
  //        = 5000 * (Th - 2ms) / 1000 = 2 * (Th - 2ms)
        co2ppm = 5 * ((duration/1000) - 2);
    }
  
//  Serial.print(co2ppm);
//    Serial.println(" ppm fra PWM");
  //  delay (30000);   //wait  30 sekunds      
*/
  
  co2volt=analogRead(A0);
Serial.println(co2volt);
// Serial.println(" volt fra A0"); 
  
  co2ppm=map(co2volt, 170, 423, 400, 5000);
// Serial.println(co2ppm);
 //Serial.println(" ppm fra analog");
 //Serial.println(); 
  digitalWrite(D4, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);              // wait for a second
  digitalWrite(D4, LOW);    // turn the LED off by making the voltage LOW
 // delay(300000); 
 
  if (client.connect(server,80)) {
String postStr = apiKey;
postStr +="&field1=";
postStr += String(co2ppm);
postStr +="&field2=";
postStr += String(co2volt);
postStr += "\r\n\r\n";
 
client.print("POST /update HTTP/1.1\n");
client.print("Host: api.thingspeak.com\n");
client.print("Connection: close\n");
client.print("X-THINGSPEAKAPIKEY: "+apiKey+"\n");
client.print("Content-Type: application/x-www-form-urlencoded\n");
client.print("Content-Length: ");
client.print(postStr.length());
client.print("\n\n");
client.print(postStr);
//Serial.println("sender til web");
 }
client.stop();
 
//Serial.println("Waiting 30 secs");
// thingspeak needs at least a 15 sec delay between updates
// 30 seconds to be safe
delay(30000);
}

Dette indlæg blev udgivet i Arduino, biologi, bioteknologi. Bogmærk permalinket.