60s Rhythmus alle 24h

Hallo zusammen,

ich benötige einmal eure Hilfe.
Mein plan ist es ein Gerät zu bauen welches ein kleines Magnetventil, eine LEDVorformatierter Text sowie einen Taster und einen Schwimmerschalter besitzt. Dieses Gerät soll unseren Wasserhahn in der Gerage intervallmäßig "durchspülen". Die Beschaffung der Komponenten und das zusammenbauen ist kein Problem. Beim Code für den Arduino struggle ich aber noch ein bisschen.

Ziel ist es, dass alle 24h (muss nicht auf die Sekunde genau passieren) nach einschalten des Geräts das Ventil für 60s angesteuert ,also einfach ein high-Pegel an einem Ausgang erzeugt werden soll. Zusätzlich soll die LED alle 10s kurz blinken, um zu sehen dass das Gerät noch an ist. Mit dem Taster soll man das Ventil händisch betätigen/testen können, ohne den 24h Rhythmus zu beeinflussen oder neu zu starten. Der Schwimmerschalter unterbricht lediglich den Kontakt zum Ventil wenn das Becken überlaufen sollte.

Hier meine Ansätze:

const byte  LED=1;

void setup() 
{
  pinMode(LED,OUTPUT);
}

void loop()
{
  digitalWrite(LED,millis()%10000<200);
}
````Vorformatierter Text`

mit dieser Zeile: digitalWrite(LED,millis()%10000<200); lasse ich die InfoLED alle 10s für 200ms blinken.


Könnte ich mit so einer Zeile mit angepassten Zahlen auch meinen 24h Timer bauen? 


Ich habe ebenso versucht für den Funktionstest mit dem Taster Folgendes einzufügen:

const byte LED=1;
const byte Ventil=2;
int taster=3;
int tasterstatus=0;

void setup()
{
pinMode(LED,OUTPUT);
pinMode(Ventil,OUTPUT);
pinMode(taster, INPUT);
}

void loop()
{
digitalWrite(LED,millis()%10000<200);

tasterstatus=digitalRead(taster);
if (tasterstatus == HIGH)
{
digitalWrite(Ventil, HIGH);
}
else
{
digitalWrite(Ventil, LOW);
}

}


Dies funktioniert soweit nur benötige ich noch einen Rat für den 24h Timer.

Eventuell kann mir ja jemand helfen. 
Besten Dank schonmal im Voraus! :slight_smile:

Im englischen Teil des Forum müssen die Beiträge und Diskussionen in englischer Sprache verfasst werden. Deswegen wurde diese Diskussion in den deutschen Teil des Forums verschoben.

mfg ein Moderator.

Rein vorsorglich: Dein Code hat keinen Schwimmerschalter.
Handelt es sich dabei um eine Sicherheitseinrichtung, gehört die dahin, wo sie wirksam ist und Du wertest nur deren tatsächlichen Zustand aus, so das notwendig ist.

Bitte lies das einstellen von Code - es wird sonst schwer Dir zu folgen.

bitte lies dir durch wie man Code einstellt.

Dann lies dir das Beispiel "Blink Without Delay" in der IDE durch.

evtl. könnte das ca machen was du willst

const byte led = 4;    // an 1 hängen wir nichts, da ist die Serielle Schnittselle
const byte ventil = 2;
const byte taster = 3;
int tasterstatus = 0;



void timerVentil()
{
  static uint32_t previousMillis = 0;
  static bool status = false;
  if (status == false && millis() - previousMillis > 24 * 60 * 60 * 1000UL)
  {
    previousMillis = millis();
    digitalWrite(ventil, HIGH);
    status = true;
  }
  else if (status == true  && millis() - previousMillis > 60 * 1000UL)
  {
    previousMillis = millis();
    digitalWrite(ventil, LOW);
    status = false;
  }
}

void timerLed()
{
  static uint32_t previousMillis = 0;
  static bool status = false;
  if (status == false && millis() - previousMillis > 10 * 1000UL)
  {
    previousMillis = millis();
    digitalWrite(led, HIGH);
    status = true;
  }
  else if (status == true  && millis() - previousMillis > 1000UL)
  {
    previousMillis = millis();
    digitalWrite(led, LOW);
    status = false;
  }
}

void setup()
{
  pinMode(led, OUTPUT);
  pinMode(ventil, OUTPUT);
  pinMode(taster, INPUT);
}

void loop()
{
  tasterstatus = digitalRead(taster);
  if (tasterstatus == HIGH)
  {
    digitalWrite(ventil, HIGH);
  }
  else
  {
    digitalWrite(ventil, LOW);
  }
  timerLed();
  timerVentil();
}

wenn du den Taster gegen High verbindest brauchst du Pulldown Widerstände. Hast du die verbaut?

Na denn...
gibt es von mir auch einen Vorschlag.
Du schreibst nicht, was Du verwendest.
Auf einem Arduino ist 1 als PIN ggfls. nicht die beste Idee. auf 0 und 1 ist die USB-Schnittstelle mit drauf, Du sperrst Dich ggfls. aus.

const byte LED = 1;
const byte Ventil = 2;
const byte taster = 3;
const unsigned long tag = 86400 * 1000UL;     // Jeder Tag hat 86400 sekunden
const unsigned long ventilzeit = 60 * 1000UL; // zeit in ms
unsigned long laststart = 0;

void setup()
{
  pinMode(LED, OUTPUT);
  pinMode(Ventil, OUTPUT);
  pinMode(taster, INPUT);
}

void loop()
{
  if (!manual()) automatic();                 // manuell nicht ausgelöst? Dann Automatik
  heartbeat();                                // blinkblink
}

bool manual()
{
  if (digitalRead(taster))                    // ausgelöst?
  {
    digitalWrite(Ventil, HIGH);               // ventil setzen
    return true;                              // Schluss
  }
  return false;
}

void automatic()
{
  if (millis() - laststart >= tag)            // ein ganzer Tag ist abgelaufen
  {
    digitalWrite(Ventil, HIGH);               // Ventil setzen
    laststart = millis();                     // Startzeit merken
  }
  if (millis() - laststart >= ventilzeit)     // Laufzeit - Startzeit erfüllt?
  {
    digitalWrite(Ventil, LOW);                // Aus
  }
}

void heartbeat()
{
  static unsigned long lastmillis = 0;
  if (millis() - lastmillis >= 500)
  {
    digitalWrite(LED, !digitalRead(LED));
    lastmillis = millis();
  }
}
// die neueste CombieLib.zip findest du mit der Forensuche
#include <CombieTypeMangling.h>
using namespace Combie::Millis;

#include <CombiePin.h>
#include <CombieTimer.h>

//                                       onInterval,    offInterval                           
Combie::Timer::PpmGenerator blitzTimer  {0.1_Sekunden,  10_Sekunden};
Combie::Timer::PpmGenerator ventilTimer {60_Sekunden,   24_Stunden - 60_Sekunden};
Combie::Pin::InputPin<3>    taster;
Combie::Pin::OutputPin<13>  blitzDiode;
Combie::Pin::OutputPin<12>  ventil;

void setup() 
{
  ventil.init();
  taster.init();
  blitzDiode.init();
}

void loop() 
{
  ventil     = ventilTimer || taster ; 
  blitzDiode = blitzTimer;
}

Edit; Schwimmer entfernt

Erstmal vielen Dank für die Vorschläge!
Ich werde sie nachher mal ausprobieren.

@my_xy_projekt der Schwimmerschalter soll zwischen der Spannungsversorgung des Ventils verbaut sein und so mit rein physisch unterbrechen.

Achja und verwenden werde ich wohl einen Attiny wegen seiner kompakten Bauform den ich allerdings mit meinem Arduino Uno proggen werde.

@my_xy_projekt dein Sketch funktioniert soweit super. Nur wenn ich den Taster innerhalb der ersten 60s nach dem einschalten betätige, bleibt das Ventil für 60s offen. Danach öffnet es nur beim drücken des Tasters und schließt auch wieder beim los lassen(wie es eigentlich von Anfang an sein sollte).
An sich keine schlimme Sache nur wundert es mich woran das liegen könnte?

liebe Grüße
Tim

Ja.. ich weiss.
Ich war mir gestern nicht sicher, ob das wirklich richtig gedacht war.
Ersetze den manual.
Was der Code machen soll:
Ich benötige eine zusätzliche Variable um mir den letzten Zustand der Taste zu merken, die ist default nicht gesetzt.
Wenn die Taste gedrückt wird, wird der PIN gesetzt und die Variable.
-Bis hierhin wie vorher auch.
Was jetzt zusätzlich dazu kommt:
Wenn ich die Taste wieder loslasse UND die merker-Variable vorher gesetzt war, NUR dann setze ich das Ventil wieder LOW.
Die Rückgabe des Zustandes erfolgt über den Inhalt der Variablen.

Der lokale Merker muss static sein, weil beim verlassen der Funktion der Inhalt nicht verloren gehen darf.

bool manual()
{
  static bool isManual = false;
  if (digitalRead(taster))                    // ausgelöst?
  {
    digitalWrite(Ventil, HIGH);               // ventil setzen
    isManual = true;                          // merken
  }
  else if (isManual)                          // taste war vorher und jetzt nicht mehr ausgelöst
  {
    digitalWrite(Ventil, LOW);                // ventil setzen
    isManual = false;                         // wieder merken (Buchstabensalat korrigiert)
  }
  return isManual;                            // Rückgabe des Merkers
}

@my_xy_projekt jetzt funktioniert es.

vielen Dank! :smiley:

Da war ich mir schon recht sicher.
Die Geschichte hat nur einen Haken...
Das Timing kommt durcheinander, wenn manual() startet und dann zeitlich in die automatik()-Phase läuft.
Nach aktuellem Codestand würde automatic erst nach loslassen von manual() wieder starten und den Versatz nicht mehr aufholen.

Wenn Dich das nicht stört, ist es egal.
Wenn doch, weil du automatik() immer zur selben Zeit ausführen willst, ist das nur eine kleine Änderung...

was wäre denn diese kleine Änderung?

laststart nicht mit millis füllen sondern mit tag.
Willst Du selbst probieren und rausfinden warum? Dann Zettel und Stift nehmen und die zeitlichen Abläufe aufschreiben.
Ich habe dafür auch etwas länger gebraucht. Einmal aufschreiben.. und seitdem erinner mich immer mal wieder daran :wink:

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.