Difference between revisions of "Projets:Perso:2015:LedTube:Conseils"
(Created page with "=Conseils aux utilisateurs de dandes de WS2812B= En résumé *Bien assurer que votre conception respecte que DI n'est jamais au dessus de VCC+0.5V, et tout de même au dess...") |
|||
Line 1: | Line 1: | ||
=Conseils aux utilisateurs de dandes de WS2812B= | =Conseils aux utilisateurs de dandes de WS2812B= | ||
+ | |||
+ | Datasheet https://www.adafruit.com/datasheets/WS2812B.pdf | ||
En résumé | En résumé | ||
Line 55: | Line 57: | ||
Si dans votre design, vous ne pilotez qu'une seule bande (même longue), les choses sont plus simples. Vous pouvez vous permettre d'avoir un circuit d'adaptation prenant comme référence de tension l'alim VCCLed. Un transistor en collecteur ouvert (avec pull-up) pourrait être OK. | Si dans votre design, vous ne pilotez qu'une seule bande (même longue), les choses sont plus simples. Vous pouvez vous permettre d'avoir un circuit d'adaptation prenant comme référence de tension l'alim VCCLed. Un transistor en collecteur ouvert (avec pull-up) pourrait être OK. | ||
+ | |||
+ | ==Pilotage des Leds par DMA== | ||
+ | Le timing DI offre une opportunité. | ||
+ | |||
+ | *Data Bit 0 : 1 pendant 0.4us±150ns puis 0 pendant 0.85µs±150ns | ||
+ | *Data Bit 1 : 1 pendant 0.8us±150ns puis 0 pendant 0.45µs±150ns | ||
+ | |||
+ | par conséquent on reste dans la spec avec ce timing : | ||
+ | |||
+ | *Data Bit 0 : 1 pendant 0.4us±150ns puis 0 pendant '''0.8µs'''+200ns-100ns | ||
+ | *Data Bit 1 : 1 pendant 0.8us±150ns puis 0 pendant '''0.4µs'''±200ns-100ns | ||
+ | |||
+ | L'idée est d'utiliser un DMA, Mémoire->GPIO avec chaque transfert déclenché par un timer toutes les 0.4µs | ||
+ | |||
+ | Tous les micros ne savent pas faire ça, mais les STM32F446 oui. | ||
+ | |||
+ | A supposer qu'on configure le DMA pour envoyer la mémoire vers le GPIOB | ||
+ | |||
+ | Si par exemple on remplit la mémoire avec la séquence | ||
+ | 0xFFFF,0xFFFF,0x0000 32*60 fois de suite, on va allumer 16 bandes de 60 leds connectées à GPIOB0..GPIOB15 au blanc max | ||
+ | |||
+ | Si par exemple on remplit la mémoire avec la séquence | ||
+ | 0xFFFF,0x0000,0x0000 32*60 fois de suite, on va passer 16 bandes de 60 leds connectées à GPIOB0..GPIOB15 au noir | ||
+ | |||
+ | Le signal de RESET est obtenu avec >50µs à 0. 50/0.4 = 125. Pour ça, j'ai mis en tête de séquence 140 fois 0x0000. | ||
+ | |||
+ | Le DMA est mis ultra prioritaire pour ce qui est de la prise du bus, si possible plus prioritaire que le CPU. | ||
+ | |||
+ | Le gros avantage de la méthode est de supprimer toute contrainte temps réel tordue au niveau du code. On remplit la mémoire à sa guise et on démarre le DMA. En pratique, le remplissage de la mémoire se fait quasiment à la même vitesse que le transfert DMA. Donc, on ne perd même pas de temps. Pendant le transfert DMA, la charge sur le BUS est négligeable. |
Revision as of 15:28, 29 April 2016
Conseils aux utilisateurs de dandes de WS2812B
Datasheet https://www.adafruit.com/datasheets/WS2812B.pdf
En résumé
- Bien assurer que votre conception respecte que DI n'est jamais au dessus de VCC+0.5V, et tout de même au dessus de 0.7V*VCC, c'est le plus délicat en raison des chutes de tension dans le systeme.
- Alimenter la bande de leds du coté DI sinon, cela ne fait qu'empirer le probleme de différence de tension entre l'alim et DI.
- Respecter les consignes Electrostatiques.
A savoir sur les LEDS RGB WS2812B
Work in progress !! Je continue d'observer un effet que je n'explique pas encore : selon la temperature, et quand la charge est élevée (image blanche et lumineuse), il se peut que sur certaines bandes (toujours les mêmes) que à partir d'une led, pas necessairement la première, mais toujours la même sur cette bande, le signal de contrôle ne passe plus. Maintenant que j'arrive bien à reproduire le problème, je vais faire des mesures oscillo. Je me demande si ce ne serait pas juste un probleme de capa de découplage qui aurait une soudure sèche.
La datasheet précise trois choses importantes
- La tension d'alimentation du chip peut aller de 3.5V à 5.3V
- La tension haute (bit à 1) du fil de contrôle DI ne doit pas dépasser la tension d'alimentation Led de plus de 0.5V (absolute max rating)
- Le niveau haut DI minimum est 0.7 * VCCLed. Sous 3.5V ça fait 2.45V. Sous 5V, ça fait 3.5V.
Le chip WS2812B effectue une régulation en courant sur les leds. Cela permet d'avoir une luminosité insensible à la tension d'alimentation et ainsi un éclairage régulier entre bandes.
Le courant dans l'alim va varier et introduire une chute de tension dans les cables d'alimentation et la bande d'autant plus élevée que la luminosité est grande.
Cette chute de tension n'est pas du tout négligable. On parle de courants de l'ordre de 3.6A pour 60 WS2812B en série si on s'en tient à la spec.
Par exemple, si le cablage a une impédance de 0.1 ohms, ça fait une chute de tension de 0.1*3.6 = 0.36V
J'ai pu vérifier que la WS2812B n'aime pas du tout que DI soit hors spec. Elle ne crame par pour autant immédiatement, mais finit par battre de l'aile jusqu'à rendre l'âme au bout de quelques heures.
Le problème est alors, de bien piloter le niveau haut de DI, en dessous du seuil max et au dessus du seuil min, cela quelque soit la luminosité (et donc le courant et donc la chute de tension).
Quand la tension d'alim de la led vaut 5V, on voit qu'on ne peut pas piloter DI par une puce alimentée en 3.3V, car on ne peut dépasser 3.3V alors qu'on doit générer au minimum du 3.5V.
J'ai donc alimenté mes buffers 74ACT244 vers DI en 5V (5VSB alim PC). Mais là, on tombe sur le probleme que lorsque la chute de tension sur les leds descend à 3.5, envoyer du 5V est assez destructeur. J'ai mis une résistance série de 100 ohm pour un minimum de protection en courant et pour adapter l'impédance. Cela donne un signal très propre à l'oscillo, mais il reste qu'il est hors spec sur les bandes de LED en forte charge.
Revenons à la spec : Le niveau haut DI minimum est 0.7 * VCCLed. Sous 3.5V ça fait 2.45V. Sous 5V, ça fait 3.5V. Un bon compromis serait alors d'injecter sur DI du 4V. Avec ça, dans toute la plage de tension fontionnelle VCCLed, on est en dessous de VCCLed+0.5 et au dessus du seuil bit à 1. On reste quand même aux limites de la spec absolue. On voit d'ailleurs qu'il est impossible d'avoir une tension fixe qui respecte la spec exactement dans toute la plage de tension d'alim acceptée. Au mieux, ce serait 3.5V, mais sous 5V, on arriverait jamais en pratique à atteindre le seuil bit à 1 de 3.5V
Dans mon cas, où j'ai 20 bandes, chacune allumée différemment, avec donc des chutes de tension différentes, mais une seule source de tension pour le signal DI, c'est problématique.
Donc, pour redescendre à 4V, une possibilité serait de mettre une resistance de 400 ohms entre DI et la masse. Le pont diviseur donne : vout = vcc*(400)/(400+100) = 4V. Mais le problème devient la quantité de courant tirée : 5/500 = 10mA. Pour un fil ça irait, mais avec 20 fils, ça fait 200mA (1 Watt total, 80mA par octo buffer), ce qui est vraiment beaucoup (en plus, ce sont des courants impulsionnels). D'autant que le firmware fait que tous les DI passent à 1 simultannément. Ce serait bien, pour réduire le courant, d'augmenter la résistance série à 270 ohms (avec 1000 vers la masse => VDI = 3.93V, courant total = 20*5/1270=78mA, 31mA par octo buffer). Mais le probleme devient (peut-être) alors les temps de montée et descente ainsi que la sensibilité au bruit ambient. Je n'ai pas encore testé ça. C'est la modif la plus simple par rapport à mon design actuel.
Dans mon cas, pour ça, j'aurais pu faire ceci : un LDO (low drop regulator) génère du 4V à partir du 5V. Et ce 4V alimente VCC des 74ACT244. La sortie des buffers sont des resistances de 100ohms qui vont vers DI. Peut-être même devrait-on prendre un LDO ajustable pour trouver le meilleur compromis selon chaque configuration.
La plupart du temps, ce sont les WS2812B aux extrémités qui font fusible. Coté alim/DI pour des problemes de tension. Mais aussi à l'autre extrémité non branchée. Comme j'ai vu mourir des leds en bout de bande alors que cette extrémité n'était pas connectée, j'en déduit qu'elles sont sensibles aux décharges electrostatiques.
Autre Info : En pratique, j'ai mesuré, et cela de plusieurs façons différentes (courant sur une alim 13.8V avec derrière un convertisseur DCDC12/24V vers 5V , mais aussi directement sur le 220V avec 1200 LEDs connectées) qu'en réalité le courant moyen par WS2812B lorsqu'elle est à fond est plutôt de 30mA et non pas 60mA comme annoncé dans la spec. Peut-être est ce parce que la spec indique le courant max instantanné et que la PWM ne dépasse jamais le rapport cyclique de 50%.
Si dans votre design, vous ne pilotez qu'une seule bande (même longue), les choses sont plus simples. Vous pouvez vous permettre d'avoir un circuit d'adaptation prenant comme référence de tension l'alim VCCLed. Un transistor en collecteur ouvert (avec pull-up) pourrait être OK.
Pilotage des Leds par DMA
Le timing DI offre une opportunité.
- Data Bit 0 : 1 pendant 0.4us±150ns puis 0 pendant 0.85µs±150ns
- Data Bit 1 : 1 pendant 0.8us±150ns puis 0 pendant 0.45µs±150ns
par conséquent on reste dans la spec avec ce timing :
- Data Bit 0 : 1 pendant 0.4us±150ns puis 0 pendant 0.8µs+200ns-100ns
- Data Bit 1 : 1 pendant 0.8us±150ns puis 0 pendant 0.4µs±200ns-100ns
L'idée est d'utiliser un DMA, Mémoire->GPIO avec chaque transfert déclenché par un timer toutes les 0.4µs
Tous les micros ne savent pas faire ça, mais les STM32F446 oui.
A supposer qu'on configure le DMA pour envoyer la mémoire vers le GPIOB
Si par exemple on remplit la mémoire avec la séquence 0xFFFF,0xFFFF,0x0000 32*60 fois de suite, on va allumer 16 bandes de 60 leds connectées à GPIOB0..GPIOB15 au blanc max
Si par exemple on remplit la mémoire avec la séquence 0xFFFF,0x0000,0x0000 32*60 fois de suite, on va passer 16 bandes de 60 leds connectées à GPIOB0..GPIOB15 au noir
Le signal de RESET est obtenu avec >50µs à 0. 50/0.4 = 125. Pour ça, j'ai mis en tête de séquence 140 fois 0x0000.
Le DMA est mis ultra prioritaire pour ce qui est de la prise du bus, si possible plus prioritaire que le CPU.
Le gros avantage de la méthode est de supprimer toute contrainte temps réel tordue au niveau du code. On remplit la mémoire à sa guise et on démarre le DMA. En pratique, le remplissage de la mémoire se fait quasiment à la même vitesse que le transfert DMA. Donc, on ne perd même pas de temps. Pendant le transfert DMA, la charge sur le BUS est négligeable.