Forum: Mikrocontroller und Digitale Elektronik WS2812 LED-Stripe Library gesucht


von Tobias (Gast)


Lesenswert?

Hallo,
ich habe einen LED-Stripe (WS2818 mit integriertem controller).
Jetzt habe ich immer gedacht, ich könnte die Adafruit-Neopixel library 
benutzen. Aber diese ist ja nur für Arduinos. Zumindest wird Adruino.h 
bzw. pins-arduino.h/WProgramm.h benötigt.
Ich habe zwar auch einen Atmega 328p, aber einzeln (also nicht als 
Arduino)
Kennt jemand eine library, die ich sonst noch dafür verwenden kann?

Tobias

von Planlos (Gast)


Lesenswert?

Der Großteil der Ansteuerung ist in der Lib m.W. als Inline-ASM gelöst, 
um das Timing hinzubekommen.
Falls du nicht's passendes ohne Ardiuno findest, kopier dir halt den 
Block raus, der geht auch ohne C++, pinMode und digitalWrite.

von Thomas E. (thomase)


Lesenswert?

Wie wäre es denn mit selbst machen?
Achja, du willst ja das Rad nicht nochmal erfinden.

von Horst (Gast)


Lesenswert?


von Tobias (Gast)


Lesenswert?

Horst schrieb:
> Die funktioniert:
> https://github.com/cpldcpu/light_ws2812

mhh, muss man da noch etwas berücksichtigen?

Habe PB2 auf Data (ist in der ws2818_config.h), 5V und Gnd mit dem 
LED-Stripe verbunden. Aber ich bekomme keine Farbe auf den LEDs. Diese 
sind immer weiss.

Tobias

von Tobias (Gast)


Lesenswert?

ah,
man sollte auch die Fuses richtig setzen.

von Tobias (Gast)


Lesenswert?

Hallo,
zur light_ws2812 library habe ich noch eine Frage
1
#define CONCAT(a, b)            a ## b
2
#define CONCAT_EXP(a, b)   CONCAT(a, b)
3
4
#define ws2812_PORTREG  CONCAT_EXP(PORT,ws2812_port)
5
#define ws2812_DDRREG   CONCAT_EXP(DDR,ws2812_port)
1
void ws2812_sendarray(uint8_t *data,uint16_t datlen)
2
{
3
  ws2812_sendarray_mask(data,datlen,_BV(ws2812_pin));
4
}
5
6
void inline ws2812_sendarray_mask(uint8_t *data,uint16_t datlen,uint8_t maskhi)
7
{
8
  uint8_t curbyte,ctr,masklo;
9
  uint8_t sreg_prev;
10
  
11
  ws2812_DDRREG |= maskhi; // Enable output
12
  
13
  masklo  =~maskhi&ws2812_PORTREG;
14
  maskhi |=        ws2812_PORTREG;
15
  
16
  sreg_prev=SREG;
17
  cli();  
18
19
  while (datlen--) {
20
    curbyte=*data++;
21
    
22
    asm volatile(
23
    "       ldi   %0,8  \n\t"
24
    "loop%=:            \n\t"
25
    "       out   %2,%3 \n\t"    //  '1' [01] '0' [01] - re
26
#if (w1_nops&1)
27
w_nop1
28
#endif
29
#if (w1_nops&2)
30
w_nop2
31
#endif
32
#if (w1_nops&4)
33
w_nop4
34
#endif
35
#if (w1_nops&8)
36
w_nop8
37
#endif
38
#if (w1_nops&16)
39
w_nop16
40
#endif
41
    "       sbrs  %1,7  \n\t"    //  '1' [03] '0' [02]
42
    "       out   %2,%4 \n\t"    //  '1' [--] '0' [03] - fe-low
43
    "       lsl   %1    \n\t"    //  '1' [04] '0' [04]
44
#if (w2_nops&1)
45
  w_nop1
46
#endif
47
#if (w2_nops&2)
48
  w_nop2
49
#endif
50
#if (w2_nops&4)
51
  w_nop4
52
#endif
53
#if (w2_nops&8)
54
  w_nop8
55
#endif
56
#if (w2_nops&16)
57
  w_nop16 
58
#endif
59
    "       out   %2,%4 \n\t"    //  '1' [+1] '0' [+1] - fe-high
60
#if (w3_nops&1)
61
w_nop1
62
#endif
63
#if (w3_nops&2)
64
w_nop2
65
#endif
66
#if (w3_nops&4)
67
w_nop4
68
#endif
69
#if (w3_nops&8)
70
w_nop8
71
#endif
72
#if (w3_nops&16)
73
w_nop16
74
#endif
75
76
    "       dec   %0    \n\t"    //  '1' [+2] '0' [+2]
77
    "       brne  loop%=\n\t"    //  '1' [+3] '0' [+4]
78
    :  "=&d" (ctr)
79
    :  "r" (curbyte), "I" (_SFR_IO_ADDR(ws2812_PORTREG)), "r" (maskhi), "r" (masklo)
80
    );
81
  }
82
  
83
  SREG=sreg_prev;
84
}

im speziellen geht es um die pin-konfiguration und maskhi bzw. masklo

in einer config-header steht
1
#define ws2812_port B     // Data port 
2
#define ws2812_pin  2     // Data out pin

Im hauptcode wird die Funktion ws2818_sendarray aufgerufen. In dieser 
Funktion wird der define ws2818_pin verwendet ( _BV(ws2818_pin) -> (1 << 
ws2818_pin) oder?)
mit diesem makro wird dann die Funktion ws2812_sendarray_mask 
aufgerufen.
In dieser Funktion wird erst der Daten-Pin deklariert.
dazu wird
 ws2812_DDRREG |= maskhi;
maskhi ist aus der vorigen Funktion übergeben worden. Dort war es aber 
ws2818_pin. Müsste aber nciht eigentlich der Port genommen werden?`woher 
weiss man jetzt, dass Port B gemeint ist? (Passt zwar, da B auch 2 ist, 
aber das ist ja eher zufall).
In den nächsten zwei Zeilen kommt dann

  masklo  =~maskhi&ws2812_PORTREG;
  maskhi |=        ws2812_PORTREG;

da weiss ich leider gar nicht, was da passiert

masklo und maskhi werden dann erst wieder in einer der letzten Zeilen 
versendet (assembler-code)
    :  "r" (curbyte), "I" (_SFR_IO_ADDR(ws2812_PORTREG)), "r" (maskhi), 
"r" (masklo)

was macht diese Zeile?

Meine Frage:
kann jemand erläutern, wie genau der Datenpin deklariert und 
initialisiert wird? und wofür masklo und maskhi genau sind?

Gruß
Tobias

von Tim  . (cpldcpu)


Lesenswert?

Tobias schrieb:
> Meine Frage:
> kann jemand erläutern, wie genau der Datenpin deklariert und
> initialisiert wird? und wofür masklo und maskhi genau sind?

Der Datenpin wird im Configfile deklariert. Genauer: Die Defines werden 
im Headerfile zusammengesetzt.
1
/*
2
 * Internal defines
3
 */
4
5
#define CONCAT(a, b)            a ## b
6
#define CONCAT_EXP(a, b)   CONCAT(a, b)
7
8
#define ws2812_PORTREG  CONCAT_EXP(PORT,ws2812_port)
9
#define ws2812_DDRREG   CONCAT_EXP(DDR,ws2812_port)

 Masklo und Maskhi sind die Werte, die ins Portregister geschrieben 
werden, um den Datenpin auf High oder Lo zu setzen.

von Oliver S. (phetty)


Lesenswert?

Diese hier geht ab wie eine Rakete:

https://github.com/Makuna/NeoPixelBus

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
Noch kein Account? Hier anmelden.