NeLiS - Die Netzwerk-Lichtsteuerung

Die NeLiS ist bislang eines meiner größten privaten Bastelprojekte, an dem ich gut dreieinhalb Jahre (natürlich nicht ununterbrochen) gearbeitet habe. NeLiS ist eine Netzwerk-Lichtsteuerung (daher die Kurzbezeichnung), mit der man RGB(W)-LED-Streifen betreiben kann. Die Steuerung kann per Taster am Gerät oder auch über einen integrierten Webserver erfolgen, ist also drahtlos über jedes Gerät mit Browser (Smartphone, PC, Tablet ...) möglich.

NeLiS in Aktion

NeLiS war bisher nicht nur das zeitlich umfangreichste Projekt, sondern auch das kompletteste: vom Schaltungsentwurf, Layout, Software, Dokumentation bis hin zum Gehäusedesign und Herstellung mittels 3D-Drucker war wirklich alles mit dabei. Der TCP/IP-Netzwerkstack, der im Controller werkelt, ist quasi komplett selbst geschrieben; das war ein Ar*** voll Arbeit, hatte aber einen großen Lerneffekt zur Folge und außerdem den Vorteil, dass der Stack so ist, wie ich ihn haben wollte - dazu später mehr.

NeLiS im Gehäuse

Entstehungsgeschichte

Alles begann, als mich Anfang November 2012 eine Mail hier über die Webseite und das Kontaktformular erreichte. Sie kam von Peter, einem Bastler aus Ludwigsburg, der gerne meine DCF Nixie-Clock nachbauen wollte und dazu ein paar Fragen hatte. So kamen wir nach und nach ins Gespräch und ins fachsimpeln, und aus dem Kontakt ist mit der Zeit eine Bastlerfreundschaft geworden. Quasi ein Zwei-Mann-Hackerspace. Ein knappes Jahr später, im September 2013, kam die Idee zu einem gemeinsamen Projekt auf: NeMo.

NeMo, der Bruder von NeLiS

Den Begriff "NeMo" werdet ihr hier und in den Dokus öfter lesen, NeMo steht für "Netzwerk-Modul" und ist quasi der Bruder meiner NeLiS. Den NeMo haben wir zuerst entwickelt, als Hardware-Basis diente anfangs das AVR-Net-I/O von Pollin, auf dem wir die erste Software geschrieben haben. Nachdem die Software soweit gediehen war, haben wir unsere jeweilige Hardware erstellt und die Software dafür angepasst. Beiden gemeinsam ist also im Kern der "NeMo-Stack", doch während Peter mit dem NeMo (siehe Bild) eine kleine Hausautomatisierungs-Zentrale drum herum gebaut hat, hab ich mich dazu entschlossen, daraus die NeLiS werden zu lassen.

Features

Mit der NeLiS können RGB- oder RGBW-LED-Stripes (RGBW: mit zusätzlichen weißen LEDs, für ein "echtes" Weiß) angesteuert werden, welche mit 12V oder 24V und gemeinsamer Anode arbeiten. Im Speicher können 16 Licht-Programme abgelegt werden, die aus jeweils bis zu 248 Befehlen (Farbe setzen, Pause, Farbwechsel) bestehen können. Das sollte genug Raum für sämtliche Eventualitäten und Stimmungslagen bieten :-)

Die Steuerung ist wie schon erwähnt über Taster direkt am Gerät, als auch über einen integrierten Webserver möglich. Dazu muss die NeLiS nur mit dem Netzwerk verbunden werden und mit einem internetfähigen Gerät ein Browser mit der IP-Adresse der NeLiS geöffnet werden. Das Ganze sieht dann etwa so aus:

Die Weboberfläche der NeLiS

Über die Buttons können direkt die programmierten Lichtprogramme aufgerufen werden. Auf die Bedienung und die Einrichtung will ich hier gar nicht näher eingehen, dafür gibt es eine eigene kleine Bedienungsanleitung im PDF-Format, die ihr euch hier ansehen könnt.

Hardware

Die erste Hardwareversion (V1.0, blaue Platine) enthielt noch einen Fehler im Anschluss der Netzwerkbuchse, so dass es bereits eine erste Revision gibt (V1.1, schwarze Platine). Die Revision enthält auch die drei Taster, welche bei der ersten Version noch nicht vorhanden waren. Hier könnt ihr euch den Schaltplan der aktuellen NeLiS V1.1 ansehen. Seite 1 enthält nur die Übersicht, los geht's auf Seite 2 mit dem Controller und der Peripherie.

Controller und Peripherie

Als Controller habe ich einen ATmega1281 ausgewählt, da dieser 4 getrennte 16 Bit-PWMs hardwaremäßig bietet, was für die Ansteuerung der LED-Streifen notwendig ist (ich hatte keine Lust, mir da mit Software-PWMs einen abzufummeln - zumal der Controller mit den Netzwerksachen timingmäßig eh schon gut beschäftigt ist). Der Controller ist standardmäßig beschaltet mit einem 16MHz-Quarz (X1), einem LC-Glied (L1, C12) für die Versorgung des internen AD-Wandlers und meiner klassischen ISP-Schnittstelle, bestehend aus einer einreihigen, sechspoligen Stiftleiste (P1, unten links). Über P2 ist zur Konfiguration die UART-Schnittstelle (UART0) zugänglich.

Das EEPROM (U2), ein 24FC256 mit 256kBit Speicher, enthält die Lichtprogramme und ist über den I²C-Bus an den Controller angebunden. R7 und R10 sind die für den Bus notwendigen Pullup-Widerstände. Oben links auf der Seite sind schließlich drei Spannungsteiler zu sehen, die die Betriebsspannungen (5V, 3.3V sowie die Eingangsspannung VLED) auf "irgendwas knapp über 2V" (damit noch Luft zur Referenzspannung von 2,56V ist) herunterteilen, damit der Controller per AD-Wandler die Spannungen messen und berechnen kann.

NeLiS geöffnet

Rechts vom Controller sieht man schließlich die drei LEDs, die mittlere LED ist eine Zweifarb-LED, welche den Zustand aktiv (grün) oder pausiert (rot) anzeigt. Sie ist an zwei Controllerpins angeschlossen, um beide Dioden leuchten lassen zu können. Unter den LEDs schließlich die drei Taster für Stop, Play/Pause und Nächstes Programm. Die Pullups hab ich aus Angst mal eindesigned, sie sind aber nicht notwendig und werden nicht bestückt.

Netzwerkinterface

Die Schnittstelle zum Netzwerk stellt ein ENC28J60 Netzwerkcontroller von Microchip her, wie auch im AVR Net-I/O. Dieser Chip stellt einen kompletten Ethernet-PHY bereit, also das physikalische Interface zum Ethernet, und bietet außerdem einige Filterfunktionen, mit denen empfangene Pakete sortiert werden können, damit der Mikrocontroller nur die Pakete erhält, die ihn auch interessieren. Die Schaltung ist streng nach Datenblatt aufgebaut und enthält ein paar "krumme" Widerstandswerte (49,9 Ohm, 2,32 Kiloohm), die gegebenenfalls nicht in jeder Bastelkiste liegen. Gegebenenfalls kann man sich die Werte aus zwei oder mehr Widerständen zusammenschalten (z.B. 2,32 Kiloohm = 2,2 Kiloohm + 120 Ohm). Für den 49,9 Ohm-Typ kann man selbstverständlich auch 50 Ohm verwenden, aber wenn ich die eh schon bestellen muss, nehme ich gleich die Richtigen ;-)

Netzwerk-Interface der NeLiS V1.0

Die Anbindung an den Mikrocontroller erfolgt an die SPI-Schnittstelle über die Schutz- und Serienwiderstände R25 bis R29. Die Interrupt-Leitung (Pin 4 am ENC) wird benutzt, um ein neues, eingetroffenes Packet zu signalisieren, dass der Mikrocontroller dann abholen kann. Der Ethernet-Anschluss erfolgt über eine Netzwerkbuchse des Typs TRJ0011BANL, die es günstig bei Pollin zu erstehen gibt. Sie enthält die notwendigen Übertrager und zwei LEDs (gelb und grün), mit denen z.B. ein bestehender Link und eine Datenübertragung signalisiert werden kann. Die LEDs werden vom ENC28J60 angesteuert.

Vorsicht beim Bestellen, den ENC28J60 gibt es in zwei SMD-Gehäusevarianten, SOIC-28 und SSOP-28. Ich habe das etwas größere SOIC eingesetzt, da es sich per Hand einfacher löten lässt.

Spannungsversorgung

Seite 4 zeigt die Spannungsversorgung der NeLiS. Die Eingangsspannung von der Eingangsklemme geht zunächst auf eine 5A-Sicherung. Bei kleineren LED-Stripes kann (und sollte) hier ein kleinerer Sicherungswert eingesetzt werden, den das verwendete Netzteil im Fehlerfall auch sicher auslösen kann. Die Verpolschutz- und Überspannungsschutzdiode D5 sorgt dafür, dass keine zu hohen oder falsch gepolte Spannungen angeschlossen werden; in diesem Fall würde die Sicherung auslösen. Anschließend geht die Eingangsspannung als "VLED" weiter zu den Endstufen und direkt auf den Schaltregler.

Intern werden stabile 5V für den Mikrocontroller als auch 3,3V für den ENC28J60 benötigt. Da sowohl 12V- als auch 24V-LED-Stripes verwendet werden können, kommt ein Schaltregler vom Typ LM2574 zum Einsatz, um die Verlustleistung gering zu halten. Im Leerlauf benötigt die NeLiS etwa 1,2W, das sind bei 5V 240mA. Bei einer Eingangsspannung von 24V wäre das für einen Linearregler eine Verlustleistung von (24V - 5V) * 240mA = 4,56 Watt, was eine ganze Menge ist und erst mal weggekühlt werden will. Die 3,3V werden dann über einen Linearregler vom Typ LM317EMP aus den 5V erzeugt, aufgrund der geringen Spannungsdifferenz ist die Verlustleistung hier nicht mehr so enorm.

Dass mit dem Schaltregler alles relativ kühl bleibt, kann man auch im Thermobild sehen (aufgenommen nach ca. 5 Minuten im Leerlauf). Der "heißeste" Punkt ist nicht der Schaltregler (oben links), sondern der ENC28J60 (Markierung):

Thermografie der NeLiS

Nach beiden Spannungsreglern sind kleine, grüne SMD-LEDs vorgesehen, damit man das Vorhandensein beider Betriebsspannungen gleich optisch erkennen kann.

Endstufe

Auf Seite 5 im Schaltplan sieht man die vier "Endstufen" für die vier LED-Kanäle. Sie sind jeweils identisch aufgebaut und bestehen aus einem Logic-Level-N-Kanal-MOSFET (IRLR2905: 55V, 42A, 27mOhm) und einer Schutzdiode zur Ableitung möglicher Spannungsspitzen. Über einen Gate-Widerstand werden die MOSFETs direkt vom Controller gesteuert.

Links von den Endstufen ist die Temperaturmessung zu sehen. Diese erfolgt über einen NTC vom Typ KTY82-210, der in einen Spannungsteiler eingebaut ist. Die Spannung am Teilerpunkt wird dann vom Controller über den ADC gemessen.

Im unteren Teil der Seite ist noch eine Option zu sehen, die jedoch bislang nicht genutzt wird und auch in der Software nicht implementiert ist. Über eine RS485-Schnittstelle sollte es möglich sein, weitere Slave-Module anzusteuern, die quasi nur einen Controller und die Endstufen enthalten und weitere LED-Streifen ansteuern können, um auch größere Systeme zu realisieren. Dazu ist ein Schnittstellentreiber des Typs MAX483 vorgesehen sowie die notwendigen Abschlusswiderstände und Schutzdioden für den RS485-Bus.

Software

Die Software für NeLiS liegt in einem öffentlichen Bitbucket-Repository. Ihr könnt euch die jeweils aktuellste Version direkt hier ansehen und herunterladen: Link zum NeLiS-Bitbucket-Repository. Wer die NeLiS einfach nur nachbauen möchte, benötigt erst mal nur das Hex-File "NeLiS.hex" im Unterordner "Release" zum Flashen des Controllers.

Da das Ganze doch recht umfangreich ist, gehe ich hier nur auf ein paar "Highlights" ein und erspare mir tieferes Eintauchen in den Quellcode.

Der Netzwerk-Stack

Im Rahmen des NeMo-Projektes haben wir uns entschlossen, den Netzwerk-Stack komplett selbst zu schreiben, auch wenn es im Netz schon viele fertige Stacks für AVR-Controller gibt. Jedoch hat ein eigener Stack neben einem riesigen Lerneffekt auch den Vorteil, dass man den Stack so gestalten kann, wie man ihn haben möchte. Unser Stack kann Stand heute - neben dem ICMP-Protokoll für Ping-Anfragen und dem für die Ermittlung der MAC-Adresse notwendigen ARP-Protokoll - zwar "nur" das HTTP- und das TCP/IP-Protokoll und er ist auch relativ speicherhungrig aufgrund der eingesetzten Buffer, jedoch bietet unser Stack beispielsweise die komfortable Möglichkeit, so etwas zu tun:

tcpHandle = tcpOpen(remoteIp, 1397, 1234, NULL);
tcpSend(tcpHandle, (uint8_t *)"Hallo Welt!\r", 12);
tcpClose(tcpHandle);

Es wird mit dem ersten Befehl eine TCP-Verbindung zu einem Remote-Partner, dessen IP in der Variable remoteIp enthalten ist, geöffnet (vom lokalen Port 1397 zum Remote-Port 1234). Im zweiten Befehl wird diesem Partner dann die Nachricht "Hallo Welt!" gesendet, und anschließend wird die Verbindung wieder geschlossen. Diese drei Befehle können in unserem Stack direkt so hintereinander stehen, ohne Wartezeiten einhalten zu müssen. Um alles andere, sprich um den Aufbau der Verbindung, die Abfrage der MAC-Adresse des Verbindungspartners, das Speichern der Nachricht in einem Buffer, das Versenden der Nachricht inklusive gegebenenfalls notwendiger Wiederholung, sowie das anschließende Abbauen der Verbindung, kümmert sich der Stack selbständig.

NeLiS von der Seite

Natürlich kann der Stack auch als Server eingesetzt werden, wie es bei der NeLiS hauptsächlich gemacht wird. Neben dem Webserver, der auf Port 80 auf eingehende Verbindungen lauscht, gibt es noch die Ports 1396 und 1397, die als Befehlsschnittstelle und zur Programmierung von Lichtprogrammen dienen (siehe die Bedienungsanleitung weiter oben).

Für weitere Details zum Stack sei auf die Doku "NeMo-Stack - TCP/IP-Netzwerkstack für AVR-Controller" verwiesen, in der der Stack im Detail erklärt wird.

Ansteuerung der LED-Stripes

Die 4 Kanäle der LED-Stripes (rot, grün, blau und weiß) werden über vier 16 Bit-PWMs angesteuert, intern werden jedoch nur 8 Bit-Farbwerte (0-255) verwendet. Warum dieses? Schuld ist die Helligkeitsverarbeitung des menschlichen Auges. Würde man zum Beispiel eine 8 Bit-PWM nehmen und die Einschaltdauer langsam erhöhen, würde man bei kleinen Einschaltdauern größere Helligkeitsunterschiede zwischen den Stufen wahrnehmen als bei höheren Einschaltdauern. Um das zu korrigieren, muss man einen exponentiellen Verlauf verwenden, der in der NeLiS über eine Look-Up-Tabelle (zu finden in der Datei light.c) realisiert ist. Sie enthält 256 Werte zu je 16 Bit, und weist so quasi jedem 8-Bit-Wert von 0-255 einen entsprechenden, exponentiell korrigierten 16-Bit-Wert für die PWM-Register zu. Das Ergebnis: Wenn man die Werte der Tabelle nacheinander durchfährt, erhält man einen für das Auge linear erscheinenden Helligkeitsverlauf.

Die ganze Theorie hierzu habe ich von der Sofabeleuchtung von Zabex abgekuckt, von ihm ist auch die Look-Up-Tabelle übernommen.

Für Rot, Grün und Blau wird Timer 1 verwendet, falls auch der Weiß-Kanal benutzt wird, zusätzlich Timer 3. Beide Timer werden direkt aus der Taktfrequenz (16 MHz) des Controllers ohne Prescaler getaktet, somit ergibt sich eine PWM-Frequenz von 16MHz / 65536 = 244Hz. Damit ist für das Auge kein Flackern mehr wahrnehmbar.

NeLiS in Aktion

Ablaufsteuerung und Programmierung der Lichtprogramme

Die Lichtprogramme sind, wie schon erwähnt, in einem externen EEPROM abgelegt, das per I²C an den Mikrocontroller angebunden ist. Die Ablaufsteuerung wird vom Timer alle 10ms angesprungen und arbeitet den aktuellen Befehl ab bzw. holt den nächsten Befehl. Die Programme können über einen einfachen Befehlssatz mit 4 Befehlen definiert werden:

Alle Farben werden als RGB(W)-Werte mit einem Wert von 0-255 für jede Farbe dargestellt. Gelb wäre dann zum Beispiel 255;255;0 - also eine Mischung aus Rot und Grün, während Blau aus ist. Alle Pausenzeiten werden über einen Wert dargestellt, der ein Vielfaches von 10ms - der internen Zeitbasis - repräsentiert. 3 Sekunden wären demnach ein Wert von 300.

Ein Lichtprogramm kann dann zum Beispiel so aussehen:

001>S;255;0;0;0
002>P;300
003>F;300;0;255;0;0
004>P;300
005>F;300;0;0;255;0
006>P;300
007>F;300;0;0;0;255
008>P;300
009>F;300;255;0;0;0
010>X

In Befehl 1 wird die Farbe Rot gesetzt (Rot=255, Grün=0, Blau=0, Weiß=0), und in Befehl 2 direkt für 3 Sekunden (300 * 10ms = 3s) pausiert. In Befehl 3 erfolgt eine Überblendung nach Grün (Rot = 0, Grün = 255, Blau = 0, Weiß = 0), wobei der erste Wert (300) die Überblendungszeit angibt, also wieder 3 Sekunden. So geht es weiter, bis am Schluss in Befehl 9 wieder zu Rot übergeblendet wird. Befehl 10 ist der Exit-Befehl, das heißt, es wird wieder zum ersten Befehl gesprungen und dort weitergemacht. Der Befehl 1 ist dann wirkungslos, da ja Rot schon ansteht, und es wird wieder 3 Sekunden pausiert und so weiter.

Die Lichtprogramme können über eine Telnet-Schnittstelle auf die Ports 1396 oder 1397 sowie über die intern zugängliche serielle Schnittstelle programmiert und konfiguriert werden. Genaueres hierzu ist in der oben schon erwähnten Kurzanleitung beschrieben.

Nachbau

Sämtliche Unterlagen zum Projekt, das Platinen-Layout inkl. Gerber-Files, die Software (Quellcode und Hex-Files), die Gehäuse-Files, Dokus und die wichtigsten Datenblätter, könnt ihr euch hier als Projektarchiv zu NeLiS V1.1 herunterladen.

Layout und Platine

Die Platine der NeLiS V1.1 ist bis auf die Elkos und Steckverbinder komplett in SMD gehalten. Jedoch sollte die Bestückung mit einer feinen Lötspitze auch von Hand kein Problem sein. Bei der Bestückung sollte man mit den kleinen Bauteilen, wie Widerstände und (SMD-)Kondensatoren beginnen und sich so langsam zu den höheren Bauteilen vorarbeiten. Bei Verwendung meines selbst designten Gehäuses müssen die LEDs im Abstand von 19mm (gemessen von der Spitze der LED zur Platinenoberfläche) bestückt werden.

NeLiS teilbestückt

Den ENC28J60 sowie den Mikrocontroller sollte man zunächst noch nicht bestücken; ist ansonsten alles auf dem Board, kann man die Platine vorab mit 12V versorgen. Dann sollten die beiden SMD-LEDs leuchten, und man kann die beiden Betriebsspannungen (5V und 3,3V) mit einem Multimeter kontrollieren. Sind diese soweit in Ordnung, dann kann man den Controller und den Netzwerkchip bestücken.

Inbetriebnahme

Sind Controller und Netzwerkchip bestückt, kann man die Platine mit Spannung versorgen. Die Stromaufnahme sollte bei 12V um die 100mA liegen. Anschließend kann die Firmware geflasht und die Fuse-Bits des Controllers gesetzt werden. Die Fuses werden auf low = 0xFF, high = 0xD1 und extended = 0xFF gesetzt, wodurch der externe Quarz aktiviert und ansonsten alles bis auf die Programmierung per SPI abgeschaltet wird.

Ist der Controller programmiert, folgt als nächstes die Grundkonfiguration, sprich das Setzen der MAC- und IP-Adressen sowie das "Anmelden" in eurem lokalen Netzwerk, wie in der Kurzanleitung beschrieben. Wichtig: Bitte ändert unbedingt die MAC-Adresse, so dass ihr nicht alle mit der von mir eingesetzten Adresse arbeitet! Eine alte, freie MAC kann man aus alter, nicht mehr benutzter PC-Hardware recyceln.

Ist auch das erledigt, kann man schon erste Lichtprogramme einprogrammieren. Als erstes Programm zum Testen kann das oben gezeigte Programm benutzt werden, das die RGB-Kanäle der Reihe nach bedient.

Gehäuse

Als Gehäuse kann man ein fertiges Gehäuse verwenden, die Platine der NeLiS ist so ausgelegt, dass sie in ein EG-1545L von Bopla passt. Hier muss man eventuell nur die LEDs verlängern und den Tastern ausreichend lange Tasterkappen spendieren (die Kappen in der Stückliste passen nur für das selbst gedruckte Gehäuse!).

NeLiS Gehäusedesign mit FreeCAD

Alternativ habe ich auch ein eigenes Gehäuse entworfen und mit FreeCAD gezeichnet. Die FreeCAD-Files sowie die exportierten STL-Dateien liegen mit im Projektarchiv. Für das Bodenteil gibt es zwei Varianten, bei der normalen Variante müssen M3-Gewinde zum Befestigen der Platine und des Deckels geschnitten werden, während bei der Variante mit Muttern im Boden sechseckige Ausschnitte zum Einlegen von Muttern vorgesehen sind, wodurch man sich das Gewindeschneiden spart.

NeLiS im Gehäuse

Das Schöne am selbstgedruckten Gehäuse ist, dass man sich das Bohren von Löchern und Ausfeilen von Ausbrüchen erspart :-) Lediglich die Überhänge sind für die Drucker ein Problem, wie im Bild bei den Schraubenlöchern zu sehen. Hier muss man gegebenenfalls noch mit dem Cutter-Messer etwas nacharbeiten.