Hallo zusammen, ich habe schon ein paar Sachen mit dem Atmega hinbekommen, so z.b. ein Lauflicht (einfarbig) mit mehreren LEDs, aber bei 15 oder 20 LEDs finde ich dass dann schon lästig wenn ich 20 FETs benutzen muss. Da bin ich zufällig über die WS2812b gestolpert. Das tolle scheint zu sein, dass man mehrere LEDS hintereinander schalten kann und der Controller in der LED durch die DATA Leitung die Fatrbe selbst einstellt. Ich habe mich jetzt ein bissl durch das Forum gelesen, aber verstehe die C Codes nicht wirklich sehr gut. Könnte jemand mal ein ganz simplen Code psoten wie 3 LEDs hintereinander gesteuert werden, dann könnte ich versuchen das für meinen Fall zu erweitern. Das wäre echt nett :-)
Mike88 schrieb: > Ich habe mich jetzt ein bissl durch das Forum gelesen, aber verstehe die > C Codes nicht wirklich sehr gut. Verständlich. Weil die auf möglichst exakte Timings optimiert sind. Da das Protokoll doch recht pingelig und nicht grade langsam ist. > Könnte jemand mal ein ganz simplen Code psoten wie 3 LEDs hintereinander > gesteuert werden, dann könnte ich versuchen das für meinen Fall zu > erweitern. Die Codes sind eigentlich das Minimum. Die andere Frage ist: Hast du dir im Datenblatt mal angeschaut wie das Protokoll aussieht? Eventuell werden dir dann die Codes auch klarer. Nur rein aus den Codes kann man das Protokoll nur schwer ablesen. Als erstes solltest du mal das Datenblatt lesen und die Ansteuerung VERSTEHEN. Dann kannst du dir Gedanken um die Umsetzung machen. gruß cyblord
http://www.mikrocontroller.net/articles/WS2812_Ansteuerung Das funktionierte bei mir am Besten: https://github.com/cpldcpu/light_ws2812
1 | /*
|
2 | * Light_WS2812 library example - RGB_blinky
|
3 | *
|
4 | * cycles one LED through red, green, blue
|
5 | *
|
6 | * This example is configured for a ATtiny85 with PLL clock fuse set and
|
7 | * the WS2812 string connected to PB4.
|
8 | */
|
9 | |
10 | #define F_CPU 16000000
|
11 | |
12 | #include <util/delay.h> |
13 | #include <avr/io.h> |
14 | #include <avr/interrupt.h> |
15 | #include "light_ws2812.h" |
16 | |
17 | struct CRGB { uint8_t g; uint8_t r; uint8_t b; }; |
18 | struct CRGB led[2]; //NEU NEU NEU |
19 | |
20 | int main(void) |
21 | {
|
22 | uint8_t mask; |
23 |
|
24 | #ifdef __AVR_ATtiny10__ |
25 | CCP=0xD8; // configuration change protection, write signature |
26 | CLKPSR=1; // set cpu clock prescaler =1 (8Mhz) (attiny 4/5/9/10) |
27 | mask=_BV(PB2); |
28 | #else |
29 | CLKPR=_BV(CLKPCE); |
30 | CLKPR=0; // set clock prescaler to 1 (attiny 25/45/85/24/44/84/13/13A) |
31 | mask=_BV(PB0); |
32 | #endif |
33 | DDRB|=mask; |
34 |
|
35 | while(1) |
36 | { |
37 | led[0].r=255;led[0].g=00;led[0].b=0; // Write red to array |
38 | ws2812_sendarray((uint8_t *)&led[0],3); // Send array to WS2812 LED. The output pin is low after send. |
39 | led[1].r=0;led[0].g=255;led[0].b=0; // green LED1 NEU NEU NEU |
40 | ws2812_sendarray((uint8_t *)&led[1],3); // NEU NEU NEU |
41 | _delay_ms(500); // Issue reset and wait for 500ms. |
42 |
|
43 | led[0].r=0;led[0].g=255;led[0].b=0; // green |
44 | ws2812_sendarray((uint8_t *)&led[0],3); |
45 | _delay_ms(500); |
46 | |
47 | led[0].r=0;led[0].g=00;led[0].b=255; // blue |
48 | ws2812_sendarray((uint8_t *)&led[0],3); |
49 | _delay_ms(500); |
50 | } |
51 | }
|
Also den folgenden Code werde ich dann mal ausprobieren, muss mir aber erst noch diesen Attiny85 zulegen, habe nur einige Atmega8 hier rumliegen. Ich habe die beiden Zeilen bei denen NEU NEU NEU steht selbst eingefügt, hoffe das passt so wenn ich 2 LEDs habe
Der Code von https://github.com/cpldcpu/light_ws2812 funktioniert auch auf einem Mega, ich habe ihn auf einem Mega328 ausprobiert. Du musst nur in der light_ws2812.h den Port + die Bit-Nummer anpassen und auswählen (nicht mittel F_CPU, sondern durch das richtige define im header!!!), welche Frequenz dein System hat. DDR auf Ausgang für diesen Port nicht vergessen. für 2 LEDS musst du sendarray nur einmal aufrufen, aber mit 3*2:)
1 | led[0].r=0;led[0].g=00;led[0].b=255; // blue |
2 | led[1].r=0;led[1].g=00;led[1].b=255; // blue |
3 | |
4 | ws2812_sendarray((uint8_t *)&led[0],3*2); |
5 | // Kann man reduzieren, auf die Resetdauer, stweht irgendwo im Datenblatt
|
6 | //ich glaube 50 oder sowas. Kann man aber auch weglassen, wenn dazwischen
|
7 | // genug Code ist, das die Zeit auf jeden fall reicht.
|
8 | // Wichtig ist nur, das der Pegel auf dem Ausgang in dieser Zeit auf 0 ist.
|
9 | _delay_ms(500); |
Sven schrieb: > und auswählen (nicht mittel F_CPU, sondern durch das richtige define im > header!!!), welche Frequenz dein System hat. F_CPU wird benutzt, damit der Präprozessor bei allen Files die gleiche Frequenz berücksichtigt. Mach es bitte nicht über defines in irgendeinem header.
Pete K. schrieb: > Sven schrieb: >> und auswählen (nicht mittel F_CPU, sondern durch das richtige define im >> header!!!), welche Frequenz dein System hat. > > F_CPU wird benutzt, damit der Präprozessor bei allen Files die gleiche > Frequenz berücksichtigt. Mach es bitte nicht über defines in irgendeinem > header. Das stimmt, aber der Header "light_ws2812.h" hat keinerlei Abfragen für F_CPU implementiert, sondern basiert darauf, das dort das richtige define genutzt wird. Daher meine Warnung.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.