Ankündigung

Einklappen
Keine Ankündigung bisher.

Arduino-Sensor für CO² bzw. VOC

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

    Für die Mini-Anhänger unter uns habe ich einen Sketch erstellt. Wenn der Setup stimmt, müssen nur die Adressen eingestellt und an KNX angebunden werden, so sollte es sofort funktionieren. Der Sketch beinhaltet keine Leseanfrage, da mir das Schreiben auf den Bus - bei Änderung der Werte - reicht.
    Ausserdem funktioniert der Sketch OHNE iAQ-Lib, da die Lib bei mir heikel war. Danke an Stefan für den Code. Leider enthielt er einen Fehler. VOC wurde nicht ausgelesen. Die Datenbytes waren die von CO2.
    Deshalb habe ich hier gespickt. Die LIB finde ich sehr gut und enthält auch noch den Code für einen Kombisensor VOC/BME280. Einfach den Beispielsketch zum Test nehmen.

    Code:
    // Pro Mini Version
    #include "Wire.h"
    
    
    //KNX
    #include <KnxTpUart.h>
    #define KNX_PHYSICAL_ADRESS                 "1.1.2"
    #define KNX_WRITE_GROUPADRESS_STATUS        "7/0/200"
    #define KNX_WRITE_GROUPADRESS_CO2           "7/0/201"
    #define KNX_WRITE_GROUPADRESS_TVOC          "7/0/202"
    #define KNX_MEASSURE_INTERVAL_MS            30000    // Messintervall alle 30 sekunden
    #define KNX_SEND_INTERVAL_MS_STATUS         1800000  // senden des Status mindestens alle 30 minuten
    #define KNX_SEND_INTERVAL_MS_CO2            1800000  // senden des CO2 Werts mindestens alle 30 minuten
    #define KNX_SEND_INTERVAL_MS_TVOC           1800000  // senden des VOC Werts mindestens alle 30 minuten
    #define watchdog_time                       3600000  // Watchdog = 1 Stunde
    const int ledpin = 13;
    #define iaqaddress 0x5A
    
    //Initialize LNX
    KnxTpUart knx(&Serial, KNX_PHYSICAL_ADRESS);
    
    int32_t iAQ_Res;
    uint16_t airQuality;
    uint8_t iAQstatus;
    uint16_t airTvoc;
    
    unsigned long startTime;
    unsigned long watchdog;
    unsigned long sendTimeStatus;
    unsigned long sendTimeCO2;
    unsigned long sendTimeVOC;
    uint16_t oldairQuality;
    uint8_t oldiAQstatus = 255;
    uint16_t oldairTvoc;
    #define uns8  uint8_t
    #define uns16 uint16_t
    #define sn32  int32_t
    uns8 data[9];
    
    bool result;
    
    void setup() {
      // join I2C bus (I2Cdev library doesn't do this automatically)
      Wire.begin();
    
       //initialize connection to KNX BCU
      Serial.begin(19200);
      while (!Serial) {
        ; // wait for serial port to connect
      }
      UCSR0C = UCSR0C | B00100000;
    
       // Reset UART
      knx.uartReset();
    
      startTime = millis();
      watchdog = millis();
    
      // VOC Status
      // 0 = OK
      // 1 = BUSY
      // 16 = WARMUP
      // 128 = ERROR
    
    }
    
    void loop() {
    
      readRegisters();
    
      delay(1000); //sonst geht immer wieder mal Status auf Busy
      // Wenn unterhalb des messintervalls: nichts tun
      if (millis() - startTime < KNX_MEASSURE_INTERVAL_MS) {
        delay(1);
        return;
      }
      startTime = millis();
    
      // Wenn überhalb des sendeintrvalls
      if (millis() - sendTimeStatus > KNX_SEND_INTERVAL_MS_STATUS) {
        oldiAQstatus = 255; // undefinierter wert - damit beim nächsten befehl gesendet wird
      }
    
      // Wenn überhalb des sendeintrvalls
      if (millis() - sendTimeCO2 > KNX_SEND_INTERVAL_MS_CO2) {
        oldairQuality = 10; // undefinierter wert - damit beim nächsten befehl gesendet wird
      }
    
      // Wenn überhalb des sendeintrvalls
      if (millis() - sendTimeVOC > KNX_SEND_INTERVAL_MS_TVOC) {
        oldairTvoc = 10; // undefinierter wert - damit beim nächsten befehl gesendet wird
      }
    
      // Wenn über Watchdog-time: Fehler auf BUS senden, reboot
      if (millis() - watchdog > watchdog_time) {
     //   result = knx.groupWrite1ByteInt(KNX_WRITE_GROUPADRESS_STATUS, 127);
        delay(1000);
        asm volatile ("  jmp 0");
        return;
      }
    
      // read sensor status
      if (iAQstatus != oldiAQstatus) {
        oldiAQstatus = iAQstatus;
        result = knx.groupWrite1ByteInt(KNX_WRITE_GROUPADRESS_STATUS, iAQstatus);
        sendTimeStatus = millis();      // define last Status send time
        watchdog = millis();            // set Watchdog
        //Serial.print("Status: ");
        //Serial.println(iAQstatus);
      }
      // read seansor CO2
      if (airQuality >= (oldairQuality + 50) || airQuality <= (oldairQuality - 50)) {
        oldairQuality = airQuality;
        result = knx.groupWrite2ByteInt(KNX_WRITE_GROUPADRESS_CO2, airQuality);
        sendTimeCO2 = millis();       // define last CO2 send time
        watchdog = millis();          // set Watchdog
        //Serial.print("CO2: ");
        //Serial.println(airQuality);
       }
      // read seansor TVoc
      if (airTvoc >= (oldairTvoc + 30) || airTvoc <= (oldairTvoc - 30)) {
        oldairTvoc = airTvoc;
        result = knx.groupWrite2ByteInt(KNX_WRITE_GROUPADRESS_TVOC, airTvoc);
        sendTimeVOC = millis();         // define last VOC send time
        watchdog = millis();            // set Watchdog
        //Serial.print("VOC: ");
        //Serial.println(airTvoc);
      }
      // Serial.print("Widerstand: : ");
      // Serial.println(iAQ_Res);
    }
    
    void readRegisters() {
      int i = 0;
      Wire.requestFrom(iaqaddress, 9);
      while(Wire.available()) {
        data[i] = Wire.read();
        i++;
      }
      airQuality = (uns16)((data[0] << 8) + data[1]);
      iAQstatus = data[2];
      //iAQ_Res = (sn32)(data[3] << 24) + (sn32)(data[4] << 16) + (sn32)(data[5] << 8) + (sn32)data[6]; //Widerstand in OHM
      airTvoc = (uns16)(data[7] << 8) + (uns16)(data[8]);
    
    }
    Achja, wenn alles passt, dann sieht das so aus:
    Die Werte x100 und alles ist gut.

    2017-06-06 19_44_12-ETS5™ - Test Jung.png
    Zuletzt geändert von WagoKlemme; 06.06.2017, 18:46.
    >>Smelly One<<
    >> BURLI <<
    Grüße Armin

    Kommentar


      Hallo Armin,

      saugeil...danke fürs Teilen!
      Viele Grüße,
      Stefan

      DIY-Bastelprojekte: || >> Smelly One << || >> BURLI << ||

      Kommentar


        Zitat von WagoKlemme Beitrag anzeigen
        Leider enthielt er einen Fehler. VOC wurde nicht ausgelesen. Die Datenbytes waren die von CO2.
        Hmmm...sicher? Bei mir hat der aber 1a funktioniert und es kamen auch unterschiedliche Werte für CO2 und VOC raus...die Register werden ja nacheinander aus dem IAQ ausgelesen. Aber: möglicherweise war es nicht der richtige, ich hatte leider einige Varianten davon :-(

        Aber egal, hauptsache es funzt :-)

        Blöde Frage: warum nimmst Du den Wert nicht gleich im Code *100? Dann hast Du gleich den realen Wert im KNX und bauchst dort keine Rechnung mehr machen.
        Zuletzt geändert von dreamy1; 06.06.2017, 21:05.
        Viele Grüße,
        Stefan

        DIY-Bastelprojekte: || >> Smelly One << || >> BURLI << ||

        Kommentar


          Zitat von dreamy1 Beitrag anzeigen
          Blöde Frage: warum nimmst Du den Wert nicht gleich im Code *100? Dann hast Du gleich den realen Wert im KNX und bauchst dort keine Rechnung mehr machen.
          Hi Stefan,
          das ist nur ein Problem mit ETS, da ich DPT9 genommen habe. Dann macht ETS ein Float draus. In Edomi oder sonst was, dann den Wert x100 nehmen und schon passts.
          Im Code geht es nicht, weil es zwei einzelne Bytes sind, die zusammen ein Int ergeben. Das wollte/muss ich so lassen.
          >>Smelly One<<
          >> BURLI <<
          Grüße Armin

          Kommentar


            Hallo zusammen,

            bin auch gerade dabei einen KNX-BCU-Arduino-VOC-Prototypen :-) zu basteln. Habe den Thread gelesen und frage mich nun welcher VOC-Sensor am besten geeignet ist. So wie ich es verstanden habe, nutzen viele den IAQ-CORE C-ND Sensor. Der liegt preislich bei 30-40 Euro, wohingegen bspw. der MP503 bei 1-2 Euro pro Stück liegt. Ich habe gesehen, dass beim zweiten eine Range von 10-1000ppm angegeben ist. Das ist sicher nicht optimal.

            Es gibt auch Pakete mit mehreren Sensoren (MQ-2 MQ-3 MQ-4 MQ-5 MQ-6 MQ-7 MQ-8 MQ-9 MQ-135) für zusammen 12,60USD bei Dr. Wong.

            Übersehe ich dabei sonst noch was? Gibt es einen anderen Sensor, den ihr empfehlen würdet bzw. mit welchem Sensor seid ihr zufrieden?

            Viele Grüße,
            Flo
            Zuletzt geändert von gkamp; 02.08.2017, 14:21.

            Kommentar


              Ich schwöre auf die AMS IAQ Core. Lassen sich wunderbar selbst löten und haben bereits alle Kalibrierroutinen mit eigenem µC an Bord, das müsste man sonst alles selbst programmieren. Ohne Kalibriergas für die Erstinbetriebnahme und Nullpunkteinstellung kriegst Du da mit Onkel Wongs Erben keine vernünftige Messung hin. Einzige für mich brauchbare Alternative wäre der CCS811 von AMS, aber der ist schwer von Hand zu löten, hat keinen Filter gegen Staub etc. und so viel günstiger ist der am Ende auch nicht.
              Zuletzt geändert von dreamy1; 02.08.2017, 16:55.
              Viele Grüße,
              Stefan

              DIY-Bastelprojekte: || >> Smelly One << || >> BURLI << ||

              Kommentar


                Danke für das Feedback. Das habe ich tatsächlich nicht bedacht. Habe auch von @ThorstenGehrig gelesen, dass er zufrieden war. Von daher ist dieser Sensor mein aktueller Favorit.

                Kommentar


                  Der ziemlich zu Beginn des Threads genannte BME680 von Bosch ist mittlerweile verfügbar:
                  http://www.mouser.de/search/ProductD...rtualkeyBME680

                  Bei Watterott gibt es ein kleines BreakoutBoard für die, die auf die schnelle testen wollen:
                  http://www.watterott.com/en/BME680-Breakout

                  Gruß

                  Kommentar


                    Vielleicht eine ganz interessante Randinfo zum BME680:

                    Ich habe mir mal die verfügbaren Libs für den BME680 angesehen...also wenn ich das richtig interpretiere, muss die ganze Hauptarbeit zum Erfassen eines Luftgütemesswerts letztendlich der Arduino leisten, und das Ganze dann auch noch zeitkritisch (es wird letztendlich nur Widerstand des Heizelementes nach X Millisekunden Betrieb geliefert, d.h. das Heizelement wird periodisch an- und abgeschaltet und nach einer exakten Zeitdauer wird dann der Widerstand gemessen, dazu gibt es diverse Zeitschleifen im Code).
                    Über den I²C werden also nur reine Rohdaten geliefert, die ganze Umrechnung auf einen ppm-Wert mitsamt den ganzen Kalibrierdaten muss der Arduino mehr oder minder in Echtzeit machen. Ich fürchte, dass wenn der Arduino auch noch was anderes tun muss außer den BME zu betüdeln und man nicht alles interruptgesteuert optimiert, kommt da nur noch Schrott raus (zumindest bei der Luftgütemessung). Kommt dann aber sicher auch auf die Potenz des gewählten Arduino an.

                    Das erklärt dann auch den Preisunterschied zu einem IAQ, der über I²C direkt alle Messwerte liefert (der hat dazu aber auch einen eigenen µC onboard). Und ein CO2-Equivalent liefert der IAQ auch noch extra...
                    Viele Grüße,
                    Stefan

                    DIY-Bastelprojekte: || >> Smelly One << || >> BURLI << ||

                    Kommentar


                      Hallo Stefan,

                      ich habe mal DB von BME680 angeschaut, du hast wohl Recht, Ardunino muss sich um die Berechnung kümmern. Bosch will sogar noch eine Binary verticken, womit man T und RH besser berechnen kann...
                      Ich glaube aber wenn man einen besseren uC als 328p einsetzt (z.B. SAMD21 oder STM32) soll es auch kein Problem sein. Und die neue uC verbrauchen auch noch weniger oder zumindest gleich viel Strom bei mehr Leistung.

                      AMS IAQ hat zwar uC onBoard, ist besser lötbar, aber auch 4x teuerer... und auch viel größer. Und wenn man noch T und RH Sensoren mitberücksichtigt, ist er sogar bis zu 5x teuerer...

                      Kannst mir bitte noch erklären, wo der Vorteil ist CO2 Equivalent zu wissen?
                      Ich finde z.B. ganz gut, dass Bosch gleich "gut"/"schlecht" sagt und nicht nur 1500ppm... mit der Zahl kann ich nicht soviel anfangen, bzw. muss trotzdem zu "gut"/"schlecht" zuorndnen. Und für Zuhaus wo man die Lüftungsanlage steuern möchte, reicht doch auch "gut"/"schlecht" aus, oder?

                      Kommentar


                        Hallo Eugen,

                        das muss jeder für sich selbst enstscheiden - ich gebe lieber etwas mehr aus und habe dafür weniger Fehlerquellen und wahrscheinlich auch die besseren Messergebnisse. Der IAQ ist ein professioneller Sensor mit Staubschutzkappe und direkter Messwertausgabe, der BME ein für den Massenmarkt im Handybereich beworbener Sensor, wo der Messwert vom Endgerät ermittelt werden muss (was für einen potenten Handyprozessor kein Problem ist).

                        Ich finde gerade den CO2-Wert sehr hilfreich, da man sowohl die Luftqualität "als Ganzes" (CO2) als auch einzelne "Miefereignisse" (VOC) sauber detektieren und mit beliebigen Grenzwerten versehen kann (Beispiel: Kellerraum versus Schlafzimmer versus Gäste-WC). "Gut/Schlecht" wäre mir da einfach zu wenig.

                        Siehe auch: http://ams.com/eng/content/view/download/380636

                        Bezüglich der Grenzwerte, siehe hier einen Artikel des Umweltbundesamtes (Tabelle 3 auf Seite 9):
                        https://www.google.de/url?sa=t&rct=j...k4KfeYef_eYqLQ

                        Viele Grüße,
                        Stefan

                        DIY-Bastelprojekte: || >> Smelly One << || >> BURLI << ||

                        Kommentar


                          Hallo,

                          Zitat von dreamy1 Beitrag anzeigen
                          ch schwöre auf die AMS IAQ Core.
                          wo ist der denn für einen Normalsterblichen erhältlich?

                          Gruß,
                          Hendrik

                          Kommentar


                            Bei Digikey und Mouser, man kann auch als Privatperson dort bestellen.
                            Viele Grüße,
                            Stefan

                            DIY-Bastelprojekte: || >> Smelly One << || >> BURLI << ||

                            Kommentar


                              Ok, danke
                              Google hat mir gerade den WSP2110 als Werbung vorgeschlagen.
                              Kennt den jemand ?

                              Gruß,
                              Hendrik

                              Kommentar


                                Detection range 1~50ppm
                                Vergiss es.... ansonsten kann ich auch CCS811 empfehlen. Den gibt es bei eBay, Beispiel: https://www.ebay.de/itm/Digital-Sens...i/172865435746

                                Kommentar

                                Lädt...
                                X