Arduino mit Relais und Button Zeitverzögerung Ein & Ausschalten

Hallo an alle,

mein Plan ist ein Relais und Druckknopf (1-Kanal 5V Relay / Relais Modul 10A - 250VAC, 0,75 €) mit dem Arduino zu verbinden. 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.

Kennt da einer ein Link zu einem ähnlichen Projekt?

Danke euch

schau dir die zwei Beispiele in der IDE an:

  1. Digital Debounce
  2. Digital BlinkWithoutDelay

wenn du die durchmachst und verstehen lernst, hast du 95% dessen was du brauchst wenn du das unbedingt mit einem Arduino lösen musst.

In der IDE findest du Beispiele, die deine gewünschten Funktionen liefern.
Eine Zeitverlängerung kannst du anfangs mit delay() erreichen.

Danke für die schnelle Antwort.

Ich bin natürlich kein Profi deswegen weiß ich auch nicht wie man zwei Codes zusammen fügen kann (bzw. programmieren) muss.

Daher habe ich immer gerne ein Projekt zum Lernen welches man umsetzt und dann versteht wie es gemacht wurde. So klappt das für mich immer am besten. Gibt es da was? Oder könnt ihr mir helfen mit dem Code?

Ich denke mit einem Arduino ist es am billigsten und genausten Anstatt einem Timer relais und Druckknopf.

Grüße

Wenn du lernen willst, dann mach die zwei Beispiele durch.

Wenn du nur eine Lösung willst, schau bei Conrad nach einem Zeitrelais, Nachlaufrelais, Timer Bausatz ...

Ich werde mir das angucken und klar will ich lernen. Doch geht es wie beschrieben für mich am besten. Selsbt wenn ich beide Beispiele durch habe ist es mir immer noch nicht klar wie ich beides kombiniere.Also falls noch irgendeiner ein ähnliches Projekt kennt bitte um Link.

Grüße

ArneDunio:
Ich bin natürlich kein Profi deswegen weiß ich auch nicht wie man zwei Codes zusammen fügen kann (bzw. programmieren) muss.

Daher habe ich immer gerne ein Projekt zum Lernen welches man umsetzt und dann versteht wie es gemacht wurde. So klappt das für mich immer am besten. Gibt es da was? Oder könnt ihr mir helfen mit dem Code?
.....

Ein fertiges Projekt hilft dir da überhaupt nicht, da du daran nicht erkennen kannst, wie 2 Sketche zusammen gesetzt werden.
Also sieh dir die Beispiele an und versuche es diese zusammen zu setzen.
Wenn du beim compilieren einen Fehler bekommst, kannst du den entsprechend der Meldung entfernen.

Tipp:
In einem Sketch gibt es nur ein Setup, eine loop und die Definitionen und Variablen dürfen nur einmal genannt werden.

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 :wink:
(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! :slight_smile: 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. :slight_smile:

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...:frowning:

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

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