RGB LED WS2812?
Moderator: Benj
RGB LED WS2812?
Bonjour,
Je voudrais savoir s’il y a quel qu’un qui a déjà réaliser un programme pour Controller les LED Intelligente WS2812 du manufacturier Worldsemi??
Merci à tous
Chris
Je voudrais savoir s’il y a quel qu’un qui a déjà réaliser un programme pour Controller les LED Intelligente WS2812 du manufacturier Worldsemi??
Merci à tous
Chris
-
- Posts: 594
- Joined: Thu Sep 17, 2009 7:52 am
- Location: Belgium
- Has thanked: 63 times
- Been thanked: 102 times
- Contact:
Re: RGB LED WS2812?
Pas moi, mais ça n'a pas l'air bien compliqué.
Tu as des problèmes avec ton code/flowchart ?
- Nicolas
Tu as des problèmes avec ton code/flowchart ?
- Nicolas
Re: RGB LED WS2812?
Bonjour Nicolas,
Effectivement ça n’a pas l'air très complique!
Mais je ne suis pas très familiariser avec le C Code dans Flowcode et encore moins pour écrire un code pour la transmission de donnée, je cherche un tutorial en français ou quel qu’un qui pourrais me donner un p’tit court ou seulement répondre a mes questions me guider à ce sujet, jusqu’à maintenant je n’ai pas de chance
Merci
Chris
Effectivement ça n’a pas l'air très complique!
Mais je ne suis pas très familiariser avec le C Code dans Flowcode et encore moins pour écrire un code pour la transmission de donnée, je cherche un tutorial en français ou quel qu’un qui pourrais me donner un p’tit court ou seulement répondre a mes questions me guider à ce sujet, jusqu’à maintenant je n’ai pas de chance
Merci
Chris
-
- Posts: 594
- Joined: Thu Sep 17, 2009 7:52 am
- Location: Belgium
- Has thanked: 63 times
- Been thanked: 102 times
- Contact:
Re: RGB LED WS2812?
Hmmm, en revoyant les timings du protocole, c'est assez court...
Datasheet : http://www.adafruit.com/datasheets/WS2812.pdf
Tout d'abord faut voir comment envoyer plusieurs couleurs si tu as plusieurs LED en cascade.
Sur la page 5 du datasheet, il y a une image qui montre comment tu contrôles des LED en cascade.
Celui ci montre un exemple pour 3 LED.
Ton microcontrolleur envoi donc 3 fois 24 bits et un reset.
Led D1 prends les données du "first 24 bits" et puis envoie les données entrante suivantes aux autres LEDs. C'est comme si, une fois qu'il a lu sa couleur, il fait un lien entre DI (data in) et DO (data out) et tout se que le microcontrolleur envoi est directement passé aux autres LEDs.
Là, D2 prends les données du "second 24 bit" et puis fait passer le reste des données au LED suivant.
Ainsi de suite, jusqu'au reset.
Pour envoyer une couleur RGB, tu dois suivre leur protocole.
Pour un bit de valeur 0, tu dois mettre DI 'high' pendant 350ns (+/- 150ns) puis 'low' pendant 800ns.
Pour un bit de valeur 1, tu dois mettre DI 'high' pendant 700ns puis 'low' pendant 600ns.
Un reset consiste à mettre DI 'low' pendant plus de 50us.
Pour faire se signal, à mon avis, utiliser des delays et set/clear un I/O n'est pas la bonne solution.
Le mieux serait d'utiliser un PWM ou encore un timer interrupt, voir même les deux.
Le PWM serait le plus simple je pense. Là tu n'as qu'a dire quelle fréquence utiliser et modifier le TON au fur et à mesure.
Pour faire simple on va dire que le signal d'un bit, fait 1.2µs.
T0H = 400ns
T0L = 800ns
T1H = 700ns
T1L = 500ns
Se qui te donne une fréquence de (à peu près) 833kHz.
A toi de voir comment tu gères la couleur de tes LEDs, disons que tu as une variable couleurLED qui contient 24 bits. Tu y stocke la couleur d'un LED avec le format GRB.
Le but est de faire en sorte de parcourir les bits de cette variable (de MSB à LSB), et de modifier le TON du PWM en conséquences.
Donc, si ton bit X de la variable couleurLED est à 1, tu dois changer TON pour qu'il soit égal à 700ns. Si ton bit X est à 0, tu changes TON à 400ns.
Une fois que tu as fini d'envoyer 24 bits, tu passes a la couleur du prochain LED, et ainsi de suite jusqu'à faire tout les LEDs.
Une fois fini, tu dois reset le tout. Pour ça tu pourrais, par exemple, désactiver le PWM et mettre sa sortie à 0 pendant plus de 50µs.
Si tu veux le faire via le timer interrupt, tu dois le configurer afin qu'il s'exécute tout les 100ns (par ex.).
Dans ton interrupt, tu n'as qu'à mettre un compteur. Celui-ci incrémente de 1, tout les 100ns.
Se compteur est remit à 0 à chaque fois que tu finis de transmettre un bit.
Dans ton main tu va parcourir chaque bit de ta variable couleurLED. Si la valeur est a 1, tu dois mettre un I/O à 1, puis attendre que ton compteur soit égal ou plus grand que 700ns, puis a 0 pendant 600ns.
Si la valeur est a 0, tu mets un I/O à 1 pendant 400ns puis a 0 pendant 800ns.
Voilà se que ça donne en pseudo code:
Voilà, j'espère que c'est assez clair, si t'as des questions n'hésite pas.
- Nicolas
Datasheet : http://www.adafruit.com/datasheets/WS2812.pdf
Tout d'abord faut voir comment envoyer plusieurs couleurs si tu as plusieurs LED en cascade.
Sur la page 5 du datasheet, il y a une image qui montre comment tu contrôles des LED en cascade.
Celui ci montre un exemple pour 3 LED.
Ton microcontrolleur envoi donc 3 fois 24 bits et un reset.
Led D1 prends les données du "first 24 bits" et puis envoie les données entrante suivantes aux autres LEDs. C'est comme si, une fois qu'il a lu sa couleur, il fait un lien entre DI (data in) et DO (data out) et tout se que le microcontrolleur envoi est directement passé aux autres LEDs.
Là, D2 prends les données du "second 24 bit" et puis fait passer le reste des données au LED suivant.
Ainsi de suite, jusqu'au reset.
Pour envoyer une couleur RGB, tu dois suivre leur protocole.
Pour un bit de valeur 0, tu dois mettre DI 'high' pendant 350ns (+/- 150ns) puis 'low' pendant 800ns.
Pour un bit de valeur 1, tu dois mettre DI 'high' pendant 700ns puis 'low' pendant 600ns.
Un reset consiste à mettre DI 'low' pendant plus de 50us.
Pour faire se signal, à mon avis, utiliser des delays et set/clear un I/O n'est pas la bonne solution.
Le mieux serait d'utiliser un PWM ou encore un timer interrupt, voir même les deux.
Le PWM serait le plus simple je pense. Là tu n'as qu'a dire quelle fréquence utiliser et modifier le TON au fur et à mesure.
Pour faire simple on va dire que le signal d'un bit, fait 1.2µs.
T0H = 400ns
T0L = 800ns
T1H = 700ns
T1L = 500ns
Se qui te donne une fréquence de (à peu près) 833kHz.
A toi de voir comment tu gères la couleur de tes LEDs, disons que tu as une variable couleurLED qui contient 24 bits. Tu y stocke la couleur d'un LED avec le format GRB.
Le but est de faire en sorte de parcourir les bits de cette variable (de MSB à LSB), et de modifier le TON du PWM en conséquences.
Donc, si ton bit X de la variable couleurLED est à 1, tu dois changer TON pour qu'il soit égal à 700ns. Si ton bit X est à 0, tu changes TON à 400ns.
Une fois que tu as fini d'envoyer 24 bits, tu passes a la couleur du prochain LED, et ainsi de suite jusqu'à faire tout les LEDs.
Une fois fini, tu dois reset le tout. Pour ça tu pourrais, par exemple, désactiver le PWM et mettre sa sortie à 0 pendant plus de 50µs.
Si tu veux le faire via le timer interrupt, tu dois le configurer afin qu'il s'exécute tout les 100ns (par ex.).
Dans ton interrupt, tu n'as qu'à mettre un compteur. Celui-ci incrémente de 1, tout les 100ns.
Se compteur est remit à 0 à chaque fois que tu finis de transmettre un bit.
Dans ton main tu va parcourir chaque bit de ta variable couleurLED. Si la valeur est a 1, tu dois mettre un I/O à 1, puis attendre que ton compteur soit égal ou plus grand que 700ns, puis a 0 pendant 600ns.
Si la valeur est a 0, tu mets un I/O à 1 pendant 400ns puis a 0 pendant 800ns.
Voilà se que ça donne en pseudo code:
Code: Select all
// Dans cette exemple, DI est branché au pin 0 du PORTB
long compteur; // variable globale
void interrupt()
{
compteur++; // compteur incrémente toutes les 100ns
}
void main()
{
long couleurLED = 0x0000FF; // format de couleur GRB -> 0xGGRRBB
int bit;
// initialiser interrupt avec les bon paramètres
compteur = 0;
for (bit = 0; bit < 24; bit++) // boucle pour test les 24 bits dans une variable qui contient la couleur d'un LED.
{
// simple AND de la variable couleurLED et un 'mask', pour voir si un bit est à 1 ou 0
if ( couleurLED & ( 1 << ( 24 - 1 - bit ) ) ) // si la condition est 'vrai'
{
if ( compteur <= 7) // si le compteur est en dessous des 700ns (= T1H)
PORTB = 1; // mettre le I/O à 1
else if (compteur <= 13) // sinon, si le compteur est en dessous des 1300ns (= T1H + T1L)
PORTB = 0; // mettre le I/O à 0
else // sinon, si le compteur est plus grand que 13
compteur = 0;
}
else // si la condition est fausse / le bit est 0
{
if ( compteur <= 4) // si le compteur est en dessous des 400ns (= T0H)
PORTB = 1; // mettre le I/O à 1
else if (compteur <= 12) // sinon, si le compteur est en dessous des 1200ns (= T0H + T0L)
PORTB = 0; // mettre le I/O à 0
else // sinon, si le compteur est plus grand que 12
compteur = 0;
}
}
}
- Nicolas
Re: RGB LED WS2812?
Bonjour Nicolas,
Je comprends bien la théorie mais au niveau pratique ca bug. J’ai tenté de faire un programme à partir de ton pseudo code est quand est venu le temps de compiler j’ai eu pleins d’erreurs!
Le code doit-il être dans le Main ou dans l’ interrupt?
J’utilise Flocode v5 et un PIC16F876A avec un crystal de 20.000MHZ.
Je prévois avoir plusieurs LED en cascade, tout d’abord je me suis procurer pour faire des tests le Flora Neopixel Ring de Adafruit http://www.adafruit.com/products/1463
Merci de ton aide c’est très apprécier
Chris
Je comprends bien la théorie mais au niveau pratique ca bug. J’ai tenté de faire un programme à partir de ton pseudo code est quand est venu le temps de compiler j’ai eu pleins d’erreurs!
Le code doit-il être dans le Main ou dans l’ interrupt?
J’utilise Flocode v5 et un PIC16F876A avec un crystal de 20.000MHZ.
Je prévois avoir plusieurs LED en cascade, tout d’abord je me suis procurer pour faire des tests le Flora Neopixel Ring de Adafruit http://www.adafruit.com/products/1463
Merci de ton aide c’est très apprécier
Chris
-
- Posts: 594
- Joined: Thu Sep 17, 2009 7:52 am
- Location: Belgium
- Has thanked: 63 times
- Been thanked: 102 times
- Contact:
Re: RGB LED WS2812?
Uploade ton fichier flowcode que je puisse y jeter un œil.
Dans mon pseudo code, j'ai 2 fonctions. Une fonction main et une fonction interrupt. Tout se qui est dans main, va dans le main, et tout se qui se trouve dans interrupt va dans ton timer interrupt.
- Nicolas
Dans mon pseudo code, j'ai 2 fonctions. Une fonction main et une fonction interrupt. Tout se qui est dans main, va dans le main, et tout se qui se trouve dans interrupt va dans ton timer interrupt.
- Nicolas
-
- Posts: 594
- Joined: Thu Sep 17, 2009 7:52 am
- Location: Belgium
- Has thanked: 63 times
- Been thanked: 102 times
- Contact:
Re: RGB LED WS2812?
Oui je l'ai reçu, je check ça.
EDIT:
Ah oui je vois le souci. Il fallait pas copier-coller mon pseudo-code dans ton interrupt.
Je l'ai justement appelé "pseudo code" pour dire que c'est un code qui ne marchera pas, sans que tu l'écrives correctement.
Je te conseille de lire le code C de tes programmes flowcode (du moins la fonction "main" et les interrupt). ça va énormément t'aider à comprendre comment ça marche, et ça t'aidera à lire des codes C rédigée par d'autres personnes comme des exemples de code sur le net.
EDIT2:
Bon... L'interrupt ne va pas assez vite... max 19kHz.
Et le PWM ne va que jusqu'à 50us ... Alors qu'il te faudrait 100ns.
Je vais essayer de le faire manuellement (set/clear un pin).
EDIT:
Ah oui je vois le souci. Il fallait pas copier-coller mon pseudo-code dans ton interrupt.
Je l'ai justement appelé "pseudo code" pour dire que c'est un code qui ne marchera pas, sans que tu l'écrives correctement.
Je te conseille de lire le code C de tes programmes flowcode (du moins la fonction "main" et les interrupt). ça va énormément t'aider à comprendre comment ça marche, et ça t'aidera à lire des codes C rédigée par d'autres personnes comme des exemples de code sur le net.
EDIT2:
Bon... L'interrupt ne va pas assez vite... max 19kHz.
Et le PWM ne va que jusqu'à 50us ... Alors qu'il te faudrait 100ns.
Je vais essayer de le faire manuellement (set/clear un pin).
-
- Posts: 594
- Joined: Thu Sep 17, 2009 7:52 am
- Location: Belgium
- Has thanked: 63 times
- Been thanked: 102 times
- Contact:
Re: RGB LED WS2812?
Bon voilà, j'ai fait un code qui le fait manuellement.
Je ne l'ai pas testé mais il compile chez moi.
Les icones de code C contiennent uniquement une instructions ASM (répétée plusieurs fois), notamment l'instruction NOP qui indique au PIC qu'il ne doit rien faire du tout.
Il faut savoir que les microcontrolleurs PIC exécutent une instruction tout les 4 periodes de l'oscillateur choisit. Donc ici pour ta frequence de 20MHz, le PIC exécute une instruction tout les 5MHz, soit 200ns.
Je peux donc me créer un petit delay de 400ns et de 800ns grâce à l'instruction NOP et en la répétant plusieurs fois.
Vérifie le code que je t'ai écrit et check si ça marche en mesurant le signal avec un oscilloscope (si c'est pas bon poste des photo's du signal).
- Nicolas
Je ne l'ai pas testé mais il compile chez moi.
Les icones de code C contiennent uniquement une instructions ASM (répétée plusieurs fois), notamment l'instruction NOP qui indique au PIC qu'il ne doit rien faire du tout.
Il faut savoir que les microcontrolleurs PIC exécutent une instruction tout les 4 periodes de l'oscillateur choisit. Donc ici pour ta frequence de 20MHz, le PIC exécute une instruction tout les 5MHz, soit 200ns.
Je peux donc me créer un petit delay de 400ns et de 800ns grâce à l'instruction NOP et en la répétant plusieurs fois.
Vérifie le code que je t'ai écrit et check si ça marche en mesurant le signal avec un oscilloscope (si c'est pas bon poste des photo's du signal).
- Nicolas
- Attachments
-
- LED WS2812 v.BETA.fcf
- (9.84 KiB) Downloaded 544 times
Re: RGB LED WS2812?
Malheureusement ça ne fonctionne pas?
Voir la photo's du signal
Chris
Voir la photo's du signal
Chris
- Attachments
-
- WS2812 Data.png
- (24.91 KiB) Downloaded 18403 times
-
- Posts: 594
- Joined: Thu Sep 17, 2009 7:52 am
- Location: Belgium
- Has thanked: 63 times
- Been thanked: 102 times
- Contact:
Re: RGB LED WS2812?
Je me doutais bien que ça n'allait pas fonctionner, le timing est très rapide.
Le 'high' pulse devrait être correcte, je ne sais pas si tu as mesuré la largeur de celui-ci ?
Le 'low' pulse est plus compliqué à régler. Il y a des calculs et des conditions qui font que la largueur du low pulse s'élargisse.
Et si tu desactive le second block C dans les deux branches du "IF" ?
- Nicolas
Le 'high' pulse devrait être correcte, je ne sais pas si tu as mesuré la largeur de celui-ci ?
Le 'low' pulse est plus compliqué à régler. Il y a des calculs et des conditions qui font que la largueur du low pulse s'élargisse.
Et si tu desactive le second block C dans les deux branches du "IF" ?
- Nicolas
Re: RGB LED WS2812?
La largeur du 'high' pulse est de 1.250us jusqu'à la 16 bit ensuit elle s’élargit a 1.750us.
Si je désactive le second block C dans les deux branches du "IF" la largeur du 'high' pulse est de 1.250us pour les 24 bit mais le low pulse s'élargisse.
Chris
Si je désactive le second block C dans les deux branches du "IF" la largeur du 'high' pulse est de 1.250us pour les 24 bit mais le low pulse s'élargisse.
Chris
-
- Posts: 594
- Joined: Thu Sep 17, 2009 7:52 am
- Location: Belgium
- Has thanked: 63 times
- Been thanked: 102 times
- Contact:
Re: RGB LED WS2812?
C'est dommage ça ...
Je sais pas, faudrait p'tet essayer de le faire tout en ASM... :/
Sinon revoir le PWM, p'tet que je me suis trompé.
Essaye d'envoyer un MP a Benj (en anglais) voir si lui a une idée.
Je sais pas, faudrait p'tet essayer de le faire tout en ASM... :/
Sinon revoir le PWM, p'tet que je me suis trompé.
Essaye d'envoyer un MP a Benj (en anglais) voir si lui a une idée.
-
- Posts: 1314
- Joined: Sun Jan 15, 2012 3:15 pm
- Has thanked: 474 times
- Been thanked: 458 times
- Contact:
Re: RGB LED WS2812?
Hi
Theres a lot of code written for arduino for that chip, maybe download one and convert into a flowchart ??
Regards
Dazz
Theres a lot of code written for arduino for that chip, maybe download one and convert into a flowchart ??
Regards
Dazz
To sign up to the V5 forum follow this link http://www.matrixmultimedia.com/forum_upgrades.php
-
- Posts: 594
- Joined: Thu Sep 17, 2009 7:52 am
- Location: Belgium
- Has thanked: 63 times
- Been thanked: 102 times
- Contact:
Re: RGB LED WS2812?
Dazz, the advantage of the AVR for this sort of application it's how fast it executes an instruction. 1 clock cycle / instruction instead of 4 clock cycles / instructions for a PIC.
So, you'd have to program it in ASM, just like the Adafruit NeoPixel library. That's what I told him that he might have to do.
- Nicolas
So, you'd have to program it in ASM, just like the Adafruit NeoPixel library. That's what I told him that he might have to do.
- Nicolas
Re: RGB LED WS2812?
Donc je serais mieux d'aller vers un AVR pour ce type de projet et quel famille des microcontrôleurs AVR me conseille-tu?
Merci,
Chris
Merci,
Chris
-
- Posts: 594
- Joined: Thu Sep 17, 2009 7:52 am
- Location: Belgium
- Has thanked: 63 times
- Been thanked: 102 times
- Contact:
Re: RGB LED WS2812?
Non pas spécialement.
Dans les 2 cas, tu devras le faire via ASM vu que la compilation du C et l'optimisation du code font que le timing ne soit pas correcte.
Perso, j'ai ma petite idée de comment le faire en ASM, mais pour l'integrer dans un code C et que le code ASM utilise des variables du code C, ça je ne sais pas .
- Nicolas
Dans les 2 cas, tu devras le faire via ASM vu que la compilation du C et l'optimisation du code font que le timing ne soit pas correcte.
Perso, j'ai ma petite idée de comment le faire en ASM, mais pour l'integrer dans un code C et que le code ASM utilise des variables du code C, ça je ne sais pas .
- Nicolas
Re: RGB LED WS2812?
Ok, voudrais-tu partager t'a p'tit idée sur comment le faire en ASM et je trouverez une solution pour l'intégrer dans un code C??
Est si ça fonction tu pourra le publier sur ton site!.......en pansent super ton site
Merci,
Chris
Est si ça fonction tu pourra le publier sur ton site!.......en pansent super ton site
Merci,
Chris
-
- Posts: 594
- Joined: Thu Sep 17, 2009 7:52 am
- Location: Belgium
- Has thanked: 63 times
- Been thanked: 102 times
- Contact:
Re: RGB LED WS2812?
Oui pas de souci, là maintenant je ne peux pas parce que je pars travailler.
Dès que je l'aurais fait, je vais aussi le mesurer avec le scope voir si c'est juste et je t'envoi tout ça.
Merci, mais ça fait un baille que j'ai rien posté sur mon site... C'est assez embêtant à entretenir x).
Dès que je l'aurais fait, je vais aussi le mesurer avec le scope voir si c'est juste et je t'envoi tout ça.
Merci, mais ça fait un baille que j'ai rien posté sur mon site... C'est assez embêtant à entretenir x).
-
- Posts: 594
- Joined: Thu Sep 17, 2009 7:52 am
- Location: Belgium
- Has thanked: 63 times
- Been thanked: 102 times
- Contact:
Re: RGB LED WS2812?
Hmmm... C'est assez juste le timing...
Je n'ai pas pu utiliser de boucle, fallait faire bit par bit.
La fonction que j'ai faite envoi un byte entier via le protocole utilisé dans les LED WS2813.
Chez moi ça compile donc d'apres moi ça devrait marcher.
Si tu as MPLABX, crée toi un project utilisant le compilateur mpasm et copie-colle le code si-dessous.
Compile le projet et envoi le hex, via PPPv3, à ton PIC et vérifie les timings, ou mieux encore, branche le à un LED et regarde si ça marche.
La couleur devrait être un peu du genre cyan, (blue a 100% et un peu de vert).
Si tu regardes mon code tu verras que dans la fonction SendColor il y a des trucs du genre :
Ces petits commentaires montre le nombres de clock cycles (4 * 1/20MHz) entre 2 point. C'est comme ça que j'ai calculé le timing des impulsions a envoyé au LED.
Je n'ai pas pu utiliser de boucle, fallait faire bit par bit.
La fonction que j'ai faite envoi un byte entier via le protocole utilisé dans les LED WS2813.
Chez moi ça compile donc d'apres moi ça devrait marcher.
Si tu as MPLABX, crée toi un project utilisant le compilateur mpasm et copie-colle le code si-dessous.
Compile le projet et envoi le hex, via PPPv3, à ton PIC et vérifie les timings, ou mieux encore, branche le à un LED et regarde si ça marche.
La couleur devrait être un peu du genre cyan, (blue a 100% et un peu de vert).
Si tu regardes mon code tu verras que dans la fonction SendColor il y a des trucs du genre :
Code: Select all
; (2)
; From (1) to (2), RA0 has been 0 for 2 CC = 400ns (T0H)
Code: Select all
; WS2812 Test library
; 20MHz internal osc
; 5MHz/instruction -> 200ns/instruction
; *CC = clock cycles
errorlevel -302, -305
LIST P=16F876A
#include P16F876A.inc
; Config : Ext OSC, No Watchdog, No code protect
__CONFIG _FOSC_HS & _WDT_OFF & _BODEN_OFF & _CP_OFF & _CPD_OFF
; Vars (General Purpose Registers)
RED EQU H'020'
GREEN EQU H'021'
BLUE EQU H'022'
TEMP EQU H'023'
ORG H'00'
GOTO init
ORG H'05'
init:
BCF STATUS, RP0
BCF STATUS, RP1 ; Set Bank 0
CLRF PORTA ; Clear PORTA register
BSF STATUS, RP0 ; Set Bank 1
MOVLW H'07' ; W_REG = 0x07
MOVWF ADCON1 ; ADCON1 = W_REG -> Set PORTA to digital IO
MOVLW H'FE' ; W_REG = 0xFE
MOVWF TRISA ; TRISA = 0xFE -> Set RA0 to output, all others to input
BCF STATUS, RP0 ; Set Bank 0
; Set Color
MOVLW H'00'
MOVWF RED
MOVLW H'55'
MOVWF GREEN
MOVLW H'FF'
MOVWF BLUE
main:
MOVFW GREEN
MOVWF TEMP
CALL WS2813_SendColor
MOVFW RED
MOVWF TEMP
CALL WS2813_SendColor
MOVFW BLUE
MOVWF TEMP
CALL WS2813_SendColor
CALL WS2813_SendReset
GOTO main
WS2813_SendReset:
BCF PORTA, 0 ; Clear RA0
MOVLW H'0FF' ; WREG = 0xFF
WS2813_SendReset_1:
DECFSZ TEMP
GOTO WS2813_SendReset_1
RETURN
; T0H = 400ns
; T0L = 800ns
; T1H = 800ns
; T1L = 600ns
WS2813_SendColor:
WS2813_SendColor_bit7:
; if (TEMP & (1 << 7))
BTFSC TEMP, 7
; if true
; send T1H + T1L
GOTO WS2813_SendColor_bit7_1 ;
; if false
; send T0H + T0L
BSF PORTA, 0 ; Set RA0
; (1)
NOP ; | 1 CC
BCF PORTA, 0 ; Clear RA0 | 1 CC
; (2)
; From (1) to (2), RA0 has been 0 for 2 CC = 400ns (T0H)
GOTO WS2813_SendColor_bit6 ; | 2 CC
WS2813_SendColor_bit7_1:
BSF PORTA, 0 ; Set RA0
; (3)
NOP ; | 1 CC
NOP ; | 1 CC
NOP ; | 1 CC
BCF PORTA, 0 ; Clear RA0 | 1 CC
; (4)
; From (3) to (4), RA0 has been 1 for 4 CC = 800ns (T1H)
; ----- bit 7 end -----
; ----- bit 6 start ----
WS2813_SendColor_bit6:
; if (TEMP & (1 << 6))
BTFSC TEMP, 6
; if true | 1 CC
; send T1H + T1L
GOTO WS2813_SendColor_bit6_1 ; | 2 CC
; if false | 2 CC
; send T0H + T0L
BSF PORTA, 0 ; Set RA0 | 1 CC
; (5)
; From (2) to (5), RA0 has been 0 for 5 CC = 1000ns (T0L + 200ns)
; From (4) to (5), RA0 has been 0 for 3 CC = 600ns (T1L)
NOP ; | 1 CC
BCF PORTA, 0 ; Clear RA0 | 1 CC
GOTO WS2813_SendColor_bit5 ; | 2 CC
WS2813_SendColor_bit6_1:
BSF PORTA, 0 ; Set RA0 | 1 CC
; (6)
; From (2) to (6), RA0 has been 0 for 6 CC = 1200ns (T0L + 400ns)
; From (4) to (6), RA0 has been 0 for 4 CC = 800ns (T1L + 200ns)
NOP ; | 1 CC
NOP ; | 1 CC
NOP ; | 1 CC
BCF PORTA, 0 ; Clear RA0 | 1 CC
; ----- bit 6 end -----
; ----- bit 5 start ----
WS2813_SendColor_bit5:
BTFSC TEMP, 5
GOTO WS2813_SendColor_bit5_1
BSF PORTA, 0 ; Set RA0
NOP
BCF PORTA, 0 ; Clear RA0
GOTO WS2813_SendColor_bit4
WS2813_SendColor_bit5_1:
BSF PORTA, 0 ; Set RA0
NOP
NOP
NOP
BCF PORTA, 0 ; Clear RA0
; ----- bit 5 end -----
; ----- bit 4 start ----
WS2813_SendColor_bit4:
BTFSC TEMP, 4
GOTO WS2813_SendColor_bit4_1
BSF PORTA, 0 ; Set RA0
NOP
BCF PORTA, 0 ; Clear RA0
GOTO WS2813_SendColor_bit3
WS2813_SendColor_bit4_1:
BSF PORTA, 0 ; Set RA0
NOP
NOP
NOP
BCF PORTA, 0 ; Clear RA0
; ----- bit 4 end -----
; ----- bit 3 start ----
WS2813_SendColor_bit3:
BTFSC TEMP, 3
GOTO WS2813_SendColor_bit3_1
BSF PORTA, 0 ; Set RA0
NOP
BCF PORTA, 0 ; Clear RA0
GOTO WS2813_SendColor_bit2
WS2813_SendColor_bit3_1:
BSF PORTA, 0 ; Set RA0
NOP
NOP
NOP
BCF PORTA, 0 ; Clear RA0
; ----- bit 3 end -----
; ----- bit 2 start ----
WS2813_SendColor_bit2:
BTFSC TEMP, 2
GOTO WS2813_SendColor_bit2_1
BSF PORTA, 0 ; Set RA0
NOP
BCF PORTA, 0 ; Clear RA0
GOTO WS2813_SendColor_bit1
WS2813_SendColor_bit2_1:
BSF PORTA, 0 ; Set RA0
NOP
NOP
NOP
BCF PORTA, 0 ; Clear RA0
; ----- bit 2 end -----
; ----- bit 1 start ----
WS2813_SendColor_bit1:
BTFSC TEMP, 1
GOTO WS2813_SendColor_bit1_1
BSF PORTA, 0 ; Set RA0
NOP
BCF PORTA, 0 ; Clear RA0
GOTO WS2813_SendColor_bit0
WS2813_SendColor_bit1_1:
BSF PORTA, 0 ; Set RA0
NOP
NOP
NOP
BCF PORTA, 0 ; Clear RA0
; ----- bit 1 end -----
; ----- bit 0 start ----
WS2813_SendColor_bit0:
BTFSC TEMP, 0
GOTO WS2813_SendColor_bit0_1
BSF PORTA, 0 ; Set RA0
NOP
BCF PORTA, 0 ; Clear RA0
RETURN ; 2 CC
WS2813_SendColor_bit0_1:
BSF PORTA, 0 ; Set RA0
NOP
NOP
NOP
BCF PORTA, 0 ; Clear RA0
RETURN ; 2 CC
END
-
- Posts: 80
- Joined: Fri Jul 20, 2012 8:55 am
- Location: Chambly (France)
- Been thanked: 4 times
- Contact:
Re: RGB LED WS2812?
Bonjour Nicolas, bonjour Chris,
j'ai été intéressé par vos échanges sur le WS2812. Avez vous solutionné tout vos problèmes.
J'ai une application similaire à réaliser.
Je vous explique:
J'ai Flowcode V5 et V6 Professional pour Microchip. Je réalise des éclairages à LED piloté par ces puce.
Aujourd'hui j'aimerai réalisé un montage avec un PIC 16Fxxxx, et des modules WS2811.
Mais je ne veux pas piloter des LED. J'y ajoute un transistor MosFet IRF510 sur les sorties R, G, B et je contrôle une tension de 24V ou 48V.
Le module WS2811 et capable de fournir un courant de 18,5mA pour contrôler le Mosfet.
Je voudrai contrôler 64, ou 256, ou 4096 module WS2811.
Un test avec 2 ou 3 me permettrai de valider le programme Flowcode.
Je sais programmer les pic, mais pas le module WS2811. (et encore moins programmer en C).
Pourriez vous m'aider à élaborer mon programme Flowcode. Une fois que la structure est en place, j'apprend pour le restant
Merci pour votre aide précieuse.
Pascal
j'ai été intéressé par vos échanges sur le WS2812. Avez vous solutionné tout vos problèmes.
J'ai une application similaire à réaliser.
Je vous explique:
J'ai Flowcode V5 et V6 Professional pour Microchip. Je réalise des éclairages à LED piloté par ces puce.
Aujourd'hui j'aimerai réalisé un montage avec un PIC 16Fxxxx, et des modules WS2811.
Mais je ne veux pas piloter des LED. J'y ajoute un transistor MosFet IRF510 sur les sorties R, G, B et je contrôle une tension de 24V ou 48V.
Le module WS2811 et capable de fournir un courant de 18,5mA pour contrôler le Mosfet.
Je voudrai contrôler 64, ou 256, ou 4096 module WS2811.
Un test avec 2 ou 3 me permettrai de valider le programme Flowcode.
Je sais programmer les pic, mais pas le module WS2811. (et encore moins programmer en C).
Pourriez vous m'aider à élaborer mon programme Flowcode. Une fois que la structure est en place, j'apprend pour le restant
Merci pour votre aide précieuse.
Pascal
Re: RGB LED WS2812?
Bonjour Pascal
Comme j'ai mentionné à Nicolas, je n'ai pas eu le temps de valider son code faute de temps, débordé par le travail. Je devrais avoir du temps cette semaine.
Je vous tiendrais au courent pour la suite!
Merci et a bientot
Chris
Comme j'ai mentionné à Nicolas, je n'ai pas eu le temps de valider son code faute de temps, débordé par le travail. Je devrais avoir du temps cette semaine.
Je vous tiendrais au courent pour la suite!
Merci et a bientot
Chris
Re: RGB LED WS2812?
Bonjour Nicolas,
J'ai copié ton code et crée un projet en utilisent MPLAB et compile le projet et envoi le hex, via PPPv3. J'ai branché la LED et ça marche super bien.
Ne reste plus qu'à prendre le code asm et le faire fonctionner dans Flowcode, c’est ce que je vais tester aujourd’hui!
A suivre,
Merci pour ton aide précieuse.
Chris
J'ai copié ton code et crée un projet en utilisent MPLAB et compile le projet et envoi le hex, via PPPv3. J'ai branché la LED et ça marche super bien.
Ne reste plus qu'à prendre le code asm et le faire fonctionner dans Flowcode, c’est ce que je vais tester aujourd’hui!
A suivre,
Merci pour ton aide précieuse.
Chris
-
- Posts: 594
- Joined: Thu Sep 17, 2009 7:52 am
- Location: Belgium
- Has thanked: 63 times
- Been thanked: 102 times
- Contact:
Re: RGB LED WS2812?
Ah je suis content que ça marche!
Faudrait pouvoir faire une boucle pour envoyer les couleurs de tout tes LED un apres l'autre.
- Nicolas
PS: Le programme a marché du premier coup ?
Faudrait pouvoir faire une boucle pour envoyer les couleurs de tout tes LED un apres l'autre.
- Nicolas
PS: Le programme a marché du premier coup ?