INFO: Dieses Forum nutzt Cookies...
Cookies sind für den Betrieb des Forums unverzichtbar. Mit der Nutzung des Forums erklärst Du dich damit einverstanden, dass wir Cookies verwenden.

Es wird in jedem Fall ein Cookie gesetzt um diesen Hinweis nicht mehr zu erhalten. Desweiteren setzen wir Google Adsense und Google Analytics ein.

Antwort schreiben 
 
Themabewertung:
  • 0 Bewertungen - 0 im Durchschnitt
  • 1
  • 2
  • 3
  • 4
  • 5
Humidity Control
19.02.2014, 22:24
Beitrag #1
Humidity Control
Werte Community,

ich blicke bei meinen Problem nicht mehr durch Sad

Bei dem beigefügten Sketch (Auszug aus dem Part Humidity Control) habe ich das Problem, dass mir das betreffende Relais zum "flattern" anfängt.

Normalerweise sollte das Relais bei Unterschreitung der 60% Luftfeuchte einschalten und über 60% eben wieder ausschalten.

Bei Unterschreitung der 60% flattert das Relais ob wohl ja mittels digitalWrite der Status HIGH gesetzt wurde oder gilt der nur "temporär"?

Der void AutomatischeRegelung wird mittels void loop abgearbeitet.

Danke für eure Unterstützung!

MFG pahe87


Angehängte Datei(en)
.ino  AutomatischeRegelung.ino (Größe: 370 Bytes / Downloads: 59)

Hoffe um Nachsicht mit meiner Unwissenheit & bin Neuling und brav am lernen.
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
19.02.2014, 22:39 (Dieser Beitrag wurde zuletzt bearbeitet: 19.02.2014 22:44 von Sloompie.)
Beitrag #2
RE: Humidity Control
(19.02.2014 22:24)pahe87 schrieb:  Werte Community,

ich blicke bei meinen Problem nicht mehr durch Sad

Bei dem beigefügten Sketch (Auszug aus dem Part Humidity Control) habe ich das Problem, dass mir das betreffende Relais zum "flattern" anfängt.

Normalerweise sollte das Relais bei Unterschreitung der 60% Luftfeuchte einschalten und über 60% eben wieder ausschalten.

Bei Unterschreitung der 60% flattert das Relais ob wohl ja mittels digitalWrite der Status HIGH gesetzt wurde oder gilt der nur "temporär"?

Der void AutomatischeRegelung wird mittels void loop abgearbeitet.

Danke für eure Unterstützung!

MFG pahe87

Hoi,

für Codes gibt es Extra oben die CODE Funktion nutz einfach in Zukunft die #
und füg den Code ein - wenn jeder Helfer jeden Code erst auf seinen Rechner laden müsste Big Grin

Ich hab den Code von Dir mal angefügt:
Code:
void AutomatischeRegelung()
  {
   float h = dht.readHumidity();
   float t = dht.readTemperature();

  if (isnan(t) || isnan(h))
  {
   digitalWrite(9, LOW);
   lcd.setCursor(0,0);
   lcd.print("Sensor fehler...");
   lcd.setCursor(0,1);
   lcd.print("DHT22 prüfen!");
  }
  else if (h > 60)
  {
   digitalWrite(9, LOW);
  }
  else
  {
   digitalWrite(9, HIGH);
  }

Das macht es für alle Helfer und Leser einfacher.
Greetz
Sloompie

ok ist nur nen Auszug - sorry trotzdem wär der ganze code meist sinnig- erleichtert dat Suchen

Dimidium facti, qui coepit, habet: SAPERE AUDE, incipe!©Horaz

Vor allem sapere aude! oder wie Immanuel Kant sagt:
"Habe Mut, dich deines eigenen Verstandes zu bedienen!"

Es tut auch nicht weh! Daher: incipe! oder Tu es! wie Yoda sagen würde.
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
20.02.2014, 09:22
Beitrag #3
RE: Humidity Control
Ein Problem könnte sein, dass die Werte des Sensors schwanken und nicht der Ausgang, d.h. der Sensor liefert schnell hintereinander Werte wie 59, 60, 61, 60, 59, usw.
Daher wird natürlich auch dein Ausgang entsprechend aktiviert und wieder deaktiviert.

Abhilfe würden unterschiedliche Schwellenwerte beim Zustandswechsel deaktiv -> aktiv und aktiv -> deaktiv helfen.
Zahlenmäßig z.B. so ausgedrückt: Erst beim Wert von z.B. > 62 den Pin auf LOW setzen und erst beim Wert von < 58 auf HIGH setzen. Bei Werten zwischen 58 und 62 wird nichts gemacht.

In der Hardware-Welt würde man dies über einen Schmitt-Trigger lösen.

Gruß, Alex
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
26.02.2014, 18:24
Beitrag #4
RE: Humidity Control
Hallo Hysteresekurfe fehlt bei der Programierung.
Gruß
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
26.02.2014, 22:43
Beitrag #5
RE: Humidity Control
Hallo pahe,
ich nehme mal einen Auszug aus Wiki zum Thema Hysterese:
Zitat: charakterisiert ein – bezogen auf die Eingangsgröße – variant verzögertes Verhalten einer Ausgangsgröße. Allgemein formuliert handelt es sich um ein Systemverhalten, bei dem die Ausgangsgröße nicht allein von der unabhängig veränderlichen Eingangsgröße, sondern auch von dem vorherigen Zustand der Ausgangsgröße abhängt. Das System kann also – abhängig von der Vorgeschichte – bei gleicher Eingangsgröße einen von mehreren möglichen Zuständen einnehmen.
Ergo haben Alex und Stich für sich genommen recht, nur gehört beides zusammen.
Ich würde es folgendermaßen interpretieren:
If-Abfrage nicht auf einen einzelnen Wert beziehen, sondern auf einen unteren und oberen Schaltwert zB. 59 und 61 Grad Celsius.
Weiterhin musst du die Werte der jeweils letzten Messung merken.
Wenn unter 61 und aktuelle Messung < letzte Messung -> bleibt auf LOW, bis <= 59
Wenn unter 61 und aktuelle Messung > letzte Messung -> bleibt auf HIGH bis >= 61
So sollte das Flattern zurückgehen. Kommt es noch zu oft vor musst du die Schaltpunkte weiter auseinander "ziehen".

Hope it helps!

Grüße Ricardo

Nüchtern betrachtet...ist besoffen besser Big Grin
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
27.02.2014, 17:00
Beitrag #6
RE: Humidity Control
Hallo habe das mal in Zahlen gebannt.

Code:
int Relais = 9;
int h = 10;
void setup(){
pinMode(Relais, OUTPUT);
pinMode(h, INPUT);
}

// Ein-Ausschaltwerte auf den gewünschten Bereich anpassen.
// Aktuell zwischen 60%-65% Luftfeuchte
void loop(){
  // Luftfeuchte unter 60% Einschalten
if ((h < 60) && (digitalRead(Relais) == LOW)){
digitalWrite(9, HIGH);
lcd.print("Anlage An"); // Ausgabe auf LCD
}

else {
  //Luftfeuchte größer 65% Ausschalten.
if ((h > 65) && (digitalRead(Relais) == HIGH)){
digitalWrite(9, LOW);
lcd.print("Anlage Aus"); //Ausgabe auf LCD
   }
  }
  
  // Störmeldung nicht Vergessen
if(h < 55){
   lcd.print("STÖRUNG"):
  }
}
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
04.03.2014, 10:55
Beitrag #7
RE: Humidity Control
Hallo an alle,

sorry das meine Antwort verspätet kommt, bin leider beruflich gestresst!

Danke für die zahlreichen Hinweise, was ich noch nicht wusste bzw. übersehen hatte.

Werde eure Vorschläge prüfen, sobald ich dazu die Möglichkeit habe.
Leider funktioniert der jetzige DHT22 nicht richtig, aber zwei neue sind bereits bestellt.

Was ich noch mitbekommen habe, ist dass der Sensor bei einem Lesefehler 0% ausgibt.
Ist gut zu wissen, weil sonst schwimmt mir das Terrarium bei einem Lesefehler oder Sensordefekt weg!

MFG Patrick

Hoffe um Nachsicht mit meiner Unwissenheit & bin Neuling und brav am lernen.
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
14.03.2014, 13:08 (Dieser Beitrag wurde zuletzt bearbeitet: 14.03.2014 13:11 von pahe87.)
Beitrag #8
RE: Humidity Control
Hallo,

habe eure Vorschläge geprüft und stoße aber immer wieder auf das bestehende Problem Angry

Im Sketch gibt es eine manuelle Befeuchtung mittels Taster & automatisiert.
Wird der Taster länger als 1 Sekunde gedrückt bzw. wird die automatische Regelung aktiv, schaltet das Relais nach einer Sekunde immer für alle Sekunden ein und aus.

Egal, wie ich es schreibe, es ändert sich nicht - darum "flattert" mir das Relais.
Unten stehend der Code - natürlich noch nicht komplett fertig programmiert.
(Der große Part mit der Zeit Steuerung ist von einem anderen User geschrieben worden)

Code:
int hdpin = 9;
int tasterpin = 3;
int tasterstatus;

float t;
float h;

#include "DHT.h"

#define DHTPIN 2
#define DHTTYPE DHT22

DHT dht(DHTPIN, DHTTYPE);

#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

struct schaltRelais_t{
  byte pin;
  int ein;
  int aus;
};

// Hier die Relais-Pins definieren mit Ein- und Ausschaltzeiten
schaltRelais_t schaltRelais[3]={
  {6, 850, 2100},  // pin, Einschaltzeit, Ausschaltzeit
  {7, 855, 2055},
  {8, 900, 2050},
};


struct timerRelais_t{
  byte pin;
  byte dauer;
  int timer1;
  int timer2;
};

// Hier den Kurzzeittimer definieren
timerRelais_t timerRelais={9, 2, 2100}; // Timer an Pin-9 für 4 Sekunden um 21:00 Uhr

//----------------------------------------------//

void relaisTimerNachZeit(int thishour, int thisminute)
{
  int thisTime= thishour*100+thisminute;
  if (thisTime==timerRelais.timer1 || thisTime==timerRelais.timer2)
  {
    digitalWrite(timerRelais.pin,HIGH);
    delay(timerRelais.dauer*1000L);
    digitalWrite(timerRelais.pin,LOW);
  }
}

//----------------------------------------------//

void relaisSchaltenNachZeit(int thishour, int thisminute)  
// Schaltet die Zeitschaltuhr ein und aus und setzt den Ausgang entsprechend
{
  boolean state;
  // Aus der aktuellen Zeit eine Schaltzeit bilden
  int thisTime= thishour*100+thisminute;
  // Alle Schaltzeiten durchgehen, falls eine davon EIN sagt, einschalten
  for (int i=0;i<sizeof(schaltRelais)/sizeof(schaltRelais_t);i++)
  {
    state=LOW;  // Amnahme: Es sei nichts geschaltet
    if (schaltRelais[i].ein < schaltRelais[i].aus)
    { // normale Schaltzeit von bis
      if (thisTime>=schaltRelais[i].ein && thisTime<schaltRelais[i].aus)
        state=HIGH;
    }
    else if (schaltRelais[i].ein > schaltRelais[i].aus)
    { // Schaltzeit über Mitternacht hinweg wenn die Einschaltzeit größer als die Ausschaltzeit ist
      if (thisTime>=schaltRelais[i].ein || thisTime<schaltRelais[i].aus)
        state=HIGH;
    }
    else ; // gleiche Ein- und Ausschaltzeit ignorieren
    if (digitalRead(schaltRelais[i].pin)!=state) // Falls geschaltet werden soll
    digitalWrite(schaltRelais[i].pin, state); // Schaltzustand setzen
  }
}  



#include <Wire.h>

#define RTC_I2C_ADDRESS 0x68

int jahre,monate,tage,stunden,minuten,sekunden;
// wochentag bleibt in diesem Test-Sketch unberücksichtigt

//----------------------------------------------//

void rtcReadTime(int &jahre, int &monate, int &tage, int &stunden, int &minuten, int &sekunden)
// aktuelle Zeit aus RTC auslesen
{
// Reset the register pointer
  Wire.beginTransmission(RTC_I2C_ADDRESS);
  Wire.write(0);
  Wire.endTransmission();
  Wire.requestFrom(RTC_I2C_ADDRESS, 7);
  // A few of these need masks because certain bits are control bits
  sekunden    = bcdToDec(Wire.read() & 0x7f);
  minuten     = bcdToDec(Wire.read());
  stunden     = bcdToDec(Wire.read() & 0x3f);  // Need to change this if 12 hour am/pm
  /*wochentag   = */bcdToDec(Wire.read());
  tage        = bcdToDec(Wire.read());
  monate      = bcdToDec(Wire.read());
  jahre       = bcdToDec(Wire.read())+2000;  
}

//----------------------------------------------//

void rtcWriteTime(int jahre, int monate, int tage, int stunden, int minuten, int sekunden)
// aktuelle Zeit in der RTC speichern
{
  Wire.beginTransmission(RTC_I2C_ADDRESS);
  Wire.write(0);
  Wire.write(decToBcd(sekunden));    // 0 to bit 7 starts the clock
  Wire.write(decToBcd(minuten));
  Wire.write(decToBcd(stunden));      // If you want 12 hour am/pm you need to set
                                   // bit 6 (also need to change readDateDs1307)
                                  
  Wire.write(decToBcd(0)); // Wochentag unberücksichtigt
  Wire.write(decToBcd(tage));
  Wire.write(decToBcd(monate));
  Wire.write(decToBcd(jahre-2000));
  Wire.endTransmission();  
}

byte decToBcd(byte val) // Hilfsfunktion zum Lesen/Schreiben der RTC
// Convert decimal number to binary coded decimal
// Hilfsfunktion für die Echtzeituhr
{
  return ( (val/10*16) + (val%10) );
}

byte bcdToDec(byte val)  // Hilfsfunktion zum Lesen/Schreiben der RTC
// Convert binary coded decimal to decimal number
// Hilfsfunktion für die Echtzeituhr
{
  return ( (val/16*10) + (val%16) );
}


int getIntFromString (char *stringWithInt, byte num)
// input: pointer to a char array
// returns an integer number from the string (positive numbers only!)
// num=1, returns 1st number from the string
// num=2, returns 2nd number from the string, and so on
{
  char *tail;
  while (num>0)
  {
    num--;
    // skip non-digits
    while ((!isdigit (*stringWithInt))&&(*stringWithInt!=0)) stringWithInt++;
    tail=stringWithInt;
    // find digits
    while ((isdigit(*tail))&&(*tail!=0)) tail++;
    if (num>0) stringWithInt=tail; // new search string is the string after that number
  }  
  return(strtol(stringWithInt, &tail, 10));
}  

//----------------------------------------------//

void setup()
{
  pinMode(13, OUTPUT);
  digitalWrite(13, HIGH);
  
  pinMode(9, OUTPUT);
  
  pinMode(3, INPUT);
  
  lcd.begin(16,2);
  
  lcd.clear();
  lcd.setCursor(2,0);
  lcd.print("TerraControl");
  lcd.setCursor(2,1);
  lcd.print("Firmware 1.0");
  delay(4000);
  lcd.clear();
  
  dht.begin();
  
  Wire.begin();       // initialisiert die Wire-Library
  Serial.begin(9600); // Serielle Kommunikation starten
  while (!Serial);    // wait for serial port to connect. Needed for Leonardo only
  Serial.println("Die Zeit kann mit einem 'set' Befehl im 'Serial Monitor' neu setzen.\r\n");
  Serial.println("Aktuelle Uhrzeit:");
  Serial.println("Beispiel:");
  Serial.println("set 28.08.2013 10:54\r\n");
  for (int i=0;i<sizeof(schaltRelais)/sizeof(schaltRelais_t);i++)
  {
    digitalWrite(schaltRelais[i].pin,LOW);
    pinMode(schaltRelais[i].pin,OUTPUT);
  }  
  digitalWrite(timerRelais.pin,LOW);
  pinMode(timerRelais.pin,OUTPUT);
}

//----------------------------------------------//

void behandleSerielleBefehle()
{
  char linebuf[30];
  byte counter;
  if (Serial.available())
  {
    delay(100); // Warte auf das Eintreffen aller Zeichen vom seriellen Monitor
    memset(linebuf,0,sizeof(linebuf)); // Zeilenpuffer löschen
    counter=0; // Zähler auf Null
    while (Serial.available())
    {
      linebuf[counter]=Serial.read(); // Zeichen in den Zeilenpuffer einfügen
      if (counter<sizeof(linebuf)-1) counter++; // Zeichenzähler erhöhen
    }
    // Ab hier ist die Zeile eingelesen
    if (strstr(linebuf,"set")==linebuf) // Prüfe auf Befehl "set" zum Setzen der Zeit
    { // Alle übermittelten Zahlen im String auslesen
      tage=getIntFromString (linebuf,1);
      monate=getIntFromString (linebuf,2);
      jahre=getIntFromString (linebuf,3);
      stunden=getIntFromString (linebuf,4);
      minuten=getIntFromString (linebuf,5);
      sekunden=getIntFromString (linebuf,6);
    }
    else
    {
      Serial.println("Befehl unbekannt.");
      return;
    }
    // Ausgelesene Werte einer groben Plausibilitätsprüfung unterziehen:
    if (jahre<2000 || monate<1 || monate>12 || tage<1 || tage>31 || (stunden+minuten)==0)
    {
      Serial.println(linebuf);
      Serial.println("\r\nFehlerhafte Zeitangabe im 'set' Befehl");
      Serial.println("\r\nBeispiel:");
      Serial.println("set 28.08.2013 10:54\r\n");
      return;
    }
    rtcWriteTime(jahre, monate, tage, stunden, minuten, sekunden);
    Serial.println("Zeit und Datum wurden auf neue Werte gesetzt.");
  }
}

//----------------------------------------------//

void loop()
{
  char buffer[30];
  static unsigned long lastMillis;
  static int lastMinute;
  int stunden, minuten, sekunden, dummy;
  if (millis()-lastMillis>1000) // nur einmal pro Sekunde
  {
    lastMillis=millis();
    rtcReadTime(dummy, dummy, dummy, stunden, minuten, sekunden);
    if (minuten!=lastMinute) // die aktuelle Minute hat gewechselt
    {
      lastMinute=minuten;
      snprintf(buffer,sizeof(buffer),"%02d:%02d Uhr",stunden,minuten);
      Serial.println(buffer);
      relaisSchaltenNachZeit(stunden,minuten);
      relaisTimerNachZeit(stunden,minuten);
    }
  }
  behandleSerielleBefehle();
  LeseSensor();
  AutomatischeHumidity();
  UpdateLCD();
  SchalterStatus();
}

//----------------------------------------------//

void SchalterStatus()
  {
   tasterstatus = digitalRead(tasterpin);
   if(tasterstatus == HIGH)
   digitalWrite(hdpin,HIGH);
   else
   digitalWrite(hdpin,LOW);
  }

//----------------------------------------------//
  
void LeseSensor()
  {
  h = dht.readHumidity();
  t = dht.readTemperature();
  }
  
void AutomatischeHumidity()
  {
  if ((h < 50) && (digitalRead(3) == LOW))
  {
   digitalWrite(9, HIGH);
  }
  else
  {
   digitalWrite(9, LOW);
   }
  }

//----------------------------------------------//

void UpdateLCD()
  {
   lcd.setCursor(0,0);
   lcd.print("Hum:");
   lcd.setCursor(10,0);
   lcd.print(h);
   lcd.setCursor(15,0);
   lcd.print("%");
   lcd.setCursor(0,1);
   lcd.print("Tem:");
   lcd.setCursor(10,1);
   lcd.print(t);
   lcd.setCursor(15,1);
   lcd.print("C");  
  }

Die Zeit Steuerung, DHT & LCD funktionieren einwandfrei.
Bin um eure Hilfe echt froh, ich komme einfach nicht auf den Fehler!

MFG Patrick[/code]

Hoffe um Nachsicht mit meiner Unwissenheit & bin Neuling und brav am lernen.
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
Antwort schreiben 


Gehe zu:


Benutzer, die gerade dieses Thema anschauen: 1 Gast/Gäste