[WIP] Rollosteuerung für's Gewächshaus - Ansteuern von Relais

Moin,

zusammen mit meinem Vater plane ich für sein Gewächshaus eine automatische Steuerung für einen Vorhang der über einen Arduino angesteuert wird.

Wir sind beide neu im Umgang mit dem Arduino, er hat aber Elektrotechnik studiert und ich habe Grundkenntnisse in der Programmierung, sodass sich unsere Kenntnisse da bisher recht gut ergänzen.

Momentan sind wir so weit, dass der Motor (12V, aus einem alten Akkuschrauber) über 2 Taster und Relais in beide Richtungen gedreht werden kann. Parallel dazu habe ich heute einen Sketch programmiert der, in Ermangelung des Motors und der Relais (wir wohnen einige hundert Kilometer voneinander entfernt, was die Sache nicht leichter macht ^^), erstmal nur LEDs schaltet.
Jetzt bin ich dabei, den Sketch an die Relais anzupassen, was meiner Meinung nach ja nicht groß was anderes sein sollte.
Bevor meinem Vater jetzt aber die Relais abrauchen oder der Motor durchdreht, würde ich mich freuen wenn mal jemand kurz über den Code gucken könnte ob soweit alles passt.

Die Drehzahl des Motors wird über einen Poti gesteuert, in einem späteren Schritt, und da komme ich dann vermutlich wieder auf euch zurück, werden dann Lichtschranken als Wegbegrenzer eingebaut. Oder gibt es da eurer Meinung nach sinnvollere Möglichkeiten um den Verfahrweg des Rollos zu begrenzen?

Vielen Dank im voraus,
André

// T unter 10 Grad > Rollo zu
// T zwischen 11 und 29 Grad > Rollo auf
// T über 30 Grad > Rollo zu


#include <dht11.h>

const int REL1 = 8;    //Relais 1 auf Pin 8 für Rollo auf
const int REL2 = 9;    //Relais 2 auf Pin 9 für Rollo zu

dht11 DHT11;
#define DHT11PIN 2      //DHT11 auf Pin 2
 

void setup()
{
pinMode(REL1,OUTPUT);
pinMode(REL2,OUTPUT);
}
 

void loop()
{
  
  int chk = DHT11.read(DHT11PIN);

 
  if((float)DHT11.temperature > 30)
  {
      digitalWrite(REL1,LOW);
      digitalWrite(REL2,HIGH);
  }
  if(((float)DHT11.temperature < 29) && ((float)DHT11.temperature > 11))
  {
      digitalWrite(REL1,HIGH);
      digitalWrite(REL2,LOW);
  }
   if((float)DHT11.temperature < 10)
  {
      digitalWrite(REL1,LOW);
      digitalWrite(REL2,HIGH);
  }     
  
  
  delay(2000);
}

Das Ding neigt so zum Schwingen.

Wenn die Temperatur um die Schaltpunkte herum schwankt - das können auch messschwankungen sein, fährt das immer hoch und runter - im Zweifel mitten in der Bewegung, wenn die Rollos nicht in 3 Sehunden am Ende sind.
Das delay ist auch schlecht, wenn Du später Endschalter abfragen willst. Die werden dann erst nach 3 Sekunden abgefragt.

Neuer Ansatz ohne Delay mit millis(). Schau Dir BlinkWithoutDelay und die Nachtwächtererklärung (kein Witz) an.

Ansatz:

  1. Du merkst dir die aktuelle Lage
  2. Du bestimmst die notwendige Lage (oben oder unten.
    if (temp < 9 || temp > 31) lage = 1; //auf
    if (temp >10 && temp < 29) lage = 0; // zu
    Hier hast Du eine Hysterese drin und verhinderst damit das Schwingen
  3. if ((lage != altlage) && !bewegung) {
    bewegung = true;
    if (lage) {
    Motoren auf hoch
    }
    else {
    Motoren auf runter
    }
    }
    Endschalter setzen Bewegung auf false

Si vermeidest Du eine Umkehr mitten in der Bewegung. Dazu musst Du aber die Endschalter oder Lichtschranken mit einbauen.

Gruß Tommy

dza0411:
... delay(2000);

Wie Tommy schon geschrieben hat, ist delay() ungünstig. Besser wäre ein endlicher Automat, der mit millis() arbeitet – siehe z. B. hier, Links zu anderen Erklärungen stehen im Kasten am unteren Ende der Seite.

HTH

Gregor

Nachtrag: Die von Tommy erwähnte Nachtwächter-Erklärung ist wirklich sehr gut!

Wie wäre es, abgesehen von der fehlenden Hysterese, damit:

if(((float)DHT11.temperature > 30) || ((float)DHT11.temperature < 10))

Wobei ich das (float) nicht verstehe, da Du mit einem Int vergleichst.

Endschalter sollten gegen Kabelbruch "gesichert" sein: Im Programm INPUT_PULLUP und am Arduino einen zusätzlichen PullUp-Widerstand von 1 kOhm, damit zur Störfestigkeit mehr Strom fließt. Der Enschalter sollte ein Öffner gegen Masse sein. Dann LOW=freie Fahrt, HIGH=Stopp.

Anstatt direkt die Relais anzusteuern, erst nur Merker setzen. Dann kannst Du eine Priorisierung vornehmen, also erst Temperatur auswerten, dann Endschalter prüfen. Erst am Ende die Relais ansteuern:

digitalWrite(REL1,merker1);
digitalWrite(REL2,merker2);

Zwecks Transparenz solltest Du ein kleines Display verwenden, LCD 4x20 mit I2C beispielsweise. Mehr farbige Textinfo paßt auf ein Grafikdisplay.

Lichtschranken finde ich unpraktisch, da auch Spinnen, schnell wachsende Pflanzen und Dreck lichtundurchlässig sind. Endschalter wie aus dem Maschinenbau, Reedschalter oder Hallsensoren könnten besser funktionieren.