Eine elegante automatische Treppenbeleuchtung (Teil1)

Im ersten Teil einer neuen spannenden Reihe eine elegante automatische Treppenbeleuchtung für bis zu maximal 16 Stufen auf, bei der jede einzelne Stufe der Treppe nacheinander als Lauflicht beleuchtet wird, sobald einer der beiden Infrarotmelder, die jeweils einzeln am oberen und am unteren Ende der Treppe angebracht sind, eine Bewegung melden. Dabei wird jede einzelne Treppe dazu noch sanft per PWM Steuerung auf die maximale Helligkeit hochgedimmt und später bis um erlöschen wieder heruntergedimmt. Der Zeiträume, in der die Treppe eingeschaltet bleibt, oder die eine Stufe herauf- oder herabdimmt ist dabei frei im Sketch nach eigenem Belieben einstellbar. Eine solche Lösung gibt es bereits schon kommerziell (hier im Video im Betrieb zu sehen).

Heute zeige ich, wie man eine in der Funktion ähnliche Steuerung mithilfe des Arduinos und einiger externen Bauteilen selbst bauen kann.

 

Wir brauchen für unsere do-it-yourself Treppenbeleuchtung folgende Elektronik-Teile:

 

Anzahl

Beschreibung

Anmerkung

2

PIR Modul HC-SR501 PIR

Bewegungssensor

1

PCA9685 16 Kanal 12 Bit PWM Driver

 

1

Nano V3

 

1

MB102 Netzteil Adapter

Für Breadboardaufbau

bis 16

IRF520 MOS Driver Modul 0-24V 5A

Anzahl je nach Treppenzahl

1

Netzteil für LED/Lampen für die Stufen

Maximal 24 Volt

 

Im folgenden Schaltplan ist die Kernsteuerung zu sehen. Exemplarisch sind jedoch nur 2 Treiberstufen der maximal möglichen 16 Treiberstufen zu sehen. Falls mehr Treiberstufen benötigt werden, werden diese sinngemäß wie die beiden eingezeichneten angeschlossen. Zu beachten ist unbedingt eine sicherheitsgerechte Verwendung von Stromkabeln und Leitungen sowie ein ausreichend dimensioniertes Netzteil. Das Netzteil muss Überlast geschützt sein und alle Treppenstufenlichter und den Arduino mit stabilisierter Gleichspannung versorgen können ohne überlastet zu werden! Es besteht Brandgefahr bei nicht sachgerechtem Einbau und/oder Betrieb!

 

Wir bauen die Schaltung für unsere Treppe wie folgt auf einem Breadboard zum testen auf:

 

Aufbau auf Steckbrett

 

Im nächsten Schritt passen wir den Quellcode des Arduinos an die eigenen Bedürfnisse an. Interessant sind die folgenden 3 Zeilen im Code:

#define Num_Stages 15
#define Delay_Stages 10
#define Delay_ON_to_OFF 5

 

Num_Stages

Definiert die Anzahl der zu beleuchtenden Treppen (maximal 16, von 0 anzählend zu beginnen. Maximalwert: 15)

Delay_Stages

Fade Zeitraum für jede Treppenstufe -> je kleiner der Wert desto größer der Zeitraum, desto langsamer.

Delay_ON_to_OFF

Zeitraum der vergeht indem die Treppe im Status „an“ verbleibt.

 

Nachdem wir die werte den eigenen Vorlieben angepasst habe, kann der Code auf den Arduino hochgeladen werden :

 

 

// 2019 Tobias Kuch GPL 3.0
#include <Wire.h>

#define PWM_Module_Base_Addr 0x40 //10000000b  Das letzte Bit des Adressbytes definiert die auszuführende Operation. Bei Einstellung auf logisch 1  0x41 Modul 2
//wird ein Lesevorgang auswählt, während eine logische 0 eine Schreiboperation auswählt.
#define OE_Pin  8           // Pin für Output Enable
#define PIRA_Pin 2
#define PIRB_Pin 3

#define Num_Stages  15
#define Delay_Stages  10
#define Delay_ON_to_OFF  30  // Minimum Delay_ON_to_OFF in Seconds

byte Pwm_Channel = 0;
int Pwm_Channel_Brightness = 0;

bool Motion_Trigger_Down_to_Up = false;
bool On_Delay = false;

// interrupt Control
byte A60telSeconds24 = 0;
byte Seconds24;

ISR(TIMER1_COMPA_vect)
{
  A60telSeconds24++;
  if (A60telSeconds24 > 59)
  {
    A60telSeconds24 = 0;
    Seconds24++;
    if (Seconds24 > 150)
    {
      Seconds24 = 0;
    }
  }
}

void ISR_PIR_A()
{
  bool PinState = digitalRead(PIRA_Pin);
  if (PinState)
  {
    Motion_Trigger_Down_to_Up = true; // PIR A ausgelöst
  }
}

void ISR_PIR_B()
{
  bool PinState = digitalRead(PIRB_Pin);
  if (PinState)
  {
    Motion_Trigger_Down_to_Up = true; // PIR B ausgelöst
  }
}

void Init_PWM_Module(byte PWM_ModuleAddr)
{
  pinMode(OE_Pin, OUTPUT);
  digitalWrite(OE_Pin, HIGH); // Active LOW-Ausgangsaktivierungs-Pin (OE).
  Wire.beginTransmission(PWM_ModuleAddr); // Datentransfer initiieren
  Wire.write(0x01);                       // Wähle  Mode 2 Register (Command Register)
  Wire.write(0x04);                       // Konfiguriere Chip: 0x04:  totem pole Ausgang 0x00: Open drain Ausgang.
  Wire.endTransmission();                 // Stoppe Kommunikation - Sende Stop Bit
  Wire.beginTransmission(PWM_ModuleAddr); // Datentransfer initiieren
  Wire.write(0x00);                      // Wähle Mode 1 Register (Command Register)
  Wire.write(0x10);                      // Konfiguriere SleepMode
  Wire.endTransmission();                // Stoppe Kommunikation - Sende Stop Bit
  Wire.beginTransmission(PWM_ModuleAddr); // Datentransfer initiieren
  Wire.write(0xFE);                       // Wähle PRE_SCALE register (Command Register)
  Wire.write(0x03);                       // Set Prescaler. Die maximale PWM Frequent ist 1526 Hz wenn das PRE_SCALEer Regsiter auf "0x03h" gesetzt wird. Standard : 200 Hz
  Wire.endTransmission();                 // Stoppe Kommunikation - Sende Stop Bit
  Wire.beginTransmission(PWM_ModuleAddr); // Datentransfer initiieren
  Wire.write(0x00);                       // Wähle Mode 1 Register (Command Register)
  Wire.write(0xA1);                       // Konfiguriere Chip:  ERrlaube All Call I2C Adressen, verwende interne Uhr,                                           // Erlaube Auto Increment Feature
  Wire.endTransmission();                 // Stoppe Kommunikation - Sende Stop Bit
}


void Init_PWM_Outputs(byte PWM_ModuleAddr)
{
  digitalWrite(OE_Pin, HIGH); // Active LOW-Ausgangsaktivierungs-Pin (OE).
  for ( int z = 0; z < 16 + 1; z++)
  {
    Wire.beginTransmission(PWM_ModuleAddr);
    Wire.write(z * 4 + 6);      // Wähle PWM_Channel_ON_L register
    Wire.write(0x00);                     // Wert für o.g. Register
    Wire.endTransmission();
    Wire.beginTransmission(PWM_ModuleAddr);
    Wire.write(z * 4 + 7);      // Wähle PWM_Channel_ON_H register
    Wire.write(0x00);                     // Wert für o.g. Register
    Wire.endTransmission();
    Wire.beginTransmission(PWM_ModuleAddr);
    Wire.write(z * 4 + 8);   // Wähle PWM_Channel_OFF_L register
    Wire.write(0x00);        // Wert für o.g. Register
    Wire.endTransmission();
    Wire.beginTransmission(PWM_ModuleAddr);
    Wire.write(z * 4 + 9);  // Wähle PWM_Channel_OFF_H register
    Wire.write(0x00);             // Wert für o.g. Register
    Wire.endTransmission();
  }
  digitalWrite(OE_Pin, LOW); // Active LOW-Ausgangsaktivierungs-Pin (OE).
}

void setup()
{
  //Initalisierung
  pinMode(PIRA_Pin, INPUT);
  pinMode(PIRB_Pin, INPUT);
  Serial.begin(9600);
  Wire.begin(); // Initalisiere I2C Bus A4 (SDA), A5 (SCL)
  Init_PWM_Module(PWM_Module_Base_Addr);
  Init_PWM_Outputs(PWM_Module_Base_Addr);
  noInterrupts();
  attachInterrupt(0, ISR_PIR_A, CHANGE);
  attachInterrupt(1, ISR_PIR_B, CHANGE);
  TCCR1A = 0x00;
  TCCR1B = 0x02;
  TCNT1 = 0;      // Register mit 0 initialisieren
  OCR1A =  33353;      // Output Compare Register vorbelegen
  TIMSK1 |= (1 << OCIE1A);  // Timer Compare Interrupt aktivieren
  interrupts();
}

void Down_to_Up_ON()
{
  Pwm_Channel = 0;
  Pwm_Channel_Brightness = 0;
  while (Pwm_Channel < Num_Stages + 1)
  {
    Wire.beginTransmission( PWM_Module_Base_Addr);
    Wire.write(Pwm_Channel * 4 + 8);   // Wähle PWM_Channel_0_OFF_L register
    Wire.write((byte)Pwm_Channel_Brightness & 0xFF);        // Wert für o.g. Register
    Wire.endTransmission();
    Wire.beginTransmission( PWM_Module_Base_Addr);
    Wire.write(Pwm_Channel * 4 + 9);  // Wähle PWM_Channel_0_OFF_H register
    Wire.write((Pwm_Channel_Brightness >> 8));             // Wert für o.g. Register
    Wire.endTransmission();
    if (Pwm_Channel_Brightness < 4095)
    {
      Pwm_Channel_Brightness = Pwm_Channel_Brightness + Delay_Stages;
      if (Pwm_Channel_Brightness > 4095) {
        Pwm_Channel_Brightness = 4095;
      }
    } else if ( Pwm_Channel < Num_Stages + 1)
    {
      Pwm_Channel_Brightness = 0;
      delay(200);
      Pwm_Channel++;
    }

  }
}

void Down_to_Up_OFF()
{
  Pwm_Channel = 0;
  Pwm_Channel_Brightness = 4095;
  while (Pwm_Channel < Num_Stages + 1)
  {
    Wire.beginTransmission( PWM_Module_Base_Addr);
    Wire.write(Pwm_Channel * 4 + 8);   // Wähle PWM_Channel_0_OFF_L register
    Wire.write((byte)Pwm_Channel_Brightness & 0xFF);        // Wert für o.g. Register
    Wire.endTransmission();
    Wire.beginTransmission( PWM_Module_Base_Addr);
    Wire.write(Pwm_Channel * 4 + 9);  // Wähle PWM_Channel_0_OFF_H register
    Wire.write((Pwm_Channel_Brightness >> 8));             // Wert für o.g. Register
    Wire.endTransmission();
    if (Pwm_Channel_Brightness > 0)
    {
      Pwm_Channel_Brightness = Pwm_Channel_Brightness - Delay_Stages;
      if (Pwm_Channel_Brightness < 0) {
        Pwm_Channel_Brightness = 0;
      }
    } else if ( Pwm_Channel < Num_Stages + 1)
    {
      Pwm_Channel_Brightness = 4095;
      delay(200);
      Pwm_Channel++;
    }

  }
}

void loop() {
  if ((Motion_Trigger_Down_to_Up) and !(On_Delay))
  {
    Seconds24 = 0;
    On_Delay = true;
    Down_to_Up_ON();
    Motion_Trigger_Down_to_Up = false;
  }
  if ((On_Delay) and  (Seconds24 > Delay_ON_to_OFF))
  {
    Motion_Trigger_Down_to_Up = false;
    On_Delay = false;
    Down_to_Up_OFF();
  }
}

 

 

Ich wünsche viel Spaß beim Nachbauen dieses Projektes und bis zum nächsten Teil.

 

 

 

 

13 Kommentare

Helmut Tack

Helmut Tack

Zunächst, tolles Projekt. Ich habe mich schon an einem Projekt eines anderen Entwicklers heran getraut, aber die von ihm implementierte 220V Abschaltung mit Relais funktioniert nicht wirklich. Irgendwas am Quellcode ist da im Argen. Hilfe, wie so oft, der Fehler sitz vor der Tastatur. Da ich nicht gerne in anderen Codes herumkrame, habe ich mit Freuden dieses Projekt gefunden.
1. Frage : Brauch ich für 10 SDufen 10 PCA9685 16 Kanal 12 Bit PWM Driver oder nur einen?
2. Frage : Kann der Code um eine 220V Stromabschaltung per Relais erweitert werden. Wäre der Sicherheits- un d Umweltgedanke.
Ich werde das Projekt mal umsetzen und sehen, ob ich wieder (wie beim Mitbewerber) die Materialien und die Zeit in die “Tonne kloppe”
Das Projekt ist für einen lieben Menschen gedacht, dessen sehfähigkeit im Dunkeln gleich Null ist. Damit er noch lange sein Schlafzimmer im Obergeschoss des Hauses nutzen kann, will ich eine soche LED Beleuctung implementieren.
Liebe Grüße und schon mal danke für die Antwort, gerne auch per Mail.

Tobias

Tobias

Ich kann Wolfgang nur zustimmen. Bitte beachtet im eigenen Interesse alle Sicherheitsbestimmungen, VDE Bestimmungen, im Text genannte Hinweise und natürlich auf eine sichere und saubere Verlegung der Kabel.

Tobias

Tobias

Ich kann Wolfgang nur zustimmen. Bitte beachtet im eigenen Interesse alle Sicherheitsbestimmungen, VDE Bestimmungen, im Text genannte Hinweise und natürlich auf eine sichere und saubere Verlegung der Kabel.

Wolfgang

Wolfgang

Die Idee finde ich toll und ein Anstoß für das Zusammenwirken von Komponenten (auch für andere Projekte.
Aber:
Das Zusammenwirken von Steuerungen mit Lichtstrom (Netzstrom) ist eine echte Herausforderung, weil in unserer technischen Welt alles diesbezüglich mit Sicherheitsvorschriften geregelt ist, deren Nichtbeachtung fatale Folgen haben kann. In diesem Falle trifft die VDE für Kleinspannungen zu. Damit meine ich nicht die ARDUINO Steuerung sondern die Leistungssteuerung. Deswegen unterstütze ich die Kommentare meiner Vorgänger, die Beleuchtung auf LED im Kleinleistungsbereich (<5W) gegenüber X* max ca.100W vorschlagen. Abgesehen von der Wärmeentwicklung. Bei allen Projekten sollte auch die “Klimaverträglichkeit” mitspielen. Etwas, woran sich die “Maker-Szene” heran tasten sollte.

In einigen Kommentaren war die Aktivierung mit Lichtempfindlichkeit angesprochen: Die PIR Module haben 2 Einstellungen: Pulslänge bei Aktivierung und Umgebungshelligkeit.

Im Rettungsdienst sind wir immer wieder mit Verunglückten konfrontiert, die auf Treppen stürzen. Kabel sind nicht selten dabei ein Grund. Bitte, im eigenen Interesse, wenige Kabel und sichere Verlegung, gerade bei Stiegen und Treppen!

Udo Schulz

Udo Schulz

Es wäre schön, wenn die Lampen , wenn man oben an der Treppe ist, von oben nach unten angehen und wenn man unten ist, von unten nach oben angehen und entsprechend auch ausgehen.

Tobias

Tobias

vielen Dank für die ganze positive Rückmeldung ! Das Projekt kann ganz einfach auch mit LED Streifen ohne Änderung der Schaltung oder des Codes verwendet werden. Einfach an den Ausgang ein LED Streifen hängen, das wars..

Tim

Tim

Hallo
Ich bekomme nur Fehlermeldungen beim Kompilieren.
Arduino: 1.8.10 (Windows 10), Board: “Arduino Nano, ATmega328P”

treppenlicht1:58:16: error: expected primary-expression before ‘,’ token

pinMode(OE_Pin8, OUTPUT); ^

treppenlicht1:59:21: error: expected primary-expression before ‘,’ token

digitalWrite(OE_Pin8, HIGH); // Active LOW-Ausgangsaktivierungs-Pin (OE). ^

C:\Users\frogg\Documents\Arduino\treppenlicht1\treppenlicht1.ino: In function ‘void Init_PWM_Outputs(byte)’:

treppenlicht1:81:21: error: expected primary-expression before ‘,’ token

digitalWrite(OE_Pin8, HIGH); // Active LOW-Ausgangsaktivierungs-Pin (OE). ^

treppenlicht1:101:21: error: expected primary-expression before ‘,’ token

digitalWrite(OE_Pin8, LOW); // Active LOW-Ausgangsaktivierungs-Pin (OE). ^

C:\Users\frogg\Documents\Arduino\treppenlicht1\treppenlicht1.ino: In function ‘void Down_to_Up_ON()’:

treppenlicht1:128:22: error: ‘Num_Stages’ was not declared in this scope

while (Pwm_Channel < Num_Stages + 1) ^~~~~~~~~~

C:\Users\frogg\Documents\Arduino\treppenlicht1\treppenlicht1.ino:128:22: note: suggested alternative: ‘Num_Stages15’

while (Pwm_Channel < Num_Stages + 1) ^~~~~~~~~~ Num_Stages15

treppenlicht1:140:51: error: ‘Delay_Stages’ was not declared in this scope

Pwm_Channel_Brightness = Pwm_Channel_Brightness + Delay_Stages; ^~~~~~~~~~~~

C:\Users\frogg\Documents\Arduino\treppenlicht1\treppenlicht1.ino:140:51: note: suggested alternative: ‘Delay_Stages10’

Pwm_Channel_Brightness = Pwm_Channel_Brightness + Delay_Stages; ^~~~~~~~~~~~ Delay_Stages10

C:\Users\frogg\Documents\Arduino\treppenlicht1\treppenlicht1.ino: In function ‘void Down_to_Up_OFF()’:

treppenlicht1:158:22: error: ‘Num_Stages’ was not declared in this scope

while (Pwm_Channel < Num_Stages + 1) ^~~~~~~~~~

C:\Users\frogg\Documents\Arduino\treppenlicht1\treppenlicht1.ino:158:22: note: suggested alternative: ‘Num_Stages15’

while (Pwm_Channel < Num_Stages + 1) ^~~~~~~~~~ Num_Stages15

treppenlicht1:170:51: error: ‘Delay_Stages’ was not declared in this scope

Pwm_Channel_Brightness = Pwm_Channel_Brightness – Delay_Stages; ^~~~~~~~~~~~

C:\Users\frogg\Documents\Arduino\treppenlicht1\treppenlicht1.ino:170:51: note: suggested alternative: ‘Delay_Stages10’

Pwm_Channel_Brightness = Pwm_Channel_Brightness – Delay_Stages; ^~~~~~~~~~~~ Delay_Stages10

C:\Users\frogg\Documents\Arduino\treppenlicht1\treppenlicht1.ino: In function ‘void loop()’:

treppenlicht1:192:32: error: ‘Delay_ON_to_OFF’ was not declared in this scope

if ((On_Delay) and(Seconds24 > Delay_ON_to_OFF)) ^~~~~~~~~~~~~~~

C:\Users\frogg\Documents\Arduino\treppenlicht1\treppenlicht1.ino:192:32: note: suggested alternative: ‘Delay_ON_to_OFF30’

if ((On_Delay) and(Seconds24 > Delay_ON_to_OFF)) ^~~~~~~~~~~~~~~ Delay_ON_to_OFF30

Mehrere Bibliotheken wurden für “Wire.h” gefunden
Benutzt:
expected primary-expression before ‘,’ token

Diddi

Diddi

Das Projekt finde ich sehr gelungen, aber es fehlt noch ein Lichtsensor um bei Tageslicht nicht unnötig Strom zu verbrauchen.
Ein Kombisensor wäre die ideale Ergänzung.

Andreas

Andreas

Ich kann Mustafa Sari nur zustimmen, eine Umsetzung mit LED wäre super.

HJThom

HJThom

Hallo zusammen, ich finde das Thema auch total spannend. Direkt habe ich mir den Aufbau mal angeschaut und stellte mir wie Mustafa die Frage, warum das Geraffel wenn man das Ganze auch mitWS2812B realisieren kann? Die Möglichkeiten sind hier vielfältiger. Die HC-SR501 sind mir persönlich zu großflächig und somit ungenau aber das ist je nach Anwendung verschieden, ich würde auf eine Lichtschranke setzten. Ich verfolge das Thema mal weiter.

Danke und Gruß
HJThom

Dirk

Dirk

ein toller Sketch den ich ähnlich auch bei YouTube gesehen habe. Was mir fehlt sind ein paar Erklärungen um den Sketch nachvollziehen zu können. Ich werde es auf jeden Fall bauen uns ausprobieren.

Stephan Strittmatter

Stephan Strittmatter

Tolles Projekt! Ich kann mich da nur anschließen: ich fände eine Variante mit LED-Streifen auch super finden!
Ich bin gespannt.

Mustafa sari

Mustafa sari

Hi es wäre super, wenn ihr die Beleuchtung mal mit dem LED Streifen umsetzt.
Ich hatte schon lange überlegt ein Lauflicht pro Stufe zu realisieren und ich glaube das würde den meisten auch gefallen.
Über das PWM kann man die einzelnen Stufen dann nach und nach immer heller werden lassen.

Einen Kommentar hinterlassen

Alle Kommentare werden vor der Veröffentlichung moderiert