Arduino mit Relais und Button Zeitverzögerung Ein & Ausschalten

Hi

Wobei debounce hier wohl eher Kür ist - zum EINschalten braucht man nur die eine Flanke, egal, wie viele Flanken danach noch kommen. Klar, wenn die Laufzeit so kurz sein soll, daß der Taster noch prellt - Das Problem habe ich aber so noch nicht hier gelesen.

Wenn Knopf gedrückt, schalte LED ein, warte 10 Sekunden, schalte LED aus. Könnte ein Weg mit delay() sein (unschön durch delay(), aber für den ersten Versuch benutzbar)

In echten Code musst Du Das schon selber umsetzen - fertige Sketche gibt's hier nur seeehr selten, zuletzt vor Karneval ;) (hat man von Dem eigentlich noch was gehört??)

MfG

Hallo

Beispiel / 02digital / button ist super geeignet dann noch den erklärenden link wegen der Hardware.

das else am ende ersetzen durch ein delay

fertig.

postmaster-ino:
Wobei debounce hier wohl eher Kür ist

Ich mag kein Delay empfehlen. Abgesehen davon, dass der TO damit auch debouncen kann, ist der Sketch mit ein paar wenigen Zeile auf einen Timer abänderbar.

Einfach statt dem toggeln den Ausgang einschalten und eine weitere Long Variable auf millis() setzen.
Dann am Ende vom loop den exisitierenden digitalwrite zum Ausschalten verwenden und ein If (millis()- … drüberpacken.
Und für den Schönheitspreis im setup() den Digitalausgang auf LOW setzen
Variablen deklarieren und “fast fertig” … das schreiben dieses Posts hat länger gedauert :wink:

      if (buttonState == HIGH) {
        //ledState = !ledState;               //noiasca: we don't want to toggle, but...
        digitalWrite(ledPin, HIGH);           //noiasca: switch on the LED
        lastOnTime = millis();                //noiasca: start timer
      }

und

  if (digitalRead(ledPin) && millis() - lastOnTime > onDelay)
  {
    digitalWrite(ledPin, LOW);                //noiasca: LED Off after timeout
  }

Hallo,

ArneDunio: Dieses Relais sollte auf Druck des Knopfes eingeschaltet werden, für eine Gewisse zeit! Dann sollte es automatisch Abschalten und auf nächsten Befehl (Knopf gedrückt) wieder einschalten.

Du brauchst einen Endlichen Automat (in Mini Form). Es gibt hier genug Beiträge zu dem Thema.

Allerdings brauchst auch die genannten Beispiele um zu verstehen wie so ein Programm aufgebaut ist:

Das ist lediglich ein Beispiel Code der nur den Programmablauf darstellen soll

zustand = 0;
loop {
  if(digitalRead(2)) { // Wenn der Button auf Pin 2 gedrückt wird
    delay(150);  // Taster entprellen, das gehört allerdings ohne delay aber dazu gibt es die Beispiele...
    if(zustand == 0) {
      digitalWrite(3, HIGH); // Schaltet den Pin auf HIGH, bei solchen Relais (boards) muss meistens auf LOW geschalten werden, umgekehrte Logik wegen den Transistor
      zustand++;  // Zustand + 1, der nächste zustand
      // Hier kann noch alles mögliche stehen, was passieren soll
    }
    if(zustand == 1) {
     digitalWrite(3, LOW); // Schaltet den Pin auf LOW, bei solchen Relais (boards) muss meistens auf LOW geschalten werden, umgekehrte Logik wegen den Transistor
     zustand++;  // Zustand + 1, der nächste zustand
    }
  }
}

Von noiasca hast Du den Entprell bzw. ohne delay Code, das sollte Dir für den Anfang weiterhelfen.

Grüße, Donny

Oh..ha

Das hört sich alles kompliziert an. Danke euch für die Antworten!!! Ich gucke mir das die nächsten Tage mal an.

ArneDunio: Das hört sich alles kompliziert an. Danke euch für die Antworten!!! Ich gucke mir das die nächsten Tage mal an.

So kompliziert ist das nicht. Delay sollte nur wirklich gewollt verwendet werden weil delay() das ganze Arduino auf Pause setzt (vereinfacht gesagt). In dieser "Pause" kann weder ein Tastendruck regestriert werden noch sonst irgendwas gemacht werden. Die einfachste Variante eine LED (Softwareseitig ist es egal ob LED oder Relais) für eine gewisse Zeit einzuschalten ist:

digitalWrite(13, HIGH); // Schalten den Pin 13 auf HIGH
delay(1000); // 1 Sekunde Pause
digitalWrite(13, LOW); // Und wieder ausschalten

In der Zwischenzeit kann allerdings nichts gemacht werden. edit: Fast Kein Multitasking! :) Das muss man sich quasi selber machen. Also gehst Du her und fragst bei jedem loop() durchgang nach ob die eine Sekunde bereits um ist. Die Funktion millis() , gibt Dir die Laufzeit des arduinos zurück.

Und der Vollständigkeit halber, Quelle: BlinkWithoutDelay()

 unsigned long currentMillis = millis(); // die verstrichene Zeit

if (currentMillis - previousMillis >= interval) { // Überprüfen ob die Zeit abgelaufen ist
  // save the last time you blinked the LED
  previousMillis = currentMillis; // Die Zeit vom letzten loop durchgang speichern.

Hoffentlich ist es jetzt etwas weniger kompliziert. :)

Grüße, Donny

In der Zwischenzeit kann allerdings nichts gemacht werden. Kein Multitasking!

Das ist nicht ganz richtig. Denn es gibt ja noch yield() und Interrupts.

Aber schon recht... Dein Vorschlag mit millis() und interval ist schon richtig so! Das sollte auch auf jeden Fall verstanden werden.

Ich bin immer noch dran und habe keine Lösung gefunden. ich habe einen Code aber auch der Arbeitet nicht wie erwartet.

int pinButton = 8;
int Relay = 2;
int stateRelay = LOW;
int stateButton;
int previous = LOW;
long time = 0;
long debounce = 500;
int stayON = 5000; //stay on for 5000 ms

void setup() {
  pinMode(pinButton, INPUT);
  pinMode(Relay, OUTPUT);
}

void loop() {
  stateButton = digitalRead(pinButton);  
  if(stateButton == HIGH && previous == LOW && millis() - time > debounce) {
    if(stateRelay == HIGH){
      digitalWrite(Relay, LOW);
    } else {
       digitalWrite(Relay, HIGH);
       delay(stayON);
       digitalWrite(Relay, LOW);
    }
    time = millis();
  }
  previous == stateButton;
}

Sobald ich den Code auf den Arduino lade fängt das Relais an wie ein Blinker an und aus zu gehen. Egal ob ich den Button drücke oder nicht?

Ich kann dir vorstellen, wie es bei mir aussehen würde…
(aber ob dir das hilft, weiß ich nicht)

Der Taster an Pin 8, wird bei Betätigung gegen GND geschaltet.
Das Relais an Pin 2, ist eins der China typischen, invertiert arbeitenden, Relais.

Nach dem erkennen eines Tastendrucks zieht das Relais an.
Nach loslassen des Tasters, fällt das Relais nach 500ms ab.

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



Combie::Pin::RelaisINV<2>        relais;
Combie::Pin::TasterGND<8>        taster;
Combie::Timer::EntprellTimer     entprellen(20);// ms
Combie::Timer::FallingEdgeTimer  toff(5000); //ms abfallende Flanke wird verzoegert
Combie::Tools::FlankenErkennung  flankenerkennung;


void setup() 
{
  relais.init();
  taster.initPullup();
}

void loop() 
{
  // Datenfluss von rechts nach links
  relais = toff = flankenerkennung = entprellen = taster;
}

CombieLib.zip (50.8 KB)

ArneDunio: Ich bin immer noch dran und habe keine Lösung gefunden. ich habe einen Code aber auch der Arbeitet nicht wie erwartet. ..... Sobald ich den Code auf den Arduino lade fängt das Relais an wie ein Blinker an und aus zu gehen. Egal ob ich den Button drücke oder nicht?

Dann solltest du dich unbedingt mit den Grundlagen beschäftigen und nicht irgend etwas aus dem Web kopieren.

Auch solltest du dich an die von den Forenmitgliedern gemachten Vorschlägen halten, nur so können wir dir zielgenau helfen.

Kein Herz für Noobs...:(

ArneDunio: Kein Herz für Noobs...:(

Klar doch!

Allerdings, mir ist dein Code zu verschachtelt. Ich kann nicht überblicken, was da passiert. Und ihn damit auch nicht reparieren. Klartext: Ich bin zu doof und zu faul dazu.

Und für dich selber, ist er offensichtlich auch zu kompliziert!

Tipps: Modularisiere deinen Code.

Teile ihn in klar getrennte Bereiche auf. Benenne diese Bereiche.

Das macht es übersichtlicher. Das verbessert die Wiederverwendbarkeit, für spätere Projekte.

-- Leitsatz: Für alles, was du schon mehr als drei mal gemacht hast, baue dir eine Lib.

// Taster schaltet gegen Vcc 
// PullDown erforderlich

// Relais schaltet bei High


const byte pinButton         = 8;
const byte Relay             = 2;
const unsigned long debounce = 500;
const unsigned long stayON   = 5000; //stay on for 5000 ms
unsigned long entprellCount  = 0;

void setup() 
{
  pinMode(pinButton, INPUT);
  pinMode(Relay, OUTPUT);
}


void loop() 
{

  // entprellen
  entprellCount = 0;
  while(entprellCount < debounce)
  {
    if(digitalRead(pinButton)) entprellCount++;
      else entprellCount = 0;
    delay(1);
  }


  // Relais betaetigung
  digitalWrite(Relay, HIGH);
  delay(stayON);
  digitalWrite(Relay, LOW);
}

Der Code ist blockierend.
Erweiterungen sind damit quasi unmöglich.(yield()?)
Der Nachtwächter liefert dir bessere Möglichkeiten

ArneDunio: Kein Herz für Noobs...:(

Wurde ja schon geschrieben: Klar doch !

Aber die Grundlagen solltest du dir selbst beibringen, da können und wollen wir nicht einsteigen.

Aber die Grundlagen solltest du dir selbst beibringen, da können und wollen wir nicht einsteigen.

Soweit würde ich nicht gehen!

Aber: Es hilft dem ArneDunio nicht, wenn ich die Grundlagen lerne....

Erstens, habe ich das schon, zumindest zu einem großen Teil. Zweitens muss er/sie/es das selber tun, weil ich nicht auf so großen Entfernungen, in fremder Leute Köpfe rum fummeln kann, oder gar will.

Hi Arne,

ich habe im Januar etwas sehr ähnliches geschrieben, einen Belichtungstimer, der etwa 90% Deiner Anforderung entspricht. Schau da einfach mal rein : https://forum.arduino.cc/index.php?topic=524803.0

Was Dir dann eigentlich noch fehlt, ist die Wiederholung, was zu viel ist, ist die Möglichkeit der Zeitverstellung ... Um ein Teilproblem zu lösen sind Ideen Anderer immer gut, aber was man selber macht versteht man um Längen besser!

Gruß André

SpaghettiCode: Um ein Teilproblem zu lösen sind Ideen Anderer immer gut, aber was man selber macht versteht man um Längen besser!

Da stimme ich dir zu, aber nur, wenn es nicht aus Copy&Paste besteht.

HotSystems: Da stimme ich dir zu, aber nur, wenn es nicht aus Copy&Paste besteht.

Das meinte ich mit dem Verweis auf ein Teilproblem. Ich persönlich erwarte nirgends einen Sketch zu finden, der 100% das macht, was ich mir vorstelle, also quasi ein Fertigprodukt. Aber es gibt auch Codeschnipsel die für mich funktionieren, auf die ich selbst nie kommen würde, da ich auch in Monaten nie so tief im Arduino stecken werde.

Gruß André

Wenn Du diese Codeschnipsel nutzt, um zu lernen sie zu verstehen, ist das ein durchaus brauchbarer Weg, um seine Kenntnisse zu erweitern.

Wenn Du sie nur in Deine Anwendung kopierst, ohne sie zu verstehen, ist das nicht der erstrebenswerte Weg.

Das wollte hotsystems, wohl etwas kürzer formuliert, ausdrücken.

Gruß Tommy