Licht im Treppenhaus steuern

Guten Tag, ich möchte das Licht im Treppenhaus steuern, doch ich habe keine Idee, wie der Code aussehen soll. Mein Plan: Beim kurzen Drücken, soll das Licht ca. 30 Sekunden lang an sein. (Das reicht, um hoch oder runter zu gehen.) Beim langen Drücken, soll das Licht, 10 Minuten lang an sein. (Um z. B. die Treppe zu putzen.)

Wie erwähnt, habe ich keine Vorstellung, wie der Code aussehen soll. Falls jemand eine Idee hat, kann er/sie, diese gerne mit mir teilen. MfG und Dank im voraus.

Mein Tipp zum Sketch. Übe mit den Beispielen der IDE. Dann kommst du selbst mal auf die Idee, wie der für die Treppenlichtsteuerung aussehen könnte.

Hallo,

Na dann schau Dir erst mal die einfachen Beispiele aus der IDE an. Wenn Du dann ein paar Grundlagen verstanden hast musst Du dir überlegen wie man einen kurzen Tastedruck und einen langen unterscheiden könnte. Richtig man könnte die Zeit messen, dazu bietet sich millis() an. Wenn Du dann mit deinem Sketch nicht mehr weiterkommst zeigst Du uns was Du hast.

Dann musst Du auch noch etwas haben um das Licht zu schalten. Wenn das 220V sind und Du keine Ahnung von Elektrik hast dann lass da die Finger von weg und mach es mit 12V LED´s und einem passende Netztgerät.

Heinz

Hallo, Mein Tipp aus der Praxis: als Kickstarter kannst du dein Projekt nach dem EVA-Prinzip zerlegen. E=Eingabe --> Taster V=Verarbeitung --> Zeitgeber A= Ausgabe --> Relais Als Ergebnis aus dieser Strukturierung entstehen Funktionen, taster(), timer() und relais(), die du einzeln testen kannst und dannach zur der Gesamtfunktion zusammenfügt werden. Starte mit dem Zeitgeber, mit den Funktionen: eventTimer(), startTimer() und stopTimer(). Viel Erfolg

Du mußt erkennen ob der Taster gerade gedrückt wurde oder losgelassen worden. (Flankenerkennung)

Sobald der Taster gedrückt wird speicherst Du den millis() Wert in einer Variablen ab. Dann kontrolierst Du ob die Zeit für Kurz-drücken vorbei ist oder der Taster losgelassen wurde.

Grüße Uwe

Wie erwähnt, habe ich keine Vorstellung, wie der Code aussehen soll. Falls jemand eine Idee hat, kann er/sie, diese gerne mit mir teilen.

Gar kein Problem…
(ich weiß allerdings nicht, ob dir das aufs Pferd hilft)

Hier mit 3 retriggerbaren Monoflops.

Die CombieLib muss du dir allerdings hier im Forum suchen, ich kann zur Zeit leider keine Dateien hochladen, warum auch immer …
Edit: Habe sie gefunden, sollte die frischeste sein

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

#include <CombieTypeMangling.h>
using namespace Combie::Millis;

Combie::Pin::TasterGND<2> taster; // Taster zwischen Pin und GND(invertierend)
Combie::Pin::OutputPin<3> licht;

Combie::Timer::RisingEdgeTimer  ton       { 2_sec};  // langen Tastendruck erkennen
Combie::Timer::FallingEdgeTimer kurzTimer {30_sec};  // abfallende Flanke wird verzoegert
Combie::Timer::FallingEdgeTimer langTimer {10_min};  // abfallende Flanke wird verzoegert
 
void setup(void) 
{
  taster.initPullup();
  licht.init();
}

void loop(void) 
{
  bool kurz = kurzTimer = taster; 
  bool lang = langTimer = ton = taster; 
  licht = kurz || lang;
}

So elegant wie combie bekomme ich das nicht hin, aber da ich gerade die MobaTools teste und die auch dafür geeignet sind, mache ich Dir einen Vorschlag mit dieser Bibliothek. Sie kann über die IDE installiert werden. Programm getestet mit ESP32:

/*
 * Licht im Treppenhaus steuern:
 * - nach kurzem Druck Licht kurz einschalten zum Begehen
 * - nach langem Druck Licht lange einschalten zum Treppeputzen
 * 
 * MoToButtons wird zum Entprellen eines mechanischen Tasters verwendet und zur Definition eines langen Drucks.
 * MoToTimer wird für die Brenndauer des Treppenlichts verwendet.
 */
// Zeiten in Millisekunden
const unsigned long TREPPENLICHTKURZ = 5000;
const unsigned long TREPPENLICHTLANG = 10000;
const unsigned long TASTENENTPRELLZEIT = 30;
const unsigned long TASTENDRUCKLANG = 1000;

const byte led_pin = 13;                 // Lichtrelais an Pin 13
const byte pinArray [] = { 4 };          // Lichttaster an Pin 4
const byte pinCount = sizeof(pinArray);
byte schritt = 0;

#define MAX8BUTTONS
#include <MobaTools.h>
MoToButtons Taster( pinArray, pinCount, TASTENENTPRELLZEIT, TASTENDRUCKLANG );
MoToTimer Treppenlicht;

void setup() {
  for (byte j = 0; j < pinCount; j++) {
    pinMode(pinArray[j], INPUT_PULLUP);  // Taster-Pins als Input definieren (gedrückt = LOW)
  }
  pinMode(led_pin, OUTPUT);
}

void loop() {
  Taster.processButtons();
  if (Taster.pressed(0)) {
    digitalWrite(led_pin, HIGH);
  }
  if (Taster.shortPress(0)) {
    Treppenlicht.setTime(TREPPENLICHTKURZ);
    schritt = 1;
  }
  if (Taster.longPress(0)) {
    Treppenlicht.setTime(TREPPENLICHTLANG);
    schritt = 1;
  }

  switch (schritt) {
    case 0:
      break;
    case 1:
      digitalWrite(led_pin, HIGH);
      schritt++;
      break;
    case 2:
      if (!Treppenlicht.running()) {
        schritt++;
      }
      break;
    case 3:
      digitalWrite(led_pin, LOW);
      schritt = 0;
      break;
  }
}

Die einfacheren Varianten folgen in #8 und #9.

thisone0815:
Beim kurzen Drücken, …
Beim langen Drücken, …
Wie erwähnt, habe ich keine Vorstellung, wie der Code aussehen soll. Falls jemand eine Idee hat, kann er/sie, diese gerne mit mir teilen.

Guck hier.

Gruß

Gregor

Der Sketch von agmue lässt sich auch noch etwas einkürzen :wink: :

/*
 * Licht im Treppenhaus steuern:
 * - nach kurzem Druck Licht kurz einschalten zum Begehen
 * - nach langem Druck Licht lange einschalten zum Treppeputzen
 *
 * MoToButtons wird zum Entprellen eines mechanischen Tasters verwendet und zur Definition eines langen Drucks.
 * MoToTimer wird für die Brenndauer des Treppenlichts verwendet.
 */
// Zeiten in Millisekunden
const unsigned long TREPPENLICHTKURZ = 5000;
const unsigned long TREPPENLICHTLANG = 10000;
const unsigned long TASTENENTPRELLZEIT = 30;
const unsigned long TASTENDRUCKLANG = 1000;

const byte led_pin = 13;                 // Lichtrelais an Pin 13
const byte pinArray [] = { 4 };          // Lichttaster an Pin 4
const byte pinCount = sizeof(pinArray);

#define MAX8BUTTONS
#include <MobaTools.h>
MoToButtons Taster( pinArray, pinCount, TASTENENTPRELLZEIT, TASTENDRUCKLANG );
MoToTimer Treppenlicht;

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

void loop() {
  Taster.processButtons();
  if (Taster.shortPress(0)) {
    digitalWrite(led_pin, HIGH);
    Treppenlicht.setTime(TREPPENLICHTKURZ);
  }
  if (Taster.longPress(0)) {
    digitalWrite(led_pin, HIGH);
    Treppenlicht.setTime(TREPPENLICHTLANG);
  }
  if ( Treppenlicht.expired() ) {
    digitalWrite(led_pin, LOW);
  }
}

EIn Druck während die Beleuchtung an ist, verlängert die Lauchtdauer entsprechen.

P.S. die ESP-Variante lässt sich leider noch nicht über den Bibliotheksverwalter installieren - die Ist ja noch im Test :wink:
Der Sketch läuft aber auf anderer Hardware auch mit der Bibliotheksverwalter-Variante.

Edit: Pinnummern an Kommentar angepasst

MicroBahner:
Der Sketch von agmue lässt sich auch noch etwas einkürzen :wink:

Oh wie wahr :-[

Die Methode expired() ist wie geschaffen dafür.

MicroBahner:
Ein Druck, während die Beleuchtung an ist, verlängert die Lauchtdauer entsprechend.

Nur eine Kleinigkeit, aber wenn man bei #8 den Taster drückt, geht nicht sofort das Licht an. Daher würde ich lieber die Methode pressed() anstelle shortPress() verwenden:

// https://forum.arduino.cc/index.php?topic=736616.msg4956968#msg4956968
// Licht im Treppenhaus steuern

/*
 * Licht im Treppenhaus steuern:
 * - nach kurzem Druck Licht kurz einschalten zum Begehen
 * - nach langem Druck Licht lange einschalten zum Treppeputzen
 *
 * MoToButtons wird zum Entprellen eines mechanischen Tasters verwendet und zur Definition eines langen Drucks.
 * MoToTimer wird für die Brenndauer des Treppenlichts verwendet.
 */
// Zeiten in Millisekunden
const unsigned long TREPPENLICHTKURZ = 5000;
const unsigned long TREPPENLICHTLANG = 10000;
const unsigned long TASTENENTPRELLZEIT = 30;
const unsigned long TASTENDRUCKLANG = 1000;

const byte led_pin = 13;                 // Lichtrelais an Pin 13
const byte pinArray [] = { 4 };          // Lichttaster an Pin 4
const byte pinCount = sizeof(pinArray);

#define MAX8BUTTONS
#include <MobaTools.h>
MoToButtons Taster( pinArray, pinCount, TASTENENTPRELLZEIT, TASTENDRUCKLANG );
MoToTimer Treppenlicht;

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

void loop() {
  Taster.processButtons();
  if (Taster.pressed(0)) {
    digitalWrite(led_pin, HIGH);
    Treppenlicht.setTime(TREPPENLICHTKURZ);
  }
  if (Taster.longPress(0)) {
    digitalWrite(led_pin, HIGH);
    Treppenlicht.setTime(TREPPENLICHTLANG);
  }
  if ( Treppenlicht.expired() ) {
    digitalWrite(led_pin, LOW);
  }
}

agmue:
Nur eine Kleinigkeit, aber wenn man bei #8 den Taster drückt, geht nicht sofort das Licht an.

Das ist wahr - hat aber einen Vorteil: Man erkennt sofort, wenn man lange genug für die lange Leuchtdauer gedrückt hat. Denn das Licht geht an. sobald die ‘Langdrückzeit’ erreicht ist ( oder eben wenn man vorher losgelassen hat ). Ich würde dann vielleicht auch die Zeit für’s lange drücken etwas kürzer machen. Aber das ist alles Geschmacksache und der TO kann sich aussuchen, was ihm am besten gefällt.

MicroBahner:
EIn Druck während die Beleuchtung an ist, verlängert die Lauchtdauer entsprechen.

D.h. übrigens auch, wenn man während der langen Leuchtdauer kurz drückt, wird nach der kurzen Leuchtzeit ausgeschaltet. So kann die lange Leuchtdauer bei Bedarf auch abgekürzt werden.

Hallo
Gleich mal ausprobieren wie das neue Forum tickt.
Hier kommt meine Sketch, der ohne Class-Definitionen und Bibliotheken auskommt.

String projectName {"\nTreppenhauslicht - Forum\n"};
// gestest mit Arduino UNO und Taste mit INPUT_PULLUP
const unsigned long ZeitTasteGedrueckt {5000};
const unsigned long ZeitKurzLampeAn {10000};
const unsigned long ZeitLangLampeAn {15000};
const byte TastePin {A0};
const byte LedPin {2};
struct TASTE {
  byte pin;
  bool status;
} taste {TastePin, HIGH};
struct LED {
  byte pin;
} licht {LedPin};
enum { Kurz, Lang};
enum { Taste, LeuchtDauer};
enum {Stopp};
struct ZEITGEBER {
  unsigned long stempel;
  unsigned long dauer[2];
} zeit [] {
  {Stopp, {ZeitTasteGedrueckt, 0}},
  {Stopp, {ZeitKurzLampeAn, ZeitLangLampeAn}},
};
const int heartBeat {LED_BUILTIN};
void startTimer(ZEITGEBER &zeit) {
  zeit.stempel = millis();
}
void stoppTimer(ZEITGEBER &zeit) {
  zeit.stempel = Stopp;
}
enum {NoEvent,Event};
bool eventTimer(ZEITGEBER &zeit, int dauer) {
  return ((millis() - zeit.stempel >= zeit.dauer[dauer] && zeit.stempel) ? Event : NoEvent);
}
enum {AUS,AN}; 
void lichtAnAUS(bool modus){
   digitalWrite (licht.pin, modus);
   Serial.print("Licht ");
   Serial.println(modus?"AN":"AUS\n");
}
void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode (heartBeat, OUTPUT);
  pinMode (licht.pin, OUTPUT);
  pinMode (taste.pin, INPUT_PULLUP);
  Serial.println(projectName);
}
void loop() {
  // put your main code here, to run repeatedly:
  digitalWrite(heartBeat, millis() / 500 % 2);

  static int leuchtdauer = Kurz;
  bool status = digitalRead(taste.pin);
  if (taste.status != status ) {
    taste.status = status;
    if (!status &&  digitalRead (licht.pin) ^ 1) {
      leuchtdauer = Kurz;
      startTimer(zeit [LeuchtDauer]);
      startTimer(zeit [Taste]);
      lichtAnAUS(AN);
    }
  }
  if (eventTimer(zeit[Taste], 0) ) {
    stoppTimer(zeit[Taste]);
    if (taste.status) {
      stoppTimer(zeit[Taste]);
      Serial.println("eventTimer(zeit[Taste],KURZ");
    }
    else {
      leuchtdauer = Lang;
      Serial.println("eventTimer(zeit[Taste],LANG");
    }
  }
  if (eventTimer(zeit[LeuchtDauer], leuchtdauer)) {
    stoppTimer(zeit[LeuchtDauer]);
    Serial.println("eventTimer(zeit[LeuchtDauer]");
    lichtAnAUS(AUS);
  }
}

Und nun hat der TO die Wahl. Sketch A, SketchB oder SketchC?
Der richtige Sektch wird angezeigt, wenn das Treppenlicht angeht :wink:

Hallo,
ich möchte Relais verwenden, da das Licht mit 230V läuft. Kann ich einfach anstatt die LED, das Relais anschließen?

Kommt ganz auf dein Relais drauf an.

Das sind die, die ich verwende.

Das sollte funktionieren.
Du musst nur darauf achten, dass der Ausgangspin auf LOW geschaltet werden muss, damit das Relais anzieht.

// Combie::Pin::OutputPin<3> licht; // positive Logik
Combie::Pin::InvOutputPin<3> licht; // invertierte Logik

Und die sollen für 230V geeignet sein?
Das glaube ich so erstmal nicht!

Auf der Oberseite steht

10A 250V AC
10A 30V DC

Das ist klar!
Viel spannender, als die Aufschrift, ist die Unterseite der Platine, ob da auch die in DE-Land geforderten Sicherheitsabstände eingehalten werden…

Auf der Seite ist ein CE Zeichen