CO2 Meter

Aus der Mikrocontroller.net Artikelsammlung, mit Beiträgen verschiedener Autoren (siehe Versionsgeschichte)
Wechseln zu: Navigation, Suche

von Philipp Kälin Benutzer:philippk

Einleitung

Ziel war es im Home-Office immer eine gute Luftqualität zu haben, damit die Konzentration nicht nachlässt.

CO2-Meter

Mir war es wichtig, dass das CO2-Meter sowohl im Standalone Betrieb als auch als Logger am PC verwendet werden kann. Die Anzeige soll möglichst simpel über eine "Ampel" realisiert werden und nicht über eine umständliche Ziffernanzeige. Auf einen Alarm und sonstige Spielereien wurde gezielt verzichtet, ganz getreu dem KISS Prinzip (Keep it simple, stupid).

Eine Diskussionsseite dazu gibt es im Forum

Aufbau

Lessons Learned

Der Aufbau hat mehr als einen Iterations-Schritt benötigt, daher ist dies wahrscheinlich das wichtigste Kapitel, ihr müsst ja nicht die gleichen Fehler und Lernprozesse wie ich machen. Bei den Sensoren muss man nämlich auf ein paar Dinge achten: - In einem ersten Versuch habe ich einen günstigen Gas-Sensor genommen (einen CJMCU-811). Dumm nur dass der einen eCo2 ausgibt, also nur ein äquivalenter Wert der angibt wie gut die Luft ist. Die Ergebnisse sind aus meiner Sicht für ein Wohnzimmer oder Büro schlicht unbrauchbar. Der Sensor gibt zwar sofort an wenn jemand auch nur in der Nähe beginnt zu kochen, sagt aber absolut nichts über die CO2 Konzentration aus.

Zwei weitere Erkenntnisse die ich gemacht habe sind: - Ein "richtiger" CO2 Sensor produziert Abwärme, den Temperatursensor auf der gleichen Platine bzw. in der Nähe zu montieren verfälscht die Temperatur stark. - Die Genauigkeit des hier verwendeten CO2 Sensors ist extrem abhängig von der Betriebsspannung. Und vergesst den Mythos dass bei USB 5V raus kommt ;-) Ich habe irgendwas zwischen 4.5V und etwa 5.3V gemessen, je nach PC oder verwendetem USB-Hub.

Sensorauswahl

Es gibt erstaunlich wenige vernünftige CO2 Sensoren die wirklich CO2 messen, dafür sehr viel mist, die irgendwas messen und dann als eCO2 ausgeben. Die Wahl fiel bei mir auf einen Winsen MH-Z19C. Dieser kostet übrigens um die 25€, alles Andere was es bei Aliexpress und eBay günstiger gibt ist Fake, daher genau hinsehen beim Kaufen. Es gibt in Foren auch gute Tipps wie man die Fake-Sensoren erkennt. Die Luxusvariante wäre natürlich ein Sensirion SCD30, aber der Kosten noch ein ganzes Stück mehr.


Hardware

Die Hardware des CO2-Meters besteht im Wesentlichen aus folgenden Komponenten: - USB <-> UART Wandler (extern via FTDI FT232) - CO2 Sensor Modul (MH-Z19C) - Temperatursensor (DS18B20) - Spannungsversorgung - Drehschalter für Warnschwelle - Mikrocontroller (ATtiny2313)

Der USB-UART Wandler braucht glaube ich keine nähere Erklärung. Er ist nicht einmal zwingend notwendig, da wie gesagt auch ein Standalone Betrieb möglich ist. Die Daten sind nur unidirektional vom Sensor zum PC, in die Gegenrichtung gibt es keine Daten.

Der CO2 Sensor bietet zwei Schnittstellen für den Messwert, einmal als Analogsignal und einmal per UART. Ich habe mich für die UART entschieden, aus einem ganz einfachen Grund: Die Umrechnung von Spannung zu Messwert ist zwar schön linear, aber der Programmspeicher auf dem ATtiny2313 ist mit 2kB sehr begrenzt. Von Floating Point kann man nicht mal träumen, das ist schlicht nicht möglich mit 2kB, und selbst mit Ganzzahlen macht das ganze auch nicht wirklich Spass zumal man auf eine Division verzichten muss, denn selbst die braucht zu viel Platz. Man ist also auf Addition und Multiplikation beschränkt. Da ist es irgendwie schon viel schöner wenn man das ganze per UART als Zahl bekommt.

Die Spannungsversorgung des Sensors muss mit 5V ± 0.1V erfolgen, daher hat die Spannungsversorgung ein eigenes Kapitel bekommen.

Beim Temperatursensor fiel die Wahl auf den DS18B20 da dieser sehr genau ist und die Temperatur digital via One-Wire liefert. Die Genauigkeit bekommt man natürlich auch mit genauen NTC's und OP Beschaltung hin, aber dann sind wir wieder am Punkt der Umrechnung die hier sogar nicht-Linear ist und den Programmspeicher sprengt. Der Sensor funktioniert auch mit einem Meter umgeschirmten Kabel dazwischen wunderbar.

Die Spannungsversorgung muss wie gesagt sehr genau 5V entsprechen und wenn möglich auch rauscharm sein. Natürlich könnte man einen kombinierten Buck/Boost Konverter nehmen, nur haben die meisten Wandler es normalerweise nicht so gern wenn die Eingangsspannung ungefähr der Ausgangsspannung entspricht und sie die ganze Zeit zwischen Buck und Boost wechseln. Genau das wollen wir aber ~5V in genau 5V zu wandeln. Ein zweiter, besserer Ansatz ist die Spannung zuerst auf ca. 7V zu bringen und dann mittels Linearregler wieder auf 5V zu regeln. Das ist simpel, robus und rauscharm. Nur gibt es fast keine DC/DC Wandler die von 5V auf ~7V wandeln. Die Idee ist nun, dass man einen 5V nach 3.3V Wandler nimmt, und dieser 3.3V zu den 5V (USB) addiert. Das funktioniert dann wenn die 3.3V isoliert, also potentialgetrennt sind. Dann hat man im Worst-Case bei 4.5V USB-Spannung immer noch 7.8V, die man wider auf 5V regeln kann. Genau solche DC/DC Wandler gibt recht günstig, z.B. den TBA 1 von TRACO. Die Schaltung sieht auf den ersten Blick ein bisschen gewöhnungsbedürftig aus, funktioniert aber einwandfrei.

Spannungsversorgung

Für den Warnschwelle habe ich einen Drehschalter mit Zahlen von 0..9 genommen. Man kann den Wert aber auch fix programmieren.

Beim Mikrocontroller habe ich mich für einen ATtiny2313 entschieden. Warum? a) DIL-Bauform b) ist grad rumgelegen c) ich hatten den Ehrgeiz, die ganze SW in 2kB Flash zu quetschen d) ich hatte keine Lust einen Tausendfüssler auf die Lochraster-Pplatine zu legen (soll ja auch optisch was hergeben) und e) meiner hat sogar noch einen wunderschönen weissen Siebdruck und nicht nur eine Lasergravour. Die Gründe c bis e muss man übrigens nicht nachvollziehen können.

Software

Die Software habe ich in C++ geschrieben. An C++ Features habe ich eigentlich nur Namespaces, bool's und enums verwendet. Und NEIN, es braucht nicht weniger Platz wenn man es in C schreibt! Ich habe das selber kurz umgeschrieben um diese Behauptung zu untermauern.

Das schwierige bei der Software war eigentlich nur, Flash zu sparen. An dieser Stelle möchte ich noch die folgenden ganz grossartigen Libraries erwähnen (allesamt von Peter Dannegger): - OneWire und DS18B20 - Software-UART Ich habe daran nur noch Anpassungen gemacht um Teilfunktionen wegzulassen und damit sie sich wie echter C++ anfühlen.

Ein bisschen Speziell an der Architektur ist, dass ich von der Hardware-UART den Receive Teil für die Daten vom Sensor verwendet habe und den Transmit Teil um die Daten zum PC zu übertragen. Somit wird von der Software-UART nur der Transmit Teil verwendet um Befehle an den Sensor zu senden. Warum habe ich nicht einfach die Sensor komplett auf die Hardware-UART genommen und den Transmit Teil der Software-UART für die Daten zum PC? Die Idee war mal, das Senden zum PC aus einem Buffer heraus Interrupt gesteuert zu machen, dazu ist es aber nie gekommen. Es funktioniert trotzdem, die Daten kommen einfach nicht ganz so schnell an weil nicht zuerst alles in ein Buffer gespeichert wird und dann am Stück gesendet sondern einzeln.

Mechanischer Aufbau

Der Aufbau ist komplett ohne SMD Bauteile und ohne 3D-Druck ;-) Passt aber trotzdem auf 65 x 65 mm. Wenn man die Oberflächen behandelt, würde ich vorsichtshalber darauf achten, dass die Behandlung nicht ausdünstet, also z.B. Holz nicht Ölen oder Wachsen. Ich habe mich für einen Acryllack entschieden der auch ohne Lösungsmittel auskommt.

Kalibrierung & Validierung

Kalibrierung

Die Kalibrierung kann man normal an der frischen Luft machen, den Sensor also einfach nach draussen stellen. Wichtig ist zu beachten, dass die Temperatur an der frischen Luft ungefähr der Raumtemperatur entsprechen sollte. Das heisst im Winter ist dies wesentlich schwieriger als im Sommer. Die automatische Kalibrierung habe ich bei mir ausgeschaltet. Die manuelle Kalibrierung kann man bei mir anstossen, indem der Drehschalter auf 0 gedreht wird. Danach muss die Luftqualität 30 Minuten lang unter dem Schwellwert von 450 ppm sein (in dieser Zeit blinkt die LED rot/blau). Sobald die Kalibrierung abgeschlossen ist blinkt die LED grün/blau.

Validierung

Zur Validierung hatte ich kein zweites CO2 Messgerät zur Hand. Was man jedoch machen kann ist, dass man sich ein Modell eines Raumes berechnen lässt (z.B. hier: [1]). Danach setzt man sich selber über eine längere Zeit zusammen mit dem CO2 Sensor in diesen geschlossenen Raum und vergleicht den CO2 Anstieg mit dem Modell. Bei mir hat das sehr gut übereingestimmt.

User Interface

Das GUI an sich ist ebenfalls in C++ geschrieben und nutzt die Qt Bibliothek. Damit sollte es auf allen Plattformen benutzbar sein. Ich habe es sowohl unter Linux als auch unter Windows in Betrieb.

Das GUI ist zum einen dafür da, den aktuellen Wert einfach anzuzeigen, kann aber auch als Logger verwendet werden, wenn die Standardausgabe in eine Datei umgeleitet wird. Alle Einstellungen für das GUI werden einfach in der INI Datei vorgenommen, welche dem Programm als Parameter mitgegeben wird. Ein Aufruf unter Linux kann dann z.B. sol lauten:

./Co2Meter ../Co2MeterSettings.ini > logdata.txt
GUI

Die Ausgabe ist Tabulator getrennt und sieht dann so aus:

INI-File:  "/opt/Co2Meter/Co2MeterSettings.ini"
Opacity:   0.8
Port:      "/dev/ttyUSB0"
T-Offset:  0
Min:       400
Max:       800
--------------------------------------------------------------------------
Date & Time     Co2 Concentration[ppm]  Temperature[°C]
2023-01-08 05:10:22      688     19.3
2023-01-08 05:10:25      688     19.3
2023-01-08 05:10:28      688     19.3
2023-01-08 05:10:31      688     19.3

Downloads

Schema

Software