Ster inactiefSter inactiefSter inactiefSter inactiefSter inactief
 

Wie probbeert het CO2-niveau in de lucht te meten, vindt in de MH-Z14 sensor van Winsensor een reeks modules die een gekalibeerd en digitaal resultaat bieden...

De MH-Z14 is een vrij geavanceerde CO2-sensor die een gecalibeerde waarde in digitale of analoge vorm doorstuurt. De technische fiche helpt je op weg om de verschillende protocols te implementeren. De sensor kan op 3 bereiken aangekocht worden: een bereik van 2000 ppm, van 5000 ppm en van 10000 ppm. Het mogelijk aantal meetwaarden is steeds 1000 (de nauwkeurigheid is dus respectievelijk 2, 5 of 10 ppm). Voor deze test gebruikte ik een 2000 ppm sensor module.

Omwille van de beperkte resolutie van de analoge poorten (slechts 1023 waarden tussen 0 en 5 volt), is de analoge output van de sensor (0 tot 2,4V) niet bijster bruikbaar.

De digitale uitvoer communiceert via PWM of UART. Het signaal (uit, en voor UART ook in) loopt op 3,3 volt. Dit betekent dat je dus je referentiesignaal op je Arduino moet wijzigen naar 3,3 volt - of je moet het signaal hardwarematig opvoeren naar 5 volt.

Voor dit experiment, heb ik de waarden gereden via de PWM.

Gebruik makend van een OpAmp en twee weerstanden (200 MΩ and 100MΩ) wordt het niveau met een factor 1,5 opgevoerd (maar gelimiteerd tot 5V - de spanning die de OpAmp krijgt om te kunnen werken).

Uit de technische fiche leerde ik dat de PWM waarden berekend worden door het aantal milliseconden van een lage cyclus van de blokgolf te vermenigvuldigen met twee (voor de 2000 PWM versie) en de volledige cyclus duurt 1004 milliseconden.

Aan de hand van onderstaande code, wordt het CO2-gehalte in ppm (en nog wat andere statistische waarden) uitgevoerd:

 

// set pin numbers:

const int sensorPin = 2;     // the number of the sensor pin

long laag = 0;
long hoog = 0;
long laagTijd = 0;
long hoogTijd = 0;

void setup() {
  Serial.begin(9600);
  // initialize the sensor pin as an input
  pinMode(sensorPin, INPUT);
  // Read starting value for millis... (just some value)
while(digitalRead(sensorPin) == LOW) {;}
  hoog = millis();
}

void loop(){
  // Check for high and low timing - low time * 2 = PPM
  while(digitalRead(sensorPin) == HIGH) {;}
  laag = millis();
  hoogTijd = laag - hoog;
 
  while(digitalRead(sensorPin) == LOW) {;}
  hoog = millis();
  laagTijd = hoog - laag;

  // Validity check high+low = 1004 (small margin or error allowed -> 998)  if(laagTijd + hoogTijd > 998)
  {
    Serial.print("H: ");
    Serial.println(hoogTijd,DEC);
    Serial.print("L: ");
    Serial.println(laagTijd,DEC);
    Serial.print("CO2  -  ");
    Serial.print(laagTijd * 2,DEC);
    Serial.println(" ppm");    
  } else {
    // Output in case of invalid check: value instead of 1004 ms
    Serial.print("-- CK:");
    Serial.println(laagTijd+hoogTijd, DEC);
  }
}

De code is voor verbetering vatbaar (gebruik maken van pulseIn() voor nauwkeuriger leeswaarden) ... maar voorlopig werkt het nauwkeurig genoeg. Door gebruik te maken van een controle (hoge en lage tijd samen moeten dicht in de buurt van 1004 ms liggen), worden onbetrouwbare waarden weggefilterd.

De volgende stat is om dit prachtig stukje hardware te verwerken in de logger waaraan ik werk.

Gewoon voor de lol: een klein filmpje van deze koele sensor. Het knipperende licht zorgt ervoor dat het ook wel indrukwekkend oogt... :)

Leave your comments

Post comment as a guest

0 / 4096 Character restriction
Your text should be in between 42-4096 characters
Your comments are subjected to administrator's moderation.
terms and condition.
  • No comments found
Powered by Komento