88-WS2812_8CH-Library (STM32F4)

Mit dieser Library können bis zu 8 LED-Ketten vom Typ WS2812 betrieben werden.

Für eine nähere Beschreibung der WS2812 siehe meine andere Library
(78=WS2812-Lib)

Wenn man alle 8 Stränge parallel legt, kann man auch Texte darstellen.
Einen entsprechenden Font mit 8×6 Pixel habe ich dazugepackt.

Im H-File können nicht benutzte Kanäle per Define abgeschaltet werden.
(Um RAM zu sparen)

Im H-File muss die Länge der längsten LED-Kette eingetragen werden
(um Speicherplatz zu reservieren) Die Software versucht aber die tatsächliche
Längen aller angeschlossener Ketten zu messen (wärend der Init-Funktion).

Dazu müssen die Ausgänge der letzten LEDs von allen Ketten über Dioden
(z.B. BAT46) per “Wired-Or” mit dem externen Interrupt-Pin “PD0″
verbunden werden. Falls die Längenmessung bei einer Kette nicht funktioniert,
geht die Software von der maximalen Länge aus die im H-File eingestellt ist.
Die Init-Funktion liefert in dem Fall ein “Error” zurück.
Die gemessenen Längen aller Ketten steht in “WS2812_CHAIN_LEN.ch1″
bis “WS2812_CHAIN_LEN.ch8″

Bild :

ws2812_8ch

Hinweis : falls ihr die automatische Längenmessung nicht benutzen wollt,
müsst ihr NACH der Init-Funktion alle Längen manuell setzen :

1
2
3
4
5
6
7
8
// init WS2812
UB_WS2812_Init();
 
// ignore automatic chain length and
// set chain lenght manually
WS2812_CHAIN_LEN.ch1=5;
WS2812_CHAIN_LEN.ch2=3;
WS2812_CHAIN_LEN.ch3=4;

Zur Software :

Alle Funktionen die LEDs betreffend, ändern nur die Farbwerte im RAM.
Um die geänderten Werte an die LEDs zu senden, muss einmal die Funktion
“UB_WS2812_RefreshAll” aufgerufen werden.

Bei den Shift/Roll-Funktionen kann über eine Bitmaske bestimmt werden,
welche LED-Ketten benutzt werden sollen. Damit ist es möglich nur eine einzelne
LED-Kette zu verschieben oder mehrere gleichzeitig.

Benutzte Pins :

1
2
3
4
5
6
7
8
9
10
CH1 = PC6
CH2 = PB5
CH3 = PB0
CH4 = PB1
CH5 = PE9
CH6 = PE11
CH7 = PE13
CH8 = PE14
 
EXTI = PD0 (zum messen der Anzahl der LEDs aller WS2812-Ketten)

Voraussetzungen :

1
2
Benutzte Module der CooCox-IDE : GPIO, TIM, DMA, MISC, EXTI, SYSCFG
Benutzte Librarys : keine

Funktionen :

1
2
3
4
5
6
7
8
9
10
11
12
ErrorStatus UB_WS2812_Init(void);                                                     // zum init aller WS2812-Kette(n)
void UB_WS2812_RGB_2_HSV(WS2812_HSV_t hsv_col, WS2812_RGB_t *rgb_col);                // HSV-Wert in RGB umrechnen
void UB_WS2812_Pixel_RGB(uint32_t x, uint8_t y, WS2812_RGB_t rgb_col);                // eine einzelne LED setzen (als RGB Wert)
void UB_WS2812_All_RGB(uint8_t ch_maske, WS2812_RGB_t rgb_col);                       // alle LEDs der Kette(n) setzen
void UB_WS2812_Shift_Left(uint8_t ch_maske);                                          // alle LEDs der Kette(n) einen Step links schieben
void UB_WS2812_Shift_Right(uint8_t ch_maske);                                         // alle LEDs der Kette(n) einen Step rechts schieben
void UB_WS2812_Rotate_Left(uint8_t ch_maske);                                         // alle LEDs der Kette(n) einen Step links rotieren
void UB_WS2812_Rotate_Right(uint8_t ch_maske);                                        // alle LEDs der Kette(n) einen Step rechts rotieren
void UB_WS2812_Char_RGB(uint32_t x, uint8_t ascii, WS2812_RGB_t vg, WS2812_RGB_t bg); // zeichnet ein Ascii-Zeichen (8 Ketten notwendig)
void UB_WS2812_String_RGB(uint32_t x, char *ptr, WS2812_RGB_t vg, WS2812_RGB_t bg);   // zeichnet einen String (8 Ketten notwendig)
void UB_WS2812_RefreshAll(void);                                                      // sendet alle Daten an die LEDs
ErrorStatus UB_WS2812_Check_Len(void);                                                // test der Laenge aller Ketten

Beispiel :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
//--------------------------------------------------------------
// File     : main.c
// Datum    : 04.10.2014
// Version  : 1.0
// Autor    : UB
// EMail    : mc-4u(@)t-online.de
// Web      : www.mikrocontroller-4u.de
// CPU      : STM32F4
// IDE      : CooCox CoIDE 1.7.4
// GCC      : 4.7 2012q4
// Module   : CMSIS_BOOT, M4_CMSIS_CORE
// Funktion : Demo der WS2812_8CH Library
// Hinweis  : Diese zwei Files muessen auf 8MHz stehen
//              "cmsis_boot/stm32f4xx.h"
//              "cmsis_boot/system_stm32f4xx.c"
//--------------------------------------------------------------
 
#include "main.h"
#include "stm32_ub_ws2812_8ch.h"
 
int main(void)
{
  WS2812_RGB_t hg_col, vg_col;
 
  SystemInit(); // Quarz Einstellungen aktivieren
 
  // init aller WS2812-Ketten
  // (8 Ketten mit je max 100 LEDs)
  UB_WS2812_Init();
 
  // Farbe fuer Hintergrund auf gruen setzen
  hg_col.blue=0;
  hg_col.green=10;
  hg_col.red=0;
 
  // Farbe fuer Vordergrund auf rot setzen
  vg_col.blue=0;
  vg_col.green=0;
  vg_col.red=10;
 
  // setzen aller LEDs auf Hintergrund Farbe
  UB_WS2812_All_RGB(0xFF, hg_col);
 
  // Zeichnen vom Text 'Hallo' an Position 0
  UB_WS2812_String_RGB(0,"Hallo", vg_col, hg_col);
 
  // Ausgabe aller Daten an die LEDs
  UB_WS2812_RefreshAll();
 
  while(1)
  {
    // nichts zu tun
  }
}

Hier die Library zum Download :

ub_stm32f4_ws2812_8ch_v100

Hier der komplette CooCox-Projektordner zum Download :

Demo_88_WS2812_8CH


7 Antworten auf 88-WS2812_8CH-Library (STM32F4)

  1. Michael sagt:

    Hallo Uwe,

    sagmal es ist wahrscheinlich nicht möglich die Ausgaben noch schneller zu gestalten oder? Weil es kommt mir relativ langsam vor, wenn ich z.B. eine LED Durchlaufen lasse dann kann man zugucken beim durchlaufen wenn die LED Kette mehr als 250-300 LEDs hat.

    • admin_ub sagt:

      rechne doch mal nach. Eine LED = 30us -> 300 LEDs = 9ms. Ein kompletter refresh dauert also 9ms. Wenn du eine LED von vorne nach hinten also um 300 LEDs durchlaufen lassen willst und jeden Zwischenschritt anzeigst, dauert das 9ms * 300 = 2,7 sekunden. schneller geht nur, wenn du kürzere Ketten nimmst und diese hintereinander anordnest, oder wenn du nicht jeden Schritt anzeigst.

      • Michael sagt:

        Ja da hast du wohl Recht, das hatte ich gar nicht berücksichtigt. Hab’s nun auf max 150 LEDs beschränkt und dementsprechend die Programme angepasst das es trotzdem aussieht wie ein durchgängiger Strip.
        Trotzdem vielen Dank für deine Hilfe

  2. vasa sagt:

    Good afternoon!
    Trying to 12 LED strings.
    It will not conflict DMA and interrupt? What are the problems?
    Project:https://docviewer.yandex.ru/?url=ya-disk%3A%2F%2F%2Fdisk%2F%D0%94%D0%BE%D0%BA%D1%83%D0%BC%D0%B5%D0%BD%D1%82%D1%8B%2FWS2812B.7z&name=WS2812B.7z&c=5657e27abf60
    Thank you!

    • admin_ub sagt:

      sorry, i dont search failure in external code.

      • vasa sagt:

        How to determine the channel interrupts and process it? I can do so and will not conflict because the interrupt handler is the same?

        if (DMA_GetITStatus(DMA1_Stream2, DMA_IT_TCIF2))
        {}
        => TIM3-CC4 => DMA1, Channel5, Stream2
        => TIM5-CC1 => DMA1, Channel6, Stream2

        Thank you!

        • admin_ub sagt:

          you cant use two channels on the same stream at the same dma. either use dma2 or another stream. or use the channels one after the other.


Wie hat Dir dieser Artikel gefallen?

1 Stern2 Sterne3 Sterne4 Sterne5 Sterne (Noch keine Bewertungen)
Loading...

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.