Leds programmables WS2812 |
Maj : 01/07/2024
Abstract :
Résumé : |
Cette page sans prétention n’est là que pour faire découvrir ce composant intéressant à ceux qui sont passés à côté… Il y a beaucoup d’informations sur le Net. Une WS2812 comporte 3 leds RVB (Red, Green Blue) indépendantes. Chaque couleur est réglable de 0 (éteinte) à 255 (pleine puissance) et la luminosité globale de l’ensemble se règle de 10 (minimum) à 255. L’astuce est que ces modules ne sont commandés que par un seul fil série et sont cascabables. |
Présentation of the LEDs This unassuming page aims to introduce this interesting component to those who might have overlooked it. There is plenty of information available on the Internet. A WS2812 LED contains three independent RGB (Red, Green, Blue) LEDs. Each color can be adjusted from 0 (off) to 255 (full power), and the overall brightness can be set from 10 (minimum) to 255. The trick is that these modules are controlled by a single serial wire and can be cascaded. The first LED has address 0, the next 1, and the last in an 8x32 panel has address 255. You can chain as many panels as you want. An 8x32 panel costs around 16€ when ordered from China, offering excellent value for these high-performance products. |
||||||||||||||||||||||||||
Il n'y a pas que les grands panneaux qui présentent de l'intérêt. Ces leds sont disponibles à l’unité, ce qui est très pratique sur une carte de développement pour remplacer les anciennes leds. |
It's not just large panels that are interesting. These LEDs are available individually, which is very practical on a development board to replace older LEDs. They also come in strips of 8 LEDs, fully assembled for easier soldering. There are two versions: |
||||||||||||||||||||||||||
Les nouvelles générations des excellents ESP32 -S3 comprennent une WS2812 en remplacement de la simple led monochrome en G13.Cela m'a donné une nouvelle idée. |
The new generations of the excellent ESP32 -S3 include a WS2812 instead of a simple monochrome LED on G13. This gave me a new idea: |
||||||||||||||||||||||||||
Dans un premier temps j’ai testé sur une barrette de 8 WS2812, toutes sortes d’animations, mais cela devenait un arbre de Noël un peu ridicule sur une carte de développement. Le délire calmé, sur mes nouvelles cartes les anciennes cinq leds discrètes sont remplacées par trois WS2812 en 3.3 V, qui offrent raisonnablement plus de choix de séquences en prenant moins de place. |
Initially, I tested various animations on an 8-LED strip, but it turned into a somewhat ridiculous Christmas tree on a development board. After calming down, on my new boards, the old five discrete LEDs have been replaced by three WS2812 LEDs at 3.3V, offering more reasonable sequence options while taking up less space. | ||||||||||||||||||||||||||
Consommation C'est joli, mais si une simple éteinte ne consomme rien, une WS2812 qui possède évidement une électronique interne consomme 1.6 mA éteinte sous 3.3 V et plus de 10 mA allumée, alors qu’une petite led simple se contente de 0.5 mA ; il faudra donc oublier les WS2812 si l’on recherche le « low power » |
Power Considerations While it looks nice, if a simple LED doesn't consume any power when off, a WS2812 with its internal electronics consumes 1.6 mA when off and over 10 mA when on, compared to a small simple LED that uses only 0.5 mA. Therefore, WS2812 LEDs should be avoided if you're aiming for low power consumption. |
||||||||||||||||||||||||||
|
Technical Features The fill time for an 8x32 panel is only 8ms, which is very fast and allows you to create modest animations similar to cartoons. |
||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||
Attention au sens ! Pour notre panneau 8*32, considérons que la position 0 est en haut à gauche. Le balayage est en zigzags, les colonnes paires descendent, les colonnes impaires montent. |
|
Adressing Attention to the direction! The scanning is done in a zigzag pattern, with even columns going down and odd columns going up For our 8*32 panel, consider position 0 to be at the top left. |
|||||||||||||||||||||||||
Ce zigzag est gênant quand on veut afficher des fonts ou transposer des images bmp car on s’attend à ce que toutes les colonnes descendent ainsi : |
|
This zigzag pattern is inconvenient when displaying fonts or transposing BMP images because we expect all columns to go down like this: | |||||||||||||||||||||||||
Ma petite routine résout ce problème qui est montré dans "WS2812_fonts_....ino" (fichiers joints). |
|
My little routine solves this problem, which is shown in "WS2812_fonts_....ino" (attached files). | |||||||||||||||||||||||||
|
|||||||||||||||||||||||||||
Voici les résultats pour une seule WS2812 sous 3.3 V (en alimentant sous 5V, la consommation double). Interprétation de ces résultats : Les courants sont très élevés : il y a 3 WS2812 sur ma carte de développement, en blanc maximum, c’est énorme à 55 mA, il vaut mieux éviter les luminosités maximum. Il pourrait être tentant de réduire le VDD, mais vers 2.5 V il y a plantage irréversible, c’est une mauvaise idée. Il est intéressant de prévoir une patte GPIO pour couper via un MosFet les alimentations et économiser l’énergie, mais attention si vous coupez l’alimentation en éteignant la WS2812, il ne faut pas oublier de tout réinitialiser à l’appel suivant après avoir réactivé VDD, sinon elle restera éteinte. |
|
Here are the results for a single WS2812 under 3.3V (when powered at 5V, the consumption doubles). The board's power supply is external, as USB cannot support such high currents at maximum brightness. Interpretation of these results: The currents are very high: there are 3 WS2812 LEDs on my development board. At maximum white, the consumption is enormous at 55 mA. It's better to avoid maximum brightness. It might be tempting to reduce the VDD, but at around 2.5V, it causes irreversible crashes, which is a bad idea. Each WS2812 needs to be individually decoupled closely with at least 0.2 µF, preferably more, and a few ohms of resistance in series to avoid crashing the board. It's beneficial to have a GPIO pin to cut the power via a MOSFET to save energy. However, be careful: if you cut the power by turning off the WS2812, you must remember to reset everything on the next call after reactivating VDD, or else the LED will remain off. |
|||||||||||||||||||||||||
|
|||||||||||||||||||||||||||
L’alimentation étant vue, reste le hardware. J’ai utilisé un ESP32, GPIO 17, comme pour le Nextion. Il existe deux types de leds : |
Hardware With the power supply addressed, let's move on to the hardware. I used an ESP32, GPIO 17, as with the Nextion display. The documentation suggests using a "level shifter" to reliably convert the control signal from 3.3V to 5V. In practice, this is unnecessary; direct connection works fine. There are two types of LEDs: |
||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||
L’alimentation étant vue, reste le rendu des couleurs. Avec brightness un très bas, les couleurs s’altèrent, les trois diodes réagissant différemment à très faible courant. |
Brightness and Colorimetry With power supply considerations addressed, we turn to color rendering. At very low brightness, colors are distorted because the three diodes react differently to very low current. Compared to a reference RGB chart (Pantone), the colorimetry is not as expected. |
||||||||||||||||||||||||||
La luminosité La sensibilité de l’œil est très grande aux faibles luminosités mais décroît logarithmiquement quand la stimulation augmente (loi de Weber) c’est pour cela que l’on détecte pas les variations de niveau à forte luminosité alors qu’elles sont bien perceptibles avec un capteur électronique. |
Brightness The eye’s sensitivity is very high at low brightness levels but decreases logarithmically as stimulation increases (Weber's law). This is why we do not detect level variations at high brightness even though they are noticeable with an electronic sensor. Initially, I tried to establish thresholds for the eye to perceive a transition from one level to another, similar to other physiological sensations, with a doubling representing 3 dB. Testing the following: |
||||||||||||||||||||||||||
uint8_t tabPump[]= {0, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF}; | |||||||||||||||||||||||||||
Cela ne fonctionne pas ! Il n’y a donc pas plus de 3 paliers bien discernables (plus le noir) possibles.
|
uint8_t tabPump[]= {0x01, 0x10, 0xFF}; | Did not works! Therefore, there are no more than 3 clearly discernible levels (plus black).
|
|||||||||||||||||||||||||
La colorimétrie Le mélange des couleurs pose un nouveau problème. Les couleurs intermédiaires sont : Mais si le mélange entre les couleurs fondamentales se fait à des niveaux différents, la couleur secondaire générée a des teintes bizarres qu’il vaut mieux éviter ! |
Colorimétry Color mixing presents a new challenge. The intermediate colors are: If the primary colors are mixed at different levels, the resulting secondary color has odd shades that are best avoided. |
||||||||||||||||||||||||||
Cela n’a aucun sens à cause des paliers évoqués au-dessus, en réalité c’est 3 états par couleurs soit un total combiné de 3 puissance 3 (est à dire 27 combinaisons que l’oeil sait séparer, et sur les 27 des intermédiaires douteux que l’on évitera. Cela reste un choix formidable avec lequel on pourra composer toutes sortes d’animations. En mélangeant deux couleurs fondamentales la couleur complémentaire utilisant deux leds simultanément est beaucoup trop brillante, la table des couleurs dans la classe compense cela au mieux. |
A superficial reading of the official documentation might lead one to believe that with 256 levels for each color, you get 256*256*256 colors and 256 brightness levels, resulting in 2 to the power of (16*4), or 2^64 = 1.8 followed by 19 zeros (18 quintillion) variations! This makes no sense due to the steps mentioned above. In reality, it’s 3 states per color, totaling 3^3 (27 combinations) that the eye can distinguish. Out of the 27, some intermediate shades are dubious and should be avoided. This still offers a great selection for creating various animations. When mixing two primary colors, the resulting complementary color, using two LEDs simultaneously, is much too bright. The color table in the class compensates for this as best as possible. |
||||||||||||||||||||||||||
Détermination des paliers perceptibles L’utilisation d’une cellule (comme le capteur solaire "SFE_TSL2561" utilisé dans le programme de domotique Domus), pour visualiser les écarts de luminosité par paliers de courant ne donne rien. Il y a bien une progression très sensible du résultat de la mesure, mais l’œil ne perçoit pas ces petits écarts. Les tests sont effectués à 3.3 V, à 5 V les niveaux maximums sont trop éblouissants. Le programme <WS2812_256_steps> illustre ces paliers avec différents pas : |
uint8_t steps[] ={0,1,30,255};
|
Détermination of perceptible levels Using a sensor, such as the "SFE_TSL2561" solar sensor used in the program domotique Domus),, to visualize brightness differences in current steps does not yield useful results. While there is a very subtle progression in the measurement results, the eye does not perceive these small differences. Tests were conducted at 3.3V, as at 5V the maximum levels are too dazzling. We always keep: <#define MAXBRIGHTNESS 255> because otherwise the colors are very distorted when reducing the levels. The program <WS2812_256_steps> illustrates these levels with different steps: The program <WS2812_256_all_colors> shows the results of the 7 colors and their three optimized shades. |
|||||||||||||||||||||||||
J’ai choisi sur Github la très bonne bibliothèque Adafruit_NeoPixel. On peut tout faire avec un minimum de commandes simplistes : begin, clear, setBrightness, show et surtout : setPixelColor(position, r,g,b) Pour m’amuser, j’ai voulu tout refaire à la main en C++, sans regarder le travail des autres. |
Firmware I chose the excellent Adafruit_NeoPixel library from GitHub. You can do everything with a minimal set of simple commands: begin, clear, setBrightness, show, and most importantly: setPixelColor(position, r, g, b). For fun, I wanted to redo everything from scratch in C++ without looking at others' work. I simply used a pre-made font to display text and programmed some animations based on BMP drawings. |
||||||||||||||||||||||||||
Depuis 2023, j’ai encore changé de microcontrôleur et abandonné tous mes ESP32 DevkitV1 ! Expressif n’arrête pas de sortir des produits de plus en plus performants, heureusement bien documentés, mais avec des fonctions toujours plus complexes à exploiter, en particulier du côté du BlueTooth ! |
Hardware Since 2023, I have once again switched microcontrollers and abandoned all my ESP32 DevkitV1! Espressif keeps releasing increasingly powerful products, fortunately well-documented, but with increasingly complex functions to utilize, especially on the Bluetooth side! |
||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||
N’hésitez pas à m’envoyer vos remarques sur le fond (parties à compléter ou modifier), et sur la forme (fautes de frappe…). Que peut-on faire de ce panneau ? |
Conclusion Please feel free to send me your comments on the content (parts to complete or modify) and the form (typos, etc.). What can be done with this panel? |
||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||
Annexe : Contenu du Pack_WS2812 Il existe un pack d’utilitaires ADAFRUIT WS2812FX considérablement plus évolué et complexe que le mien, mais je cherchais à faire quelque chose de très simple que puisse comprendre un débutant qui se lance. Classe de base Fichiers ino Eagle
|
Appendix: Contents of the Pack_WS2812 There is a considerably more advanced and complex ADAFRUIT WS2812FX utility pack available, but I aimed to create something very simple that a beginner just starting out could understand. Base class Ino files Eagle |
Mise à jour 01/07/2024 |