After looking at JonnyMac's jm_ws2812.spin driver it looks like the only thing needed to make the driver for the WS2811 LEDs instead is to comment out the routine fix_colors which moves the color bytes for red and green.
After looking at JonnyMac's jm_ws2812.spin driver it looks like the only thing needed to make the driver for the WS2811 LEDs instead is to comment out the routine fix_colors which moves the color bytes for red and green.
Robert
All I did was add another parameter and a TJZ to skip over that code if the parameter is not set. The parameter gets set for swapping R and G.
I've never seen WS2812 style LEDs that DIDN'T require the swap. In my WS2801 code, there is a swap parameter. I'll add that to my WS2812 code (later -- have to prep for Hacakday event).
I think I have Jon's single-shot update mode working in my C code but I'm having a bit of trouble with calls to ws2812_execute that are too close together. Can anyone see the problem? If I add a delay between the calls then things seem to work okay. First, I'll show some of the C++ code I've been playing with to support the single-shot driver.
Here is my test program. It uses two animation classes: ws2812_FillWheelDim fills a color array with a rainbow of colors and rotates the rainbow on every update and ws2812_Chase does Jon's chase effect. In this program I'm using two AdaFruit LED devices, one 16 LED ring and an 8 LED strip. The ring is being driven by the ws2812_FillWheelDim animation (matching my Christmas ornament from last year) and the strip is being driven by the ws2812_Chase animation. Each device is on a different Propeller pin illustrating that more than one chain of LEDs can be managed by Jon's single-shot update mode.
#include <propeller.h>
#include "ws2812.h"
#define LED_PIN 15
#define LED_COUNT 16
#define LED2_PIN 14
#define LED2_COUNT 8
uint32_t Chakras[] = {
COLOR_RED,
COLOR_ORANGE,
COLOR_YELLOW,
COLOR_GREEN,
COLOR_BLUE,
COLOR_INDIGO
};
int Chackras_count = sizeof(Chakras) / sizeof(uint32_t);
int main(void)
{
int cog;
// 16 LED ring
uint32_t colors[LED_COUNT];
ws2812_FillWheelDim wheel(colors, LED_COUNT, LED_COUNT+5, 128);
// 8 LED strip
uint32_t colors2[LED2_COUNT];
ws2812_Chase chase(colors2, LED2_COUNT, Chakras, Chackras_count);
// animation array
ws2812_Animation *animations[] = {
&wheel,
&chase
};
if ((cog = ws2812_init()) < 0)
return 1;
for (;;) {
for (unsigned int i = 0; i < sizeof(animations) / sizeof(animations[0]); ++i)
animations[i]->update();
ws2812_execute(LED_PIN, colors, LED_COUNT);
ws2812_pause(10); [COLOR="#FF0000"]// why is this needed?[/COLOR]
ws2812_execute(LED2_PIN, colors2, LED2_COUNT);
ws2812_pause(100);
}
cogstop(cog);
return 0;
}
Here is the PASM code that is invoked when you call ws2812_execute(). I've also attached a .zip file containing all of the code including the C++ class definitions for ws2812_FillWheelDim and ws2812_Chase. These are in test.cpp which is a file I've been using to test a C++ animation interface.
'' Modified for use with PropGCC by David Betz
'' Derived from:
'' File....... jm_ws2812.spin
'' Purpose.... 800kHz driver for WS2812 LEDs
'' Author..... Jon "JonnyMac" McPhalen
'' Copyright (c) 2013 Jon McPhalen
{{
// parameter structure
typedef struct {
uint32_t pin;
uint32_t *colors;
volatile uint32_t count;
} ws2812_params;
// driver header structure
typedef struct {
uint32_t jmp_inst;
uint32_t resettix;
uint32_t bit0hi;
uint32_t bit0lo;
uint32_t bit1hi;
uint32_t bit1lo;
uint32_t swaprg;
} ws2812_hdr;
}}
pub driver
return @ws2812
dat
org 0
ws2812 jmp #get_cmd
resettix long 0 ' frame reset timing
bit0hi long 0 ' bit0 high timing
bit0lo long 0 ' bit0 low timing
bit1hi long 0 ' bit1 high timing
bit1lo long 0 ' bit1 low timing
swaprg long 0 ' swap r and g
clear_cmd mov t1, #0 ' clear last command
wrlong t1, par
get_cmd rdlong t1, par wz ' look for packed command
if_z jmp #get_cmd
mov t2, t1 ' get pin
and t2, #$1F ' isolate
mov txmask, #1 ' create mask for tx
shl txmask, t2
andn outa, txmask ' set to output low
or dira, txmask
mov ledcount, t1 ' get count
shr ledcount, #8 ' isolate
and ledcount, #$FF
add ledcount, #1 ' update (1 to 256 leds)
mov hubpntr, t1 ' get hub address
shr hubpntr, #16 ' isolate
temporary mov t1, #0 ' clear last command
wrlong t1, par
rgbmain mov bittimer, resettix ' set reset timing
add bittimer, cnt ' sync timer
waitcnt bittimer, #0 ' let timer expire
mov addr, hubpntr ' point to rgbbuf[0]
mov nleds, ledcount ' set # active leds
frame_loop rdlong colorbits, addr ' read a channel
add addr, #4 ' point to next
' Correct placement of color bytes for WS2812
' $RR_GG_BB --> $GG_RR_BB
fix_colors tjz swaprg, #shift_out ' skip if R and G don't need swapping
mov t1, colorbits ' copy for red
mov t2, colorbits ' copy for green
and colorbits, HX_0000FF ' isolate blue
shr t1, #8 ' fix red pos (byte1)
and t1, HX_00FF00 ' isolate red
or colorbits, t1 ' add red back in
shl t2, #8 ' fix green pos (byte2)
and t2, HX_FF0000 ' isolate green
or colorbits, t2 ' add green back in
' Shifts long in colorbits to WS2812 chain
'
' WS2812 Timing
'
' 0  0.35us / 0.80us
' 1  0.70us / 0.60us
'
' WS2812B Timing
'
' 0  0.35us / 0.90us
' 1  0.90us / 0.35us
'
' At least 50us (reset) between frames
shift_out shl colorbits, #8 ' left-justify bits
mov nbits, #24 ' shift 24 bits (3 x 8)
:loop rcl colorbits, #1 wc ' msb --> C
if_c mov bittimer, bit1hi ' set bit timing
if_nc mov bittimer, bit0hi
or outa, txmask ' tx line 1
add bittimer, cnt ' sync bit timer
if_c waitcnt bittimer, bit1lo
if_nc waitcnt bittimer, bit0lo
andn outa, txmask ' tx line 0
waitcnt bittimer, #0 ' hold while low
djnz nbits, #:loop ' next bit
djnz nleds, #frame_loop ' done with all leds?
jmp #clear_cmd ' get ready for next command
' --------------------------------------------------------------------------------------------------
HX_0000FF long $0000FF ' byte masks
HX_00FF00 long $00FF00
HX_FF0000 long $FF0000
hubpntr res 1 ' pointer to rgb array
ledcount res 1 ' # of rgb leds in chain
txmask res 1 ' mask for tx output
bittimer res 1 ' timer for reset/bit
addr res 1 ' address of current rgb bit
nleds res 1 ' # of channels to process
colorbits res 1 ' rgb for current channel
nbits res 1 ' # of bits to process
t1 res 1 ' work vars
t2 res 1
fit 496
{{
Terms of Use: MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy of this
software and associated documentation files (the "Software"), to deal in the Software
without restriction, including without limitation the rights to use, copy, modify,
merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be included in all copies
or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
}}
I figured out why I needed the additional delay. I had inadvertently left some debugging code in my version of JonnyMac's driver. Here is a working version of the driver that actually matches Jon's code better as well.
'' Modified for use with PropGCC by David Betz
'' Derived from:
'' File....... jm_ws2812.spin
'' Purpose.... 800kHz driver for WS2812 LEDs
'' Author..... Jon "JonnyMac" McPhalen
'' Copyright (c) 2013 Jon McPhalen
{{
// parameter structure
typedef struct {
uint32_t pin;
uint32_t *colors;
volatile uint32_t count;
} ws2812_params;
// driver header structure
typedef struct {
uint32_t jmp_inst;
uint32_t resettix;
uint32_t bit0hi;
uint32_t bit0lo;
uint32_t bit1hi;
uint32_t bit1lo;
uint32_t swaprg;
} ws2812_hdr;
}}
pub driver
return @ws2812
dat
org 0
ws2812 jmp #get_cmd
resettix long 0 ' frame reset timing
bit0hi long 0 ' bit0 high timing
bit0lo long 0 ' bit0 low timing
bit1hi long 0 ' bit1 high timing
bit1lo long 0 ' bit1 low timing
swaprg long 0 ' swap r and g
reset_delay mov bittimer, resettix ' set reset timing
add bittimer, cnt ' sync timer
waitcnt bittimer, #0 ' let timer expire
clear_cmd mov t1, #0 ' clear last command
wrlong t1, par
get_cmd rdlong t1, par wz ' look for packed command
if_z jmp #get_cmd
mov t2, t1 ' get pin
and t2, #$1F ' isolate
mov txmask, #1 ' create mask for tx
shl txmask, t2
andn outa, txmask ' set to output low
or dira, txmask
mov ledcount, t1 ' get count
shr ledcount, #8 ' isolate
and ledcount, #$FF
add ledcount, #1 ' update (1 to 256 leds)
mov hubpntr, t1 ' get hub address
shr hubpntr, #16 ' isolate
mov addr, hubpntr ' point to rgbbuf[0]
mov nleds, ledcount ' set # active leds
frame_loop rdlong colorbits, addr ' read a channel
add addr, #4 ' point to next
' Correct placement of color bytes for WS2812
' $RR_GG_BB --> $GG_RR_BB
fix_colors tjz swaprg, #shift_out ' skip if R and G don't need swapping
mov t1, colorbits ' copy for red
mov t2, colorbits ' copy for green
and colorbits, HX_0000FF ' isolate blue
shr t1, #8 ' fix red pos (byte1)
and t1, HX_00FF00 ' isolate red
or colorbits, t1 ' add red back in
shl t2, #8 ' fix green pos (byte2)
and t2, HX_FF0000 ' isolate green
or colorbits, t2 ' add green back in
' Shifts long in colorbits to WS2812 chain
'
' WS2812 Timing
'
' 0  0.35us / 0.80us
' 1  0.70us / 0.60us
'
' WS2812B Timing
'
' 0  0.35us / 0.90us
' 1  0.90us / 0.35us
'
' At least 50us (reset) between frames
shift_out shl colorbits, #8 ' left-justify bits
mov nbits, #24 ' shift 24 bits (3 x 8)
:loop rcl colorbits, #1 wc ' msb --> C
if_c mov bittimer, bit1hi ' set bit timing
if_nc mov bittimer, bit0hi
or outa, txmask ' tx line 1
add bittimer, cnt ' sync bit timer
if_c waitcnt bittimer, bit1lo
if_nc waitcnt bittimer, bit0lo
andn outa, txmask ' tx line 0
waitcnt bittimer, #0 ' hold while low
djnz nbits, #:loop ' next bit
djnz nleds, #frame_loop ' done with all leds?
jmp #reset_delay ' get ready for next command
' --------------------------------------------------------------------------------------------------
HX_0000FF long $0000FF ' byte masks
HX_00FF00 long $00FF00
HX_FF0000 long $FF0000
hubpntr res 1 ' pointer to rgb array
ledcount res 1 ' # of rgb leds in chain
txmask res 1 ' mask for tx output
bittimer res 1 ' timer for reset/bit
addr res 1 ' address of current rgb bit
nleds res 1 ' # of channels to process
colorbits res 1 ' rgb for current channel
nbits res 1 ' # of bits to process
t1 res 1 ' work vars
t2 res 1
fit 496
{{
Terms of Use: MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy of this
software and associated documentation files (the "Software"), to deal in the Software
without restriction, including without limitation the rights to use, copy, modify,
merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be included in all copies
or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
}}
I'm glad you got it all sorted out. I just finished mounting a bunch of the WS2811 5mm LEDs in metal holders. It seems that many places stopped carrying the LED holders to I tried some of the imported ones on ebay. I wasn't really thrilled about those since they are smaller and the finish isn't as nice. I may end up using them on another project. The best ones I could still find came from Radio Shack of all places. They run about $1 each for the holders but they are well made and the finish is great. They are the same physical size as some early ones that I wanted to replace. The trick was to use a small pick to poke two extra holes in the rubber piece that locks the LED in place. The results were exactly what I wanted.
I'm glad you got it all sorted out. I just finished mounting a bunch of the WS2811 5mm LEDs in metal holders. It seems that many places stopped carrying the LED holders to I tried some of the imported ones on ebay. I wasn't really thrilled about those since they are smaller and the finish isn't as nice. I may end up using them on another project. The best ones I could still find came from Radio Shack of all places. They run about $1 each for the holders but they are well made and the finish is great. They are the same physical size as some early ones that I wanted to replace. The trick was to use a small pick to poke two extra holes in the rubber piece that locks the LED in place. The results were exactly what I wanted.
Robert
I've started playing with my WS2811 5mm LEDs from AdaFruit and I can't get them to do anything except glow blue.
I thought you mentioned that it was working now. Attached it a picture of how I was testing them, I had five WS2811 LEDs and then two WS2812B LEDs all in the same chain. If you are just using the C code then it may be worth trying the latest SPIN object in the OBEX to see if it behaves the same. At least that will help determine if there is an odd issue with the LEDs/wiring or something that needs to be adjusted in the C version of the driver.
I thought you mentioned that it was working now. Attached it a picture of how I was testing them, I had five WS2811 LEDs and then two WS2812B LEDs all in the same chain. If you are just using the C code then it may be worth trying the latest SPIN object in the OBEX to see if it behaves the same. At least that will help determine if there is an odd issue with the LEDs/wiring or something that needs to be adjusted in the C version of the driver.
Robert
The driver works with both an AdaFruit LED ring and an LED strip so I think it's okay. The PASM code is pretty much identical to what is in JonnyMac's driver. My wiring looks pretty much like yours except that I'm using the breadboard on an ActivityBoard so I don't have power rails. I daisy chained the power for each of the LEDs and connected the one at the end of the string to the power headers on the ActivityBoard. I currently have only one LED connected to try to diagnose this problem. Here is a picture.
The driver works with both an AdaFruit LED ring and an LED strip so I think it's okay. The PASM code is pretty much identical to what is in JonnyMac's driver. My wiring looks pretty much like yours except that I'm using the breadboard on an ActivityBoard so I don't have power rails. I daisy chained the power for each of the LEDs and connected the one at the end of the string to the power headers on the ActivityBoard. I currently have only one LED connected to try to diagnose this problem. Here is a picture.
Are you LEDs water clear or diffused? The ones I picked up from Pololu are diffused white when off. I wonder if they are the same and how many variations are out there.
With all those short jumper wires there are a lot of extra connections. Maybe one of the wires is loose for an open connection.
Are you LEDs water clear or diffused? The ones I picked up from Pololu are diffused white when off. I wonder if they are the same and how many variations are out there.
With all those short jumper wires there are a lot of extra connections. Maybe one of the wires is loose for an open connection.
Robert
They are clear. In fact, they are of a type that has since been discontinued by AdaFruit. I thought the wires looked overly complex myself so I removed all of the jumpers and wired everything directly to power and ground. The LED still glows blue with no DIN signal applied. I have 10 LEDs. I guess I could try some of the others.
They are clear. In fact, they are of a type that has since been discontinued by AdaFruit. I thought the wires looked overly complex myself so I removed all of the jumpers and wired everything directly to power and ground. The LED still glows blue with no DIN signal applied. I have 10 LEDs. I guess I could try some of the others.
I thought I read somewhere that the older versions of these style LEDs were limited to a 400Khz refresh. I may be wrong about that but if that is the case then maybe the current driver you have is sending the data too fast for it.
I thought I read somewhere that the older versions of these style LEDs were limited to a 400Khz refresh. I may be wrong about that but if that is the case then maybe the current driver you have is sending the data too fast for it.
Robert
That could be but these LEDs glow blue even with no data being sent to them at all. They should be off in that case shouldn't they?
That could be but these LEDs glow blue even with no data being sent to them at all. They should be off in that case shouldn't they?
You would think that but I saw one of mine turn blue when it wasn't getting data properly. Maybe that is what some of them do if they receive invalid data. I'm not sure how the DIN would react if left disconnected on a breadboard. Do they have any sort of weak pull-up/pull-down resistor on the DIN or act more like CMOS with an input not connected. It sounds like there may be something odd about the particular batch of LEDs that you have.
You would think that but I saw one of mine turn blue when it wasn't getting data properly. Maybe that is what some of them do if they receive invalid data. I'm not sure how the DIN would react if left disconnected on a breadboard. Do they have any sort of weak pull-up/pull-down resistor on the DIN or act more like CMOS with an input not connected. It sounds like there may be something odd about the particular batch of LEDs that you have.
Robert
Actually, DIN is connected to ground through a 2.2K resistor. This was suggested to me by someone on the AdaFruit forum for attempting to diagnose this problem. I have 10 LEDs and have tried 6 of them and they all exhibit this behavior. I guess this could be the result of two different problems. Maybe these particular LEDs have an idle state of blue and they also require more than 3.3v on their DIN pin to successfully transmit data. Maybe I should try a level converter between the Propeller pin and the LED DIN? Actually, the LEDs aren't very useful to me if they don't have "off" as their idle state when receiving no data because I don't want to constantly drive the DIN pin just to keep them off.
Actually, DIN is connected to ground through a 2.2K resistor. This was suggested to me by someone on the AdaFruit forum for attempting to diagnose this problem. I have 10 LEDs and have tried 6 of them and they all exhibit this behavior. I guess this could be the result of two different problems. Maybe these particular LEDs have an idle state of blue and they also require more than 3.3v on their DIN pin to successfully transmit data. Maybe I should try a level converter between the Propeller pin and the LED DIN? Actually, the LEDs aren't very useful to me if they don't have "off" as their idle state when receiving no data because I don't want to constantly drive the DIN pin just to keep them off.
I just read the following on the Pololu site which sells similar LEDs:
"After power is applied to these LEDs, they will emit bright blue light until the first color command is received."
That is exactly what mine are doing. I guess it could be that the 3.3v output on the Propeller pin is not sufficient to drive DIN on these LEDs and hence the color never changes from the default color. I have an ATtiny85 5V module I may try tomorrow to verify this. If that works, I guess I need a level shifter to use these on a Propeller.
Try the "other" frequency too. Ie if you think your leds are 800kHz and its not working, try 400kHz. Or vice versa
You can also run WS2812's successfully from 3v3, its just the green and blue won't be as bright, but for test purposes it'll help nail whats going on
You can also run them from +5V but through a suitable diode which will drop around 0.7V or so and this is enough margin for 3.3V to be regarded as a valid high level input. I also use this trick in designs when it is not really that important that the driver has exactly +5V, just that it runs from the +5V supply rather than the 3.3V logic supply.
Do you have any 74HC14 chips on hand? I've used two gates from one (back to back) as a buffer from the 3.3V propeller to a 5V device. The 74HC14 is powered by the 5V supply. You also need to ties the other 4 unused inputs on that chip either high or low unless you are using them for something else. Maybe worth trying if you have one.
Do you have any 74HC14 chips on hand? I've used two gates from one (back to back) as a buffer from the 3.3V propeller to a 5V device. The 74HC14 is powered by the 5V supply. You also need to ties the other 4 unused inputs on that chip either high or low unless you are using them for something else. Maybe worth trying if you have one.
Robert
I don't think I have one. I'll have to order a few I guess. Thanks for the suggestion.
Do you have any 74HC14 chips on hand? I've used two gates from one (back to back) as a buffer from the 3.3V propeller to a 5V device. The 74HC14 is powered by the 5V supply. You also need to ties the other 4 unused inputs on that chip either high or low unless you are using them for something else. Maybe worth trying if you have one.
I don't think you want to use those, David; they are bi-directional, open-collector/drain interfaces that are best for I2C and half-duplex serial coms (all EFX-TEK boards use that circuit; I've talked about it in my N&V columns many times).
My favorite (hence recommended) little booster for 3.3v-to-5.0v is the TC4427. It's actually a MOSFET driver with very stiff output so it works very well against long cables. I've used it with WS2801s (Wes Borland costume), WS2812s (Cylon dress for Jinyo), and even a focus/zoom app for a client that uses servos. It comes in breadboard-friendly DIP form, too.
Vih for the part is 2.4v which makes it very compatible with the Propeller. The output voltage is set by what you connect to the Vdd pin -- which can be up to 18V; obviously, this should be connected to a 5V supply for WS281x apps.
David, later but sure.
I was playing with that leds strips, it's very easy to controll them, (anyway you've enough info yet).
Also try a code with: netDrv : "etherCog-enc28j60", sock : "etherCog-udp-socket", and bufq : "etherCog-buffer-queue" code, and you'll be able to control them in Art-Net way, using the free Jinx software, or you can use also the Madrix software to test them free.
Good luck !!
I don't think you want to use those, David; they are bi-directional, open-collector/drain interfaces that are best for I2C and half-duplex serial coms (all EFX-TEK boards use that circuit; I've talked about it in my N&V columns many times).
My favorite (hence recommended) little booster for 3.3v-to-5.0v is the TC4427. It's actually a MOSFET driver with very stiff output so it works very well against long cables. I've used it with WS2801s (Wes Borland costume), WS2812s (Cylon dress for Jinyo), and even a focus/zoom app for a client that uses servos. It comes in breadboard-friendly DIP form, too.
Vih for the part is 2.4v which makes it very compatible with the Propeller. The output voltage is set by what you connect to the Vdd pin -- which can be up to 18V; obviously, this should be connected to a 5V supply for WS281x apps.
Put a 10K pull-down (one side connected to pin, other side connected to ground) on the WS281x control pin that goes into the TC4427; this will keep the line in a 0 state when the Propeller is booting.
I don't think you want to use those, David; they are bi-directional, open-collector/drain interfaces that are best for I2C and half-duplex serial coms (all EFX-TEK boards use that circuit; I've talked about it in my N&V columns many times).
My favorite (hence recommended) little booster for 3.3v-to-5.0v is the TC4427. It's actually a MOSFET driver with very stiff output so it works very well against long cables. I've used it with WS2801s (Wes Borland costume), WS2812s (Cylon dress for Jinyo), and even a focus/zoom app for a client that uses servos. It comes in breadboard-friendly DIP form, too.
Vih for the part is 2.4v which makes it very compatible with the Propeller. The output voltage is set by what you connect to the Vdd pin -- which can be up to 18V; obviously, this should be connected to a 5V supply for WS281x apps.
Jon,
One more question. Are you saying that this module won't work or just that it's overkill since it is bi-directional? Can I use it until my TC4427 chips arrive?
It may work, but no better than if you changed the WS2812 driver to open-drain output with a 10K pull-up on the signal line. The output of the circuit is somewhat "soft." Give it a try, I could be wrong. I would never use that with WS2812s in a client project though -- the TC4427 is designed to drive against capacitive loads, so it works really well in this app (and many others, it's one of my favorite parts).
I've attached my variation of the circuit you want to use.
Notes:
-- if the input is floating, the output will be high (this may cause problems on WS28xx lines during reset
-- I use stiffer pull-ups than the Adafruit board
You're probably wondering how this circuit differs from the TC4427
-- default state for FET circuit is high (better for serial coms)
-- default state for TC4427 circuit is low (better for WS28xx LEDs)
-- the FET circuit can pull to ground, but high goes through pull-up on output side
-- TC4427 uses totem-pole FET outputs to drive pins directly to Vdd or ground (up to 1.5A peak)
Put a 10K pull-down (one side connected to pin, other side connected to ground) on the WS281x control pin that goes into the TC4427; this will keep the line in a 0 state when the Propeller is booting.
Comments
Robert
Here is my test program. It uses two animation classes: ws2812_FillWheelDim fills a color array with a rainbow of colors and rotates the rainbow on every update and ws2812_Chase does Jon's chase effect. In this program I'm using two AdaFruit LED devices, one 16 LED ring and an 8 LED strip. The ring is being driven by the ws2812_FillWheelDim animation (matching my Christmas ornament from last year) and the strip is being driven by the ws2812_Chase animation. Each device is on a different Propeller pin illustrating that more than one chain of LEDs can be managed by Jon's single-shot update mode.
Here is the PASM code that is invoked when you call ws2812_execute(). I've also attached a .zip file containing all of the code including the C++ class definitions for ws2812_FillWheelDim and ws2812_Chase. These are in test.cpp which is a file I've been using to test a C++ animation interface.
ws2812.zip
[video=youtube_share;OmJZKRz4uGk]
Robert
I thought you mentioned that it was working now. Attached it a picture of how I was testing them, I had five WS2811 LEDs and then two WS2812B LEDs all in the same chain. If you are just using the C code then it may be worth trying the latest SPIN object in the OBEX to see if it behaves the same. At least that will help determine if there is an odd issue with the LEDs/wiring or something that needs to be adjusted in the C version of the driver.
Robert
Are you LEDs water clear or diffused? The ones I picked up from Pololu are diffused white when off. I wonder if they are the same and how many variations are out there.
With all those short jumper wires there are a lot of extra connections. Maybe one of the wires is loose for an open connection.
Robert
I thought I read somewhere that the older versions of these style LEDs were limited to a 400Khz refresh. I may be wrong about that but if that is the case then maybe the current driver you have is sending the data too fast for it.
Robert
You would think that but I saw one of mine turn blue when it wasn't getting data properly. Maybe that is what some of them do if they receive invalid data. I'm not sure how the DIN would react if left disconnected on a breadboard. Do they have any sort of weak pull-up/pull-down resistor on the DIN or act more like CMOS with an input not connected. It sounds like there may be something odd about the particular batch of LEDs that you have.
Robert
I just read the following on the Pololu site which sells similar LEDs:
"After power is applied to these LEDs, they will emit bright blue light until the first color command is received."
That is exactly what mine are doing. I guess it could be that the 3.3v output on the Propeller pin is not sufficient to drive DIN on these LEDs and hence the color never changes from the default color. I have an ATtiny85 5V module I may try tomorrow to verify this. If that works, I guess I need a level shifter to use these on a Propeller.
You can also run WS2812's successfully from 3v3, its just the green and blue won't be as bright, but for test purposes it'll help nail whats going on
You can also run them from +5V but through a suitable diode which will drop around 0.7V or so and this is enough margin for 3.3V to be regarded as a valid high level input. I also use this trick in designs when it is not really that important that the driver has exactly +5V, just that it runs from the +5V supply rather than the 3.3V logic supply.
Robert
I have one of these: https://www.adafruit.com/products/757
Do you think that would work?
I don't think you want to use those, David; they are bi-directional, open-collector/drain interfaces that are best for I2C and half-duplex serial coms (all EFX-TEK boards use that circuit; I've talked about it in my N&V columns many times).
My favorite (hence recommended) little booster for 3.3v-to-5.0v is the TC4427. It's actually a MOSFET driver with very stiff output so it works very well against long cables. I've used it with WS2801s (Wes Borland costume), WS2812s (Cylon dress for Jinyo), and even a focus/zoom app for a client that uses servos. It comes in breadboard-friendly DIP form, too.
-- http://www.digikey.com/product-detail/en/TC4427CPA/TC4427CPA-ND/115309
Vih for the part is 2.4v which makes it very compatible with the Propeller. The output voltage is set by what you connect to the Vdd pin -- which can be up to 18V; obviously, this should be connected to a 5V supply for WS281x apps.
I was playing with that leds strips, it's very easy to controll them, (anyway you've enough info yet).
Also try a code with: netDrv : "etherCog-enc28j60", sock : "etherCog-udp-socket", and bufq : "etherCog-buffer-queue" code, and you'll be able to control them in Art-Net way, using the free Jinx software, or you can use also the Madrix software to test them free.
Good luck !!
One more question. Are you saying that this module won't work or just that it's overkill since it is bi-directional? Can I use it until my TC4427 chips arrive?
Thanks,
David
I've attached my variation of the circuit you want to use.
Notes:
-- if the input is floating, the output will be high (this may cause problems on WS28xx lines during reset
-- I use stiffer pull-ups than the Adafruit board
You're probably wondering how this circuit differs from the TC4427
-- default state for FET circuit is high (better for serial coms)
-- default state for TC4427 circuit is low (better for WS28xx LEDs)
-- the FET circuit can pull to ground, but high goes through pull-up on output side
-- TC4427 uses totem-pole FET outputs to drive pins directly to Vdd or ground (up to 1.5A peak)