RGB-Led WS2812 und Bascom          

von Heinz D.                   
Elektronik-Labor  Projekte  AVR 



20 x SMD-LED WS2812S RGB 5050 PLCC6 mit integriertem WS2811 Controller



Wie wäre es mit Bascom und der RGB-Led Ws2812(WS2811)?  Sie enthält ein Controllerchip, der die 3 Farben mit je 256 Helligkeiten steuert.



Der Verdrahtungsaufwand für ein recheckiges Array hält sich in Grenzen (3-draht). Für jede RGB-Led werden 3*8Bit an die erste Led (auf Din) gesendet. Die zweiten 3*8Bit werden von der Led (über Dout) an die nächste durchgereicht, und so weiter. Die gesendeten Farben und Helligkeiten bleiben bis zum RESET erhalten. 





Ein Array mit 8*8=64 RGB-Led erfordert ein Netzteil mit 64*60mA=3,84A (5V/20W). Bei diesen Strömen sind die Versorgungsleitungen sorgfältig auszulegen. Die Kühlung ist auch nicht vernachlässigbar. Jede Led verursacht ~0,25W Wärme.

WARNUNG: Durch falsches Timing sollen schon RGB-Led gestorben sein! Die Benutzung des Programm erfolgt daher auf eigene Gefahr! Das Datenblatt hält noch eine Falle bereit: Werden zwei Stromquellen benutzt, MUSS die Led-Quelle zuerst eingeschaltet werden! Aus diesem Grund haben wir 10k in Reihe mit Din geschaltet, um den Eingang nicht abzufackeln.

Das Programm
Bleiben die Telegramme für mehr als 50us aus, werden alle RGB-Led RESETet. Das Senden eines kompletten Telegramms erfolgt über einen beliebigen Port-Pin. In der Subroutine ist B.0 eingestellt.




Die Übertragungszeit für eine RGB-Led dauert demnach 3Farben*8Bit(Helligkeit)*1250ns=30us. Bis ~2000 (40*50) RGB-Led (600W) lassen sich noch flackerfreie 'Bilder' darstellen. In der asm-Subroutine 'SEND' wird das ganze RGB-Feld an einen Port-Pin gesendet. Durch ein Wait bleibt das Feld bis zur nächsten Sendung erhalten.

Tiny13/9,6MHz: Für den T13 wird die Kompilierung 8MHz-10,7MHz gewählt. In der Main-Loop können verschiedene Muster angelegt werden oder von der seriellen Schnittstelle gelesen werden. Im Beispiel-Programm ist das Zufallsmuster für 12 RGB-Led (oder weniger) kompiliert. Die Helligkeit ist auf 0-15 von 255 eingestellt, um nicht gleich die Netzhaut weg zu brennen.

Mega8/8MHz: Für den M8 kann bei Zeile ~70 das NOP entfernt werden, falls die Darstellung flackert. Ohne NOP sollten das Timing von 7,5MHz-8,5MHz passen.

Mega../16MHz: Für einen schnellen Mega wird die Kompilierung auf MHz=12 eingestellt. Das Timing passt dann für 12MHz-16,9MHz.

Ohne Assembler geht es in Bascom leider nicht. Die SEND-Subroutine ist Byte-orientiert. Somit lassen sich RGB-Felder von max. 255/3=85 RGB-Led ansteuern.

16,77Mio Farben machen Spaß und lassen sich sicher auch für die optische Bank einsetzen, um Filter interaktiv zu bestimmen. (Das wäre eine andere/neue Baustelle.)


Downlaod: 1312-WS2812-T13.zip


'( 1312-WS2812-T13, Test für max. 12 RGB-Led
BENUTZUNG AUF EIGENE GEFAHR

Achtung : Stromquelle Vor Oder Gleichzeitig Mit Der Datenleitung Anlegen!
Zur Sicherheit wird ein 10k in Reihe mit der Datenleitung Din geschaltet.
Das Rgbfeld wird mit Daten gefüllt,

T0H=250-550 + T0L=700-1000 / T1H=650-950 + T1L=300-600
bedingte Kompilierung für das Maschinensprache-Sub:
MHz= 8 8,0MHz -> 500ns+1000ns/ 875ns+500ns
9,6MHz -> 417ns+ 833ns/ 729ns+417ns
MHz=12 12 MHz -> 500ns+1000ns/ 916ns+500ns
16 MHz -> 375ns+ 750ns/ 688ns+375ns
################################################################################
')
Const Mhz = 8 ' 8-10,7MHz 4+ 8/ 7+4 Cyclen
'Const Mhz = 12 '12-16,9MHz 6+12/11+6 Cyclen

'$PROG &HFF,&H7A,&HFF,&H00' generated. Take care that the chip supports all fuse bytes.
$regfile = "attiny13.dat"
$crystal = 9600000
$hwstack = 8
$swstack = 4
$framesize = 8

Open "comb.4:9600,8,n,1,inverted" For Input As #2 'B.4 <- com-Daten
Ddrb = 1 'B.0 = &18 , 0

Declare Sub Send 'asm-Subroutine
Dim Rgbfeld(36) As Byte 'max.12Led -> r0
Dim Bytmax As Byte : Bytmax = 36 '3*rgb-led -> r17
Dim Inbyte As Byte 'vom com-Port
Dim Index As Byte 'wie der Name sagt

Do 'Main-Loop
'aus Dta1 lesen
' Restore Dta1 : For Index = 1 To Bytmax : Read Rgbfeld(index) : Next Index
'aus com-Port lesen
' Inbyte = Inkey(#2) : If Inbyte > 0 Then : Rgbfeld(index) = Inbyte : If Index >= Bytmax Then Index = 1 Else Incr Index : End If
'Zufallsmuser ausgeben
For Index = 1 To Bytmax : Rgbfeld(index) = Rnd(15) : Next Index : Send : Wait 1
'Ampel
' Restore Dta2 : For Index = 1 To Bytmax : Read Rgbfeld(index) : Next Index : Send : Wait 5 'grün
' Restore Dta3 : For Index = 1 To Bytmax : Read Rgbfeld(index) : Next Index : Send : Wait 2 'gelb
' Restore Dta4 : For Index = 1 To Bytmax : Read Rgbfeld(index) : Next Index : Send : Wait 5 'rot
' Restore Dta5 : For Index = 1 To Bytmax : Read Rgbfeld(index) : Next Index : Send : Wait 2 'rotgelb
Loop
'###############################################################################
Sub Send
push r17 '2
push r16 '2
push r0 '2
Loadadr Bytmax , X 'Bytmax holen
ld r17,x '1
Loadadr Rgbfeld(1) , X 'Feldadr holen
Nextbyte:
ld r0,x+ '2
ldi r16,8 '1
Nextbit:
' T0H=250-550 + T0L=700-1000 / T1H=650-950 + T1L=300-600
' 62,5-137,5 87,5-125 92,9-135,7 75-150
'4+8/7+4 -------------------------------------
#if Mhz = 8 '8 MHz-10,76 MHz
Sbi $18 , 0 '2 <- 2 2
lsl r0 '1 1 1
brcs Bit1 '1/2 1 2
Bit0:
cbi $18 , 0 '2 <- 2
Bit1:
Nop '1 1 1 * ggf. für M8/8M entfernen
dec r16 '1 1 1
cbi $18 , 0 '2 <- 2 2
brne Nextbit '1/2 2 2
#endif
' 41,7-91,7 58,3-83,3 59,1-86,4 50-100
'6+12/11+6 -------------------------------------
#if Mhz <> 8 '12 MHz-16,92 MHz
Sbi $18 , 0 '2 <- 2 2
nop '1 1 1
Nop '1 1 1
lsl r0 '1 1 1
brcs Bit1 '1/2 1 2
Bit0:
cbi $18 , 0 '2 <- 2
Bit1:
Nop '1 1 1
Nop '1 1 1
Nop '1 1 1
dec r16 '1 1 1
cbi $18 , 0 '2 <- 2 2
Nop '1 1 1
nop '1 1 1
brne Nextbit '1/2 2 2
#endif
'-------------------------------------------------------------------------------
Waitus 5
dec r17 '1
cpi r17,0 '1
brne Nextbyte '1/2
'---
pop r0 '2
pop r16 '2
pop r17 '2
End Sub
'################################################################################
Dta1:
' grün rot blau
Data &H0F , &H00 , &H00 'grün
Data &H00 , &H0F , &H00 'rot
Data &H00 , &H00 , &H0F 'blau
Data &H0F , &H0F , &H00 'gelb
Data &H0F , &H00 , &H0F 'cyan
Data &H00 , &H0F , &H0F 'magenta
Data &H0F , &H0F , &H0F 'weiss
Data &H00 , &H00 , &H00 'schwarz
Data &H0F , &H00 , &H00 'grün
Data &H00 , &H0F , &H00 'rot
Data &H00 , &H00 , &H0F 'blau
Data &H0F , &H0F , &H00 'gelb
Data &H0F , &H00 , &H0F 'cyan
Data &H00 , &H0F , &H0F 'magenta
Data &H0F , &H0F , &H0F 'weiss
Data &H00 , &H00 , &H00 'schwarz

Dta2:
' grün rot blau
Data &H0F , &H00 , &H00 'grün
Data &H00 , &H00 , &H00
Data &H00 , &H00 , &H00
Data &H00 , &H00 , &H00
Data &H00 , &H00 , &H00
Data &H00 , &H0F , &H00 'rot
Data &H00 , &H00 , &H00
Data &H00 , &H00 , &H00
Data &H00 , &H00 , &H00
Data &H00 , &H0F , &H00 'rot

Dta3:
' grün rot blau
Data &H00 , &H00 , &H00
Data &H0F , &H0F , &H00 'gelb
Data &H00 , &H00 , &H00
Data &H00 , &H00 , &H00
Data &H00 , &H00 , &H00
Data &H00 , &H0F , &H00 'rot
Data &H00 , &H00 , &H00
Data &H00 , &H00 , &H00
Data &H0F , &H0F , &H00 'gelb
Data &H00 , &H0F , &H00 'rot

Dta4:
' grün rot blau
Data &H00 , &H00 , &H00
Data &H00 , &H00 , &H00
Data &H00 , &H0F , &H00 'rot
Data &H00 , &H00 , &H00
Data &H0F , &H00 , &H00 'grün
Data &H00 , &H00 , &H00
Data &H00 , &H00 , &H00
Data &H0F , &H00 , &H00 'grün
Data &H00 , &H00 , &H00
Data &H00 , &H00 , &H00

Dta5:
' grün rot blau
Data &H00 , &H00 , &H00
Data &H0F , &H0F , &H00 'gelb
Data &H00 , &H0F , &H00 'rot
Data &H00 , &H00 , &H00
Data &H00 , &H00 , &H00
Data &H00 , &H0F , &H00 'rot
Data &H00 , &H00 , &H00
Data &H00 , &H00 , &H00
Data &H0F , &H0F , &H00 'gelb
Data &H00 , &H00 , &H00

'ENDE


Elektronik-Labor  Projekte  AVR