Sonntag, 27. Dezember 2020

Lampensteuerung mit Tastern

Die nächste Bastelidee ist eine Beleuchtungssteuerung, die Lampen, LEDs oder LED-Streifen ein- und ausschaltet. Da die Steuerung mittels eines Arduino Nano erfolgt, kann man auch diverse Funktionen programmieren, die - wenn überhaupt! - nur mit recht hohem Aufwand an Denkleistung und Bauteilen als diskrete Schaltung realisierbar wäre. Da die Schaltung die Beleuchtung meines Wohnzimmers steuert, ist sie auf meine speziellen Bedürfnisse zugeschnitten. Es gibt drei Deckenleuchten, die einzeln an- oder abgeschaltet werden können, mit einem separaten Zentraltaster aber auch alle zusammen geschaltet werden können. Leuchten einer oder mehrere der drei LED-Streifen, schaltet ein Druck auf den Zentraltaster sie aus. Sind alle drei aus, werden sie bei Betätigung des Zentraltasters alle drei eingeschaltet. Des weiteren habe ich noch eine Beleuchtung unter meinem Multifunktionstisch, die ich benötige, um Staubsaugen oder Wartungsarbeiten am PC nicht im Dunkeln durchführen zu müssen, und einen Flächenstrahler, der variabel über meinem Arbeitstisch hängt, und für Bastelarbeiten, Fotosessions oder Videoaufnahmen die Arbeitsfläche ausleuchtet. Nachdem nun jedem klar sein sollte, um was es konkret geht, kommen wir ohne weiteres Gelabere zur Sache.


Die Schaltung



Lampensteuerung mit Tastern


Der Schaltplan der Steuerung ist recht simpel gestrickt. Da Google das mit dem Skalieren von Bildern eher schlecht als recht auf die Reihe bekommt, empfehle ich, den Schaltplan über den Link herunterzuladen und auszudrucken...

Man benötigt für meine Version der Schaltung einen Arduino Nano, sechs Taster, sechs Widerstände mit jeweils zehn Kiloohm, fünf Power-MOSFETs (ich verwende meinen Standardtyp IRFZ44N) und fünf (oder mehr...) Leuchtmittel mit einer Nennspannung von 12 Volt. Sparschwaben dürfen gern die 5 Cent für die sechs Widerstände einsparen, und die sechs Eingangspins explizit als INPUT_PULLUP deklarieren. Da mein Code die Eingangspins über trgX.attach(PinZuordnung.INPUT) definiert, kann ich allerdings nicht garantieren, dass das funktioniert. In meiner Schaltung liegen die Eingänge normalerweise auf 5 Volt und werden beim Betätigen des entsprechenden Tasters auf Null Volt gezogen. Die verwendete Funktion trgX.fell() reagiert auf diese Änderung, und die Auswertelogik schaltet dann entsprechend die Leuchtmittel ein oder aus. Mehr ist zur Schaltung nicht anzumerken.


Der Quellcode


Herunterladen kann man den Quellcode hier. Es handelt sich um eine *.ino-Datei, die man in einen gleichnamigen Ordner packen sollte, um sie aus der Arduino-IDE heraus starten zu können. Alternativ dazu kann man die Datei auch im Herunterladungs-Ordner per Doppelklick "starten" - die Arduino-IDE poppt dann auf und fragt, ob sie einen Projektordner gleichen Namens anlegen soll. Nach der Bestätigung ist man am gleichen Punkt, an dem man nach manuellem Anlegen des Ordners wäre. Sollte die Arduino-IDE beim ersten Kompilierversuch die Bounce2.h nicht finden, ist es an der Zeit, die Bounce2-Bibliothek zu installieren. Das geschieht durch Ausklappen des Menüs Werkzeuge und Klick auf den Menüpunkt Bibliotheken verwalten. Ganz oben ist neben den zwei Ausklappkästchen auf der rechten Seite ein Eingabefeld, in das man Bounce2 eingibt. Nach kurzer Suche im Internet zeigt der Dialog nun alle Bibliotheken an, die den Suchbegriff enthalten. Suchen Sie Bounce2 und installieren Sie die Bibliothek. Fertig!


Definitionen


In den ersten beiden Blöcken werden Namenszuweisungen für die verwendeten Pins festgelegt, im dritten Block werden die Variablen für die Schaltzustände der einzelnen Leuchtmittel definiert und auf Null (LOW) gesetzt, der letzte Block weist sechs Instanzen der Klasse Bounce Namen zu und initialisiert sie.
#include <Bounce2.h>

#define LB0    2               /* Taster        1   D2     hinten  */
#define LB1    3               /*               2   D3     Mitte   */
#define LB2    4               /*               3   D4     vorne   */
#define LB3    5               /*               4   D5     alle    */
#define LB4    6               /*               5   D6     oben    */
#define LB5    7               /*               6   D7     unten   */

#define LS0    8               /* Leuchtmittel  1   D8     hinten  */
#define LS1    9               /*               2   D9     Mitte   */
#define LS2   10               /*               3   D10    vorne   */
#define LS3   11               /*               4   D11    oben    */
#define LS4   12               /*               5   D12    unten   */

int    out0 = LOW;             /* Leuchtmittel  1 anfänglich AUS   */
int    out1 = LOW;             /*               2                  */
int    out2 = LOW;             /*               3                  */
int    out3 = LOW;             /*               4                  */
int    out4 = LOW;             /*               5                  */

Bounce trg0 = Bounce();        /* merkwürdiges C++ Zeug...         */
Bounce trg1 = Bounce();
Bounce trg2 = Bounce();
Bounce trg3 = Bounce();
Bounce trg4 = Bounce();
Bounce trg5 = Bounce();

Setup()


Im Setup()-Teil werden die zuvor definierten Instanzen der Bounce-Klasse den zuvor definierten Pins des Arduino zugewiesen. Danach wird für jeden Taster die Entprellzeit in Millisekunden festgelegt, die 75 ms reichen aus, um selbst stark prellende Taster zuverlässig zu entprellen. Anschließend werden die Ausgangspins zugeordnet, bevor zum Abschluss alle Leuchtmittel ausgeschaltet werden. Mehr muss im Setup nicht erledigt werden.
void setup()
{
 trg0.attach(LB0, INPUT);      /* merkwürdiges C++ Zeug...         */
 trg1.attach(LB1, INPUT);
 trg2.attach(LB2, INPUT);
 trg3.attach(LB3, INPUT);
 trg4.attach(LB4, INPUT);
 trg5.attach(LB5, INPUT);
 trg0.interval(75);            /* Entprellzeiten                   */
 trg1.interval(75);
 trg2.interval(75);
 trg3.interval(75);
 trg4.interval(75);
 trg5.interval(75);
 pinMode(LS0, OUTPUT);         /* Ausgangspins festlegen           */
 pinMode(LS1, OUTPUT);
 pinMode(LS2, OUTPUT);
 pinMode(LS3, OUTPUT);
 pinMode(LS4, OUTPUT);
 digitalWrite(LS0, out0);      /* alle Leuchtmittel aus            */
 digitalWrite(LS1, out1);
 digitalWrite(LS2, out2);
 digitalWrite(LS3, out3);
 digitalWrite(LS4, out4);
}

Endlosschleife


in der loop()-Funktion, die nach dem Setup in einer Endlosschleife ausgeführt wird, ist die komplette Steuerlogik daheim. Zuerst werden die aktuellen Zustände der Taster abgefragt:
 trg0.update();
 trg1.update();
 trg2.update();
 trg3.update();
 trg4.update();
 trg5.update();
Anschließend werden - entsprechend den anfangs geschilderten Vorgaben - die Leuchtmittel entsprechend ein- oder ausgeschaltet. Um ein beliebiges Leuchtmittel ein- oder auszuschalten, genügt der folgende Code:
 if(trgX.fell())
 {
  outX = !outX;
 }
Wurde Taster X betätigt, wird der Ausgang in seinen anderen Zustand - aus HIGH wird LOW, aus LOW wird HIGH - umgeschaltet. Diese Funktion muss für jeden Taster und das zugeordnete Leuchtmittel vorhanden sein. Nutzt man die analogen Eingänge A0 bis A5 (A6 und A7 sind beim Nano ausschließlich analog nutzbar!) als digitale Eingänge, kann der Nano bis zu 9 Taster mit 9 zugeordneten Leuchtmitteln verwalten. Für den Zentraltaster, der mehrere Leuchtmittel gemeinsam schaltet, wird der folgende Code verwendet:
 if(trg3.fell())
 {
  if(out0 || out1 || out2 || out3 || out4)
  {
   out0 = 0;
   out1 = 0;
   out2 = 0;
   out3 = 0;
   out4 = 0;
  }
  else
  {
   out0 = 1;
   out1 = 1;
   out2 = 1;
  }
 }
Man beachte hier, dass trg3 ein tatsächlich vorhandener Taster ist, der auf dem Schaltpult neben den Tastern für die anderen Leuchtmittel sitzt. Es ist aber der einzige Taster, dem mehr als ein Leuchtmittel zugeordnet ist. Die Logik ermittelt zuerst einmal, ob irgendein Leuchtmittel eingeschaltet ist. Sind alle aus, werden alle drei Hauptleuchtmittel eingeschaltet. Leuchtet mindestens eines, werden alle fünf Leuchtmittel ausgeschaltet. Wenn man ein wenig mit der Logik herumspielt, kann man mit etwas mehr Code auch wesentlich komplexere Schaltvorgänge programmieren. Sind alle Zustände analysiert und der Logik entsprechend gesetzt, müssen die Änderungen der Variablen noch an die Ausgänge weitergegeben werden:
 digitalWrite(LS0, out0);
 digitalWrite(LS1, out1);
 digitalWrite(LS2, out2);
 digitalWrite(LS3, out3);
 digitalWrite(LS4, out4);
Damit sind alle Aufgaben abgearbeitet und der Arduino beginnt einmal mehr, die loop()-Funktion auszuführen.


Fazit


Auf meinem YouTube-Kanal kann man sich die Beleuchtungssteuerung in Aktion anschauen. Ich hoffe, ich konnte ein wenig dazu beitragen, die Grundlagen der in Programmen verwendeten Logik aufzuzeigen und Interesse am Programmieren zu wecken. Ach ja - die Kommentarfunktion bei YouTube und auf meinen Blogs ist moderiert. Da ich die Benutzerschnittstelle von G-mail nicht ausstehen kann, schaue ich recht selten dort vorbei, sodass sich die Freigabe von Kommentaren extrem verzögern kann. Wirklich wichtige Rückfragen daher bitte per E-mail.

Abschließend noch eine kleine Bildergalerie:











Keine Kommentare:

Kommentar veröffentlichen