heesch.net

Wireless RGB

Die hier beschriebene RGB-Lampe kann über das WLAN ferngesteuert werden - wahlweise vom eigenen Computer oder von einem Handy. Die Hardware besteht hauptsächlich aus einem ATMega 8 Controller, einem ZG2100 WLAN-Modul und ein paar MOSFET-Transistoren.

Die Software besteht aus dem Treiber für das WLAN-Modul, einer Minalimplementierung des ARP- und UDP-Protokolles und der Ansteuerung für die RGB-LEDS. Der Treiber für das WLAN-Modul (g2100.h und g2100.c) kann im Internet von der Firma AsyncLabs als GPL 2 lizensierte Software frei bezogen werden. Dort gibt es übrigens auch AVR-Boards, mit einem integrierten WLAN-Modul: BlackWidow und YellowJacket. Für diese beiden Boards müsste die hier beschrieben Software allerdings angepasst werden.

Mittlerweile hat mir Brad Rex von Asynclabs auch eine unter GPL 3 lizensierte Treiberversion für den ZG2100M zur Verfügung gestellt. Ich habe beide Orginal-Treiber von Asysynclabs noch einmal als ZIP-Archiv verpackt zum Download bereitgestellt.

Hardware

Die Schaltung der WLAN-RGB Lampe ist relativ einfach aufgebaut. Ein ATMega 8 Controller ist über den SPI-Bus mit dem ZG2100M Modul WIFI-PROTO verbunden. Über PB2 wird bei einem LOW-Pegel das ZG2100M selektiert. Wenn Daten vom ZG2100M an den ATMega 8 übertragen werden sollen, so kann dies vom ZG2100 über einen LOW-Pegel an PD2 signalisiert werden, was einen Interrupt INT0 beim ATMega 8 auslöst.

Der Mikrokontroller steuert über die Ports PD5-PD7 die Treiber für die RGB-LEDs an. Als Treiber kommen dabei Power-Mosfets vom Typ IRLIZ44 zum Einsatz. Die MOSFETs können durch ähnliche Typen mit einem Schaltplan WLAN-RGB Lampemöglichst geringen RDS(on) ersetzt werden.

 

Eine LED an Port PB1 des ATMega 8 zeigt den erfolgreichen Verbindungsaufbau zum WLAN an.  Über die Ports PD1 und PD0 kann per RS232-Pegelwandler ein Terminalprogramm mit dem ATMega 8 verbunden werden, um den Ablauf des Programmes zu monitoren. Das ist allerdings für den Betrieb als WLAN-RGB Lampe nicht notwendig.

Programmiert wird der ATMega 8 Mikrocontroller im eingebauten Zustand über sein integriertes serielles Programmierinterface. Ein 6poliger Stecker zum Anschluss des Programmierkabels ist im Schaltplan ebenfalls eingezeichnet.

Der ATMega 8 wird mit einem externen Takt betrieben, der durch einen 16 MHz Quarz an den Pins 9 und 10 erzeugt wird. Zur Bereitstellung der benötigten Versorgungsspannungen werden zwei integrierte Spannungsregler eingesetzt. Der ZG2100 benötigt dabei 3.3 Volt Betriebsspannung, die von einem LM317 geregelt wird, der ATMega 8 wird von einem LM7805 mit 5Volt versorgt. Beiden Spannungsreglern sollte man ein kleines Kühlblech spendieren, ansonsten werden sie im Betrieb sehr warm.

Software

Der Quelltext für die Software der WLAN-RGB Lampe kann über den Download-Link als freie Software bezogen werden. Er ist unter der GPL 2 oder wahlweise einer späteren Version der Lizenz verfügbar. Der Treiber für den ZG2100M wird derzeit von der Firma AyncLabs.com unter GPL2 vertrieben.

Die Ansteuerng der LED-Treiber erfolgt über Pulsweiten-Modulation (PWM). Dadurch sind pro LED 255 verschiedene Helligkeitsstufen möglich. Die Werte für die einzelnen Helligkeitsstufen werden über das WLAN mit dem UDP-Protokoll übertragen. Da mit dem ZG2100M kein Multicast eingesetzt werden kann, muss der WLAN-RGB Lampe eine IP-Adress zugewiesen werden. Die Software enthält  eine Minimal-Implementierung des ARP Protokolles, um die Zuweisung der IP-Adresse zur MAC-Adresse des ZG2100M über das Netzwerk veröffentlichen zu können.

Die Verbindung mit dem WLAN wird von dem ZG2100M und dem Treiber der Firma AsyncLabs.com durchgeführt. Das ZG2100 kümmert sich dabei auch um die Verschlüsselung der Daten nach WEP oder WPA Standard. Der Treiber kommuniziert mit der übrigen Software über einen Buffer, welcher die in Ethernet-Frames eingebetteten Netzwerdaten enthält.

Die im Folgenden beschriebenen Auszüge aus dem C-Code enthalten Verweise auf die jeweiligen Quelltextdateien um das Navigieren durch den Sourcecode etwas zu vereinfachen.

Das Hauptprogramm in main.c initialisiert das Netzwerk, wartet die Verbindung zum WLAN ab und verarbeitet dann in einer Endlosschleife die ankommenden Netzwerkdaten:

   /* Connect to WLAN
    */
    unsigned char ok = 0;
    do
    {
       ok = ConnectNetwork();
    } 
    while( ok == 0);
  
    log("\n\rConnected to WLAN.\n\r" );
   
   /* Event loop
    */
    for (;;)
    {
       HandleNetworkData();
    }

Dabei wird zunächst der ZG2100M Treiber aufgerufen, um eventuell eingetroffene Netzwerkdaten zu verarbeiten (net.c) :

 void HandleNetworkData()
 {
   /* Call network driver
    */
    zg_drv_process();

Von empfangenen Daten wird zunächst einmal die Prüfsumme entfernt, bevor sie weiterverarbeitet werden:

   /* Have we received some data?
    */
    unsigned int len = zg_get_rx_status();
    if ( len > 0 )
    {
      /* Strip off the checksum
       */
       MyNetworkBuffer[len-4] = 0;

Wurde ein ARP-Request empfangen, so wird dieser bearbeitet und ggfs. eine ARP-Response verschickt ( arp.c ). Da die Addressierung der Ethernet-Frames über MAC-Adressen läuft, wird mit der ARP-Response die MAC-Adresse des ZG2100M im Netzwerk veröffentlicht, die der eigenen IP-Adresse entspricht.
 if ( IsArpMessage ( MyNetworkBuffer ) )
 {
   ARP_Packet * arp = (ARP_Packet*) (MyNetworkBuffer + Ethernet_DataOffset);
   if ( ProcessArpMessage( arp ) )
   {
     log("Sent ARP Response :\n\r");
     DumpArpMessage( arp );
   } 
}

Falls es sich bei den empfangenen Daten nicht um einen ARP-Request handelt, wird auf den Empfang einer Nachricht zum Ansteuern der LEDs geprüft:

/* Check for ambient color message
 */  
 if ( IsAmbientColorMessage( MyAddress.IP , AMBICOLOR_PORT,
                            (char*) MyNetworkBuffer )       )
 {
    HandleAmbientColorMessage( (char*) MyNetworkBuffer );
 }

Dabei wird ein UDP-Datagram verwendet, dessen Format hier kurz beschrieben ist. Die beiden Funktionen zur Auswertung IsAmbientColorMessage und HandleAmbientColorMessage sind in der Datei ambientcolor.c definiert. Sind die Daten an die WLAN-RGB Lample adressiert, so werden sie bei einer gültigen Nachricht zum Setzen der LED-Farbe verwendet:

 void HandleAmbientColorMessage( char* msg )
 {
    if ( msg != NULL && strncmp( msg + UDP_DataOffset, "AmbientColor:",13) == 0 )
    {
       int red, green, blue, index = 0;
       char * token;
       char * context;
       token = strtok_r ( msg + UDP_DataOffset,":",&context);
       while (token != NULL)
       {
           switch( index )
           {
              case 1: red = atoi( token );
                      log("Setting RED to 0x%x\n\r", red);
                      break;
              case 2: green = atoi(token);
                      log("Setting GREEN to 0x%x\n\r", green );
                      break;
              case 3: blue = atoi(token);
                      log("Setting BLUE to 0x%x\n\r", blue );
                      break;
           }  
           ++index;       
           token = strtok_r (NULL,":",&context);
       }
       SetColors(red, green, blue);
       log("\n\r" );
    }
 }

Die LED-Farbe wird wie oben schon erwähnt per PWM eingestellt. Die Funktion SetColors setzt dabei die Werte für die Pulsweitenmodulation, die von der Interrupt-Service-Routine des Timers 1 ausgewertet werden ( timer.c ):

 ISR (TIMER1_COMPA_vect)
 {
    TIMER1_COMPA_INT_DISABLE;
    if ( ++pwm == 0 )
    {
       if ( red > 0 )  {
           LED_On ( RED   );
       }
       if ( green > 0 ) {
           LED_On ( GREEN ); 
       }
       if ( blue > 0) {
           LED_On ( BLUE );
       }
    }
   /* Pulse width modulation of LEDs
    */
    if ( pwm > red  ) {
       LED_Off( RED );
    }
    if ( pwm > green )  {
       LED_Off ( GREEN );
    }
    if ( pwm > blue ) {
       LED_Off ( BLUE );
    }
    TIMER1_COMPA_INT_ENABLE;
 }

Konfiguration

Die Netzwerkeinstellungen wie IP-Adresse und WLAN-Konfigurationen können in der Datei wlan.c vorgenommen werden. Die vorgegebene IP-Adresse 192.168.1.99 muss wahrscheinlich den eigenen Gegebenheiten angepasst werden ebenso wie die WLAN-Einstellungen.

Derzeit sind die Einstellungen noch "hardcoded", d.h. der Quelltext muss neu compiliert und an den ATMega8 übertragen werden. Am einfachsten geschieht dies mit dem AVR-Studio 4. Ein entsprechendes Projektfile ist im Quelltext enthalten.

Wichtig beim Programmieren des ATMega 8 ist die korrekte Einstellung der Fuses, insbesondere für den externen Quarz. Ich habe folgende Einstellungen verwendet:

ATMega 8 Fuse Settings

Zum Ansteuern der WLAN-RGB LEDs ist unter den Downloads ein Windows-Programm wahlweise als Executable oder als Source-Code zu finden. Das Programm kann nach eingenen Wünschen modifiziert werden oder als Ausgangspunkt für eine entsprechende Eigenentwickung eines dienen. Beim Testen ist darauf zu auchten, das auch im Windows-Programm die IP-Adresse der WLAN-RGB Leuchte verwendet wird.

Ein Port des Windows Programmes z.B. nach Linux ist ohne weiteres möglich. Es ist nur eine entsprechende UDP-Message zu generieren und an die IP der WLAN-RGB Lampe zu schicken.

WLAN-Router Probleme

Nachdem ich vermehrt Rückmeldungen wegen Verbindungsproblemen des ZG2100 WLAN-Moduls erhalten hatte, habe ich den Treiber um Log-Statements erweitert. Beim Testen beobachtete auch ich, dass ZG2100 sich anscheindend nicht mit allen WLAN-Routern verträgt. Der Verbindungsaufbau zu einem Netgear WGR614 V6 gelang sowohl mit eingeschalteter WPA-Security wie auch mit abgeschalteter Verschlüsselung ohne Probleme. Der Verbindungsaufbau zu einem WLAN-Router WN802T V2, ebenfalls von der Firma Netgear, gelang dagegen nicht.

Die Logfiles und der erweiterte Quelltext für das WLAN-Modul sind bei den Downloads zu finden.

AVR Webring