Ich möchte mal den Partikelsensor / Staubsensor testen.

Benutzeravatar
Admin
Administrator
Beiträge: 1218
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) 1769 mal betrachtet
Hier habe ich mit dem Sprachmodul meine Ersten Tests gemacht.
Benutzeravatar
Admin
Administrator
Beiträge: 1218
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: 1218
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: 1218
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: 1218
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.JPG
SEN54_SDN-T mit Sprachmodul Motor_2x Displ.JPG (695.46 KiB) 277 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
Antworten

Zurück zu „Hardware / Schaltungstechnik“

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast