Durch die Controller-Bastelei bin ich ja im Moment der C-Hacker. Perl und Python laufen auf den Dingern ja leider nicht… :-)

Da habe ich mir GNU indent installiert, um meine eigenen und fremde Quelltexte etwas anzuhübschen. Schön konfigurierbar, per Konfigurationsdatei kann ich dem Ding beibringen die Klammern so zu setzen wie es mir beliebt (und manch anderen in den Wahnsinn treibt). Das ist eine Art Weltanschauung, aber für mich gehören öffnende Klammern nicht in eine neue Zeile.

So habe ich alles einstellen können, bis auf die öffnenden geschweiften Klammern bei der Definition von Funktionen. Es scheint ein (schon länger bekannter) Bug zu sein, daß das in der Doku fehlt: mit --braces-on-func-def-line bzw. -brf steht die Funktion aber doch zur Verfügung. Muß man halt nur finden…

Dieser Text war 2006 noch nicht im Blog, den habe ich 2015 aus dem alten CMS übernommen.

Die fertige Schaltung in Aktion.

Die fertige Schaltung in Aktion.

Der USB-LED-Fader ist ein Gerät mit dem mehrere LEDs mittels USB kontrolliert werden können. Ich habe es gebaut um den Status meiner Internet-Verbindung und den Füllstand meiner Festplatte, sowie den aktuellen Zustand meines Videorecorders (VDR) anzuzeigen. Die Anzahl der Einsatzmöglichkeiten ist praktisch unbegrenzt.

Die LEDs werden mittels Pulsweitenmodulation (PWM) gesteuert. So sind sie nicht einfach an oder aus, sondern die Helligkeit kann gesteuert werden. Und genau das ist die Hauptaufgabe des Mikrocontrollers: die Firmware verfügt über mehrere ‚Wellenformen‘, die auf den LEDs wiedergegeben werden können. So kann jede LED eine Art Sinus- oder Dreieckswelle darstellen, ohne daß der Host-Computer eingreifen muß.

Jede der LEDs kann separat eingestellt werden, jede kann ein eigenes Muster zugewiesen kriegen.

Es ist möglich, für jede LED drei ‚Wellen‘ zu definieren: zwei ‚unendliche‘ Wellen (0 & 1), und eine einmalige Welle (2). Die unendlichen Wellen wechseln sich ewig ab, wenn eine komplett angezeigt wurde wird die andere aktiv. Die einmalige Welle wird dagegen nur einmal angezeigt, nach ihrem Ablauf springt die Firmware wieder zu den unendlichen Wellen, falls diese definiert wurden.

Jede Welle wird mit drei Parametern definiert: Die Wellenform, die Dauer einer Wiederholung und die Anzahl der Wiederholungen bevor zur nächsten Welle gewechselt wird.

Die hier gezeigte Version unterstützt vier LEDs, es sollte aber nicht allzu schwer sein diese Zahl zwischen eins und acht zu variieren. Ich habe keine Tests mit mehr als vier LEDs gemacht, aber ich könnte mir vorstellen daß es dabei zu Problemen mit der Last auf dem Controller kommen könnte, das könnte die Kommunikation via USB beeinträchtigen.

Die Distribution besteht aus drei Teilen: Der Firmware für einen ATmega8 Mikrocontroller, einem Kommandozeilen­Tool das unter Linux läuft und den Plänen für die Schaltung.

Dieses Projekt basiert auf dem PowerSwitch Beispielprojekt von Objective Development. Wie dort wird auch hier der Firmware-USB-Treiber verwendet, den Objective Development für Atmels AVR-Mikrocontroller entwickelt hat.

Dieser Treiber ist eine reine Firmware-Implementierung des USB 1.1 (low speed device) Standards für den Einsatz auf billigen Ein-Chip-Systemen wie der AVR-Serie von Atmel. Er kann zum Beispiel auf einem ATtiny2313 oder sogar auf einigen noch kleineren 8-Pin-Devices eingesetzt werden. Er implementiert den Standard, soweit es für einen sinnvollen Einsatz notwendig ist. In der Datei „firmware/usbdrv/usbdrv.h“ der Distribution werden Features und Grenzen beschrieben.

Bau und Installation

Die Schaltung umfaßt nur ein paar Standard-Bauteile. Darunter befindet sich kein spezieller USB-Chip.

Die Schaltung umfaßt nur ein paar Standard-Bauteile. Darunter befindet sich kein spezieller USB-Chip.

Die Installation wird in der beiliegenden Dokumentation beschrieben.

Benutzung

Nachdem das fertige Gerät an USB angeschlossen wurde, sollten alle LEDs kurz aufleuchten, um zu bestätigen daß alles funktioniert.

Dann kann der Kommandozeilen-Client wie folgt zum Einsatz kommen:

Mit der Set-Funktion können mehrere Wellen gleichzeitig definiert werden, indem einfach alle benötigten Parameter angegeben werden. Siehe Beispiele weiter unten.

Parameter

  • ledId: Nummer der LED (0-n, je nachdem wie viele LEDs das Gerät hat)
  • waveId: ID der Welle (0-1: ewige Wellen, 2: einmalige Welle).
  • waveformId: ID der Wellenform (0-31: konstante Helligkeit, 32-37: Muster). Die Form der Welle kann mit der show-Funktion angezeigt werden.
  • periodDuration: Zeit in zehntel Sekunden, die eine Anzeige der Wellenform dauern soll. Mit einem Wert von 0 wird die Welle gelöscht.
  • repetitionCount: Anzahl der Wiederholungen für diese Welle mit einer 0 an dieser Stelle wird die Welle für immer wiederholt.

Beispiele

Den Status aller LEDs anzeigen

Die Ausgabe sieht wie folgt aus:

Die Werte curvalue, curpos, nextupd und updtime dienen zum Debuggen. Sie sollten nur nach einem Blick in den Code von Interesse sein. Die Bedeutung der anderen Werte dürfte klar sein.

Die erste LED auf eine mittlere Helligkeit schalten

So wird die Welle 0 der LED 0 auf die Wellenform 15 (eine mittlere Helligkeit) gesetzt. Sie wird für eine Sekunde angezeigt und nach einmal wiederholt bevor zur nächsten Welle gewechselt wird. Noch ist keine zweite Welle definiert, also bleibt dieser Zustand bis auf weiteres.

Jetzt eine zweite Welle für die erste LED definieren, etwas heller als die erste

Dies ist Welle 1 auf LED 0, die Form 25 ist ebenfalls eine konstante Helligkeit. Nachdem die zweite Welle gesetzt wurde wechselt sie sich mit der ersten im Sekundentakt ab, weil beide Wellen die gleiche Länge und die gleiche Anzahl an Wiederholungen haben.

Eine dritte Welle auf die erste LED legen

Dies setzt die dritte Welle (Nummer 2) auf der ersten LED. Wellenform 36 ist eine schicke Sinus-ähnliche Form, also beginnt die LED zu faden. Eine Wiederholung dauert dabei zwei Sekunden, die Welle wird fünf mal wiederholt. Da dies die dritte Welle ist, kehrt die Schaltung nach diesen Wiederholungen wieder in die Abwechslung zwischen den beiden Helligkeiten zurück, diese Welle wird somit gelöscht.

Mehrere Wellen gleichzeitig definieren

Damit werden alle oben angegebenen Wellen gleichzeitig definiert. Die LED wird also erst fünf mal sinus-artig faden, und danach anfangen im Sekundentakt zwischen den beiden Helligkeitszuständen zu blinken.

Die erste LED löschen

Damit werden alle Wellen auf der ersten LED gelöscht.

Das Gerät zurücksetzen

Alle LEDs leuchten dabei einmal auf, um zu signalisieren daß alles funktioniert.

Eine Wellenform auf dem Bildschirm anzeigen

Die Ausgabe sieht wie folgt aus:

Dabei ist zu beachten, daß die angezeigte Breite der Länge der Wellenform entspricht. Eine einfache konstante Helligkeit (0-31) hat eine Länge von 1. Die Anzeige umfaßt also nur eine Spalte.

Das Gerät testen

Diese Funktion sendet viele zufällige Zahlen an das Gerät. Die Datenpakete werden wieder zurückgegeben und mit den Originalen verglichen, um Unterschiede zwischen den gesendeten und den empfangenen Daten festzustellen.

Schwachpunkte

Ich weiß, man kann das auch schöner anordnen... ;-)

Ich weiß, man kann das auch schöner anordnen… ;-)

Wie schon erwähnt ist die Kontrolle der Pulsweitenmodulation für mehrere LEDs eine Menge Arbeit für den kleinen Controller. Das gleiche gilt für das Sprechen des USB-Protokolls. Beides zusammen ergibt eine hohe Last auf dem Gerät, dadurch ist die Kommunikation mit dem Gerät nicht zu 100% verläßlich. Tests haben aber gezeigt, daß mehr als 99% aller Kommandos ankommen.

ACHTUNG: Man sollte diese Schaltung deshalb nicht benutzen um zum Beispiel den Zustand eines Kernreaktors zu überwachen. Solltest Du das trotz dieser Warnung vorhaben, bitte ich um kleine Nachricht… ;-)

Danke!

Ich möchte der Firma Objective Development für die Möglichkeit danken, ihren Treiber benutzen zu können. Ohne den gäbe es dieses Projekt nicht.

Und ganz besonderer Dank geht an Thomas Stegemann. Er hat das Modul für die PWM-Steuerung geschrieben, und für mich selbst wäre es nahezu unmöglich gewesen, den Rest des Projektes ohne seine Hilfe zu schreiben. C ist halt nicht meine Muttersprache… ;-)

Lizenz

Unsere Arbeit, also alles außer dem USB-Treiber, fällt unter die GNU General Public License (GPL). Eine Kopie der GPL liegt dem Projekt bei. Der USB-Treiber untersteht einer gesonderten Lizenz von Objective Development. In firmware/usbdrv/License.txt befinden sich weitere Informationen dazu.

Download

USB-LED-FaderSo, es ist vollbracht! Ich habe gerade die angekündigte Seite mit dem Elektronikprojekt hochgeladen: Mein USB-LED-Fader.

Das Teil besteht aus einem Mikrocontroller (ATmega8), vier LEDs und ein paar Kleinteilen. Der Controller ist praktisch direkt an USB angeschlossen, darüber bezieht er auch seinen Saft. Auf dem Hostrechner kann unter Linux ein Kommandozeilenprogramm benutzt werden, um die LEDs zu steuern. Dabei werden die nicht nur an- oder ausgeschaltet, sondern mittels Pulsweitenmodulation zum Faden gebracht. Das Faden an sich wird, einmal aktiv, allein von dem Mikrocontroller gesteuert. Somit wird die CPU des Linux-Rechners nicht weiter strapaziert.

Ich habe das Teil gebaut um den Zustand meines Videorecorders (VDR) und meiner Internetverbindung (ISDN ohne Flatrate… :-( ) anzuzeigen. Denkbar sind alle möglichen Anwendungen, und wenn es nur als Moodlight irgendwo rumliegt.

Ich habe das Projekt ziemlich umfangreich — geradezu geschwätzig — dokumentiert und zum Download freigegeben. Somit stellt das meine erste Veröffentlichung unter der GPL dar!

An dieser Stelle nochmal Dank an Objective Development, die den USB-Treiber für AVR zur Verfügung gestellt haben. Und an Thomas Stegemann für die Pulsweitenmodulation und allgemeine Unterstützung in Bezug auf kranke Programmiersprachen (C in diesem Fall). :-)

Das war das eine Projekt, das mich die letzten Wochen in Anspruch genommen hat. Das zweite — der Neuaufbau des erwähnten Videorecorders — ist auch schon abgeschlossen, muss aber noch etwas aufbereitet werden. Kommt dann auch ins Netz. Wann ich dazu komme steht aber noch in den Sternen… ich habe schon die nächste Schaltung auf dem Steckbrett aufgebaut… ;-)

Wer hätte gedacht, daß einem ausgerechnet der altbackene Packer tar ein Grinsen abringen kann? GNU-tar kann das zumindest, wie ich Gestern festgestellt habe als meine im Halbschlaf eingetippte tar-Brücke nicht funktioniert hat:

% ssh root@odin "tar cf /" | tar xv
Password:
tar: Anlegen eines leeren Archivs wird feige verweigert.
,tar --help' zeigt weitere Informationen.

Und nicht nur die deutschsprachige Version ist albern:

% ssh root@odin "unset LANG; tar cf /" | tar xv
Password:
tar: Cowardly refusing to create an empty archive
Try `tar --help' for more information.

Nein, ich lasse die Seite nicht sterben. Der Grund für das aktuelle Dahinsiechen liegt darin, daß ich im Moment ziemlich viel unterwegs sein muß und somit kaum noch Zeit habe mich um irgendwelche Sachen zu kümmern. Ich gelobe aber Besserung… :-)

Etwas Zeit habe ich aber in den letzten Wochen in zwei Web-fremde Projekte gesteckt: Zum einen habe ich meinen Videorecorder neu aufgebaut (der C64@1GHz musste dafuer leider Federn lassen :-( ), zum anderen bastele ich an einem neuen Elektronik-Projektchen. Damit sollen dann LEDs an- und ausgeschaltet werden. Ziemlich schnell…

Wie auch immer: Sobald ich Zeit habe lasse ich was verlautbaren…