Neuling hat eine Frage zu if/else Statements :)

Hallo liebes Forum,

ich habe eine kleine Frage zu if/else. Und zwar habe ich an meinen Arduino Uno + Base Shield mehrere Sensoren und zwei Grove Relais auf D2 und D3 angeschlossen.

Das erste if/else Statement soll überprüfen ob die Temperatur > 25 ist und dann einen Ventilator anschalten. Funktioniert auch tadellos.

Das zweite if/else Statement soll überprüfen ob die Bodenfeuchtigkeit (via soil moisture sensor) <300 ist und dann das Delay auf D3 durchhalten, daran ist eine kleine Wasserpumpe befestigt.
Wenn ich allerdings folgenden Code verwende (ich bin Neuling und froh um alle Tipps), schaltet das Real auf D3 an und sofort wieder aus, wieder an und aus ... und so weiter. Gibt es eine Möglichkeit zwei if/else hintereinander im loop laufen zu lassen?

Vielen Dank im Voraus! :slight_smile:

void loop() {

 SeeedGrayOled.clearDisplay();
 SeeedGrayOled.putString("Test");
 
 float temp = sht31.getTemperature();
 SeeedGrayOled.setTextXY(1,0); 
 SeeedGrayOled.putString("Temp: ");
 SeeedGrayOled.putNumber(temp);
 SeeedGrayOled.putString(" C");

 float hum = sht31.getHumidity();
 SeeedGrayOled.setTextXY(4,0);  
 SeeedGrayOled.putString("Humid: ");
 SeeedGrayOled.putNumber(hum);
 SeeedGrayOled.putString(" %");
 
 SeeedGrayOled.setTextXY(7,0);  
 SeeedGrayOled.putString("Light: ");
 SeeedGrayOled.putNumber(TSL2561.readVisibleLux());
 SeeedGrayOled.putString(" LUX");

 float soil = analogRead(A0);
 SeeedGrayOled.setTextXY(10,0);  
 SeeedGrayOled.putString("Soil: ");
 SeeedGrayOled.putNumber(soil);
 SeeedGrayOled.setTextXY(12,0);  
 SeeedGrayOled.putString("0/300/700");
 

//Fan

 if (temp > 25)
{
 digitalWrite(2, HIGH);
}
 
 else
{
 digitalWrite(2, LOW);
}

//Pump

 if (soil < 300)
{
 digitalWrite(3, HIGH);
}

 else
{
 digitalWrite(3, LOW);
}

 delay(OneMinute);
}

Hallo,

was zeigt denn das Display an ? Welche Werte hat soil beim schalten? grundsätzlich sollte der Code funktionieren.
Packe den Skatch bitte als Code Tag und zeig mal deine Installation ... also ein Schaltplan wäre nicht schlecht.

Gruss Temucin

//Fan

if (temp > 25)
{
 digitalWrite(2, HIGH);
}
 
 else
{
 digitalWrite(2, LOW);
}

Ersetzen durch:

digitalWrite(2,temp > 25 ); //Fan

Genauso:

digitalWrite(3, soil < 300); //Pump

Nicht, dass ich was grundsätzlich gegen if/else habe ...
Aber:

  1. Jede vermiedene if/else Konstruktion ist eine gute Konstruktion
  2. Jede vermeidbare if/else Konstruktion ist eine böse Konstruktion

// ---

Nachtrag:
Vielleicht möchtest du eine Hysterese einbauen?

Dein Code führt aktuell dazu, dass die Pumpe einschaltet und nach 1 Minute ausschaltet, falls die Feuchtigkeit genügend angestiegen ist. Wenn das Relais zappelt, dann liegt das nicht an dem if/else (sofern dein laufender Code dem entspricht, was wir hier sehen). Eher ist vielleicht dein OneMinute Intervall gar keine Minute und dein soil Messwert zappelt um die 300 rum.

Ich würde prinzipiell eher eine Lösung anstreben, die die Pumpe für eine bestimmte Dauer einschaltet, wenn die Feuchtigkeit den Schwellwert unterschreitet. Danach eine definierte Pause und dann wird erneut die Feuchtigkeit gemessen und falls immer noch zu trocken, wird der Pumpvorgang wiederholt.

Sonst hast du eventuell den Effekt, dass deine Pumpe läuft und das Wasser gelangt zu langsam zum Sensor. Somit läuft die Pumpe zu lange und schaltet erst ab, wenn genug Wasser am Sensor angekommen ist und du überflutest ungewollt.

Willst du ein Gewächshaus steuern oder soll das eine Klimaanlage werden?

T7OM:
delay(OneMinute);

Gibt es "OneMinute" schon vordefiniert oder wird oben im Sketch irgendwo OneMinute auf 60000 gesetzt?
Wenn das Relais flattert, ist wohl OneMinute nicht definiert.

Delay zu verwenden ist nicht wirklich schön oder elegant, aber sollte in dem Fall funktionieren.
Theoretisch dürfte das Relais bei diesem Sketch nur ein mal pro Minute schalten.

Stell bitte mal Deinen ganzen Sketch hier rein. Da fehlt bestimmt OneMinute = 60000

Gruß, Jürgen

Und verwende endlich mal Code-Tags, damit der Sketch vernünftig zu lesen ist.

Erstmal vielen Dank an die ganzen Antworten!

Ich hoffe ich beantworte alle Fragen die ihr mir noch gestellt habt.

  1. Mein Display zeigt die Werte Temperatur, Humidity, Light und Soil an. Funktioniert einwandfrei. Auch das Relay, welches den Fan schaltet (temp > 25) funktioniert.

  2. Das ganzer ist eine Spielerei, um eine Pflanze "automatisch" zu bewässern, wollte mich einfach mal an den Arduino ranwagen :). Der Wert ist derzeit ca. bei 180 also "zappelt" nicht herum.

  3. Mein Fan ist über das Delay am 5V Pin am Arduino angeschlossen und die Pumpe am VIN, und natürlich beide auch am GND. Beide Relais laufen über die D2 und D3 Stecker am Base Shield.

  4. "Ich würde prinzipiell eher eine Lösung anstreben, die die Pumpe für eine bestimmte Dauer einschaltet, wenn die Feuchtigkeit den Schwellwert unterschreitet. Danach eine definierte Pause und dann wird erneut die Feuchtigkeit gemessen und falls immer noch zu trocken, wird der Pumpvorgang wiederholt."
    Das wäre natürlich ideal! Ich bin dankbar um alle Gedankenanstöße. Lässt sich sowas leicht als Code schreiben? Bzw. gibt es dafür irgendwelche Erklärungen im Internet, bin wie gesagt Neuling.

  5. Der ganze Code ist hier:

#include <Arduino.h>
#include <Wire.h>
#include <SHT31.h>
#include <Digital_Light_TSL2561.h>
#include <SeeedGrayOLED.h>

#define OneSecond       1000
#define OneMinute       60000
#define OneHour         3600000

SHT31 sht31 = SHT31();

void setup() {  
  Wire.begin(0x29);
  Wire.begin(0x44);
  Wire.begin(0x3C);
  Serial.begin(9600);
  while(!Serial);
  TSL2561.init(); 
  sht31.begin(); 
  SeeedGrayOled.init(SH1107G);
  SeeedGrayOled.clearDisplay();
  SeeedGrayOled.setNormalDisplay();
  SeeedGrayOled.setVerticalMode();
}

void loop() {

  SeeedGrayOled.clearDisplay();
  SeeedGrayOled.putString("InnFarm V1.0");
  
  float temp = sht31.getTemperature();
  SeeedGrayOled.setTextXY(1,0); 
  SeeedGrayOled.putString("Temp: ");
  SeeedGrayOled.putNumber(temp);
  SeeedGrayOled.putString(" C");

  float hum = sht31.getHumidity();
  SeeedGrayOled.setTextXY(4,0);  
  SeeedGrayOled.putString("Humid: ");
  SeeedGrayOled.putNumber(hum);
  SeeedGrayOled.putString(" %");
  
  SeeedGrayOled.setTextXY(7,0);  
  SeeedGrayOled.putString("Light: ");
  SeeedGrayOled.putNumber(TSL2561.readVisibleLux());
  SeeedGrayOled.putString(" LUX");

  float soil = analogRead(A0);
  SeeedGrayOled.setTextXY(10,0);  
  SeeedGrayOled.putString("Soil: ");
  SeeedGrayOled.putNumber(soil);
  SeeedGrayOled.setTextXY(12,0);  
  SeeedGrayOled.putString("0/300/700");
  

//Fan
  digitalWrite(2, temp > 25);

//Pump
  digitalWrite(3, soil < 400);

  delay(OneMinute);
}

Wire.begin(0x29);
Wire.begin(0x44);
Wire.begin(0x3C);

Was ist das?

Lässt sich sowas leicht als Code schreiben?

Nennt sich Ablaufsteuerung, o.ä.

Suche mal nach "Nachtwächter Erklärung" hier im Forum.

Hab den Fehler gefunden, das Relais gibt 3V aus, die Pumpe hat aber 12V, werde mir ein anderes Relais besorgen und es damit probieren. Trotzdem vielen Dank für die hilfreichen Tipps zwecks Ablaufsteuerung etc.

Grüße!

T7OM:
Hab den Fehler gefunden, das Relais gibt 3V aus, die Pumpe hat aber 12V, werde mir ein anderes Relais besorgen und es damit probieren. Trotzdem vielen Dank für die hilfreichen Tipps zwecks Ablaufsteuerung etc.

Grüße!

Haaaalt!!

Dein Relais schaltet nur das durch, was du reingibst. Wenn da 3V rauskommen, dann gibst du auch nur 3V rein. Du musst dann schon dafür sorgen, dass dein Relais mit 12V versorgt wird.

Und es sollte natürlich auch für min. 12V spezifiziert sein, das versteht sich von selbst.