2016
HOME
Arduino Rheinturmuhr mit 39 LED
Arduino-Simulator und LED-Rheinturmuhr
Arduino Rheinturmuhr auf TFT-Display
Arduino Rheinturmuhr mit TFT/DCF77-Funk
Arduino Rheinturmuhr mit TFT/GPS-Funk

Helligkeit und Farbe für die Rheinturmuhr mit Arduino und WS2812b
Rheinturmuhr mit Arduino und RGB-LED
Abbildung (Foto): Drei durchgehende Leitungen am WS2812b-LED-Band
Das Projekt "Rheinturmuhr mit Arduino" mit den 39 Leuchtdioden benutzte einzelne LED und einen Trick, um überhaupt ohne viel Aufwand diese Lichterzahl mit einem Arduino anzusteuern. Inzwischen gibt es RGB-LED und das gleich als Meterware. Für eine Hand voll Dollar - etwas über 10 Euro - bekommt man heute 60 LED pro Meter. Dabei besteht jede Leuchte aus drei LED mit den Farben Rot/Grün/Blau, sowie einem eigenen Mikrocontroller WS2812. Schieberegister sind somit überflüssig. Jede einzelne LED kann individuell gesteuert werden und dazu wird nur eine einzige Leitung benutzt, die durch das ganze Band läuft. An zwei weiteren Anschlüssen liegt 5 Volt und Masse. Da diese LED-Bänder weit verbreitet sind, gibt es entsprechende Bibliotheken für den Arduino, so dass die Umsetzung der eigenen Anwendung zum Kinderspiel werden könnte. Zu Beginn soll jedoch der Energiebedarf dieser Uhr bedacht werden. Bei voller Helligkeit aller 60 Leuchtdioden berechnet sich der Gesamtstrom zu 60 x 3 x 20 mA = 3600 mA. Das sind 3,6 A oder auch 18 Watt bei 5 Volt. Das schafft der Arduino alleine nicht!
Auf den einschlägigen Internetseiten wird darauf hingewiesen, dass zwischen Arduino und Band ein Widerstand notwendig sei und ein Kondensator parallel zur Spannungsversorgung gelegt werden muss. Auch solle die Steuerleitung zwischen Arduino und der D-Leitung am LED-Band möglichst kurz sein.

Um die Uhr eventuell tatsächlich einmal irgendwo zu benutzen, soll der kleine Arduino-Pro-Mini eingesetzt werden. Auch ohne Beschaltung macht die sehr preiswerte Platine einen sehr stilvollen Eindruck. Benötigt wird ja nur ein Digitalausgang. Um dieses kleine Gerät zu programmieren wird noch ein USB/RS232-Adapter benötigt (entfällt bei Arduino Uno usw.). Die eigenständige Uhr benötigt diesen Adapter nicht mehr. Da es sich um ein Testprojekt handelt, soll die Uhr zusätzlich via Bluetooth gestellt werden können, so dass bei einer Demonstration immer die korrekte Zeit dargestellt wird. Um später eventuell das DCF-Modul oder ein GPS-Zeitgeber einzusetzen, soll die Hauptschleife der Uhr anpassungsfreundlicher gestaltet werden als in der Urversion.

Nach etwas Internet-Suche und Analyse soll die LED-Band-Rheinturmuhr mit WS2812b nach folgenden Schritten realisiert werden:

Hier die Schritte im Detail.


Bunte Helligkeit LED-Band überprüfen und Bibliothek testen

Abbildung (Foto): Testlauf der Neopixel-Demo. Windowstablet und Arduinoprogrammierung des Mini-Pro.
Mindesten zwei bekannte Bibliotheken stehen zum Zeitpunkt des Tests bereit. Es gibt die FastLED.lib und Adafruits NeoPixel.lib. Nach kurzen Testläufen erwies sich Neopxel als schneller kompilierend und subjektiv übersichtlicher bezüglich Syntax und Programmierung. Im Quelltext gibt es viel Assembler, damit hat der Benutzer aber nichts zu tun - er kann jedoch einen ehrfurchtsvollen Blick darauf werfen.

Nach der Installation der NeoPixel-Master in die Arduino IDE 1.6.6 stehen drei Beispiele bereit. Wird das Beispiel "Simple" etwas bereinigt, so bleibt erfreulich wenig übrig, um ein paar LED zu testen. Das folgende entstandene Listing schaltet einmalig die mit mit NUMLED festgelegten ersten 8 Leuchtdioden an. Die Standard-Schleife loop() bleibt daher leer. Im Originial erfolgt die Signalausgabe über PIN 6, hier wurde jedoch am Arduino pro mini PIN 2 benutzt. Wenn das festgelegt ist, kann das Neopixel-Objekt pixel angelegt werden. Dazu erfolgt der Aufruf Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800); mit Anschluss und Anzahl, sowie einer Angabe zum Ledstreifentyp.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
#include <Adafruit_NeoPixel.h>
#define PIN            6 //2
#define NUMPIXELS      8
Adafruit_NeoPixel pixels = 
 Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);

void setup() 
{pixels.begin();
 for(int i=0;i<NUMPIXELS;i++)
  pixels.setPixelColor(i, pixels.Color(0,150,0));
 pixels.show(); 
}

void loop() 
{}

Nun folgt der einmalige Ablauf von setup(). Mit pixels.begin() wird das Objekt pixels initialisiert, entsprechend der Arduino-typischen Syntax. In der Schleife werden die ersten LED so eingestellt, dass die Farbe auf den RGB-Wert 0,150,0 gesetzt ist. Dies ist laut Adafruit ein moderates Grün. Wenn die Schleife durchlaufen wurde, erfolgt mit pixels.show() die tatsächliche Darstellung auf der Hardware.

Abbildung: Schematischer Aufbau beim ersten Test mit wenig LED (Arduino als Spannungsquelle)

Es sei darauf hingewiesen, dass der RGB-Wert der Farbübergabe direkten Einfluss auf den Stromverbrauch hat. Pro LED und Farbe entspricht der vollen Helligkeit ein Strom von 20 mA. In diesem Beispiel wären das 8 x (0/255x20 + 150/255x20 + 0/255x20) mA = 94 mA, also völlig harmlos. Bei RGB (255,255,255) sind das bei 8 LED schon 600 mA - da könnte die selbstheilende 500 mA Sicherung am Adruino Uno schon ansprechen (goldenes Bauteil unterhalb der USB-Buchse).

Falls bis hier alles geklappt hat und eine entsprechende Stromversorgung verfügbar ist, kann nun die volle bunte Vielfalt der 60 RGB-LED mittels Neopixel-Demo "strandtest.ino" probiert werden. Die obige Abbildung zeigt das Ergebnis. Aber auch auf Youtube gibt es meterlange LED-Bänder - Stichwort "WS2812".


Zeit Uhrenroutinen aus Fremdbibliotheken
Auf Arduino.cc wird unter dem Stichwort "time" auf eine neue Bibliothek verlinkt, da die alte time.h nicht mehr mit der neuen IDE 1.6.6 harmoniere. Der Link führt zur "TimeLib.h" und steht dort zum Download bereit. Das mitgelieferte Beispiel "TimeSerial.pde" soll zunächst herunter gebrochen werden, um die wesentlichen Aufrufe zu isolieren und zu testen.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <TimeLib.h>

void setup()  
{Serial.begin(9600);
 //setTime(23,59,0,1,1,2016);
}

void loop()
{digitalClockDisplay();  
 delay(1000);
}

void digitalClockDisplay()
{Serial.print(hour());
 printDigits(minute());
 printDigits(second());
 Serial.println(); 
}

void printDigits(int digits)
{Serial.print(":");
 if(digits < 10)Serial.print('0');
 Serial.print(digits);
}

Die Uhrzeit wird über die serielle Schnittstelle ausgegeben und kann im Serial-Monitor überprüft werden. Die Zeit beginnt am 1.1.1970 um 00:00 Uhr, kann aber mit setTime angepasst werden. Durch Entfernung der Kommentarzeichen (//) beginnt die Uhr, wie die alte Rheinturmuhr hier auf der Seite um 23:59:00, dabei wird das Datum nicht benutzt. In der Schleife loop() erfolgt eine Zeitabfrage mit der übernommenen Uhrzeitdarstellung digitalClockDisplay() und anschließender fester 1000 ms Wartefunktion. Die Zeitabfrage gestaltet sich mit der Bibliothek erfreulich einfach. Die Hilfsfunktion printDigits des Beispiels dient nur der Darstellung führender Nullen und ist für diese Projekt eigentlich nicht relevant.


Zusammenbau Rheinturm - Neopixel - Time
Fügt man alle Routinen zusammen und gibt noch etwas #define dazu, so entsteht das folgende Listing für die Rheinturmuhr mit RGB-LED-WS1812.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include <Adafruit_NeoPixel.h>
#include <TimeLib.h>

#define PIN           2
#define NUMPIXELS     60 //46

#define ON        Color(31,31,31) // 150 mA max for all
#define OFF       Color(1,0,0)
#define MARK      Color(15,0,0)
#define AN        pixels.ON
#define AUS       pixels.OFF
#define MARKER    pixels.MARK
#define LED(x,y)  pixels.setPixelColor(x,y)

//LEDS SEC MIN HOUR
byte oneSecond[] = {0,1,2,3,4,5,6,7,8};             //09
byte tenSecond[] = {10,11,12,13,14};                //15
byte oneMinute[] = {16,17,18,19,20,21,22,23,24};    //25
byte tenMinute[] = {26,27,28,29,30};                //31
byte oneHour[]   = {32,33,34,35,36,37,38,39,40};    //41
byte tenHour[]   = {42,43};                         //44
byte Marker[]    = {9,15,25,31,41,44,45,46};      

Adafruit_NeoPixel pixels = 
 Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);

void setup() 
{pixels.begin(); // Initialize NeoPixel library.
 for(int i=0;i<sizeof(Marker);i++)LED(Marker[i],MARKER);
 //setTime(23,59,00, 1,1,2016);
}

void loop() 
{static byte s,so=0;
 s=second();
 if(so!=s)
 {so=s;
  Rheinturmuhr();
 }
 else delay(20); 
}

void Rheinturmuhr()
{int i,s,m,h;
 int s10,s1; //TENSecond ONESecond 
 int m10,m1; //TENMinute ONESecond
 int h10,h1; //Hour ..
 s=second();m=minute();h=hour();
 s1 = s % 10; s10 = s / 10;
 m1 = m % 10; m10 = m / 10;       
 h1 = h % 10; h10 = h / 10;
 for(i=0;i<sizeof(oneSecond);i++)
 (s1 <=i?LED(oneSecond[i],AUS):LED(oneSecond[i],AN));
 for(i=0;i<sizeof(tenSecond);i++)
 (s10<=i?LED(tenSecond[i],AUS):LED(tenSecond[i],AN));
 for(i=0;i<sizeof(oneMinute);i++)
 (m1 <=i?LED(oneMinute[i],AUS):LED(oneMinute[i],AN));
 for(i=0;i<sizeof(tenMinute);i++)
 (m10<=i?LED(tenMinute[i],AUS):LED(tenMinute[i],AN));
 for(i=0;i<sizeof(oneHour);i++)
 (h1 <=i?LED(oneHour[i],AUS):LED(oneHour[i],AN)); 
 for(i=0;i<sizeof(tenHour);i++)
 (h10<=i?LED(tenHour[i],AUS):LED(tenHour[i],AN));
 pixels.show(); // showtime
}

Die Definitionen sollen den Quelltext lesbarer gestalten, da der Aufruf der Neopixel-Routinen sehr buchstabenlastig ist. So müssen die Kodezeilen zumindest im obigen Listing nicht umgebrochen werden. Zeile 7 legt den wesentlichen Stromverbrauch fest. In Wohnräumen ist die Helligkeit fast immer zu hoch. Ab Zeile 16 wird - wie im Originalquelltext - die Rheinturmstruktur in arrays festgelegt. Hier kommen die Minuten und Stunden hinzu, da ja nicht mehr umgeschaltet werden muss. Die roten Markierungen (MARKER) des Turms zwischen den einzelnen Uhrabschnitten wird bereits im setup() einmalig voreingestellt

In der Hauptschleife loop() wird alle 20 ms getestet, ob sich die Sekunde geändert hat. Falls dem so ist, wird die Rheinturmuhr() auf den neuesten Stand gebracht.

Die eigentliche Rheinturmuhr-Routine ist dem ersten Arduino-Rheinturm sehr ähnlich. Die globalen Variablen sind nun lokal angeordnet und werden in den Zeilen 49 bis 51 gefüllt. Mit dem Operator % erhält man den Rest einer Ganzzahldivision (modulo). Anschließend werden die LED alle entsprechend der Uhrzeit definiert vorbereitet und zum Schluss mit pixels.show() angezeigt.


											

											 
											

										

Synchronisierung Die richtige Uhrzeit
Die TimeLib verfügt über mehrere Möglichkeiten externe Zeitgeber einzubinden. Unter anderem kann über die serielle Schnittstelle einfach die aktuelle Zeit übergeben werden. Das Format sind die Sekunden seit dem 1.1.1970, wie in der Computerwelt üblich. Ein vorangestelltes T ist dann der so genannte Header für die TimeLib-Routine. So könnte man bei angeschlossenem PC die Zeichenkette "T1357041600" übergeben und TimeLib setzt die Zeit auf den 1.1.2013 00:00 Uhr.

Im eBook Messen und Steuern mit dem Smartphone wird beschrieben, wie die serielle Schnittstelle mit Bluetooth benutzt wird. Mit einem HC-06-Bluetooth-Modul wird der PC überflüssig und kann die aktuelle Zeit dem Arduino seriell via Bluetooth übermittelt werden. Dazu verbindet man die Dinge z.B. wie hier dargestellt:

Abbildung: Schematischer Aufbau des vorläufigen Endergebnisses.

Ein Dreizeiler auf dem Android-Phone oder Tablet in rfo-BASIC! überträgt die aktuelle Zeit des Smartphones zum Arduino und so zur Rheinturmuhr. Für Demonstrationszwecke sei das erst einmal ausrechend und vermeidet umständliche Tastenbedienung am Arduino.

Mit der Importierung der Datei "btopen.bas" wird das Bluetooth-Device HC6 gewählt. Die Funktion TIME() liefert die Zeit in Millisekunden seit dem 1.1.1970 und mit der Formatierung wird aus der Fließkommazahl eine Zeichenkette, wie sie von der TimeLib im Arduino erwartet wird. Da gerade Winter ist, wird zur UTC-Zeit noch eine Stunde (3600) dazu gerechnet und noch mal 3 Sekunden Vorsprung, um die Übertragung und den Nachgang des Arduino auszugleichen.

Die Variante mit Bluetooth-Anbindung, die wenige Zeilen aus dem TimeLib-Beispiel "TimeSerial.pde" noch hinzufügt, überträgt die aktuelle Arduinozeit zusätzlich jede Sekunde über Bluetooth seriell zur Kontrolle. Arduino-ino-Datei ab IDE 1.6.6



										

Fazit Ergebnis
Abbildung: (Foto) LED-BAND als Meterware und Rheinturmuhr.
Dank der fertigen Bibliotheken war der Aufbau ein Kinderspiel. Im Gegensatz zum ersten Rheinturmuhr-Projekt aus dem Jahr 2010 leuchten nun die Lampen gleichmäßig und hell. Zusätzlich können die Farben den persönlichen Vorlieben nach gestaltet werden. Das hier nur Rot/Weiß gewählt wurde liegt eher an der Vorlage.

Der Quelltext bleibt übersichtlich und sollte es auch gestatten eine eventuelle Synchronisierung auf eine der auch auf dieser Seite vorgestellten Methoden zu erlauben. Das einbinden eines RTC-Moduls ist weiterhin noch nicht geplant, da ein Mikrocontroller der nur eine Uhr darstellt eigentlich keinen Mikrocontroller braucht, der nur eine Uhr darstellt. Zunächst wird die Uhr nun einige Zeit laufen und dabei die Abweichung pro Tag notiert. Dann wird vielleicht diese Abweichung einmal pro Tag korrigiert, so dass wenige Sekunden pro Jahr übrig bleiben, oder so ...

Die Helligkeit und die vielfältigen Möglichkeiten laden quasi dazu ein, diese Anzeige in ein künstlerisch-ästhetisches Umfeld zu bringen, so dass eine stilvolle Zeitanzeige im Wohnbereich entsteht.


											

										

Arduino Rheinturmuhr mit 39 LED
Arduino-Simulator und LED-Rheinturmuhr
Arduino Rheinturmuhr auf TFT-Display
Arduino Rheinturmuhr mit TFT/DCF77-Funk
Arduino Rheinturmuhr mit TFT/GPS-Funk

Weitere Software
.
Startseite Bücher Software Digital RTV Musik Kontakt

Für Inhalt und weitere Verzweigung externer Links sind die Betreiber der dortigen Seiten verantwortlich - H.-J. Berndt