AmbiLight 3: a.k.a. WAmbiLight, goes wireless

Inhaltsverzeichnis

4.3 Foto

 

1. Vorwort Inhalt

Fast drei Jahre nach dem letzten AmbiLight-Projekt, wessen Artikel übrigens die Grundlage für diesen Artikel liefert und deswegen unbedingt gelesen sein sollte, findet sich nun in diesem Ordner wieder etwas Berichtenswertes, ein neues AmbiLight für Leinwände oder beliebige andere Unterhaltungshardware ist geboren. Und was für Kindchen das ist, denn zwei wesentliche Feature-Upgrades hat es erfahren:

  • Gängige LED-Streifen sind alle 10 cm bzw. alle drei LEDs trennbar, es wird Zeit, dies auszunutzen.
  • Kabel ziehen ist verpönt, laßt uns den Krempel entkabeln =)

Langer Rede kurzer Sinn: Freut euch auf eine ingenieursmäßige Meisterleistung in mehrerlei Hinsicht…

2. Lizenz Inhalt

Die folgenden Dateien, Schaltpläne und Informationen stehen wie andere Projekte auch unter der Creative-Commons-Lizenz 3.0 by-nc-sa [Link]. Kurz, ihr dürft die Dateien benutzen, kopieren, verändernden und weitergeben, sofern ihr meinen Namen und diese Webseite im gleichen Atemzug, z.B. durch Verlinkung, Text „basiert auf…“ nennt. Ihr dürft die Informationen nicht kommerziell verwenden, auch nicht in Auszügen. Für die genauen Formulierungen der CC-Lizenz seht bitte unter den obigen Links nach.

3. Systemdesign Inhalt

Wir rekapitulieren kurz, wie das bisherige System aussah:

  • Auf dem Mediacenter-Rechner, vorzugsweise ausgestattet mit Windows und MediaPortal, läuft eine Software, die den Bildinhalt abtastet (übrigens über GDI getPixel(), unter Vista und 7 deaktiviere man dafür die Desktopkomposition) und für jeden konfigurierten Bildbereich einen RGB-Wert berechnet.
  • Alle RGB-Werte sendet sie in einem einstellbaren Zeitintervall an eine serielle Schnittstelle („COM-Port“).
  • Mit dem COM-Port verbunden sind ein oder mehrere LED-Controller, die die Werte empfangen und für jede LED die entsprechende Helligkeit per PWM ausgeben.

3.1 Neuerungen Inhalt

Das Konzept wird so beibehalten werden, wir werden auch mit der neuen Version einen COM-Port erhalten, an den die Bytes der Helligkeit zu senden sind. Auch die PWM-Steuerung der RGB-LEDs über einen Micro-Controller hat sich insbesondere bei dunklen Farben sehr bewährt, es flimmert nichts, es flackert nichts und dunkel genug ist es in den unteren Bereichen auch.

Neu gestaltet hingegen wird die bedarfsgerechte Anpassung der Übermittlung der Bytes vom PC zu den Controllern werden, ich hatte einfach keine Lust mehr, 10m Kabel durch’s Wohnzimmer zu legen. Und was käme dafür besser in Frage als ein preiswerter Funkchip mit 2MBit Datenrate? Die Wahl fiel dann auf den RFM70 [PDF] der Firma Hope RF, die schon durch die preiswerten RFM12* Module bekannt wurde. Mit 3,– EUR pro Stück in der Bucht im 10er Packen sind die Dinger auch hinreichend günstig und gut erhältlich.

Nachdem nun der Verkabelungsaufwand entfällt, wurden gleich Nägel mit Köpfen eingeschlagen und die Zahl der Zonen pro Seite auf 10 erhöht, was im vorliegenden Konzept Summa Summarum 40 RGB-Kanäle zur freien Verfügung bedeutet.

3.2 Funkkonzept Inhalt

Ein bißchen unklar war mir anfangs das Funkkonzept, nachdem der RFM 32 Bytes an Paketen versenden kann, pro Controller aber nur 5×3=15 benötigt werden. Erfahrungsgemäß ist die Verlustrate von Paketen allerdings relativ hoch, und möglicherweise würde ich die Auto-Retransmit Funktion für den Chip verwenden wollen. Die benötigt eine eindeutige Zieladresse, an die die Payload zu verschicken ist, damit ergeben sich also folgende Rahmenbedingungen:

  • Jeder Controller erhält eine eigene Adresse ( 0x20, 0x20, 0x20, 0x20, [0x00-0x07] ).
  • Der Sender schickt genau die 15 erforderlichen Bytes an jeden Controller.
  • Die CRC-Prüfung wird eingeschaltet, damit kaputte Frames verworfen anstatt dargestellt werden.
  • Auto-Retransmit ist derzeit nicht aktiviert, Tests zeigen, daß es bei 5m Entfernung auch ohne funktioniert.

4. Hardware Inhalt

Bei der Hardware hat sich einiges getan: Zunächst einmal stellte sich die Frage nach einem geeigneten Funk-Chip, der auch in Stückzahlen und preiswert erhältlich ist. Nachdem sie mit dem RFM70 beantwortet werden konnte, war weiters ein entsprechendes USB-Interface zu designen, und auch hier war das Vorgehen zunächst unklar.

Sollte ein FTDI-Chip und eine AVR-MCU -wie bisher- verwendet werden oder wäre es möglich, einem der diversen USB-AVRs eine virtuelle serielle Schnittstelle einzuimpfen? Basierend auf der unglaublich mächtigen und vor allem kostenfreien LUFA-Bibliothek von Dean Camera konnte dann ein ATmega32u2 als bus-powered USB-Dongle oder besser USB-RFM-Brigde eingesetzt werden.

4.1 Controller Inhalt

Am Controller gleichgeblieben ist das Herzstück, ein mittlerweile gut zu bekommender ATxMega16A4 (ohne u), dessen 6 Timer wir wie gehabt zur Erzeugung von 15 PWM-Steuersignalen verwenden.

An den einen freien SPI-Port schließen wir das RFM70 an, wobei ich da ziemlich Glück hatte, der !SS-Pin muß im SPI-Master-Betrieb ein Ausgang sein und kann gleichzeitig aber auch noch an den PWM-Treiber der Timer/Counter-Unit verbunden werden.

Eine weitere Besonderheit ist, dass die Platine keinerlei Löcher besitzt, also nichts gebohrt werden muss und komplett einseitig ausgeführt ist. PCB-Pool weint, weil sie hier nicht so viel fertigen können =) Zumindest die Platine ist damit ein Meisterwerk der Ingenieurskunst. Ist übrigens ganz lustig, bei „watch-ur-pcb“ im ersten Arbeitsschritt (Bohren) ein Foto einer blanken Kupferplatte zu bekommen…

Leider habe ich kein MOSFET-Array im SOIC-20-Gehäuse gefunden, in welchem 8 N-Channels untergebracht wären, und um so kompackt zu bleiben, nehme ich nun zwei bewährte und robuste NPN-Darlington-Treiber, ULN2803 [PDF]. Damit ist’s dann über den Haufen mit der Green-IT, die Dinger verheizen schon im Leerlauf 5mA, und genehmigen sich noch einmal insgesamt 20, wenn alle Kanäle durchschalten. In den Dioden und vor allem den Vorwiderständen bleibt eben was hängen. Auf der anderen Seite geht es ohne Treiber nicht, die LEDs ziehen pro 3 Stück 100mA, das machen die Bonddrähte einer AVR-MCU nicht lange mit. Nunja, einen Tod müssen wir sterben.

Ansonsten befinden sich neben dem Programmierstecker noch drei LEDs und drei Steckplätze für Adressjumper, mit denen das letzte Byte (LSB) der Empfangs-Adresse eingestellt wird.

An dem vierpoligen Stecker oben schließt man die Spannungsversorgung an, Masse in die Mitte, damit ist die Sache zumindest an der Platine verpolungssicher. Für meine Streifen benötigt man 12V, damit wird der Spannungsregler bei den 40mA Strom, die er liefern muß, schon ordentlich warm. Das ist aber normal, die überflüssige Energie wird verheizt. Wie gesagt, Energie-effizient ist das ganze nicht.

Auf der anderen Seite werden die LEDs -die eine gemeinsame Anode aufweisen- per Flachbandkabel angeschlossen, derzeit ist die Belegung dann wie abgebildet von links oben an gezählt 5x ANODE-BLAU-ROT-GRÜN am Flachbandkabel, genau passend für die käuflichen LED-Streifen. Wenn die aber eine andere Belegung aufweisen, kann man das in der Software natürlich ändern.

4.2 USB-Dongle Inhalt

Nun, wer noch nie eine eierlegende-Wollmilchsau gesehen hat, sollte sich jetzt festhalten und seine Brillengläser putzen. Die erste und bislang einzige Sau ihrer Art wird hier vorgestellt. Auf wenigen cm2 vereint dieser kleine Wonneproppen so einige Features:

  • USB-Device: Bietet USB-Verbindung zum Host mit allem, was die LUFA-Lib hergibt (also den virtuellen COM-Port).
  • RFM70-Port: Zum optionalen Anschluß eines RFM70-Transceiver-Moduls, IRQ-Leitung selbstverständlich an einem EXTINT-Port verbunden.
  • Sensorboard auf der TOP-Seite: SHT 10, 11 und 15 für Temperatur und Luftfeuchte, HP03s für den Luftdruck und einen APDS-9300 Lichtsensor.
  • Optional Spannungsregler auf der Top-Seite, damit „beliebiger“ Spannungbereich für den Eingang. Versorgung dann über USB-Buchse und Batterie oder Netzteil.

Ja Moment!

Den Quatsch brauch ich doch für dieses Projekt gar nicht!

Perfekt. Die Platine ist natürlich so geroutet, daß ihr nur den Bottom-Layer für RFM und USB-Funktion fertigen lassen müßt, Top-Layer nur nach Bedarf. Wenn das mal kein Kunstwerk ist. Zusammenfassend könnt ihr also drei Dinge damit anstellen:

  • USB-RFM70-Bridge
  • USB-Sensorboard
  • RFM70-Sensorboard
  • USB-Sensorboard mit RFM70-Ausgabe

Dank der 32k Flash, die übrigens mit USB-Comport und ein bißchen Bridge-Software nicht mal zu 15% voll sind, läßt sich so einiges anstellen. Ein kleiner Wermutstropfen: Der Mega32U2 darf für USB-Betrieb nur genau mit 8MHz oder 16MHz betrieben werden, sonst kann die PLL intern keine 48MHz USB-Referenz-Clock erzeugen. Bei 3,3V darf er aber maximal 8MHz CPU (=Kern)-Takt bekommen laut Datenblatt. Es steht damit nur die Hälfte der Rechenleistung zur Verfügung.

Ansonsten bietet die Platine wenig Überraschungen. Für das Bus-powered Design wird der interne Spannungsregler verwendet, der übrigens auf meinen Boards nur 2,7V schafft, keine 3,3 (tut aber trotzdem), und damit den RFM mitversorgt. Drei Debug-LEDs runden die Hardware ab, ein bißchen Gemüse sorgt für glättere Spannungen. Quarz, USB-Stecker und Programmierpinleiste werden von oben eingelötet, der Rest von unten (sollte mit jedem Kolben locker machbar sein).

In diesem Projekt bleibt die Oberseite übrigens unbestückt, aber stay tuned, im Bereich Heimautomatisierung wird’s demnächst ein größeres Update geben.

4.3 Foto Inhalt

Auch hier soll ein Bild der fertigen Hardware nicht fehlen, die Platinen sind vom PCB-Pool und ließen dank Laser-Stencil, Lötpaste und herkömmlicher Herdplatte erstaunlich gut zusammenbauen. Im Bild dargestellt ist auch die Möglichkeit, den RFM70-Chip mit angelöteter Stiftleiste zu verwenden, siehe oben rechts. Damit hat er weniger Ausbreitung und paßt besser in Gehäuse von BOPLA.

Zur Befestigung: Es können immer 5 LED-Leisten an einen Controller verbunden werden, damit ist zunächst ein 20-Poliges Kabel mit einer entsprechenden Pfostenbuchse zu verbinden (Schneidklemmtechnik). Dieses wird so eingeklemmt, dass es ohne Zugentlastung von der Platine wegzeigt, im Bild rechts also nach unten. Dann befindet sich die erste Anode am ganz linken Kabel, es folgen B1, R1 und G1. Analog für die restlichen 16 Kabel A2B2R2G3 usw.

Die Befestigung an der Leinwand  geschieht übrigens wie gehabt mit Fußtrittleisten (45°) und Maulklemmen. Um die Flachbandkabel an den Trittleisten zu befestigen, eignet sich ein Durchbohren und Umwickeln mit Draht. Siehe aber den AmbiLight-2 Artikel, dort sind detaillierte Fotos eingebunden.

5. Software Inhalt

Kommen wir zur Firmware der beiden Platinen. Es hat sich am Controller nicht sonderlich viel getan, außer daß eine Schnittstelle und Software für den RFM hinzugekommen ist. Der Dongle hingegen mußte vollständig neu programmiert werden. Das gesamte Projekt wurde im Atmel Studio geschrieben, im Download befindet sich die vollständige „Solution“. Zum Programmieren vergeßt nicht, das jeweilige Projekt auf „Startup“ zu setzen, sonst weigert sich das STK600.

5.1 Controller Inhalt

Neben den beiden Files für den RFM (cs_rfm*) besteht die Software noch aus einer Definition für die Gammakurven („flash.h“), einem Platz zum Definieren von Makros und Bitmuster-Aliasen („defines.h“) und der globalen Konfiguration („config.h“). In Letzterer ist nur der entsprechende RFM-Kanal (0-82) sowie die vier Adressbytes für die Empfangsadresse einzustellen. Sofern man die vier Bytes 0x20 behalten möchte und auf Kanal 40 senden will, ist alles in Butter:

/***********************************
 ** RFM70-CONFIGURATION           **
 ***********************************/
// Set RX Base Address
// All other configuration is done in main() INIT
// Don't forget to change implementation in cs_rfm70* as well
#define RFM70_RX_BASE_ADDRESS 0x20,0x20,0x20,0x20,0xFF
#define RFM70_RX_CHANNEL      40
#define rfm70_spi_slaveSelect()   PORTB.OUTCLR=PIN2_bm
#define rfm70_spi_slaveUnselect() PORTB.OUTSET=PIN2_bm
#define rfm70_chipEnable()        PORTB.OUTSET=PIN3_bm
#define rfm70_chipDisable()       PORTB.OUTCLR=PIN3_bm

Ansonsten befindet sich im Projekt nichts einstellbares, die RFM-Lib habe ich aus den Quellen von Hope RF selbst noch einmal zusammengeschrieben. Ihr müßtet ggf. im Datenblatt nachsehen, welche Register man wie initialisieren muß für AutoACK oder andere Datenraten. Der Code der MCU ist hoffentlich ausreichend dokumentiert.

5.2 USB-Dongle Inhalt

Dank der LUFA-Bibliothek gestaltet sich auch die Firmware für den Dongle sehr einfach. Die Bibliothek kümmert sich zusammen mit der AVR Hardware vollständig um die Kommunikation mit dem PC und USB-relevante Aufgaben. Über einfache API-Funktionen, hier int CDC_Device_BytesReceived() und int CDC_Device_ReceiveByte(), liest die Firmware byteweise die Informationen vom PC in einen RAM-Buffer.

Die Synchronisierung erfolgt zeitbasiert. Sofern 10ms lang kein Byte an den virtuellen COM-Port gesendet wird, geht die Firmware von einem neuen Frame aus und löscht den RAM-Buffer.

Sind dagegen 120 Bytes „am Stück“ empfangen worden, werden die 8 LED-Controller einfach mit jeweils 15 davon versorgt, indem in einer Schleife die Zieladresse von 0 bis 7 iteriert und jeweils das Teilstück des RAM-Buffers (0-14, 15-29, usw.) gesendet wird.

Wie beschrieben findet kein durch die Empfänger kein ACK statt: ich gehe davon aus, daß ein verlorener Frame auf einem Controller wegen der Korrelation der Bildinformation nicht auffällt. Der Controller behält ja die letzte eingestellte Farbe.

Die Firmware ist nun so geschrieben, dass die grüne LED stets dann eingeschaltet wird, wenn das USB-Gerät vom Host enummeriert wurde und tatsächlich verbunden ist. Auch dafür stellt die LUFA-Bibliothek einsprechende Funktionen bereit. Die gelbe LED leuchtet, solange ein Frame übertragen wird. Um sie überhaupt sichtbar zu machen, habe ich noch ein Delay in die Routine eingefügt.

5.3 Virtueller COM-Port Inhalt

Unter Windows ist übrigens nach dem Einstecken die beiliegende INF-Datei zu installieren, damit der virtuelle COM-Port erscheint. Nach Bestätigung der Treibersignaturwarnung (Christus, es wird eine MS-eigene Datei verwendet, trotzdem kommt diese Weltuntergangswarnung) taucht dieser dann unter einer freien Nummer auf und kann mit 8N1, 115200 Bit/s angesprochen werden, z.B. durch boblight oder irgendein anderes Programm.

Hier einmal ein Testscript für Python 2.7.3, das pySerial installiert hat:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import time, serial

ser = serial.Serial('COM4', 115200, timeout=0.01) # Selbstverständlich durch euren COM-Port ersetzen...
i=0
while 1:
	i=(i+1)%256
	teststr = ""
	print "sending %03u to all channels" % i
	while len(teststr)<120:
		teststr = teststr+chr(i)
	ser.write(teststr)
	time.sleep(0.005)

5.4 Ausblick Inhalt

Ein schönes Feature wäre noch, dass pro Device 16 Bytes übertragen werden, wovon das erste eine aufsteigend zählende Frame-Nummer ist. Immer wenn ein Frame fehlt, sollte z.B. die rote LED eingeschaltet werden. So könnte man auch bei kHz-Frequenzen noch die Link-Qualität abschätzen.

6. Projektdateien Inhalt

In diesem Teil könnt ihr die benötigten Dateien herunterladen. Bitte beachtet die Lizenz, wie eingangs erwähnt, CC 3.0 by-nc-sa, wenn ihr die Dateien verwenden möchtet.

7. Fazit und Ausblick Inhalt

Nun, jetzt bleibt im AmbiLight nicht mehr viel zu erweitern, ein einziger Wermutstropfen jedoch hängt nach: Es läßt sich im Moment nur ein PC-Bild darstellen.

Wäre schön, wenn die Bildabtastung auch von beliebigen DVI/HDMI-Quellen erfolgen könnte. HDMI ist nun leider verschlüsselt, auch bräuchte man wohl schnelle FPGAs zur Signalverarbeitung. Nun wurde ich über ein kleines Teil gestolpert, das da „HD-Fury“ heißt und aus einem HDMI-Signal ein analoges VGA-Signal fabriziert. Die Bandbreite davon liegt durchaus im Bereich dessen, was 40 MS/s-AD-Wandler abtasten können und parallel ausgeben. 8 Bit sollten reichen, welche 1:1 in einen MCU-Port geschoben und dort in einem großen Array gespeichert werden. Eine Zeile abtasten, eine Zeile berechnen. H-Sync und V-Sync an Interrupts und gut is.

Bislang keine Kommentare vorhanden.

Einen Kommentar hinterlassen