Dienstag, 10. Januar 2012

Selbstbau eines RGB LED Controllers

Im folgenden beschreibe ich wie ich einen mit RGB-LEDs hinterleuchteten Bilderrahmen für das Wohnzimmer realisiert habe. Die Bilder unten zeigen den Rahmen.





Neben festen Farben können auch zufällige Farben und Farbverläufe per Fernbedienung gewählt werden.

Bau- und Schaltungsbeschreibung:

Eine (silikonvergossene) RGB-LED Leiste wurde in 9 Teilstücke a 3 LEDs (in Serie geschaltet ) zerteilt, und diese (parallel geschaltet) in regelmäßigen Abständen an der Rückseite eines Bilderrahmens angebracht.
 


Als Versorgungsspannung der LEDs dient ein stabilisiertes 12V Steckernetzteil (4.8W). Für jeden 'Farbkanal' ist zusätzlich ein Vorwiderstand in den Teilstücken der RGB-Leiste vergossen. 331 Ohm für rot, und 133 Ohm für grün und blau, um die unterschliedlichen Flußspannungen der LEDs zu kompensieren  (ca. 1.8V für rot, 2,8V für grün und 2,9V für blau).  Die Stromaufnahme eines Teilstücks der Leiste liegt damit bei ca 20mA für jeden Farbkanal, und die gesamte maximale Stromaufnahme bei 9 x 3 x 20mA = 540mA (wenn alle Kanäle voll ausgesteuert sind). Die Ansteuerung der RGB-Kanäle erfolgt in  Pulsbreitenmodulation (PWM) bei einer Auflösung von 8 bit. Hierfür werden die Timer (1A, 1B und 2) eines ATMega8 controllers von Atmel verwendet. Das Programm wurde vollständig in BASCOM geschrieben. Der Code ist im Anhang aufgeführt. Das Bild unten zeigt die Belegung des controllers.



Die PWM Signale an den Augängen PB3, PB2 und PB1 sind über 10 kOhm Widerstande an die Gatekontakte von N-Kanal PowerMos-FETs gelegt. Die MOS-FETs schalten die Kathode der  RGB-LEDs (common anode)  gegen Masse (source) durch. Die Versorgung des controllers erfolgt über einen Festspannungsregler mit Siebkondensatoren von 0.22µF und 0.1µF. Das LCD Display hängt an den Datenleitungen PD4-7 sowie PB0. Über ein IR Empfängermodul (TSOP 1836) können an PD2 Signale im Philipsstandard RC5 von einer Fernbedienung empfangen werden (der Empfänger ist im Bild oben zu sehen). Desweiteren sind die Anschlüsse der ISP Schnittstelle (In System Programmable) nach Außen geführt. 

Das geöffnete Modul ohne controller:




  Das fertige Modul:










Beschreibung der Displayanzeige:

  • A = Adresscode der Fernbedienung
  • C = letzter Kommandocode der Fernbedienung
  • V = eingestellte Helligkeit
  • S = eigestellte Geschwindigkeit
  • R = PWM Ausgabewert Rot
  • G = PWM Ausgabewert Grün
  • B = PWM Ausgabewert Blau

Belegung der Fernbedienung:


 

  • Taste Power: Alle Ausgänge auf Null setzen
  • Taste 1: rote LEDs einschalten
  • Taste 2: grüne LEDs einschalten
  • Taste 3: blaue LEDs einschalten
  • Taste 4: Hellviolett mischen (162, 65, 106)
  • Taste 5: Cyan mischen (48, 136, 122)
  • Taste 6: Weiss mischen
  • Taste 7 (Programm 1): Farbverlauf im RGB Raum anzeigen
  • Taste 8 (Programm 2): Zufallsfarben aus einer Tabelle 'satter' Farben anzeigen
  • Taste 9 (Programm 3): Farbverlauf von in der Helligkeit an- und abschwellenden 'leichten' Farben anzeigen
  • Taste Menue (Programm 4): Farbton einstellen, Taste F1: R verringern, Taste F3: R erhöhen, Taste Punkt: G verringern, Taste Exit: G erhöhen, Taste Rückwärts: B verringern, Taste Vorwärts: B erhöhen
  • Ch. + Taste: Geschwindigkeit der Programme erhöhen (funktioniert noch nicht richtig)
  • Ch. - Taste: Geschwindigkeit der Programme vermindern (funktioniert noch nicht richtig)
  • Vol. + Taste: Helligkeit erhöhen
  • Vol. - Taste: Helligkeit verringern

Bauteilliste:

Bauteil Typ
Controller Atmega8, 28 DIL
Festspannungswandler 5V LM7805CT
Kondensator (lt. Datenblatt für 78xx) 0.22 µF
Kondensator (lt. Datenblatt für 78xx) 0,1 µF
IR Empfänger Modul  (36kHz) TSOP 1836
LCD Display 16*2 HDD44780 kompatibel
Kondensator (lt. Datenblatt IR Modul) 4,7µF
Widerstand (lt. Datenblatt IR Modul) 100 Ohm
IR Universal Fernbedienung RC5 fähig (Phillips) Vivanco UR12
Power MOS FET IRF520N
Vorwiderstand MOS FET 10k Ohm
RGB Strip 12V, 30 LEDs, ca.1m
DIL Sockel                                                          


28 pin 


Der Programmcode:

'******************************************************************************
'*
'* Programm Titel rgb_ir_fader_ATmega8.bas
'* Compiler: BASCOM-AVR v1.11.9.0
'* Processor: Atmel ATmega8
'* Programm Funktion: RGB Fader mittels IR RC5 Fernbedienung
'*
'******************************************************************************
'*
'* Komponenten:
'* ATmega8
'* TSOP 1136 IR Empfangsdiode
'* IR Universal Fernbedienung RC5 fähig (Philips TV)
'* 5V Festspannungswandler 78L05
'* optional LCD Display (HDD44780 kompatibel)
'* RGB LED's
'*
'******************************************************************************

$regfile = "m8def.dat"
$lib "mcsbyte.lbx"
$crystal = 8000000
$hwstack = 64
$swstack = 16
$framesize = 21

'LCD einbinden
Config Lcdpin = Pin , Db4 = Portd.5 , Db5 = Portd.6 , Db6 = Portd.7 , Db7 = Portb.0 , E = Portd.3 , Rs = Portd.4
Config Lcd = 16 * 2
'RC5 (TSOP1836) auf PIN D2 (INT0, Timer0)
Config Rc5 = Pind.2
Enable Interrupts

'Timer1 und Timer2 für PWM Betrieb initialisieren
Config Timer1 = Pwm , Pwm = 8 , Compare A Pwm = Clear Down , Compare B Pwm = Clear Down , Prescale = 1
Config Timer2 = Pwm , Pwm = On , Compare Pwm = Clear Up , Prescale = 1

Config Pinb.3 = Output                                      'PWM Output rot Timer2
Config Pinb.2 = Output                                      'PWM Output grün Timer1
Config Pinb.1 = Output                                      'PWM Output blau Timer1

Enable Timer1
Enable Timer2
Start Timer1
Start Timer2

Out_red Alias Ocr2                                          'PIN 17 PB3
Out_green Alias Ocr1bl                                      'PIN 16 PB2
Out_blue Alias Ocr1al                                       'PIN 15 PB1

Out_red = 0                                                 'Pulsbreite rot = 0
Out_green = 0                                               'Pulsbreite grün = 0
Out_blue = 0                                                'Pulsbreite blau = 0

Dim i As Word , j As Word , k As Word , l as Word , m as word , Vol_table2 as Word , Color As Word , prog as Word , red as word , green as word , blue as word , hold as Word
Dim vol_fader_1 as Word , vol_fader_2 as Word , vol_fader_3 as Word , vol_fader_4 as Word , vol_fader_5 as Word , vol_fader_6 as Word
Dim Address As Byte , Command As Byte , Vol As Byte , Speed as Byte
Dim S1 As String * 74 , S_out as String * 16 , S2 as String * 64
Dim Table1(42) as Word
Dim Table2(180) as Word
dim pow(70) as word
dim waiting(10) as word
Declare Sub Color_set_fader(byval Hue As Word)
Declare Sub Check_input
Declare Sub pwm_out_table1
Declare Sub pwm_out_table2
Declare Sub LCD_out

Color = 0
speed = 5
Vol = 40

for k = 0 to 41
    Table1(k + 1) = Lookup(k , Table1)
next k
for k = 0 to 14
    Table2(k + 1) = Lookup(k , Table2)
next k
for k = 0 to 69
    pow(k + 1) = Lookup(k , pow)
next k
for k = 0 to 5
    pow(k + 1) = Lookup(k , waiting)
next k

k = 0

Cursor off noblink
Cls
locate 1 , 1
lcd "Dr. Lermer"
locate 2 , 1
lcd "electronics"
wait 2
cls
locate 1 , 1
lcd "presents: remote"
locate 2 , 1
lcd "RGB-Fader"

'Hauptroutine
Do
 Getrc5(address , Command)
  If address = 8 Then                                       'Code 316 von Universal Fernbedienung UR12 auf AUX1 (Sat Receiver nach RC5 Protokoll)
    Command = Command And &B01111111                        'toggle bit löschen
    Check_input
    'LCD_out
  end if

  'Programm 1 - Hue fader
  S1 = "Take a walk through RGB space by cross fading hue values                  "
  i = 0 : l = 1
  If prog = 1 Then
  do
    vol_fader_1 = 255 * pow(vol + 1) : vol_fader_1 = vol_fader_1 \ 100
    vol_fader_2 = 2 * vol_fader_1                           'Stützstellen berechnen
    vol_fader_3 = 3 * vol_fader_1
    vol_fader_4 = 4 * vol_fader_1
    vol_fader_5 = 5 * vol_fader_1
    vol_fader_6 = 6 * vol_fader_1
    k = 1530 \ vol_fader_6
    j = i \ k                                               'bei kleiner Vol gleiche Hue Werte öfter aufrufen
    Call Color_set_fader(j)
    Incr i
    j = i Mod 3                                             'Fernbedienung bei jedem dritten Durchlauf abfragen
    If j = 0 Then
      Getrc5(address , Command) : Command = Command And &B01111111
      Check_input
    End If
    j = i mod 12                                            'nach jedem 12ten Durchlauf Laufschrift weiterschieben
    if j = 0 then
      if l > 58 then : l = 1 : end if
      cls
      Locate 1 , 1
      Lcd "V" ; Vol ; " S" ; Speed
      Locate 2 , 1
      S_out = mid(S1 , l , 16) : LCD S_out
      incr l
    end if
    waitus waiting(speed)
  Loop Until i = 1530 Or prog <> 1
  End If

  'Programm 2 - Zufallszahlen aus Tabelle anzeigen
  if prog = 2 then
  color = rnd(13) : pwm_out_table1
  i = 0
  do
  incr i
  j = i Mod 3
  If j = 0 Then
    Getrc5(address , Command) : Command = Command And &B01111111
    Check_input
  End If
  waitus waiting(speed)
  loop until i = 300 or prog <> 2
  end if

  'Programm 3 - An- und abschwellende leichte Farben anzeigen
  S2 = "Enjoy the change in brightness of light colors                  "
  if prog = 3 then
  Color = 0 : m = 1
  do
    i = 0
    do
    vol_fader_1 = 255 * pow(vol + 1) : vol_fader_1 = vol_fader_1 \ 100
    k = 255 \ vol_fader_1
    j = i \ k
    if i = 255 then
    incr color
    end if
    if j < vol_fader_1 then
    vol_table2 = vol_fader_1 - j
    pwm_out_table2
    elseif j > vol_fader_1 then
    vol_table2 = j - vol_fader_1
    pwm_out_table2
    end if
    k = i Mod 3                                             'Fernbedienung bei jedem dritten Durchlauf abfragen
    If k = 0 Then
      Getrc5(address , Command) : Command = Command And &B01111111
      Check_input
    End If
    k = i mod 12                                            'nach jedem 12ten Durchlauf Laufschrift weiterschieben
    if k = 0 then
      if m > 48 then : m = 1 : end if
      cls
      Locate 1 , 1
      Lcd "V" ; Vol ; " S" ; Speed
      Locate 2 , 1
      S_out = mid(S2 , m , 16) : LCD S_out
      incr m
    end if
    incr i
    waitus waiting(speed)
    loop until i = 510 OR prog <> 3
  loop until Color = 4 or prog <> 3
  end if

  'Programm 4 - Farbton einstellen
  if prog = 4 then
  Getrc5(address , Command) : Command = Command And &B01111111
  Check_input
  if command = 85 and out_red > 1 then                      'Taste F1 - out_red verringern
  out_red = out_red -2 : LCD_out
  end if
  if command = 86 and out_red < 254 then                    'Taste F3 - out_red erhöhen
  out_red = out_red + 2 : LCD_out
  end if
  if command = 60 and out_green > 1 then                    'Taste Punkt - out_green verringern
  out_green = out_green -2 : LCD_out
  end if
  if command = 56 and out_red < 255 then                    'Taste Exit - out_green erhöhen
  out_green = out_green + 1 : LCD_out
  end if
  if command = 46 and out_blue > 1 then                     'Taste Rueckwärts - out_blue verringern
  out_blue = out_blue -2 : LCD_out
  end if
  if command = 42 and out_red < 254 then                    'Taste Vorwärts - out_blue erhöhen
  out_blue = out_blue + 2 : LCD_out
  end if
  end IF

Loop
end                                                         'Ende Hauptprogramm




Sub Color_set_fader(byval Hue As Word)
    If Hue < vol_fader_1 Then
    Out_red = vol_fader_1
    Out_green = Hue
    Out_blue = 0
    Elseif Hue < vol_fader_2 Then
    Out_red = vol_fader_2 - Hue
    Out_green = vol_fader_1
    Out_blue = 0
    Elseif Hue < vol_fader_3 Then
    Out_red = 0
    Out_green = vol_fader_1
    Out_blue = Hue - vol_fader_2
    Elseif Hue < vol_fader_4 Then
    Out_red = 0
    Out_green = vol_fader_4 - Hue
    Out_blue = vol_fader_1
    Elseif Hue < vol_fader_5 Then
    Out_red = Hue - vol_fader_4
    Out_green = 0
    Out_blue = vol_fader_1
    Elseif Hue < vol_fader_6 Then
    Out_red = vol_fader_1
    Out_green = 0
    Out_blue = vol_fader_6 - Hue
    End If
End Sub


Sub Check_input()
If Command = 12 Then
prog = 0                                                    ' Power Taste - alles auf 0
Out_red = 0
Out_blue = 0
Out_green = 0
LCD_out
End If

If Command = 1 Then                                         ' Taste 1 - rote LED einschalten
prog = 0 : Color = 0 : pwm_out_table1
End If

If Command = 2 Then
prog = 0 : Color = 1 : pwm_out_table1                       ' Taste 2 - grüne LED einschalten
End If

If Command = 3 Then                                         ' Taste 3 - blaue LED einschalten
prog = 0 : Color = 2 : pwm_out_table1
End If

If Command = 4 Then                                         ' Taste 4 - Farbe Hellviolett mischen [162, 65, 106]
prog = 0 : Color = 3 : pwm_out_table1
End If

If Command = 5 Then                                         ' Taste 5 - Farbe Cyan mischen [48, 136 , 122]
prog = 0 : Color = 4 : pwm_out_table1
End If

If Command = 6 Then                                         ' Taste 6 - Farbe weiß mischen
prog = 0 : Color = 5 : pwm_out_table1
End If

If Command = 7 Then                                         ' Taste 7 - Fader
prog = 1
End If

If Command = 8 Then                                         ' Taste 8 - Zufallsfarben
prog = 2
End If

If Command = 9 Then                                         ' Taste 9 - Abfolge leichter Farben
prog = 3
End If

If Command = 82 Then                                        ' Taste Menu - Farben mit Funktionstasten einstellen
prog = 4
Out_red = 127
Out_blue = 127
Out_green = 127
End If

If Command = 16 And Vol < 70 Then                           ' Vol.+ Taste gedrückt - Helligkeit rauf
   Vol = vol + 1
   select case prog
   case 0 : pwm_out_table1
   case 1 : i = 1530
   case 2 : pwm_out_table1
   case 3 : j = 510
   end SELECT
End If

If Command = 17 And Vol > 0 Then                            ' Vol.- Taste gedrückt - Helligkeit runter
   Vol = vol - 1
   select case prog
   case 0 : pwm_out_table1
   case 1 : i = 1530
   case 2 : pwm_out_table1
   case 3 : j = 510
   end SELECT
End If

If Command = 32 And speed < 10 Then
speed = speed + 1                                           ' Ch. + Taste - Geschwindigkeit erhöhen
End If

If Command = 33 And speed > 0 Then
speed = speed - 1                                           ' Ch. - Taste - Geschwindigkeit vermindern
End If
End Sub


sub pwm_out_table1()
  l = Color * 3
  red = Table1(l + 1) * pow(vol + 1) : red = red \ 100 : Out_red = red
  green = Table1(l + 2) * pow(vol + 1) : green = green \ 100 : Out_green = green
  blue = Table1(l + 3) * pow(vol + 1) : blue = blue \ 100 : Out_blue = blue
  LCD_out
end sub


sub pwm_out_table2()
  l = Color * 3
  red = Table2(l + 1) * vol_table2 : red = red \ 255 : Out_red = red
  green = Table2(l + 2) * vol_table2 : green = green \ 255 : Out_green = green
  blue = Table2(l + 3) * vol_table2 : blue = blue \ 255 : Out_blue = blue
end sub


sub LCD_out
    cls
    Locate 1 , 1
    Lcd "A" ; Address ; " C" ; Command ; " V" ; Vol ; " S" ; Speed
    Locate 2 , 1
    Lcd "R" ; out_red ; " G" ; Out_green ; " B" ; Out_blue
end sub


Table1:
data 255% , 0% , 0% , 0% , 255% , 0% , 0% , 0% , 255% , 162% , 65% , 106% , 48% , 136% , 122% , 255% , 255% , 255%
data 154% , 94% , 56% , 142% , 109% , 46% , 113% , 128% , 53% , 61% , 141% , 52% , 43% , 138% , 111% , 80% , 97%
data 204% , 132% , 49% , 194% , 162% , 65% , 106%

Table2:
data 225% , 139% , 156% , 198% , 174% , 114% , 144% , 199% , 118% , 115% , 199% , 175% , 151% , 162% , 255%

pow:
data 12% , 13% , 13% , 13% , 14% , 14% , 15% , 15% , 16% , 16% , 17% , 17% , 18% , 18% , 19% , 19% , 20% , 21% , 21% , 22% , 22%
data 23% , 24% , 25% , 25% , 26% , 27% , 28% , 29% , 30% , 30% , 31% , 32% , 33% , 34% , 36% , 37% , 38% , 39% , 40% , 41% , 43%
data 44% , 45% , 47% , 48% , 50% , 51% , 53% , 54% , 56% , 58% , 60% , 61% , 63% , 65% , 67% , 69% , 72% , 74% , 76% , 78% , 81%
data 83% , 86% , 89% , 91% , 94% , 97% , 100%

waiting:
data 5000% , 4000% , 3000% , 1000% , 1000% , 500% , 300% , 100% , 50% , 10%

1 Kommentar:

  1. Hi,
    veröffentlichst du den Bascom-Programmcode auch?
    Versuche was ähnliches zu bauen, scheitere aber an dem RC5-Verarbeiten ;(

    AntwortenLöschen