WS2812 Ansteuerung per Bitbanging für AVR und ARM von 4 Mhz-60 Mhz

OP #3296459
Lesenswert?

Da ich bisher hier noch keinen Beitrag geschrieben hatte, möchte ich 
noch einmal auf meine light-weight WS2812 Library hinweisen. Die Library 
nutzt Zyklengenaues CPU-Timing ("bitbanging"), um WS2812 
RGB-Leuchtdioden anzusteuern.

Der Code wird durch bedingte compilierung automatisch für die gewünschte 
Taktgeschwindigkeit der CPU ausgelegt. Für AVR gibt es implementierungen 
ab 4 Mhz, für ARM ab 8 Mhz.

Der Code kann auf Github heruntergeladen werden:

https://github.com/cpldcpu/light_ws2812

Die Implementierung über Bitbanging hat auf AVR gegenüber Ansätzen mit 
SPI und PWM den Vorteil, dass sie weniger Ressourcen benötigen und 
kleiner sind. Die CPU-Belastung ist identisch.


1
This is a small Ansi-C library to control WS2811/WS2812 based RGB Leds and strings. Only the 800kHz high-speed mode is supported. This library uses a bit-banging approach with cycle optimized assembler innerloops. Some advantages of this approach compared to existing solutions are:
2

3
    *Compatible to all AVR MCUs since it does not rely on special periphery.
4
    *Low hardware footprint: Does not rely on any timer or the USI
5
    *Much smaller program code: Size optimized assembler without unrolled loops (<50 bytes in most cases)
6
    *No initialization required
7
    *Carefully optimized to use instructions which are available on all AVR cores and have the same instruction timing across all devices.
8
    *Supports standard AVR, reduced core AVR (Attiny 4/5/9/10/20/40) and XMEGA (untested) without special case handling.
9
    *New:Supports Cortex ARM cores.
10
    *Arduino or C++ not required
11
    *Clock speeds down to 4Mhz supported.
12

13
Release History
14
===============
15

16
    v0.3 2013/05/06
17
        *Initial release. Thanks to "Matthias H." for testing with a longer led chain.
18
    v0.4 2013/05/07
19
        *General clean up
20
        *Some code size optimizations. Thanks to "Fallobst" for suggestions
21
        *Disabled interrupts in the critical sections.
22
    v0.5 2013/05/20
23
        *Fixed timing bug from size optimization
24
    v0.6 2013/05/27
25
        *Major update: Changed all port accesses from SBI/CBI to OUT. This
26
        *removes a timing inconsistency between reduced core AVR and
27
        *standard AVR, avoiding separate implementations for different            
28
        *cores. A disadvantage is increase register usage.
29
        *Added the "ws2812_sendarray_mask" function which allows to pass 
30
         a bitmask for the selected port. This allows controlling up to 
31
         8 independent LED strips.
32
        *Removed functions for interrupt handling. Avoiding interference
33
         with interrupts is now up to the user.
34
        *4 MHz clock speed is now also supported for standard core AVRs.
35
    v0.7 2013/05/28
36
        *Optimized timing and size of 8 and 12 Mhz routines. All routines
37
         are within datasheet specs now, except of 9.6 Mhz which is
38
        *marginally off but works under all test conditions
39
    v0.8 2013/06/03
40
        *9.6 Mhz implementation now within specifications.
41
        *brvs->brcs. Loops terminate correctly (thanks to Mario Pieschel).
42
    v0.9 2013/07/29
43
        *Added first version of ARM Cortex library
44
        *20 MHz AVR Version contributed by http://github.com/denimjeans
Angehängte Dateien:
Gast #3309456
Lesenswert?

Hallo, danke für den code.
Könnte jemand den assembler code so anpassen das es auch für mehr als 
256 LED-Adressen funktioniert? momentan wird der blauwert bei mir nicht 
bei der korrekten LED angezeigt wenn ich die Variablendeklaration des 
Zeigers einfach auf uint16_t ändere.

Ich nehme an das bei dem assembler teil irgendwas mit dem Überschlag 
nicht klappt.. aber da sehe ich leider nicht durch
OP #3310609
Lesenswert?

> Hallo, danke für den code.
> Könnte jemand den assembler code so anpassen das es auch für mehr als
> 256 LED-Adressen funktioniert? momentan wird der blauwert bei mir nicht
> bei der korrekten LED angezeigt wenn ich die Variablendeklaration des
> Zeigers einfach auf uint16_t ändere.


Hallo Clemens,

- Bei welcher Routine taucht das Problem genau auf? CPU? MHz?
- Warum willst Du den Zeiger auf einen 16bit Typen verändern? Die LEDs 
benötigen nur 3 bytes pro LED.
- Außer der 4 Mhz implementierung unterstützen alle Routeinen mehr als 
256 LEDs. Dazu musst Du im Code nichts ändern.
OP #3441625
Lesenswert?

V1.0!
1
 v1.0 2013/12/11  
2
 - Moved IRQ disabling to library again.
3

4

5
Troubleshooting
6

7
Only a part of the string is lighting up / all the colours are wrong
8

9
    Please check whether the correct array length was passed to the call. The value to by passed is the array-length in bytes. Therefore you have to pass the number of LEDs multiplied by three.
10

11
The LEDs are flickering and not showing the intended colour
12

13
    Are you using a bypass capacitor for each LEDs as indicated in the datasheet? Not using a bypass capacitor will lead to erroneous behaviour.
14
    Is your power supply able to supply the required current-level? If set to white at maximum brightness, each LED will require 60mA. A single USB-Port is barely able to supply 10 LEDs.
15
    Did you choose the correct CPU frequency setting? Maybe you multiplier setting is wrong?
16
    Is anything interrupting correct executing of the write-calls? Interrupts? Watch-dog?
Gast #3441654
Lesenswert?

Nett ...

Ich würde mal in deinem Repo mal irgendeine Lizenz angeben.
Es reicht nicht das du dieses per Anmeldung auf Github machst.

Ich kenne mich jetzt nicht mit den Mikrocontrollern aus (eher Linux 
Kernel)
Kann das denn noch irgendwie erweitert werden, das diese Sache per 
serieller Schnittstelle der USB gesteuert werden kann ?
OP #3441840
Lesenswert?

Hans Ulli Kroll schrieb:
> Ich würde mal in deinem Repo mal irgendeine Lizenz angeben.
> Es reicht nicht das du dieses per Anmeldung auf Github machst.

Was hat das Eine mit dem Anderen zu tun? Ich kann natürlich eine LGPL, 
GPL o.Ä. ins Repository klatschen, aber ehrlich gesagt erscheint mir so 
etwas im µC Bereich doch eher unüblich zu sein.

> Ich kenne mich jetzt nicht mit den Mikrocontrollern aus (eher Linux
> Kernel)
> Kann das denn noch irgendwie erweitert werden, das diese Sache per
> serieller Schnittstelle der USB gesteuert werden kann ?

Wie auch unter Linux, kann man mehrere Libraries kombinieren um Software 
mit der gewünschten Funktion zu entwickeln. Für AVR gibt es z.B. V-USB, 
welches eine USB Schnittstelle zur Verfügung stellt.
Gast #3441999
Lesenswert?

Tim    schrieb:
> Hans Ulli Kroll schrieb:
>> Ich würde mal in deinem Repo mal irgendeine Lizenz angeben.
>> Es reicht nicht das du dieses per Anmeldung auf Github machst.
>
> Was hat das Eine mit dem Anderen zu tun? Ich kann natürlich eine LGPL,
> GPL o.Ä. ins Repository klatschen, aber ehrlich gesagt erscheint mir so
> etwas im µC Bereich doch eher unüblich zu sein.
>

Was du damit machst ist mir ehrlich egal ...

Als großes Bespiel fällt mir sofort ContikiOS. Das soll auf verschiedene 
µC laufen.
Dieses wird für Internet of Things benutzt. Zigbee, 6lowpan usw.

>> Ich kenne mich jetzt nicht mit den Mikrocontrollern aus (eher Linux
>> Kernel)
>> Kann das denn noch irgendwie erweitert werden, das diese Sache per
>> serieller Schnittstelle der USB gesteuert werden kann ?
>
> Wie auch unter Linux, kann man mehrere Libraries kombinieren um Software
> mit der gewünschten Funktion zu entwickeln. Für AVR gibt es z.B. V-USB,
> welches eine USB Schnittstelle zur Verfügung stellt.

Danke habe ich mir gerade ansehen. USB 1.1 reicht hier dicke.

Das könnte ein Projekt für Winterabende werden
Gast #3477028
Lesenswert?

Hallo


ich verwende deine lib für den atmega1284p mit 16mhz quarz!
gut die portpins wackeln vor sich hin allerdings funktionieren tuts 
leider nicht so wie ich das will .. es leuchtet genau gar nichts. 
Leider!

Ist die Lib für den ws2811 gemacht oder nur für den ws2812???

habe mal im datenblatt ws2811 und ws2812 verglichen. Bis auf die Timings 
arbeiten die beiden genau gleich.
Das heißt ich müsste in die Funktion:
1
void ws2812_sendarray_mask(uint8_t *data,uint16_t datlen,uint8_t maskhi)
2
{
3
        irq_disable
4
        uint8_t curbyte,ctr,masklo;
5
        masklo        =~maskhi&ws2812_port;
6
        maskhi |=ws2812_port;
7
        
8
        while (datlen--) {
9
                curbyte=*data++;
10
                
11
                asm volatile(
12
                
13
                "                ldi        %0,8                \n\t"                // 0
14
                "loop%=:out        %2,        %3                \n\t"                // 1
15
                "                lsl        %1                        \n\t"                // 2
16
                "                dec        %0                        \n\t"                // 3
17

18
                "                rjmp .+0                \n\t"                // 5
19
                
20
                "                brcs .+2                \n\t"                // 6l / 7h
21
                "                out        %2,        %4                \n\t"                // 7l / -
22

23
                "                rjmp .+0                \n\t"                // 9
24
                
25
                "                nop                                \n\t"                // 10
26
                "                out        %2,        %4                \n\t"                // 11
27
                "                breq end%=                \n\t"                // 12 nt. 13 taken
28

29
                "                rjmp .+0                \n\t"                // 14
30
                "                rjmp .+0                \n\t"                // 16
31
                "                rjmp .+0                \n\t"                // 18
32
                "                rjmp loop%=                \n\t"                // 20
33
                "end%=:                                        \n\t"
34
                :        "=&d" (ctr)
35
                :        "r" (curbyte), "I" (_SFR_IO_ADDR(ws2812_port)), "r" (maskhi), "r" (masklo)
36
                );
37
        }
38
        irq_restore
39
}

wenn ich hier ein paar "nops" dazwischen reinpacke sollte es hinhauen??
kann mir hier jemand weiterhelfen? kenn mich mit assembler absolut 
nussbrot aus!
Wäre nett wenn hier jemand fix drüber sehen könnte :)
Persönliche Seite #3477070
Lesenswert?

grindguakn schrieb:
> ich verwende deine lib für den atmega1284p mit 16mhz quarz!
> gut die portpins wackeln vor sich hin allerdings funktionieren tuts
> leider nicht so wie ich das will .. es leuchtet genau gar nichts.
> Leider!

Hast du denn die Anweisungen unter "Usage" auf 
https://github.com/cpldcpu/light_ws2812 beachtet?

Ich weise mal gezielt auf den Punkt "Wait for at least 50 us before the 
next LED update to reset the chain" hin.
OP #3477553
Lesenswert?

Ich habe mir vorgenommen, das Interface zur Library zu überarbeiten, da 
sich Missverständnisse in gewissen Bereichen zu häufen scheinen. Bisher 
habe ich nur ein "Bare-Bones" Interface definiert, da ich persönlich die 
volle Kontrolle über eine Lib bevorzuge.

Das bisherige Interface besteht nur aus zwei Funktionen:
1
void ws2812_sendarray(uint8_t *ledarray,uint16_t length);
2
void ws2812_sendarray_mask(uint8_t *ledarray,uint16_t length, uint8_t mask);

Zusätzliche wird per Define manuell die zur Taktgeschwindigkeit der CPU 
passende Routine ausgewählt.

Mir schweben folgende Änderungen vor:

- Wenn keine Routine per Define ausgewählt wurde, wird versucht 
automatisch aus F_CPU eine abzuleiten.
- Es wird im Headerfile die struct cRGB definiert und als Datentyp für 
den Aufruf verwendet.

Über das bisherige Interface wird folgendes gestülpt:
1
// Führt Reset durch
2
void ws2812_setleds(cRGB *ledarray, uint16_t number_of_leds);
3
void ws2812_setleds(cRGB *ledarray, uint16_t number_of_leds,uint8_t pin);
4

5
// Führt keinen Reset durch
6
void ws2812_setleds_noreset(cRGB *ledarray, uint16_t number_of_leds);
7
void ws2812_setleds_noreset(cRGB *ledarray, uint16_t number_of_leds,uint8_t pin);
8

9
// Wartet 100 us
10
void ws2812_reset();

Denkbar wäre es auch, den Port zur Laufzeit zu übergeben. Das wäre aber 
erst ab 12MHz umsetzbar.

Eine weitere Änderung könnte sein, dass man per Define das Timing ändern 
kann, wie es in der ARM-Version jetzt möglich ist. Allerdings erscheint 
mir dieses gefährlich, da bisher jeder impulsiv etwas an den TImings 
ändern will, die wirklich Fehlerquellen bisher aber wirklich immer 
woanders zu suchen waren.

Ist das Interface soweit verständlich? Gibt es Vorschläge zur Änderung 
der Namen?
Gast #3477844
Lesenswert?

Hallo
Also ich verwende diese 
http://m.ebay.com/itm/310772659909?nav=SEARCH&sbk=1 LED Pixel! Habe 
zurzeit testweise 1 Stück probiert!

Zur Schaltung ich habe ein Atmega1284p Board und die Pixel werden mit 
einem stabilisierten Netzteil versorgt also Spannungseinbrüche etc. Kann 
ich ausschließen.

Zur Software: ich habe das testbsp von github verwendet, demnach sollte 
es auch keine Probleme mit reset Zeiten geben .. (Software kann ich bei 
Bedarf posten! Bin aber nur am Handy)

Pb0 habe ich mir oszi nachgemessen und ja es toggelt! Allerdings reicht 
die Bandbreite meines oszis ansxheinend nicht da ich nur mehr Impulse 
erkennen kann..

Kann es eventuell sein dass ich einen pull up oder so benötige?
Oder muss ich den Portpin irgendwie initialisieren??

MfG und danke schon mal für die Hinweise!
OP #3478108
Lesenswert?

Grindguakn schrieb:
> Pb0 habe ich mir oszi nachgemessen und ja es toggelt! Allerdings reicht
> die Bandbreite meines oszis ansxheinend nicht da ich nur mehr Impulse
> erkennen kann..

Das sind gerade mal 1Mhz, mit einem 20MHz Osci sollte man etwas sehen 
können. Du kannst ja die Warteschleife einmal entfernen, dann sollte man 
auch vernünftig triggern können.

Grindguakn schrieb:
> Also ich verwende diese
> Ebay-Artikel Nr. 310772659909 LED Pixel! Habe
> zurzeit testweise 1 Stück probiert!

Wie gesagt, mit dem WS2811 habe ich keine Erfahrung. Es kann sein, dass 
das Timing wirklich anders ist. Du solltest auf jeden Fall zunächst 
überprüfen, ob Deine Clock Settings wirklich auf 16MHz sind. Ist der 
Divider richtig konfiguriert, oder läuft dein MCU vielleicht doch mit 
8MHz? Ist der WS2811 auch im high-speed Mode konfiguriert? Hast Du evtl. 
eine echte WS2812 LED, um zu testen ob alles funktioniert?

Anonsten könntest Du tatsächlich versuchen, dass Timing zu verändern und 
zu sehen ob es dann besser wird. Als erstes würde ich versuchen das 
Timing für die "1" zu verlängern. Dazu kannst Du an der markierten 
Stelle ein oder mehrere NOPS einfügen.
1
          "                dec        %0                        \n\t"
2

3
                "                rjmp .+0                \n\t"
4
                
5
                "                brcs .+2                \n\t" 
6
                "                out        %2,        %4                \n\t"
7

8
                "                rjmp .+0                \n\t" 
9
<<<------------ hier nops einfügen ------------ >>>
10
                
11
                "                nop                                \n\t"
Gast #3478432
Lesenswert?

naja da Uart funktioniert habe ich mal stark angenommen dass die quarz 
einstellungen passen. habe deinen Vorschlag befolgt und gemessen und ich 
hatte immer 0,6µS..

allerdings ist mir aufgefallen, dass auf meinem Board an PB0 eine 
DebugLED war ^^ Die hat den Fehler verursacht anscheinend... LED weg, 
prima funktioniert!


Jedenfalls in diesem Sinne Vielen Dank für deine Hilfe und natürlich 
auch für die Lib! vielleicht kommen am Ende von meinem Projekt ein paar 
nützliche Funktionen für eine API zu deinem Projekt.


mfg
OP #3494723
Lesenswert?

Ich habe soeben den ersten Release der V2 fertiggestellt. Im Vorfeld 
habe ich das Timing der WS2812 noch einmal genau untersucht, um die 
korrekte Ansteuerung von allen Devices sicherzustellen:

http://cpldcpu.wordpress.com/2014/01/14/light_ws2812-library-v2-0-part-i-understanding-the-ws2812/

Die Vorteile der neuen Version gegenüber der alten:

-Vereinfachtes Interface zur Ansteuerung.
-Es werden beliebige CPU Taktfrequenzen ab 4 MHz unterstützt. Das Timing 
wird währed der Compilierung automatisch aus "F_CPU"  bestimmt.

Download: https://github.com/cpldcpu/light_ws2812


1
Description
2
===========
3

4
This is a small Ansi-C library to control WS2811/WS2812 based RGB Leds and strings. 
5
Only the 800kHz high-speed mode is supported. This library uses a bit-banging approach with cycle optimized assembler innerloops. 
6

7
Some advantages of this approach compared to other solutions are:
8

9
    Compatible to all AVR MCUs since it does not rely on special periphery.
10
    The code timing is automatically adjusted for CPU clock speeds from 4 Mhz up to the maximum on AVR.
11
    Much smaller program code: Size optimized assembler without unrolled loops (<50 bytes in most cases)
12
    Supports standard AVR, reduced core AVR (Attiny 4/5/9/10/20/40) and XMEGA (untested) without special case handling.
13
    Arduino or C++ not required
14
    New: Experimental Cortex-M0 ARM core.
15

16
The timing values used in the library were adjusted to work on all devices. Look here for details
17

18
Usage
19
=====
20

21
    Add "light_ws2812.c", "light_ws2812.h" and "ws2812_config.h" to your project.
22
    Update "ws2812_config.h" according to your I/O pin.
23
    Make sure F_CPU is correctly defined in your makefile or the project.
24
   (For AtmelStudio: Project->Properties->Toolchain->AVR/GNU C Compiler->Symbols. Add symbol F_CPU=xxxxx)
25
    Call "ws2812_setleds" with a pointer to the LED array and the number LEDs.
26
    Alternatively you can use "ws2812_setleds_pin" to control up to 8 LED strips on the same Port.
27

28
Examples are provided in the Examples folder. You can build them with the supplied makefile.
29

30
Troubleshooting
31
===============
32

33
Please note that incorrect timing is rarely the source of problems. If you want to save some time, go through the items below before altering the library.
34

35
None or only a part of the string is lighting up.
36

37
    Did you pass the correct array size in the function call?
38
    Is the pin configuration correct?
39
    Is anything else connected to the output pin you are using? Some development boards have LEDs connected to various pins.
40
    Did you choose the correct CPU frequency setting? Did you initialize the clock correctly?
41

42
The LEDs are flickering and not showing the intended colour.
43

44
    This is usually a problem with insufficient current sourcing capability.
45
    Are you using a bypass capacitor for each LEDs as indicated in the datasheet? Not using a bypass capacitor will lead to erroneous behaviour.
46
    You may have to add an additional electrolytic capacitor at the input of your LED strip if you use long power supply lines.
47
    Is your power supply able to supply the required current-level? If set to white at maximum brightness, each LED will draw 60mA. 
48
    A single USB-Port is barely able to supply 10 LEDs.
Persönliche Seite #3494869
Lesenswert?

Tim    schrieb:
> Im  Vorfeld habe ich das Timing der WS2812 noch einmal genau
> untersucht, um die korrekte Ansteuerung von allen Devices
> sicherzustellen:
>
> http://cpldcpu.wordpress.com/2014/01/14/light_ws28...

Hi Tim,

super Arbeit! Ich habe aber einen kleinen "Schönheitsfehler" entdeckt.

Am Ende deines Artikels schreibst du

"•A “1″ can be encoded with pulses of almost arbitrary length as long as 
they are not shorter than ~625 ns (minimum on WS2812B)."

Die beliebig lange High-Time einer "1" lässt sich nur für die erste LED 
"sinnvoll" einsetzen, da die "1" am Ausgang auf jeden Fall wieder nur 
ein Puls von 4 Cycles sein wird und somit automatisch ein Lowpegel 
ausgegeben wird, welcher bei der folgenden LED zum Reset führt.
OP #3905717
Lesenswert?

V2.2 ist jetzt fertig.

    v2.1 2014/03/08
        Added Arduino and C++ support courtesy of Matthias Riegler 
(@xvzf)
    v2.2 2014/11/30
        Improved Ardunio version with variable color order, courtesy of 
Windell Oskay (@oskay)
        Fixed a bug where the other bits of the port were trashed in 
Arduino version.

Download hier:
https://github.com/cpldcpu/light_ws2812

Zusätzlich gibt es jetzt eine Library zur Ansteuerung der APA RGB-LEDs:
https://github.com/cpldcpu/light_ws2812/tree/master/light_apa102_AVR

Hintergrund zu den APA102:
https://cpldcpu.wordpress.com/2014/11/30/understanding-the-apa102-superled/
https://cpldcpu.wordpress.com/2014/08/27/apa102/
Gast #4179602
Lesenswert?

Hallo,

komischer Weise kann ich nur einmal die Funktion 
"ws2812_setleds(led,1);" aufrufen und danach nicht mehr. Ich habe das 
Beispiel Programm Blinky benutzt und die LED bleibt dauerhaft in der 
ersten eingestellten Farbe eingeschaltet.

Hier der Code aus der main.c
1
#ifndef F_CPU
2
#define F_CPU 16000000UL
3
#endif
4

5
#include <util/delay.h>
6
#include <avr/io.h>
7
#include <avr/interrupt.h>
8
#include "light_ws2812.h"
9

10
struct cRGB led[11];
11

12
int main(void)
13
{
14
  while(1)
15
  {
16
    led[0].r=255;led[0].g=255;led[0].b=255;    // Write red to array
17
    ws2812_setleds(led,1);
18
    _delay_ms(500);                         // wait for 500ms.
19

20
    led[0].r=0;led[0].g=255;led[0].b=0;      // green
21
    ws2812_setleds(led,1);
22
    _delay_ms(500);
23

24
  }
25
}

Habe ich etwas falsch verstanden?

Gruß Spawnsen
#4427950
Lesenswert?

Hallo Zusammen.

Ich bekommen die Lib (https://github.com/cpldcpu/light_ws2812) nicht ans 
laufen.
Zum Test habe ich fünf ws2812b an ein ATMega328p (an PC0) angeschlossen.
Als Testcode soll mir Rainbow.c aus der lib dienen.

Mein AVRSudio4 schreibt mir folgenden Fehler:
- In function 'main':
- warning: large fixed-point constant implicitly truncated to 
fixed-point type
- sorry, unimplemented: GCC cannot support operators with integer types 
and fixed-point types that have too many integral and fractional bits 
together
- confused by earlier errors, bailing out
1
        //fade red
2
        if(led[0].r<colors[j].r)
3
            led[0].r+=FADE;
4
->      if(led[0].r>255.r)
5
            led[0].r=255;

Da der Macher der Lib nicht antorten kann oder will, versuche ich es mal 
hier.

Als Ausweg bleibt mir nur eine andere, nicht in cpp geschriebene, Lib zu 
nehmen oder eine eigene zu entwickeln.

Danke
Axel
#4435316
Lesenswert?

Mein nächster Schritt von der Testphase weg, ist es mittels Array die 
LED zu steuern.

Was bei der Audioausgabe ohne Probelme ging, will bei den LEDs nicht 
gelingen. Ich habe den sehr einfachen Code als Datei hinterlegt.

Nach dem Start werden die fünf LED orange, wie es die zweite Zeile im 
Array auch definiert. Dann gehen die LEDs aus, was auch OK ist. Aber 
anschließend werden die LEDs nach der ersten Zeile definiert und nicht 
nach der dritten Zeile im Array, als ob irgendwo sample=0 stehen würde.

Weiß jemand rat oder hat einen Tipp für mich?
Angehängte Dateien:
#4435727
Lesenswert?

Josef D. schrieb:
> 5 Leds?
> Die for-Schleifen werden aber 6 Mal durchlaufen.
> Auch sollte samples nicht unbegrenzt hochgezählt werden.

Wenn ich für die Schleife
1
for (i=0; i<5; i++){
schreibe, leuchtet die fünfte LED nicht.

Bei
1
for (i=1; i<6; i++){
leuchtet die erste LED nicht.

Daher ist wohl die Schreibweise
1
for (i=0; i<6; i++){
richtig, da alle fünf LED angesprochen werden.

Warum sollte ich samples nicht hochzählen?

Wie ich schon schrieb, es ist irgendwo ein Wurm drin.
OP #4435825
Lesenswert?

1
ws2812_setleds(led,i);

Gibt das Array "led" von der Länge "i" auf dem Datenpin aus. Dadurch 
werden "i" LEDs angesteuert.

Ersetze den Aufruf mal durch
1
  ws2812_setleds(led,6);
für 6 LEDs. Dann sollte es funktionieren.

Leider scheint das Missverständnis häufiger aufzutreten. Ich muss wohl 
mal ein paar zusätzliche Beispiele hinzufügen.
#4435932
Lesenswert?

Tim  . schrieb:
>
1
> ws2812_setleds(led,i);
2
>
>
> Gibt das Array "led" von der Länge "i" auf dem Datenpin aus. Dadurch
> werden "i" LEDs angesteuert.
>
> Ersetze den Aufruf mal durch
>
1
>   ws2812_setleds(led,6);
2
>
> für 6 LEDs. Dann sollte es funktionieren.
>
> Leider scheint das Missverständnis häufiger aufzutreten. Ich muss wohl
> mal ein paar zusätzliche Beispiele hinzufügen.

Dies ist die Lösung. Danke.

Durch
1
#define MAXPIX 5
und
1
ws2812_setleds(led,MAXPIX);

läuft die Schleife
1
for (i=0; i<=4; ++i)
fünf mal durch und macht genau das, was sie soll.

Übrigens mit
1
ws2812_setleds(led,i+1);
ging es auch. Keine Ahnung wieso. ;-)
Angehängte Dateien:
#4460032
Lesenswert?

Tim  . schrieb:
> Für AVR gibt es implementierungen
> ab 4 Mhz,

Habe den Code gerade auf einem Atmega88 mit 8 Mhz internen Takt getestet 
und es hat nicht funktioniert, die Farben ändern sich, aber nicht 
reproduzierbar.
Gleicher Code auf Atmega328 mit 16Mhz Quarz lief alles super.
Auf dem Oszi sieht man bei 8Mhz, dass die High-Impulse nur 1/8 Mhz also 
125ns lang, und damit zu kurz sind.

Hat jemand die Bibliothek schon mal jemand mit 8MHz auf einem Atmega 
getestet?
Muß ich den Optimizer irgendwie einstellen?

Ich verwende Version 2.3.
#4460956
Lesenswert?

Die Bibliothek funktioniert nicht für 8Mhz, Grund ist das ein 
Delay-Parameter, der bei 8MHz negativ wird. Es handelt sich um w3.

#define w3 (w_totalcycles-w_fixedtotal-w1-w2)

Der folgende Code interpretiert diese Zahl aber als positiv und knallt 
alle möglichen Delays rein, dadurch kommt eine Periode von 5 us 
zustande.
OP #4460977
Lesenswert?

Julian B. schrieb:
> Die Bibliothek funktioniert nicht für 8Mhz, Grund ist das ein
> Delay-Parameter, der bei 8MHz negativ wird. Es handelt sich um w3.
>
> #define w3 (w_totalcycles-w_fixedtotal-w1-w2)
>
> Der folgende Code interpretiert diese Zahl aber als positiv und knallt
> alle möglichen Delays rein, dadurch kommt eine Periode von 5 us
> zustande.

Nö. Dafür kommt ein paar Zeilen später
1
#if w3>0
2
#define w3_nops w3
3
#else
4
#define w3_nops  0
5
#endif

Zum Problem generell: Ist die CPU wirklich mit 8Mhz getaktet, oder ist 
ein Multiplier falsch? Ist das F_CPU define korrekt?

Hast Du Dir schon einmal das Listing-File angeschaut? (*.lss)
#4461039
Lesenswert?

Tim  . schrieb:
> Zum Problem generell: Ist die CPU wirklich mit 8Mhz getaktet, oder ist
> ein Multiplier falsch? Ist das F_CPU define korrekt?

Das passt schon alles.

Ich denke es liegt wirklich daran,dass w3 negativ ist, aber als positive 
Zahl interpretiert wird, eventuell fehlt ein cast.

Damit sind alle Vergleiche wahr:

#if (w3_nops&1)
w_nop1
#endif
#if (w3_nops&2)
w_nop2
#endif
#if (w3_nops&4)
w_nop4
#endif
#if (w3_nops&8)
w_nop8
#endif
#if (w3_nops&16)
w_nop16
#endif

man hat also 16+8+4+2+1=31 nops, was die hohe Periodendauer erklärt.
OP #4461853
Lesenswert?

> Ich denke es liegt wirklich daran,dass w3 negativ ist, aber als positive
> Zahl interpretiert wird, eventuell fehlt ein cast.

Nein, w3_nop wird nie negativ.

Unten der Code, der mit F_CPU=8000000 generiert wird. Passt alles. Das 
Makefile der Beispiele legt um Unterverzeichnis \objects die *.lss Files 
ab. Am besten mal hier nachschauen, ob etwas schief läuft.

1
  dc:  e6 17         cp  r30, r22
2
  de:  f7 07         cpc  r31, r23
3
  e0:  61 f0         breq  .+24       ; 0xfa <loop42+0x14>
4
    curbyte=*data++;
5
  e2:  81 91         ld  r24, Z+
6
    
7
    asm volatile(
8
  e4:  98 e0         ldi  r25, 0x08  ; 8
9

10
000000e6 <loop42>:
11
  e6:  28 bb         out  0x18, r18  ; 24
12
  e8:  87 ff         sbrs  r24, 7
13
  ea:  38 bb         out  0x18, r19  ; 24
14
  ec:  88 0f         add  r24, r24
15
  ee:  00 00         nop
16
  f0:  00 c0         rjmp  .+0        ; 0xf2 <loop42+0xc>
17
  f2:  38 bb         out  0x18, r19  ; 24
18
  f4:  9a 95         dec  r25
19
  f6:  b9 f7         brne  .-18       ; 0xe6 <loop42>
20
  f8:  f1 cf         rjmp  .-30       ; 0xdc <ws2812_sendarray_mask+0x1c>
OP #4808180
Lesenswert?

Ein paar kleine Updates:

1) WS2813 support

1
v2.4 2016/11/27
2
    * Increased waittime to support WS2813 LEDs

https://github.com/cpldcpu/light_ws2812

2) SK9822 support für die APA102 library

1
v1.1 2016/11/27
2
    * Added reset frame to fix SK9822 update issue. Changed reset frame to 0x000000.
3
    * Added apa102_setleds_brightness function which allows to set global brightness as well.

https://github.com/cpldcpu/light_ws2812/tree/master/light_apa102_AVR
OP #4827053
Lesenswert?

Neuerdings tauchen auf den China-Seiten clones der APA102 auf, die 
SK9822. Ich habe beide Devices verglichen:

https://cpldcpu.com/2016/12/13/sk9822-a-clone-of-the-apa102/

Die SK9822 gefallen mir recht gut. Sie haben eine programmierbare 
Konstantstromquelle zum Einstellen der globalen Helligkeit. Damit können 
die Devices auch gut zur Statusanzeige genutzt werden. Dafür sind die 
anderen programmierbaren LEDs generell zu hell oder Flackern zu viele.
Gast #4866228
Lesenswert?

Hallo,
in der letzten Version von light_ws2812 ist im Readme immer noch zu 
lesen:
- Supports standard AVR, reduced core AVR (Attiny 4/5/9/10/20/40) and 
XMEGA (untested) without special case handling.

Ich hatte das gerade mal gezogen und kompiliert und den selben Fehler 
wie MichaelS98 Mitte 2014 hatte:
Beitrag "Re: Lightweight WS2811/WS2812 Library"

Zwei Beiträge später schreibt er, er habe das Problem gelöst. Weiß da 
einer mehr? Kein Eintrag im Git? Kein Update?

Vielleicht hat da ja jemand mehr Infos dazu. Ich wäre sehr dankbar.
OP #5987674
Lesenswert?

Meine Antwort kommt etwas spät, aber evtl. hilft es ja anderen.

Dennis X. schrieb:
> Hallo,
> in der letzten Version von light_ws2812 ist im Readme immer noch zu
> lesen:
> - Supports standard AVR, reduced core AVR (Attiny 4/5/9/10/20/40) and
> XMEGA (untested) without special case handling.
>
> Ich hatte das gerade mal gezogen und kompiliert und den selben Fehler
> wie MichaelS98 Mitte 2014 hatte:
> Beitrag "Re: Lightweight WS2811/WS2812 Library"
>
> Zwei Beiträge später schreibt er, er habe das Problem gelöst. Weiß da
> einer mehr? Kein Eintrag im Git? Kein Update

Das ist kein Problem mit der Library per se, sondern hat damit zu tun, 
dass der PORTD auf dem XMEGA nicht mit "out" angesprochen werden kann.

Mögliche Optionen:
 - Anderen PORT verwenden
 - PORTD auf einen der virtuellen I/O Ports mappen, damit er
mit dem Befehl "Out" beschrieben werden kann. Steht ab s. 145 im 
XMEGA-Manual.
 - Die Arduino-Version der Library nutzt indizierte Adressierung, um die 
Ports anzusprechen. Diese erlaubt Zugriff auf I/O ports außerhalb des 
I/O Bereichs und sollte auch mit dem nicht gemappeten PORTD 
funktionieren.
#6518175
Lesenswert?

Tim  . schrieb:
> Habe mich nach langer Zeit mal wieder mit den WS2812 beschäftigt. Sie
> scheinen eine Art rudimentäre Gamma-Korrektur eingebaut zu haben.

Nein haben sie def. nicht!
Den dann gabs 4Bayts, und das sind dann anderes LEDs. Schieß mich tot, 
aber die Bezeichnung Derer fällt mir gard nich ein.
Was es da gibt sind V1 bis (jetzt) V6. V1 bis kA. ist Restet-Time nicht 
wie im Dabla angegeben 50ms, sondern 5ms! V2-5 gibts da Änderungen (?). 
V6 hat den benötigten Kondensator bereits integriert.
OP #6518181
Lesenswert?

Teo D. schrieb:
> Tim  . schrieb:
>> Habe mich nach langer Zeit mal wieder mit den WS2812 beschäftigt. Sie
>> scheinen eine Art rudimentäre Gamma-Korrektur eingebaut zu haben.
>
> Nein haben sie def. nicht!

Doch! :)

Schaue Dir doch einfach die Messungen an. Oder vollziehe sie selbst 
nach.

> Den dann gabs 4Bayts, und das sind dann anderes LEDs. Schieß mich tot,

Ne das stimmt nicht. Eine Gamma-Korrektur besteht im Wesentlichen aus 
der Transformation PWM=Intensity^gamma. Dafür sind keine zusätzlichen 
Daten notwendig. Du verwechselst es möglicherweise mit einem global 
Brightness Setting, wie in der APA102. Es gibt bereits etliche andere 
LED-Kontroller mit 8 bit Intensitätswerten, die behaupten eine 
Gamma-Korrektur mit gamma=2.9 zu machen. z.B. die von Polywell. Das 
halte ich auch für etwas fragwürdig.
#6518229
Lesenswert?

Tim  . schrieb:
> Doch! :)
>
> Schaue Dir doch einfach die Messungen an. Oder vollziehe sie selbst
> nach.

KA was ich für ne Version(en) haben....

Tim  . schrieb:
> Ne das stimmt nicht. Eine Gamma-Korrektur besteht im Wesentlichen aus

Hast recht, das passiert intern. Nur bei den WS2812B.... Ich glaube ich 
wäre überrascht, denn genau das ist IMMER das (mein) Problem und es 
bleiben (mir) effektiv ~64Farben über....?!
#6518330
Lesenswert?

Teo D. schrieb:
> Hast recht, das passiert intern. Nur bei den WS2812B.... Ich glaube ich
> wäre überrascht, denn genau das ist IMMER das (mein) Problem und es
> bleiben (mir) effektiv ~64Farben über....?!

komisch das Gefühl habe ich auch seit meine wordclock12h läuft (2015), 
es gibt so viele definierte Farben, aber wehe man fängt an zu dimmen 
dann wird die unterscheidbare Farbauswahl dünn!
#6518382
Lesenswert?

Joachim B. schrieb:
> Teo D. schrieb:
>> Hast recht, das passiert intern. Nur bei den WS2812B.... Ich glaube ich
>> wäre überrascht, denn genau das ist IMMER das (mein) Problem und es
>> bleiben (mir) effektiv ~64Farben über....?!
>
> komisch das Gefühl habe ich auch seit meine wordclock12h läuft (2015),
> es gibt so viele definierte Farben, aber wehe man fängt an zu dimmen
> dann wird die unterscheidbare Farbauswahl dünn!

Naja, in der Theorie muss die gesamt Summe der PWM-Werte (hellicht) 
immer gleichbleiben, wenn NUR die Farbe geändert werden soll. In der 
Praxis hab ich ja schon so einige Farbwerte "abgetippt" nur gefallen 
hats nie. Selbst ist der Pfuscher... Oder doch auf andre, Smarten, mit 
auto Gammakorrektur RGB LEDs umsteigen!? Hatte ich ja mal angeregt im, 
in irgend einem WordClock-Thread, aber wenn das Projekt bereits fertig 
ist, bleibt halt nur die Idee. Auch wenn diese eher zur Anzeige (weniger 
hell, plus 8Bitm für Gamma == mehr Raum u. Farben zum Dimmen), als zur 
Beleuchtung geeignet sind. Ich, als Legastenigertrottel, interessiere 
mich für solche WordUhren natür5lich eher nur am Rande. ;)


PS: Alles bereits in Mark u. Blut übergangenes, bitte ignorieren. Ich 
meins ja nur gut....und weiß es nicht besser ;)
#7178728
Lesenswert?

Gibt's sowas wie diesen Code auch für den ATtiny1614 (oder ähnliche)? 
Bei mir funktioniert der nicht. Der Compiler beschwert sich über ein 
nicht definiertes "DDRB". Wie ich mittlerweile rausgefunden habe, ist 
das für die Einstellung des Ports als Ausgang. Das kann ich ja auch 
anders machen (PORTB.DIRSET = ...). Aber danach kommen weitere Fehler, 
dass irgendwas nicht berechnet werden kann. Leider verstehe ich von dem 
Assemblercode gar nichts, kann das also auch nicht beheben.

Im Wiki wird zwar eine Implementierung für ATtiny817 genannt, aber die 
nutzt USART, den ich bereits in Verwendung habe, also kann ich diesen 
Hack nicht gebrauchen und muss die Bits in Software rausschaufeln. Diese 
Bibliothek hier scheint die einzige zu sein, die das tut. Sonst habe ich 
nichts gefunden, was ohne das Arduino-Framework läuft (das ich auch 
nicht verwende).
#7179463
Lesenswert?

> Nimm einen älteren Tiny

Hab ich nicht, will ich mich eigentlich auch nicht mit beschäftigen, da 
ich meine Anwendung bereits auf diesen Chips umgesetzt habe. Ich fand 
die neueren Chips eigentlich viel attraktiver als die alten und weiß gar 
nicht, warum jemand die alten bevorzugen sollte für neue Anwendungen.

Mittlerweile konnte ich die LED-Ansteuerung aber auch selbst umsetzen, 
nur mit C-Code. Das war eigentlich nicht sonderlich schwer, nur die 
Pin-Register setzen und exaktes Warten mit der 
__builtin_avr_delay_cycles-Funktion. Bei 20 MHz ist dafür genug Zeit. 
Assembler oder SPI wird dafür gar nicht benötigt. Man darf sich nur 
nicht durch alle Empfehlungen davon abhalten lassen, es tatsächlich zu 
versuchen. ;-)

Ich muss das noch ein wenig testen bei anderen CPU-Frequenzen und die 
optimalen Timings ermitteln, dann kann ich das hier gerne auch posten.

(Warum hat mein Post eigentlich eine negative Bewertung? Gehört das hier 
zum weithin bekannten guten Ton? Die Worte meines Beitrags sollten doch 
eher nicht geeignet sein, jemanden zu beleidigen, sondern nur technische 
Anforderungen beschreiben. Ansonsten bitte ich um Aufklärung.)
#7179467
Lesenswert?

Yves G. schrieb:
> (Warum hat mein Post eigentlich eine negative Bewertung?

Fragestellung, fehlender Code

Yves G. schrieb:
> Gehört das hier
> zum weithin bekannten guten Ton?

auch das!

sowie:
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

(es sieht so aus als wenn deine Frage nicht zum Ausgangsthread passt)
#7179471
Lesenswert?

> (es sieht so aus als wenn deine Frage nicht zum Ausgangsthread passt)

Sorry, wenn ich jetzt darauf rumreite, aber inwiefern passt das nicht 
dazu? Dort wird ein Code veröffentlicht, der die LED-Ansteuerung ohne 
SPI und auf allen AVRs erledigen soll. Genau das funktioniert in meinem 
Fall aber nicht. Ich kann nirgends eine Einschränkung auf damalige 
Modelle finden, während es gleichzeitig Updates für den Code gab, die 
das möglicherweise hätten beheben können. Für mich ist das exakt 
dasselbe Thema.

> fehlender Code

Wozu soll ich den Code zeigen, der in genau diesem Thread doch 
veröffentlich wird? Diese Aussagen ergeben für mich absolut keinen Sinn.
Beitrag #7184459 wurde von einem Moderator gelöscht.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren