Ich möchte mal den Partikelsensor / Staubsensor testen.

Benutzeravatar
Admin
Administrator
Beiträge: 1231
Registriert: Mo 20. Apr 2020, 09:47
Wohnort: 82441 Ohlstadt
Kontaktdaten:

Re: Ich möchte mal den Partikelsensor / Staubsensor testen.

Beitrag von Admin »

Hier ist jetzt mal der Stand mit Sprachmodul.
Das Aktuelle Programm dazu:

Code: Alles auswählen


/*
   I2C-Generator: 0.3.0
   Yaml Version: 2.1.3
   Template Version: 0.7.0-112-g190ecaa

   Copyright (c) 2021, Sensirion AG
   All rights reserved.

    Weiterverbreitung und Nutzung in Quell- und Binärform, mit oder ohne
    Änderungen sind zulässig, sofern folgende Bedingungen erfüllt sind:

 * * Bei der Weiterverbreitung des Quellcodes muss der oben stehende Copyright-Hinweis enthalten
     sein Liste der Bedingungen und den folgenden Haftungsausschluss.

 * * Weiterverbreitungen in binärer Form müssen den oben genannten Urheberrechtshinweis
     wiedergeben. diese Liste der Bedingungen und den folgenden Haftungsausschluss in der
     Dokumentation und/oder andere Materialien, die mit der Verteilung bereitgestellt werden.

 * * Weder der Name der Sensirion AG noch deren Namen
     Mitwirkende können dazu verwendet werden, daraus abgeleitete Produkte zu unterstützen oder
     zu bewerben diese Software ohne vorherige ausdrückliche schriftliche Genehmigung.

    DIESE SOFTWARE WIRD VON DEN COPYRIGHT-INHABERN UND MITARBEITERN „WIE BESEHEN“ ZUR VERFÜGUNG
    GESTELLT.UND ALLE AUSDRÜCKLICHEN ODER STILLSCHWEIGENDEN GEWÄHRLEISTUNGEN, EINSCHLIESSLICH,
    ABER NICHT BESCHRÄNKT AUF DIE STILLSCHWEIGENDE GEWÄHRLEISTUNGEN DER MARKTGÄNGIGKEIT UND
    EIGNUNG FÜR EINEN BESTIMMTEN ZWECK WERDEN AUSGESCHLOSSEN.
    IN KEINEM FALL IST DER COPYRIGHT-INHABER ODER MITARBEITER HAFTBAR FÜR DIREKTE, INDIREKTE,
    ZUFÄLLIGE, BESONDERE, BEISPIELHAFTE ODER FOLGESCHÄDEN (EINSCHLIESSLICH, ABER NICHT BESCHRÄNKT
    AUF DIE BESCHAFFUNG VON WAREN ODER DIENSTLEISTUNGEN ERSETZEN; NUTZUNGS-, DATEN- ODER
    GEWINNVERLUST; ODER GESCHÄFT UNTERBRECHUNG) JEGLICH VERURSACHT UND AUF JEDER HAFTUNGSTHEORIE,
    OB IN VERTRAG, GEFÄHRLICHE HAFTUNG ODER unerlaubte Handlung (EINSCHLIESSLICH FAHRLÄSSIGKEIT
    ODER ANDERWEITIG) DIE IN IRGENDEINER WEISE AUS DER VERWENDUNG DIESER SOFTWARE ENTSTEHEN,
    AUCH WENN SIE DARAUF HINGEWIESEN WURDEN MÖGLICHKEIT SOLCHER SCHÄDEN.

    ACHTUNG !!! PIN:5 von SEN54 auf GND legen um die I2C Schnittstelle zu aktivieren !!!
    Version "I2C_SenX5_Beta_02"
    mit SEN54_SDN-T / CO2 Sensor MH-Z19B / 2 x Display / DTH22 Sensor / DC3231 Uhr
*/

#include <Arduino.h>
//----------------------------------
#include "DYPlayerArduino.h"
DY::Player player(&Serial2);
byte schritt = 0;
byte schrittalt = 0;
byte ANALOG_PIN = A0;
int POTI = 0;
byte Laut = 0;
byte Lautalt = 0;
//----------------------------------
#include <SensirionI2CSen5x.h>
#include <Wire.h>
#define DS3231_ADDRESSE 0x68
// LCD Display I2C 4 Zeilen je 20 Zeichen einrichten
#include <LiquidCrystal_I2C.h> // LCD Display
// Displayadresse ist 0x27 oder 0x3F
LiquidCrystal_I2C lcd1(0x27, 20, 4);
LiquidCrystal_I2C lcd2(0x3F, 20, 4);
//----------------------------------------------
#include "DHT.h"
const byte DHTPIN1 = 7;         // Hier die Pin Nummer eintragen wo der Sensor1 angeschlossen ist
#define DHTTYPE DHT22     // Hier wird definiert was für ein Sensor DHT11 oder DHT22 !!
DHT dht1(DHTPIN1, DHTTYPE); //Sensor1 einrichten
//------CO2 Sensor-------------------------------
const byte DataPin = 6; // Pin für CO2 Sensor
//----CO2 Sensor------
int ppmrange = 3000; // 2000, 3000 oder 5000 ??
unsigned long pwmtime;
int PPM = 0;
float pulsepercent = 0;
//----- Zeit für Erneuerung aller Anzeigen ------
unsigned long Sekundenablauf01 = 0;
unsigned long Pausezeit01 = 5000;     // 5 Sekunden
unsigned long milliuebergabe = 0;
unsigned long Sekundenablauf02 = 0;
unsigned long Pausezeit02 = 60000 * 10; //10 Minunten
//-------Taster-------
const byte Taster = 8;
byte Tasterstatus = 0;
byte Tastenmerker = 0;
unsigned long Sekundenablauf03 = 0; // Tastenabfrage von Taster 300ms aussetzen
const unsigned long Pausezeit03 = 300;
unsigned long Sekundenablauf04 = 0; // Displayzeit 10 Min. hell
const unsigned long Pausezeit04 = 60000 * 10UL;
//-----------------------------------------------
// Die verwendeten Befehle belegen bis zu 48 Bytes. Bei einigen Arduinos der Standardpuffer
// Der Platz ist nicht groß genug
#define MAXBUF_REQUIREMENT 48

#if (defined(I2C_BUFFER_LENGTH) &&                 \
     (I2C_BUFFER_LENGTH >= MAXBUF_REQUIREMENT)) || \
    (defined(BUFFER_LENGTH) && BUFFER_LENGTH >= MAXBUF_REQUIREMENT)
#define USE_PRODUCT_INFO
#endif

SensirionI2CSen5x sen5x;

void printModuleVersions() {
  uint16_t error;
  char errorMessage[256];

  unsigned char productName[32];
  uint8_t productNameSize = 32;

  error = sen5x.getProductName(productName, productNameSize);

  if (error) {
    Serial.print("Fehler65 beim Versuch, getProductName auszuführen(): ");
    errorToString(error, errorMessage, 256);
    Serial.println(errorMessage);
  } else {
    Serial.print("ProductName:");
    Serial.println((char*)productName);
  }

  uint8_t firmwareMajor;
  uint8_t firmwareMinor;
  bool firmwareDebug;
  uint8_t hardwareMajor;
  uint8_t hardwareMinor;
  uint8_t protocolMajor;
  uint8_t protocolMinor;

  error = sen5x.getVersion(firmwareMajor, firmwareMinor, firmwareDebug,
                           hardwareMajor, hardwareMinor, protocolMajor,
                           protocolMinor);
  if (error) {
    Serial.print("Fehler85 beim Versuch, getVersion auszuführen(): ");
    errorToString(error, errorMessage, 256);
    Serial.println(errorMessage);
  } else {
    Serial.print("Firmware: ");
    Serial.print(firmwareMajor);
    Serial.print(".");
    Serial.print(firmwareMinor);
    Serial.print(", ");

    Serial.print("Hardware: ");
    Serial.print(hardwareMajor);
    Serial.print(".");
    Serial.println(hardwareMinor);
  }
}

void printSerialNumber() {
  uint16_t error;
  char errorMessage[256];
  unsigned char serialNumber[32];
  uint8_t serialNumberSize = 32;

  error = sen5x.getSerialNumber(serialNumber, serialNumberSize);
  if (error) {
    Serial.print("Fehler110 beim Versuch, getSerialNumber auszuführen(): ");
    errorToString(error, errorMessage, 256);
    Serial.println(errorMessage);
  } else {
    Serial.print("SerialNumber:");
    Serial.println((char*)serialNumber);
  }
}
unsigned long minutenablauf = 0;
unsigned long eineminute = 60000;
//##########################################################################
//###################### SETUP #############################################
//##########################################################################
void setup() {
  //--------MP3 Player------------------
  pinMode(ANALOG_PIN, INPUT);      // Eingang für Poti A0
  player.begin();
  player.setVolume(Laut); // 100% Volume
  //------------------------------------
  Serial.begin(115200);
  while (!Serial) {
    delay(100);
  }
  // Luftfeuchte und Temperatur Sensoren
  dht1.begin(); // Sensor1 starten
  //-----------LCD1 + 2 Display Start--------------------------------------
  lcd1.begin();
  lcd1.backlight();
  lcd1.clear();
  lcd2.begin();
  lcd2.backlight();
  lcd2.clear();
  //-----------LCD1 + 2 Standart Text Display------------------------------
  lcd1.setCursor (0, 0);            // Zeile 1
  lcd1.print (F("PM1       PM2"));
  lcd1.setCursor (0, 1);            // Zeile 2
  lcd1.print (F("PM4       PM10"));
  lcd1.setCursor (0, 2);            // Zeile 3
  lcd1.print (F("FlOrgVe       mg/m3"));
  lcd1.setCursor (0, 3);            // Zeile 4
  lcd1.print (F("Tem       Hy"));
  lcd2.setCursor (0, 0);            // Zeile 1
  lcd2.print (F("AS=    CO2      ppm"));
  lcd2.setCursor (0, 1);            // Zeile 2
  lcd2.print (F("AussenTemp        C"));
  lcd2.setCursor (0, 2);            // Zeile 2
  lcd2.print (F("Lu-Feuchte        %"));

  zeigeZeit(); // Zeit ausgeben    // Zeile 1
  //----------------------------------------------------------------------
  Wire.begin();
  // Wenn die Zeit gestellt werden muß
  // aktuelle Zeit        sek min std wt tag monat jahr
  // einstellenDS3231zeit(00, 22, 22, 2, 16,  06,  20);
  sen5x.begin(Wire);

  uint16_t error;
  char errorMessage[256];
  error = sen5x.deviceReset();
  if (error) {
    Serial.print("Fehler135 beim Versuch, deviceReset auszuführen(): ");
    errorToString(error, errorMessage, 256);
    Serial.println(errorMessage);
  }

  // Drucken Sie SEN55-Modulinformationen, wenn die i2c-Puffer groß genug sind
#ifdef USE_PRODUCT_INFO
  printSerialNumber();
  printModuleVersions();
#endif

  // einen Temperatur-Offset in Grad Celsius einstellen
  // Hinweis: Unterstützt von SEN54- und SEN55-Sensoren
  // Standardmäßig werden Temperatur und Luftfeuchtigkeit vom Sensor ausgegeben
  // werden für die Eigenerwärmung der Module kompensiert. Wenn das Modul ist
  // In ein Gerät integriert, das möglicherweise eine Temperaturkompensation benötigt
  // angepasst werden, um die Änderung der thermischen Kopplung zu berücksichtigen und
  // Eigenerwärmung anderer Gerätekomponenten.
  //
  // Ein Leitfaden zur Erzielung optimaler Leistung, einschließlich Referenzen
  // zu mechanischen Design-In-Beispielen finden Sie im App-Hinweis
  // „SEN5x – Anleitung zur Temperaturkompensation“ unter www.sensirion.com.
  // Weitere Informationen finden Sie in den Anwendungshinweisen
  // über die verwendeten erweiterten Kompensationseinstellungen
  // in `setTemperatureOffsetParameters`, `setWarmStartParameter` und
  // `setRhtAccelerationMode`.
  //
  // TempOffset anpassen, um zusätzliche Temperaturunterschiede zu berücksichtigen
  // Überschreitung der Eigenerwärmung des SEN-Moduls.
  float tempOffset = 0.0;
  error = sen5x.setTemperatureOffsetSimple(tempOffset);
  if (error) {
    Serial.print("Fehler169 beim Versuch, setTemperatureOffsetSimple auszuführen(): ");
    errorToString(error, errorMessage, 256);
    Serial.println(errorMessage);
  } else {
    Serial.print("Temperatur-Offset eingestellt auf ");
    Serial.print(tempOffset);
    Serial.println(" Grad. Celsius (nur SEN54/SEN55).");
  }

  // Start Measurement
  error = sen5x.startMeasurement();
  if (error) {
    Serial.print("Fehler181 beim Versuch, startMeasurement auszuführen(): ");
    errorToString(error, errorMessage, 256);
    Serial.println(errorMessage);
  }
  minutenablauf = millis();
  pinMode(Taster, INPUT_PULLUP);      // Taster Display ein/aus
}
//#############################################################################
//############################### LOOP ########################################
//#############################################################################
void loop() {
  uint16_t error;
  char errorMessage[256];
  milliuebergabe = millis();
  //-------------Taster lesen-----------------------------------------------
  if (millis() - Sekundenablauf03 >= Pausezeit03) { // 200msec abgelaufen?
    Tasterstatus = digitalRead(Taster);         // Pin von Taster abfragen
    if (Tasterstatus == LOW) {                    // Ist Taster gedrueckt?
      Tastenmerker = !Tastenmerker;   // Merken dass Taster gedrueckt wurde
      if (Tastenmerker == LOW)
      {
        lcd1.noBacklight();
        lcd2.noBacklight();
      }
      else
      {
        lcd1.backlight();
        lcd2.backlight();
        Sekundenablauf04 = millis();
      }
      Sekundenablauf03 = millis();                  // Die 200ms neu starten
    }
  }
  if (millis() - Sekundenablauf04 >= Pausezeit04)  // 10 Min. abgelaufen?
  {
    Tastenmerker = LOW;  // Tastenmerker auf Displaybeleuchtung aus
    lcd1.noBacklight();   // Displaybeleuchtung aus
    lcd2.noBacklight();   // Displaybeleuchtung aus
  }
  //--------------MP3 Player-----------------
  POTI = analogRead (ANALOG_PIN);
  Laut = map(POTI, 0, 1023, 0, 30);
  if (Laut != Lautalt)
  {
    player.setVolume(Laut);
    Lautalt = Laut;
  }
  if (schritt == 0)//Steuerung wird neu gestartet
  {
    player.playSpecified(3); // 3= Gerät wird neu gestartet
    schritt = 10;
  }
  if (schritt != schrittalt)
  {
    lcd2.setCursor (3, 0);            // Display 2 - Zeile 1
    lcd2.print (F("  "));
    lcd2.setCursor (3, 0);            // Display 2 - Zeile 1
    lcd2.print (schritt);
    schrittalt = schritt;
  }
  //-----------------------------------------------------------------------------
  //-------------------------------- Ansagesteuerung-----------------------------
  //-----------------------------------------------------------------------------
  if (schritt < 10)//Eine Ansage muss ausgeführt werden
  {
    if (milliuebergabe - Sekundenablauf02 >= Pausezeit02)  // 5000ms abgelaufen?
    {
      if (schritt == 1)// Schlechte Luft
      {
        player.playSpecified(1); // Schlechte Luft CO2 Wert >2000
        schritt = 10;
        Sekundenablauf02 = millis();         // Die 5000ms neu starten
      }
      if (schritt == 2)// Luft ist wieder gut CO2 Wert < 400
      {
        player.playSpecified(2); // Gerät wird neu gestartet
        schritt = 10;
        Sekundenablauf02 = millis();         // Die 5000ms neu starten
      }
      if (schritt == 4)// viele Rußpartickel in der Luft
      {
        player.playSpecified(4); // Gerät wird neu gestartet
        schritt = 10;
        Sekundenablauf02 = millis();         // Die 5000ms neu starten
      }
      if (schritt == 5)// viele Rußpartickel in der Luft
      {
        player.playSpecified(5); // Gerät wird neu gestartet
        schritt = 10;
        Sekundenablauf02 = millis();         // Die 5000ms neu starten
      }
    }
  }
  //----------------------------------------------------------------------------
  //-----------Zeit ausgeben von DS3231-----------------------------------
  if (milliuebergabe - minutenablauf >= eineminute) { // Eine Minute abgelaufen?
    zeigeZeit(); // Zeit ausgeben
  }
  //--------------------------------------------------------------------------
  if (milliuebergabe - Sekundenablauf01 >= Pausezeit01) { // 5000ms abgelaufen?
    Sekundenablauf01 = millis();                     // Die 5000ms neu starten
    //------------------------------------------------------------------------
    //------------------- CO2 Messung und Aussen Temp / Feuchte---------------
    //------------------------------------------------------------------------
    pwmtime = pulseIn(DataPin, HIGH, 2000000) / 1000;
    float pulsepercent = pwmtime / 1000.0;
    PPM = ppmrange * pulsepercent;
    //Serial.print (F("PPM= "));
    //Serial.println(PPM);
    float h1 = dht1.readHumidity();    // Lesen der Luftfeuchtigkeit1 und speichern in die Variable h1
    float t1 = dht1.readTemperature(); // Lesen der Temperatur in °C1 und speichern in die Variable t1
    //Serial.print (F("Luftfeuchte= "));
    //Serial.println(h1);
    //Serial.print (F("Temperatur= "));
    //Serial.println(t1);
    lcd2.setCursor (11, 0);            // Zeile 1
    lcd2.print ("     ");
    lcd2.setCursor (11, 0);            // Zeile 1
    lcd2.print (PPM);
    //----------------------------------------------------------------------------
    //-----------------------Ansagen aktivieren/deaktivieren----------------------
    //----------------------------------------------------------------------------
    if (PPM > 2000)                 // PPM zu hoch, Fenster dringend öffnen.
    {
      schritt = 1;
    }
    if ((PPM < 500) && (PPM > 400)) // PPM wieder OK, Fenster schließen.
    {
      schritt = 2;
    }
    if ((schritt > 0) && (schritt < 4) && (PPM < 1500) && (PPM > 600)) // PPM OK, Ansagen abschalten
    {
      schritt = 10;
    }
    //----------------------------------------------------------------------------
    lcd2.setCursor (11, 1);            // Zeile 2
    lcd2.print ("     ");
    lcd2.setCursor (11, 1);            // Zeile 2
    lcd2.print (t1);// t1 = Lufttemperatur
    lcd2.setCursor (11, 2);            // Zeile 3
    lcd2.print ("     ");
    lcd2.setCursor (11, 2);            // Zeile 3
    lcd2.print (h1);// h1 = Luftfeuchte
    //-------------------------------------------------------------------------
    //--------------- CO2 Messung und Aussen Temp / Feuchte Ende --------------
    //-------------------------------------------------------------------------
    // Read Measurement
    float massConcentrationPm1p0;
    float massConcentrationPm2p5;
    float massConcentrationPm4p0;
    float massConcentrationPm10p0;
    //-----Display Werte------------
    float massConcentrationPm2p5_2;
    float massConcentrationPm4p0_2;
    float massConcentrationPm10p0_2;
    float ambientHumidity;
    float ambientTemperature;
    float vocIndex;
    float noxIndex;

    error = sen5x.readMeasuredValues(
              massConcentrationPm1p0, massConcentrationPm2p5, massConcentrationPm4p0,
              massConcentrationPm10p0, ambientHumidity, ambientTemperature, vocIndex,
              noxIndex);

    if (error) {
      Serial.print("Fehler211 beim Versuch, readMeasuredValues auszuführen(): ");
      errorToString(error, errorMessage, 256);
      Serial.println(errorMessage);
    } else {
      //Serial.print("MC -> Pm1p0: ");
      //Serial.println(massConcentrationPm1p0);
      lcd1.setCursor (4, 0);            // Zeile 1
      lcd1.print ("      ");
      lcd1.setCursor (4, 0);            // Zeile 1
      lcd1.print (massConcentrationPm1p0);
      //-------------------------------------------------------
      //-------------- Warnmeldung ----------------------------
      //-------------------------------------------------------
      if (massConcentrationPm1p0 > 50)
      {
        schritt = 4; // Warnung wegen großer Menge Rußpartikel
      }
      if ((schritt == 4) && (massConcentrationPm1p0 < 30))
      {

        schritt = 2; // Warnung beenden, Fenster zu
      }
      //-------------------------------------------------------
      //Serial.print("   MC -> Pm2p5: ");
      //Serial.print(massConcentrationPm2p5);
      massConcentrationPm2p5_2 = massConcentrationPm2p5 - massConcentrationPm1p0;
      if (massConcentrationPm2p5_2 < 10) {
        lcd1.setCursor (14, 0);            // Zeile 1
        lcd1.print ("      ");
        lcd1.setCursor (15, 0);            // Zeile 1
        lcd1.print (massConcentrationPm2p5_2);
      } else {
        lcd1.setCursor (14, 0);            // Zeile 1
        lcd1.print ("      ");
        lcd1.setCursor (14, 0);            // Zeile 1
        lcd1.print (massConcentrationPm2p5_2);
      }
      //--------------------------------------------
      //Serial.print("   MC -> Pm4p0: ");
      //Serial.print(massConcentrationPm4p0);
      massConcentrationPm4p0_2 = massConcentrationPm4p0 - massConcentrationPm2p5;
      lcd1.setCursor (4, 1);            // Zeile 2
      lcd1.print ("     ");
      lcd1.setCursor (4, 1);            // Zeile 2
      lcd1.print (massConcentrationPm4p0_2);
      //-------------------------------------------------------
      //-------------- Warnmeldung ----------------------------
      //-------------------------------------------------------
      if (massConcentrationPm4p0_2 > 20)
      {
        schritt = 4;
      }
      //--------------------------------------------
      //Serial.print("   MC -> Pm10p0: ");
      //Serial.print(massConcentrationPm10p0);
      massConcentrationPm10p0_2 = massConcentrationPm10p0 - massConcentrationPm4p0;
      lcd1.setCursor (15, 1);            // Zeile 2
      lcd1.print ("     ");
      lcd1.setCursor (15, 1);            // Zeile 2
      lcd1.print (massConcentrationPm10p0_2);
      //-------------------------------------------------------
      //-------------- Warnmeldung ----------------------------
      //-------------------------------------------------------
      if (massConcentrationPm10p0_2 > 20)
      {
        schritt = 4;
      }
      //--------------------------------------------
      //Serial.print("  /  Luftfeuchte: ");
      if (isnan(ambientHumidity)) {
        //Serial.print("n/a");
      } else {
        //Serial.print(ambientHumidity);
        lcd1.setCursor (14, 3);            // Zeile 4
        lcd1.print ("      ");
        lcd1.setCursor (14, 3);            // Zeile 4
        lcd1.print (ambientHumidity);
      }
      //Serial.print("   Temp.: ");
      if (isnan(ambientTemperature)) {
        //Serial.print("n/a");
      } else {
        //Serial.print(ambientTemperature);
        lcd1.setCursor (4, 3);            // Zeile 4
        lcd1.print ("      ");
        lcd1.setCursor (4, 3);            // Zeile 4
        lcd1.print (ambientTemperature);
      }
      //Serial.print(" / Fluechtige-Organische-Verb.:");
      if (isnan(vocIndex)) {
        //Serial.print("n/a");
      } else {
        //Serial.print(vocIndex);
        lcd1.setCursor (8, 2);            // Zeile 3
        lcd1.print ("      ");
        lcd1.setCursor (8, 2);            // Zeile 3
        lcd1.print (vocIndex / 100);
        //-----------------------------------------------------------
        //------------------ Warnmeldung ----------------------------
        //-----------------------------------------------------------
        if ((vocIndex / 100) > 20 )
        {
          schritt = 5; // Warnung wegen großer Menge Rußpartikel
        }
        if ((schritt == 5) && ((vocIndex / 100) < 10))
        {

          schritt = 2; // Warnung beenden, Fenster zu
        }
        //-----------------------------------------------------------
      }
      //Serial.print(" NoxIndex:");
      if (isnan(noxIndex)) {
        //Serial.println("n/a");
      } else {
        //Serial.println(noxIndex);
      }
    }
  }
}
//---------------Erweiterung für die DS3132---------------------------------------------------------------------
void einstellenDS3231zeit(byte sekunde, byte minute, byte stunde, byte wochentag, byte tag, byte monat, byte jahr)
{
  // Datum und Uhrzeit einstellen
  Wire.beginTransmission(DS3231_ADDRESSE);
  Wire.write(0);
  Wire.write(decToBcd(sekunde)); // Sekunden einstellen
  Wire.write(decToBcd(minute)); // Minuten einstellen
  Wire.write(decToBcd(stunde));
  Wire.write(decToBcd(wochentag)); // 1=Sonntag ... 7=Samstag
  Wire.write(decToBcd(tag));
  Wire.write(decToBcd(monat));
  Wire.write(decToBcd(jahr)); // 0...99
  Wire.endTransmission();
}
//--------------------------Die Zeit auslesen------------------------------------------------------------------
// jede Minute etwa 5000 Microsekunden
void leseDS3231zeit(byte * sekunde, byte * minute, byte * stunde, byte * wochentag, byte * tag, byte * monat, byte * jahr)
{
  Wire.beginTransmission(DS3231_ADDRESSE);
  Wire.write(0); // DS3231 Register zu 00h
  Wire.endTransmission();
  Wire.requestFrom(DS3231_ADDRESSE, 7); // 7 Byte Daten vom DS3231 holen
  *sekunde = bcdToDec(Wire.read() & 0x7f);
  *minute = bcdToDec(Wire.read());
  *stunde = bcdToDec(Wire.read() & 0x3f);
  *wochentag = bcdToDec(Wire.read());
  *tag = bcdToDec(Wire.read());
  *monat = bcdToDec(Wire.read());
  *jahr = bcdToDec(Wire.read());
}
//---------------------------Die Zeit anzeigen----------------------------------------------------------------
// jede Minute etwa 15000 Microsekunden
void zeigeZeit() {
  byte sekunde, minute, stunde, wochentag, tag, monat, jahr, minuteAlt;
  leseDS3231zeit(&sekunde, &minute, &stunde, &wochentag, &tag, &monat, &jahr);   // Daten vom DS3231 holen
  if ((minute > minuteAlt) || (minute == 0)) {
    switch (wochentag) {
      case 1:
        lcd2.setCursor(0, 3);
        lcd2.print(F("Mo "));
        break;
      case 2:
        lcd2.setCursor(0, 3);
        lcd2.print(F("Di "));
        break;
      case 3:
        lcd2.setCursor(0, 3);
        lcd2.print(F("Mi "));
        break;
      case 4:
        lcd2.setCursor(0, 3);
        lcd2.print(F("Do "));
        break;
      case 5:
        lcd2.setCursor(0, 3);
        lcd2.print(F("Fr "));
        break;
      case 6:
        lcd2.setCursor(0, 3);
        lcd2.print(F("Sa "));
        break;
      case 7:
        lcd2.setCursor(0, 3);
        lcd2.print(F("So "));
        break;
      default:
        break;
    }
    if (tag < 10) {
      lcd2.print(F("0"));
    }
    lcd2.print(tag); // ausgeben T.M.J H:M:S
    lcd2.print(F("."));
    if (monat < 10) {
      lcd2.print(F("0"));
    }
    lcd2.print(monat);
    lcd2.print(F("."));
    lcd2.print(jahr);
    lcd2.print(F("   "));

    if (stunde < 10) {
      lcd2.print(F("0"));
    }
    lcd2.print(stunde, DEC); // byte in Dezimal zur Ausgabe
    lcd2.print(F(":"));
    if (minute < 10) {
      lcd2.print("0");
    }
    lcd2.print(minute, DEC);
    minuteAlt = minute;
    // Bestimmen wann wieder eine Minute um
    minutenablauf = millis();
    eineminute = (60 - sekunde) * 1000UL;
  }
}
byte decToBcd(byte val) {
  // Dezimal Zahl zu binary coded decimal (BCD) umwandeln
  return ((val / 10 * 16) + (val % 10));
}
byte bcdToDec(byte val) {
  // BCD (binary coded decimal) in Dezimal Zahl umwandeln
  return ((val / 16 * 10) + (val % 16));
}
Und die Schaltung dazu. Ich habe in der Schaltung das zweite Display nicht extra eingezeichnet. Weil es ja einfach nur an den 4 Anschlüßen parrallel zum ersten Display hängt. Und die beiden Display müßen natürlich unterschiedliche I2C Adressen haben !!
.
SEN54_SDN-T mit Sprachmodul.JPG
SEN54_SDN-T mit Sprachmodul.JPG (333.64 KiB) 2025 mal betrachtet
Hier habe ich mit dem Sprachmodul meine Ersten Tests gemacht.
Benutzeravatar
Admin
Administrator
Beiträge: 1231
Registriert: Mo 20. Apr 2020, 09:47
Wohnort: 82441 Ohlstadt
Kontaktdaten:

Re: Ich möchte mal den Partikelsensor / Staubsensor testen.

Beitrag von Admin »

Da habe ich mal drei kleiner Videos, wo man die Ansagefunktion sieht / hört.
Der Erste Video ist der Neustart des Gerätes, erkennen und mitteilen der Schlechten Luft.
Der Zweite Video ist der Werend das Fenster zum lüften offen ist.
Der Dritte Video ist der Wenn man das Fenster wieder schließen kann.

Es gibt natürlich noch weitere Ansagen. Z.B. für übermässig viele Russ-Partikel in der Luft, u.s.w. Ich hatte schon Werte von den kleinsten Partikeln (PM1,5) 160 mykrogramm pro qm³. Die normalen Werte sind 2 bis ungefähr 8. Ab 10 sollen sie Ungesund sein, wenn man den ganzen Tag und jeden Tag, solcher Luft ausgesetzt ist.
Benutzeravatar
Admin
Administrator
Beiträge: 1231
Registriert: Mo 20. Apr 2020, 09:47
Wohnort: 82441 Ohlstadt
Kontaktdaten:

Re: Ich möchte mal den Partikelsensor / Staubsensor testen.

Beitrag von Admin »

Ich habe mir ein paar kleine Lüfter bestellt, die dann, wenn das ganze in einem Gehäuse eingbaut ist, die Luft ins Gehäuse ziehen. Das sind 12 Volt Lüfter, die ich aber nur mit 5 Volt betreiben möchte.

Franz
Benutzeravatar
Admin
Administrator
Beiträge: 1231
Registriert: Mo 20. Apr 2020, 09:47
Wohnort: 82441 Ohlstadt
Kontaktdaten:

Re: Ich möchte mal den Partikelsensor / Staubsensor testen.

Beitrag von Admin »

Habe gerade beim PartikelSensor was sehr seltsammes beobachtet. Die Sonne hat rel. nieder bei der Balkontüre reingeleuchtet und plötzlich hatte ich eine Sprachmeldung von meinen Gerät, dass sehr viel Partikel in der Raumluft sind. Ich schaute auf die Anzeige und es stieg bis über 300. Da das Fenster zu war, habe ich mich im ersten Moment gefragt, wo die Partikel denn alle plötzlich herkommen sollen. Als ich die Hand in ungefährt 20cm Entfernung vor die Lufteintrittsöffnung gehalten habe, leuchtete die Sonne nicht mehr rein, und der Wert ging schlagartig runter. Das machte mir klar, dass ich diese Lufteintritts Öffnung im Gerät auf keinen Fall direkt durch eine Öffnung nach draussen platzieren sollte, sondern im Gerät so hinter eine Lufteintrittsöffnung montieren muss, dass das Sonnenlicht von aussen nicht direkt in den Sensor scheinen kann.

Franz
Benutzeravatar
Admin
Administrator
Beiträge: 1231
Registriert: Mo 20. Apr 2020, 09:47
Wohnort: 82441 Ohlstadt
Kontaktdaten:

Re: Ich möchte mal den Partikelsensor / Staubsensor testen.

Beitrag von Admin »

Jetzt habe ich mal begonnen, das ganze in ein Gehäsue zu bauen. Das Gehäuse ist viel zu groß, aber lag noch rum hier, und ich will das ja Hauptsächlich testen. Und dafür tuts :(oo):

Da kommt jetzt auch noch der Motorregler rein, das heißt, ich kann mir vom Gerät sagen lassen, wann ich das Fenster auf und zu machen soll, oder das Gerät steuert einen Fenstermotor, der das Fenster sebstständig auf und zu macht. Die Sprachausgabe macht da ja trotzdem Sinn, um vom Gerät informiert zu werden, was gerade so läuft , oder wenn sich ein Luftwert schön langsam in eine nicht so tolle richtig ändert. Ich mache ja auch, wenn ich einen Fenstermotor einbaue, trotzdem einen Schalter mit drei Wahlstellungen rein. Da kann ich dann Stellung 1, Fenster manuell auf, Stellung 2, Fenster manuell zu, Mittelstellung Automatisch gesteuert. Und ein Taster kommt da auch rein, mit dem ich das Display ein/aus schalten kann. Wenn ich es eingechalten lasse, geht es trotzdem nach 5 Minuten aus.

Hier ist mal die aktuelle Schaltung, die ich gerade baue:
.
SEN54_SDN-T mit Sprachmodul Motor_2x Displ_Lüft.JPG
SEN54_SDN-T mit Sprachmodul Motor_2x Displ_Lüft.JPG (602.48 KiB) 104 mal betrachtet
Das ganze wird jetzt nicht mehr mit 5 Volt versorgt, sondern mit 12 Volt, weil der Fenstermotor ja mit 5 Volt nicht betrieben werden kann. Also habe ich auf 12 Volt erhöht und für die 5 Volt einen DC/DC Converter eingebaut.

Das Programm muss ich erst noch erweitern, weil ich den Teil, der das Fenster automatisch mit Motor öffnet und schließt, noch nicht integriert habe. Das kommt die Tage nach.

Franz
Benutzeravatar
Admin
Administrator
Beiträge: 1231
Registriert: Mo 20. Apr 2020, 09:47
Wohnort: 82441 Ohlstadt
Kontaktdaten:

Re: Ich möchte mal den Partikelsensor / Staubsensor testen.

Beitrag von Admin »

Inzwischen läuft die Kiste. Aber ich habe immer wieder ein paar Ideen für Software Änderungen. Ich muss nur noch den Stecker für den Fenstermotor einbauen. Und noch viele Änderungen / Anpassungen an der Software machen. Schön ist das Gerät nicht, weil das Gehäuse erstens zu groß und zweitens nicht schön ist. Aber es geht mir ja auch darum, das Gerät zu bauen und zu testen. Wenn es dann jemand nachbauen möchte, kann er ja ein besseres Gehäuse verwenden. Ich hatte das noch von einem Projekt übrig. Ich mache gelegendlich mal ein Foto. Wenn es dann Softwaremässig fürs erste fertig ist, mache ich einen Video.

Franz
.
LuftQuallität_Lüftungssteuerung.jpg
LuftQuallität_Lüftungssteuerung.jpg (500.13 KiB) 94 mal betrachtet
Hier werden links folgende Werte angezeigt:
Partikel 1 microeter je m³ / Partikel 2,5 microeter je m³
Partikel 4 microeter je m³ / Partikel 10 microeter je m³
Flüchtige Organische Verbindungen in Milligramm je Kubikmeter
Datum / Uhrzeit

Und Rechts:
Angeforderte Ansage = Nr. / CO2 in ppm Die 10 steht für keine Ansage
Schalterstellung / Poti Lautstärke der Ansage
Temperatur und Luftfeuchte innen
Temperatur und Luftfeuchte aussen

Das sind die Daten mit denen das Programm im Automatik-Modus enscheidet, ob und wann es das Fenster zum Lüften öffnet und schließt. Jedenfalls wenn ein Fenstermotor am System angeschloßen ist. Der muss dann mit 12 Volt DC gesteuert werden !! Auch die Ansagen werden nach Datenlage ausgelöst. Ich überlege gerade, ob ich im Manuellen Modus auch Notfälle genneriere, Wo das Fenster dann z.B. bei Manuell Fenster offen trotzdem das Fenster schießt, weil es draussen seeehr Stürmisch wird, oder draussen zu heißt wird. Dazu müßte ich natürlich draussen noch einen Windmesser anbauen, und den im Programm auch noch auslesen. Ich denke das wird bei dem Gerät noch eine Option. Denn das Gerät soll ja wirklich fast alleine Fehlerfrei Entscheiden können. Dazu braucht es natürlich auch alle Daten. Ich denke, wenn ich die Daten Windrichtung / Windgeschwindigkeit noch einbringe, habe ich wirklich alles was ich brauche.

Ich werde mir jedenfalls mal so einen Windsensor besorgen, und dessen Daten noch integrieren. Das Ding macht Sinn. Ich habe auch noch vor, im einem anderen Gerät das ich schon am laufen habe, so einen Windmesser einzusetzen. Das ist ein Gerät das mit zwei Achsen Solarpannels der Sonne nachführt, um möglichst viel Strom erzeugen zu können. Das Gerät führt die Panels nicht dahin, wo die Sonne vermutlich sein sollte, sondern geht immer dahin, wo tatsächlich das Beste Licht her kommt. Da kann es auch nötig sein, bei Sturm die Panals aus den Wind zu drehen, wenn dieser zu stark wird. Die Panals habe so große Angriffsflächen, dass sie wie ein mächtiges Segel wirken, und die ganze Anlage dann vom Sturm beschädigt oder zerstört werden kann. Also habe ich schon zwei gute Gründe, mir einen Windmessanlage zum Testen zu besorgen, dass ich gegebenen Falles zu starke Winde und deren Richtung im Programm erkennen kann.
Benutzeravatar
Admin
Administrator
Beiträge: 1231
Registriert: Mo 20. Apr 2020, 09:47
Wohnort: 82441 Ohlstadt
Kontaktdaten:

Re: Ich möchte mal den Partikelsensor / Staubsensor testen.

Beitrag von Admin »

Das Geräte. das in meinem Zimmer seit etwa 2 Jahren die Lüftung steuert, Mist wie dieses Gerät auch Temperatur und Luftdruck Innen und Aussen. Und CO2 innen. Den Schalter Manuel Schließen / Automatik / Manuel öffnen habe ich da auch schon. Auf "Automatik" öffnet sich das Fenster immer, wenn die Aussentemperatur größer 18 Grad ist und es schließt, wenn die Aussentempertur größer 26 Grad ist. Wenn die Aussen - Temperatur wärend der Öffnungsphase unter 16 Grad geht, schließt das Fenster auch wieder. Man merkt wohl, ich brauche es Krankheitsbedingt sehr warm. Für die Luftquallität gibt es noch eine zusätzliche Regelung. Wenn der CO2 Wert im Zimmer über 900 ppm steigt und die Temperatur im Raum größer 23 Grad ist, dann öffnet das Fenster auch. Wenn die Tempratur im Raum kleiner 21 Grad ist, oder wenn der CO2 Wert wieder kleiner 500 ppm ist. dann macht das Fenster wieder zu.

Ja, das ist schon ganz gut, aber ich möchte schon dringend die Windgeschwindigkeit und Richtung noch in die Kontrolle einbeziehen. Dann ich hatte es schon mehrfach, dass das Fenster offen war, weil die Aussentemperatur hoch genug, zum Dauerlüften war. Aber dann zog ein Unwetter auf und der Luftdruck im Haus stieg durch den sehr Starken Wind, der beim Fenster reingedrückt hat, schlug Türen mit sehr großer Wucht zu, und Glastüren können da locker zu Bruch gehen. Der Winddruck hat da richtig aufgeräumt im Haus. :agt:

Ich habe auch schon ein neues Reihenhaus aus drei Häusern gesehen, bei dem wohl die Dachfenster und sonstige Fenster offen waren, und ein plötzlich aufkommender extremer Sturm offenbar so einen Winddruck im Haus erzeugte, dass der komplette Dachstuhl von allen drei Häusern in einem Stück abgehoben wurde, sich von Haus löste, und über die zweispurige Strasse in das nächste Haus geflogen ist. Ich nehme an, wenn da im Haus keine Fenster offen gewesen wären, hätte das Dach nicht abgehoben. Unser Dach blieb oben, weil wir sofort bei Beginn dieses Sturms alle Fenster geschlossen haben. Nur das Dachfenster machte Geräusche, als ob es gleich rausgerissen wird. :???: :eek: Meine Frau hatte das Fenster aus Angst dass es sich verabschiedet, noch zusätzlich gehalten. Was natürlich keine so gute Idee war. Denn wenn da das Dach dann trotzdem abgehoben hätte, wäre es für ihre Gesundheit wesentlich sinnvoller gewesen, wenn sie so schnell wie möglich die obere Etage verlassen hätte. Aber was macht man nicht alles für Unsinn, wenn man Angst um seine Hütte hat. :???:
Benutzeravatar
Admin
Administrator
Beiträge: 1231
Registriert: Mo 20. Apr 2020, 09:47
Wohnort: 82441 Ohlstadt
Kontaktdaten:

Re: Ich möchte mal den Partikelsensor / Staubsensor testen.

Beitrag von Admin »

Ich habe von den Windsensoren, Windgeschwindigkeit und Windrichtung, 2 Sätze bestellt, die kommen mitte Juli. Dann baue ich die Probeweise mit dazu. So dass ich bei Automatic und auch bei Manuell offen das Fenster bei starken Wind Notschließen kann. Einen Satz bekommt dann Wahrscheinlich meine Lüftungssteuerung spendiert, die seit zwei Wochen hier ihren Dienst verrichtet. Man kann ja dann, wenn seit 10 Minunten kein starker Wind mehr messbar war, wieder Fenster öffnen.

Franz
Antworten

Zurück zu „Hardware / Schaltungstechnik“

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 0 Gäste