How to generate a pulse under 1uS ?

Go To Last Post
70 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Guys,

 

How can I generate a pulse below 1uS, please have a look on the picture

 

I want to use WS2812 with ATMEGA128 port, for example PORTD0....and send a serial of bits to WS2812...

Any ideas ?

thanks

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What does Adafruit say about it?

 

https://www.adafruit.com/product...

The LEDs are 'chainable' by connecting the output of one chip into the input of another - see the datasheet for diagrams and pinouts. To allow the entire chip to be integrated into a 6-pin package, there is a single data line with a very timing-specific protocol. Since the protocol is very sensitive to timing, it requires a real-time microconroller such as an AVR, Arduino, PIC, mbed, etc. It cannot be used with a Linux-based microcomputer or interpreted microcontroller such as the netduino or Basic Stamp. The LEDs basically have a WS2811 inside, but fixed at the 800KHz 'high speed' setting. Our wonderfully-written Neopixel library for Arduino supports these pixels! As it requires hand-tuned assembly it is only for AVR cores but others may have ported this chip driver code so please google around. An 8MHz or faster processor is required.

>>You<< have chosen to use this device.  So >>you<< have to do the work, or build upon the shoulders of others such as Adafruit.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Note that pulses are measured in seconds - s - not siemens - S.

 

The symbol for seconds is a lowercase 's': https://en.wikipedia.org/wiki/Se...

 

An uppercase 'S' is the symbol for siemens - the SI unit of conductance: https://en.wikipedia.org/wiki/Si...(unit)

 

http://physics.nist.gov/Pubs/SP8... - see 6.1.2 Capitalization

 

http://physics.nist.gov/cuu/Unit...

 

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yikes. One snip cancels out a dozen nice Cliff Lawson explanations. Should we warn the new guys that the Units Police wont answer poorly formed queries?

 

Imagecraft compiler user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm with you on this one Bob - does it really matter if the OP typed us or uS into the thread title - for God's sake! frown

 

(please feel free to correct this post for punctuation, spelling or anything else that seems important - err, not).

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Geezz

 

I'm glad i was a beginner here back in 04' , and not today.

The nitpicking have taken over the helping. no

 

/Bingo

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

is it possible sending 0 _delay_us(0.35);sending 1 _delay_us(0.8); ? or use SPI ? us = micro second.....

not micro siemens...or you don't understand what I'm talking about only want to critise without helping.....

like I ever said....

if you don't want to help...don't bother reading and then saying you're wasting your time to me....

that's the purpose of having a forum....reading and helping.....

it's easy.....don't want to help....don't have to read....

 

thanks for any ideas that has been given, I appreciate that...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

or ::

If you run the avr at 20mhz, a nop is 50ns, so just stick N nops in between the output set and reset to get N x50 ns delay.===> from Bob

in here :

https://www.avrfreaks.net/forum/please-check-code-and-delay-ns-question

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I thought I did help.  I posted a discussion of the issues along with a link that leads to very well commented code.

 

>>You<< have chosen to use this device.  So >>you<< have to do the work, or build upon the shoulders of others such as Adafruit.

I don't appreciate the slam, after I took the time to find prior art for you.  (Your Google searches did not uncover it?)

 

And no, _delay_us(0.35) is not a panacea.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

Last Edited: Mon. Jul 13, 2015 - 10:10 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Why not use some asm volatile("nop")   ?

Wireless remote car device using hand movements:

https://www.youtube.com/watch?v=uerWyUwLLBo

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I used GCC assembler for that code. wink Posted the code somewhere here.

John Samperi

Ampertronics Pty. Ltd.

https://www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

bianchi77 wrote:
20mhz

No comment.

 

cheeky

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If you look at the datasheet for the WS2812/WS2811, you'll see that once you start sending bits the transmission has to continue at the rate of 1 bit every 1.25us until the reset signal is applied.  I think you'll find that the difficulty lies in not just sending a 1 or a 0, but in keeping the timing accurate for the duration of the transmission.  It's very easy to delay for a few cycles and toggle a pin for a 1, or delay a few cycles extra then toggle for a 0.  It gets hard when you have to do it 24 (or more) times in a row while accounting for every instruction being executed directly perturbing your pin toggling times.  In other words, there's no time to send a 1 then say hm, do we send a 1 or 0 next?  A 0?  Ok, let's call that function.  By the time the decision has been made the train's left the station, so to speak.

 

If you look at the library theusch posted up above, it's implemented as a big block of assembly with every cycle being accounted for and bit periods being calculated two steps in advance just so the CPU has time to do everything.  Reimplementing it using NOPs A) will be a waste of time and B) won't work.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Don't try to do this with C.  You can't really get the required timing.

https://www.avrfreaks.net/forum/quick-tutorial-driving-ws2812b-rgb-leds-8mhz-avr

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi bianchi77,

 

I recommend you to read and use this library (from cpldcpu, not from me):

https://github.com/cpldcpu/light...

 

It seems to even work with a Tiny85 @ 4MHz

Have a nice day,
Kraal

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Kraal wrote:
It seems to even work with a Tiny85 @ 4MHz
In order to run at 4 MHz, the WS2812 are run out-of-spec.

Quote:
A CPU clock speed of 8 MHz and up is recommended, but even 4 MHz may work under some circumstances.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I wonder if Limor Ada is clever enough to use the mega128 modulator to multiply timer1 times timer0 to get the modulated 1 and 0 waveforms? If the hw can spit out a 1 or 0 with the right timing, a tight loop sending 24 bits sounds doable. Shell we have a c-off? Is there a prize?

Imagecraft compiler user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I just played with a couple of these LEDs last week, quite fun.

 

This Thread has a link to a short video showing the results of my Bascom driver.

The driver was all in Basic, except for the (in-line) NOP instructions.

 

The Thread mentioned the secret to my success in this endeavor.

 

JC

 

Edit: Typo

Last Edited: Wed. Jul 15, 2015 - 08:47 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What do you ,mean with that
0.25uS-1.0 us

and

0.5uS -0.75uS

are within spec!

 

And for sure I would do this with SPI, and then it should not be a problem to do it in C, just some odd 5 bit folding, but that can be done before the transmit.

Last Edited: Thu. Jul 16, 2015 - 06:47 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

sparrow2 wrote:
What do you ,mean with that
0.25uS-1.0 us

and

0.5uS -0.75uS

are within spec!

That is not achievable at 4 MHz, at least not with the library in question.

 

At 4 MHz, the inner loop (which sends a single byte) boils down to:

       ldi   r24,8  
loop%=:            
       out   PORT,rhi  ;  go high
       sbrs  rdat,7    ;  test data bit
       out   PORT,rlo  ;  bit is zero, go low early
       lsl   rdat      ;  next bit
       out   PORT,rlo  ;  bit was one, go low 1 cycle later
       dec   r24       ;  count 8 bits
       brne  loop%=    ;  8-bit loop

This loop is 8 cycles long.  At 4 MHz, that's 2 us.  The spec for both the WS2812 and WS2812B is 1.25 us +/- 600 ns, or 0.65-1.85 us.  So yes, 2 us is out of spec.

 

To use the terminology from the WS2812B datasheet:

     cyc     ns    WS2812B ds    WS2812 ds

T0H    2    500    250 -  550    200 - 500

T1H    4   1000    650 -  950    550 - 850

T0L    6   1500    700 - 1000    650 - 950

T1L    4   1000    300 -  600    450 - 750

 

Note how the only parameter which is within spec is T0H, and it is close to the limit for WS2812B, and right on the edge for WS2812.

 

The library in question has the following:

// The only critical timing parameter is the minimum pulse length of the "0"
// Warn or throw error if this timing can not be met with current F_CPU settings.
#define w_lowtime ((w1_nops+w_fixedlow)*1000000)/(F_CPU/1000)
#if w_lowtime>550
   #error "Light_ws2812: Sorry, the clock speed is too low. Did you set F_CPU correctly?"
#elif w_lowtime>450
   #warning "Light_ws2812: The timing is critical and may only work on WS2812B, not on WS2812(S)."
   #warning "Please consider a higher clockspeed, if possible"
#endif   

According to the library, running at 4 MHz will issue the warning "may only work on WS2812B, not on WS2812(S)."

 

How the author concluded that "the only critical timing parameter is the minimum pulse length of the 0" is a mystery.  There is no mention of this in either of the datasheets.  I can only conclude that it was arrived at experimentally.

 

None of this considers the additional time spent in the outer loop which manages each byte, which would result in extended T0L and T1L times between each byte sent.

 

Will it work?  Perhaps.  Even the author says so.  Might I use it in a one-off hobby project?  Maybe.  Is it out-of-spec?  Yes.

 

Quote:
And for sure I would do this with SPI, and then it should not be a problem to do it in C, just some odd 5 bit folding, but that can be done before the transmit.
I would think that idle high bit inserted between each data byte would be problematic, perhaps more so at lower cpu clock speeds.  MSPI would seem to be a better choice.  Some time ago I started just such a project, but it has been back-burnered.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

Last Edited: Fri. Jul 17, 2015 - 12:08 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

My old pappy used to tell me that if the only tool you have is a hammer, then every job looks like a nail. I'm trying to do this in c of course. Looks like 8 bits at 1.25usec per bit is 10usecs. So if I time a loop of a bunch of my sendbyte routines and keep up with 10usec a byte, I'm mostly there right? So sending a million of them should take 10 sec? I've got it down  to 11 sec on a 16MHz uno. Guess I need to buy a strip.

 

 

 

Imagecraft compiler user

Last Edited: Fri. Jul 17, 2015 - 04:10 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Bob, yes and no. The intra-bit time and intra-byte time and intra-led time are all spec'd to zero time, which complicates a general purpose driver.
JC

Last Edited: Sat. Jul 18, 2015 - 01:32 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

But it's very simple to do it in ASM, but the loop needs to be unrolled to do a bit each 5 clk.
 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

sparrow2 wrote:
But it's very simple to do it in ASM, but the loop needs to be unrolled to do a bit each 5 clk.
Yes and no.

 

What if I have a string of 100 of these things?  Each with 24 bits to send.  That's 2,400 bits.  Fully unrolled, that's 12,000 cycles, and 12,000 instructions.  24,000 bytes of program space.  Hardly practical.

 

The spec is clear and specific about the allowable minimum and maximum bit times.  Those restrictions are not lifted between bytes, nor between each group of 3 bytes which fully specify the RGB colour of one WS2812.  However the author of the library in question seems to be suggesting that these specs can be stretched somewhat.  That makes me nervous.  How far can they be stretched?  Under what circumstances?  Over what range of temperature?  Over what range of Vcc?

 

If they can be stretched, then unrolling wouldn't be necessary at all.  However, without a datasheet revision from the manufacturer, I would be reluctant to rely on any code which runs the WS2812 out-of-spec in anything but a one-off hobby project.

 

EDIT: formatting

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

Last Edited: Tue. Jul 21, 2015 - 06:39 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

???

if you place the 24 bit in 3 registers, and then have a send routine that only will be about 250 byte in size, that will make a very small overhead, but that most other solutions (other than the SPI)

will have the same.(and that can't be done @4MHz).

 

Add

ok I see the problem , I was counting on the RES time to "reload".

So for sure I would go for a SPI solution, and that would need 8MHz

Last Edited: Tue. Jul 21, 2015 - 06:13 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What if I have a string of 100 of these things?

Actually they usually come in 5m rolls with 150 or 300 LEDs per strip,  no problem with my code wink (using 48 x 300 LEDs strip in a project but a Beagle bone is running that)

https://www.avrfreaks.net/comment...

 

The number of NOPs need to be adjusted for the clock, had it running at 16MHz with a M644 but it should be able to go a bit lower.

 

svuppe also posted his version of a driver using the XCL an DMA with the Xmega https://www.avrfreaks.net/comment...

 

Now I have to show a video of course as everybody else is showing theirs......

John Samperi

Ampertronics Pty. Ltd.

https://www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Does anyone know how it actually works, and how the data come about?

I don't understand how they can say:

0.35us and 0.8us for 0

0.7us and 0.6us for 1

all +-0.15us

and at the same time say TH+TL=1.25us +- 0.6us! (should be 0.3us).

 

I was looking at some ASM code that can read the data from RAM and the best code I have found so far has to take 7 clk pr bit.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

sparrow2 wrote:
Does anyone know how it actually works, and how the data come about?

I don't understand how they can say:

0.35us and 0.8us for 0

0.7us and 0.6us for 1

all +-0.15us

and at the same time say TH+TL=1.25us +- 0.6us! (should be 0.3us).

 

I was looking at some ASM code that can read the data from RAM and the best code I have found so far has to take 7 clk pr bit.

Yes, their arithmetic is a bit wonky in the datasheet for the WS2812.

 

Matters have improved somewhat in the datasheet for the WS2812B (a later device).  The high/low times now add up correctly (0.4+0.85=1.25 for 0, 0.8+0.45=1.25 for 1), but they still have +/- 600 ns where it should be +/- 300 ns.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

Last Edited: Thu. Jul 23, 2015 - 12:12 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Does anyone actually run an AVR at 4 MHz?

If so, what went into the choice?

1 MHz and 8 MHz are the really easy to get frequencies.

The UART magic frequencies I've seen listed are all higher than 4 MHz.

 

To do large arrays at 4 MHz, one will likely need to work in stages.

Make a C callable function with an interface like this:

void w(uint8_t filler, uint8_t r, uint8_t g, uint8_t, uint8_t b) ;

filler is the number of zeros to send before the r, g and b.

The time required will be quadratic in the size of the array.

The zeros can be sent with a loop.

More than one rgb datum is possible.

Moderation in all things. -- ancient proverb

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

skeeve wrote:
Does anyone actually run an AVR at 4 MHz?

If so, what went into the choice?

1 MHz and 8 MHz are the really easy to get frequencies.

The UART magic frequencies I've seen listed are all higher than 4 MHz....

I am running a 9600 baud software uart app with a 8 mhz ÷ 4 = 2 mhz RC clock. 1 mhz leaves too little time; 4 and 8 mhz raise the average current consumption, since I can only idle the ATtiny24A and can't put it to sleep.

- John

Last Edited: Thu. Jul 23, 2015 - 04:33 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

skeeve wrote:
Does anyone actually run an AVR at 4 MHz?

That's probably my fault.  Post #15 linked to a library which claims to work at 4 MHz.  While that may be true (the author obviously thinks so), it does indeed drive the WS2812s/WS2812Bs beyond the specs declared in their datasheets.

 

Other than that, no-one has mentioned a desire to run at 4 MHz.  The 4 MHz case is only 'interesting'.

 

However, in other projects (not WS2812 related) I have run at 4 MHz simply because that is the fastest an AVR can safely run at 1.8V:

 

 

Quote:
If so, what went into the choice?
In my case, the project in question was a sensor mote running a cheap TX-only OOK radio to log temperature data remotely, running for over 2 years on one CR2032.

 

Quote:
filler is the number of zeros to send before the r, g and b.
Why is this needed?

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

joeymorin wrote:
Quote:

filler is the number of zeros to send before the r, g and b.

Why is this needed?

According to the spec sheet, to provide data for the last of 42 LEDs,

one must first provide data for the first 41 LEDS.

 

At 8 MHz+, I'd expect such contortions to be unnecessary.

Moderation in all things. -- ancient proverb

Last Edited: Thu. Jul 23, 2015 - 07:56 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

skeeve wrote:
According to the spec sheet, to provide data for the last of 42 LEDs, one must first provide data for the first 41 LEDS.
That's because multiple LEDs are daisy chained.  The first LED's DO pin is connected to the second LED's DI pin.

 

Each LED captures the first RGB 24-bit word.  It ignores the rest, but forwards (after conditioning) the remaining bitstream out its DO pin.  As far as the second LED is concerned, the first RGB word it sees is actually the second one sent by the mcu.

 

Once a reset pulse (> 50 us low) is received, this whole procedure starts over.

 

So, sending 41 'zero' words and one 'data-bearing' word will result in the first 41 LEDs going dark, and the 42nd LED displaying the 'data'.

 

If you want to address only the 42nd LED, you must still send the 'data' for the 41 LEDs before it.

 

This is the manufacturer's attempt at explaining it:

 

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Does anyone actually run an AVR at 4 MHz?

Yep! (no for this purpose though)

 

If so, what went into the choice?

 

That's was fast enough for the job and want to keep current down.

 

The UART magic frequencies I've seen listed are all higher than 4 MHz.

And if you don't need "magic frequencies"?

 

one must first provide data for the first 41 LEDS.

Correct. all LEDs are in series data wise so you sent the WHOLE packet out in one transaction for all the LEDs in the string. If you stop for more than 50us the data will be latched incorrectly.

 

It takes 30us for each led. (1/800,000) x 24 bits=0.00003 for 300 LEDs it takes 9ms per packet.

 

edit oops didn't see the above. smiley

John Samperi

Ampertronics Pty. Ltd.

https://www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

Last Edited: Thu. Jul 23, 2015 - 08:17 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

send 41 sets of zeros and data for the 42nd

send 40 sets of zeros and data for the 41st

send 39 sets of zeros and data for the 40th

...

send 0 sets of zeros and data for the first.

 

hence, quadratic.

I'd thought it was obvious.

Moderation in all things. -- ancient proverb

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You've lost me.

 

What you describe would result in a 'chase'.  This is a use for the term 'quadratic' of which I was not previously aware ;-)

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The first line sets the 42nd LED.

The second line sets the 41st LED.

The third line sets the 40th LED.

...

What's the problem?

Moderation in all things. -- ancient proverb

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

skeeve wrote:

The first line sets the 42nd LED.

It also extinguishes the first 41 LEDs.
Quote:

The second line sets the 41st LED.

It also extinguishes the first 40 LEDs.
Quote:

The third line sets the 40th LED.

It also extinguishes the first 39 LEDs.
Like I said, a chase.
Quote:

...

What's the problem?


I think we've got our wires crossed. Either you've missunderstood how to address the WS2812s, or I've misunderstood what you're driving at.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

Last Edited: Fri. Jul 24, 2015 - 05:47 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

joeymorin wrote:
skeeve wrote:

The first line sets the 42nd LED.

 

It also extinguishes the first 41 LEDs.

Eventually, that won't matter.
Quote:
Quote:

 

The second line sets the 41st LED.

 

It also extinguishes the first 40 LEDs.

Now the last two have good values.
Quote:
Quote:

 

The third line sets the 40th LED.

 

It also extinguishes the first 39 LEDs.

Now the last three have good values.
Quote:
Like I said, a chase.

Quote:

 

...

What's the problem?

 

I think we've got our wires crossed. Either you've missunderstood how to address the WS2812s, or I've misunderstood what you're driving at.

I'm not sure what "chase" means, but from context, I inferred that it meant something useless for the application under discussion.

Moderation in all things. -- ancient proverb

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The first line sets the 42nd LED.

The second line sets the 41st LED.

The third line sets the 40th LED.

...

 

Gosh that seems like a lot of work, and it takes much longer to send 42 strings of data than just sending all 42 LEDs' data with the first packet.

 

Too bad one of the 16,777,216 possible colors wasn't deleted, and that code reserved for a NOP for the LED, (Don't change your color, and pass the remaining data on).

But then I guess the high level program ought to know what each LED's data is, and hence sending a repeated color packet, if the LED doesn't change, is no big deal.

 

JC

 

Edit:  Joey correctly notes that each sequential data packet is shorter, but it is still a long process compared to sending one data packet, with the correct data for each LED.

 

 

Last Edited: Fri. Jul 24, 2015 - 09:47 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I see what you're getting at, I think.

 

In order to get around the tight timing constraints at 4 MHz (i.e. 5 cycles per bit), you propose to update the Nth LED by doing a tight loop of 24-bit zeros for the first N-1 LEDs, followed by a single data-bearing word for the Nth LED?

 

OK, I can see the first part:

zero_loop:
  out port,rhi  ; 250 ns
  out port,rlo  ; 1000 ns
  dec rbits
  brn zeroloop

This is a 5-cycle loop that sends as many zero-bits as the value of rbits.  If you want to 'skip' one LED, load rbits with 24.  If you want to 'skip' 10 LEDs, load rbits with 240.  You couldn't skip more than 10 LEDs this way, as you'd need more than an 8 bit register, but that would break the 5-cycle timing.

 

I suppose you could pre-load a 16-bit OCR register with the number of cycles required for N LEDs, and test the OCF bit instead:

  ; 5 cycles per bit
  ; 24 bits per LED
  ; 41 LEDs
  ; 5 * 24 * 41 = 4920 = 0x1338
  ; load OCR1A with 0x1338
  ; clear TCNT1
  ; clear OCF1A
  ; start TIMER1 with no prescaler
zero_loop:
  out port,rhi  ; 250 ns
  out port,rlo  ; 1000 ns
  sbis TIFR1, OCF1A
  brn zeroloop

 

Then unroll the loop to send the 24 data bits with 5-cycle timing:

  out PORT,rhi  ;
  sbrs rgreen,7 ; green bit 7
  out PORT,rlo  ;
  nop           ;
  out PORT, rlo ;
. . .
  out PORT,rhi  ;
  sbrs rgreen,0 ; green bit 0
  out PORT,rlo  ;
  nop           ;
  out PORT, rlo ;

  out PORT,rhi  ;
  sbrs rred,7   ; red bit 7
  out PORT,rlo  ;
  nop           ;
  out PORT, rlo ;
. . .
  out PORT,rhi  ;
  sbrs rred,0   ; red bit 0
  out PORT,rlo  ;
  nop           ;
  out PORT, rlo ;

  out PORT,rhi  ;
  sbrs rblue,7  ; blue bit 7
  out PORT,rlo  ;
  nop           ;
  out PORT, rlo ;
. . .
  out PORT,rhi  ;
  sbrs rblue,0  ; blue bit 0
  out PORT,rlo  ;
  nop           ;
  out PORT, rlo ;

 

This would 'work'.  Except for the progressive blanking imposed on all but one of the LEDs.  The string of LEDs would appear to grow from the tail to the head.  This might be tolerable for some applications, but I'd say it would have limited appeal.

 

The update time would suck, for one.

 

Each bit takes 1.25 us, times 24 bits, is 30 us per LED.  So a string of 42 LEDs takes 30x42 + 50 (for 'reset') = 1.310 ms.

 

With the above scheme, you're effectively updating 42 strings of LEDs, each string one shorter than the last.  For N LEDs, you're updating N(N+1)/2 LEDs, and spinning for N reset periods, so the time T it will take is

T = 30N(N+1)/2 + 50N

  = 15N(N+1) + 50N

  = 15N2 + 15N + 50N

  = 15N2 + 65N

 

There's your 'quadratic' ;-)

 

So 42 LEDs will take

T = 15x422 + 65x42

  =  29.19 ms

 

That's over 22 times slower than updating all 42 LEDs with the right data in one shot.  Maximum refresh rate of a string of 42 LEDs would be about 34 Hz.  And that doesn't include any code overhead.  Pretty slow.

 

A string of 300 would take:

T = 15x3002 + 65x300

  = 1.3695 seconds!

 

The killer I think would be the 'growing' effect (what I meant by 'chase') of each full update.

 

However, this does drive the WS2812/Bs within spec from a 4 MHz AVR ;-)

 

EDIT: typos

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

Last Edited: Fri. Jul 24, 2015 - 09:25 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

joeymorin wrote:
OK, I can see the first part:

zero_loop:
  out port,rhi  ; 250 ns
  out port,rlo  ; 1000 ns
  dec rbits
  brn zeroloop

This is a 5-cycle loop that sends as many zero-bits as the value of rbits.  If you want to 'skip' one LED, load rbits with 24.  If you want to 'skip' 10 LEDs, load rbits with 240.  You couldn't skip more than 10 LEDs this way, as you'd need more than an 8 bit register, but that would break the 5-cycle timing.

I should have written

"filler is the number of LEDs to zero before the r, g, and b." .

I had in mind sending 24 bits in the body of the zeroing loop.

The quadratic problem can be alleviated somewhat by specifying more than one good datum per call.

The blanking issue can also be alleviated somewhat.

void ww(struct rgb data[], uint8_t count) ;

ww transmits bits for count LEDs, with data[count-1] being correct and all other bytes having a low order one bit.

A one bit is necessary because we need an already known (assembly time) 6-cycle bit and a 6-cycle zero is not allowed.

Moderation in all things. -- ancient proverb

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

skeeve wrote:
I had in mind sending 24 bits in the body of the zeroing loop.
At the cost of code size.  4 instruction words per bit times 24 = 192 bytes of flash space.  Mind you, more than that is already consumes by the unrolled loop which delivers the terminating data-bearing RGB word (240 bytes).

 

Quote:
The quadratic problem can be alleviated somewhat by specifying more than one good datum per call.
Again, at the cost of code space due to more unrolled loops.

 

Quote:
A one bit is necessary because we need an already known (assembly time) 6-cycle bit and a 6-cycle zero is not allowed.
OK you lost me again.  Why?  The WS2812B certainly allows it (500 ns T0H, 1000 ns T0L).  It's 50 ns outside of T0L for the WS2812, yes.

 

For that matter, the reverse is true for T1H/T1L.  The WS2812 can handle 750 ns T1H, 750 ns T1L, but that's 150 ns outside of T1L for the WS2812B.

 

And why a 6-cycle bit anyway?  That is on the outside of the spec'd timing.  Why not shoot for the centre at 5 cycles?

 

This is all a neat exercise, and that's good enough for me, but I don't think anyone will ever want to do this.  Chances are if the library in question which claims to run at 4 MHz, but which has 2 us bit times, works for a hobbyist, that's as far as anyone will ever want to take this.  Given the state of the two datasheets, I wouldn't be surprised if much of the specs were wild guesses on the part of the manufacturer... or at least the technical writer  ;-)

 

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

Last Edited: Sat. Jul 25, 2015 - 12:08 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Check the AdaFruit NeoPixel library .cpp file.  It has this exact problem solved by using in-line assembler for C++.  Then Google for "WINAVR in-line assembler"  in order to get the ten pages or so available on the AVR/Arduino C++ in-line assember format and specification.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Simonetta wrote:
Check the AdaFruit NeoPixel library .cpp file.  It has this exact problem solved by using in-line assembler for C++.  Then Google for "WINAVR in-line assembler"  in order to get the ten pages or so available on the AVR/Arduino C++ in-line assember format and specification.
Or look at the one by local freak kk6gm, mentioned in post #14.  Or the one by cpldcpu, mentioned by Kraal in post #15.

 

Plenty of libraries to go around.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

joeymorin wrote:
Quote:

A one bit is necessary because we need an already known (assembly time) 6-cycle bit and a 6-cycle zero is not allowed.

OK you lost me again.  Why?  The WS2812B certainly allows it (500 ns T0H, 1000 ns T0L).  It's 50 ns outside of T0L for the WS2812, yes.

If a 6-cycle zero is available, so much the better.
Quote:
And why a 6-cycle bit anyway?  That is on the outside of the spec'd timing.  Why not shoot for the centre at 5 cycles?
To make 2 cycles available for an LD instruction, only one per byte.
Quote:
This is all a neat exercise, and that's good enough for me, but I don't think anyone will ever want to do this.  Chances are if the library in question which claims to run at 4 MHz, but which has 2 us bit times, works for a hobbyist, that's as far as anyone will ever want to take this.  Given the state of the two datasheets, I wouldn't be surprised if much of the specs were wild guesses on the part of the manufacturer... or at least the technical writer  ;-)
I agree.  The sheet I've got is not at all clear on how one starts and ends a sequence.

I think that idle is high and a data sequence starts with a reset pulse.

I'm not sure whether a reset pulse turns off all the LEDs.

If it does, that would be a problem.

I'm not sure what happens if a 3 us low is transmitted.

'Tis out of spec, but with such tight timings, there really should be some hint as to what happens when they are violated.

 

I'm aware that my suggestions consume a lot of flash.
The original question concerned an atmega128,
so a lot of flash is available.

 

On further analysis, I've concluded that ww can be implemented with a single byte in the body of the first loop.

A 2-byte "counter", the pointer register, is doable.

 

Regardless of implementation, the processor will spend a rather long time with interrupts disabled.

 

Moderation in all things. -- ancient proverb

Last Edited: Sat. Jul 25, 2015 - 05:40 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

'Reset' doesn't affect the state of the LED, only the communications channel.  It isn't a pulse, but the idle state (low).  If DI idles low for more than 50 us, the LED clamps the DO pin low, and then starts watching for a pulse train on DI.  It decodes the first 24 pulses as an RGB word, then it latches that word internally and drives its R, G, and B diodes at the specified levels.  Any remaining pulses seen on DI are duplicated to DO.  In this way, downstream LEDs see only the idle state until their RGB word comes along.

 

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

Last Edited: Sat. Jul 25, 2015 - 06:22 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The last bit ends with a transition from low to high.

If low is the idle level, how long does the last high have to maintained?

Considering that question is how I inferred that high was the idle level.

Moderation in all things. -- ancient proverb

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

skeeve wrote:
The last bit ends with a transition from low to high.
Eh?

 

Each bit is encoded as a pulse.  Two transitions.  First transition is from low to high, second transition if from high to low.  The pulse width encodes the bit.  Short high pulse signifies a zero bit.  Long pulse signifies a one bit.  In all cases the last transition is high to low.

 

 

Some time ago I fiddled a bit with the timing when driving these, not long after kk6gm posted his tutorial.  I'd wondered what would happen if the line were held high.  I'd hoped that the transmission would be suspended, allowing interrupts to be periodically reinstated.  I can't recall the exact results of my testing, but they were not good.  I'm certain my tests weren't thorough, because I was shortly thereafter pulled away to a paying project and never returned to the testing.  If I ever get back to it (might happen soon... summers are slow) I'll post my results.

 

 

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

joeymorin wrote:

 

skeeve wrote:

The last bit ends with a transition from low to high.

Eh?

 

 

Each bit is encoded as a pulse.  Two transitions.  First transition is from low to high, second transition if from high to low.  The pulse width encodes the bit.  Short high pulse signifies a zero bit.  Long pulse signifies a one bit.  In all cases the last transition is high to low.

Not quite.

Two pulses, a high pulse followed by a low pulse.

The high pulse, TxH, usually begins with the same low to high transition that ended the previous bit.

The same high to low transition that ends the high pulse begins the low pulse.

The low to high transition that ends the low pulse usually starts the high pulse of the next bit.

Sometimes there is not a previous bit.

Sometimes there is not a next bit.

How about a sequence that shows the last two bits and the two microseconds after that?

Quote:

 

Some time ago I fiddled a bit with the timing when driving these, not long after kk6gm posted his tutorial.  I'd wondered what would happen if the line were held high.  I'd hoped that the transmission would be suspended, allowing interrupts to be periodically reinstated.  I can't recall the exact results of my testing, but they were not good.  I'm certain my tests weren't thorough, because I was shortly thereafter pulled away to a paying project and never returned to the testing.  If I ever get back to it (might happen soon... summers are slow) I'll post my results.

If T0L and T1L apply to the last bit, then the signal has to remain high for some time after the last bit.

How long is not obvious.

Moderation in all things. -- ancient proverb

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

At the end of the packet the line can stay LOW indefinitely (50us minimum to latch data) or until the start of the next packet.

John Samperi

Ampertronics Pty. Ltd.

https://www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

skeeve wrote:
How about a sequence that shows the last two bits and the two microseconds after that?
The manufacturer didn't provide one.  The image in included in my previous post is a screencap from the datasheet (with colour added by me).

 

Quote:
If T0L and T1L apply to the last bit, then the signal has to remain high for some time after the last bit.
It does not.

 

You've been misled by the poor documentation.  As had I.  The right-hand edge of the sequence chart:

 

 

... suggests that the end of a bit must always result in a low-to-high transition.  It does not.  As you say, when there is a bit to follow, it does.  After the last bit of the last LED the line may be left in whichever state you wish i.e. you may keep it low and reset the comm line right away (after 50 us), or you can bring it high.  Since there are no LEDs after the last one to be confused by a high-idling line, and since all previous LEDs have already decoded and latched their RGB payloads and are now merely mirroring DI on DO while they wait for a reset, this should be fine but is by no means necessary.  This is one of the scenarios (idling high after the very last bit) which I did not completely test before moving on to another project.

 

Neither kk6gm's code, nor cpldcpu's library, nor the Adafruit library return the line high at the end of the last bit.  The line is merely kept low (its final state at the end of the last [well, any] bit) for at least 50 us before the next data stream is begun.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

js wrote:
At the end of the packet the line can stay LOW indefinitely (50us minimum to latch data) or until the start of the next packet.
Are you saying that the last TxL should be stretched indefinitely?

That is not at all obvious from the spec sheet.

 

If the other low pulses can also be stretched, that would alleviate a lot of timing problems.

It would also mean that the spec sheet is wrong about the TxL's.

Moderation in all things. -- ancient proverb

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

skeeve wrote:

Are you saying that the last TxL should be stretched indefinitely?

That is not at all obvious from the spec sheet.

 

If the other low pulses can also be stretched, that would alleviate a lot of timing problems.

It would also mean that the spec sheet is wrong about the TxL's.

Yes, on all counts.
The library by cpldcpu states that "The only critical timing parameter is the minimum pulse length of the '0'" in reference to T0H. This is not mentioned in the datasheet. At 4 MHz his library is out-of-spec for all parameters >>except<< T0H.
While this may 'work', and indeed the other three parameters (T0L, T1H, T1L) may be very stretchable, I am still of the opinion that writing code which drives a device outside of the datasheet specs is a bad idea. Even if the datasheet is inaccurate. If later the manufacturer makes a revision to the device which breaks out-of-spec code, there is nowhere to turn and no-one to blame.
Still, I was curious when I was playing with them a year ago. Like I said, I'll get back to them when I can and report what I find (unless someone else does first ;-) ).

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

Last Edited: Sun. Jul 26, 2015 - 03:25 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The last TxL CAN be stretched but no other, 50 us low latches the data and reset the counters so anything after that you will be addressing the 1st LED.

 

At least that's the way my code works and the code of one of my client who has a project with 14,000 LEDs.

John Samperi

Ampertronics Pty. Ltd.

https://www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

js wrote:
The last TxL CAN be stretched but no other, 50 us low latches the data and reset the counters so anything after that you will be addressing the 1st LED.

 

At least that's the way my code works and the code of one of my client who has a project with 14,000 LEDs.

I take experience seriously.

'Twould be nice to take the spec sheet seriously.

The spec sheet implies idle high.

If that does not work and idle low does, one must bow to reality.

 

'Tis strange to me that no other TxL's can be stretched at all.

Even at 4 MHz, 40 us would be enough for nearly 160 cycles of ISRs.

As is, one needs to keep interrupts off for a rather long time.

Moderation in all things. -- ancient proverb

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

One simple way for you to find out smiley buy a WS2812 LEDs string from ADA fruit and play with it...oh and let us know the results. wink

 

http://www.adafruit.com/category...

 

Can't see the 5m 150 (or 160??)  LEDs string anymore but they have 144 LEDs 1m strings http://www.adafruit.com/products...

John Samperi

Ampertronics Pty. Ltd.

https://www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I know that the data sheet is not that great, but it's wrong if idle isn't high! 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

sparrow2 wrote:
I know that the data sheet is not that great, but it's wrong if idle isn't high!
+1

Moderation in all things. -- ancient proverb

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Agreed the data sheet isn't too great.

 

But the trailing vertical line is just to show the High and Low time intervals, it isn't meant to reference edges.

 

JC

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

DocJC wrote:
But the trailing vertical line is just to show the High and Low time intervals, it isn't meant to reference edges.
-1

How does one end a low interval without a rising edge?

Moderation in all things. -- ancient proverb

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

One doesn't end the low interval when that interval isn't required to end (yet)
 

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

-1

 

How does one end a low interval without a rising edge?

I think you are missing the entire encoding concept, (albeit from a poorly written data sheet).

 

This is essentially Pulse Width Modulation.

Within each Bit Time the High interval is either short for a "O", or long for a "1".

The duration for the High Level, and for the entire Bit Time is spec'd.

(Hence the Low bit time is also spec'd, but this duration is redundant given the other info.)

Each Bit's data packet is defined by a high pulse, followed by a low segment.

 

One can view the series of 8 bits / color, 3 colors / LED, x N LEDs as a Time Division Multiplexed bit stream.

The initial High leading edge, occurring after a reset pause, initiates the timing, (conceptually).

(Agreed, the internal hardware might resynch on each bit or byte or LED).

Theoretically, one can know exactly which bit of which byte of which LED is being transmitted at any time after the initial bit's leading edge.

 

The protocol does not spec an intra-bit, intra-byte, or intra-LED time gap.

The only latitude, within spec, is the latitude given for the individual high and low durations of a given bit.

 

One sends the LED a series of Bits.

Each bit is PWM, with a leading high and a trailing low.

 

A trailing edge doesn't define the low interval.  <-- That is the key point.

The bit interval is spec'd, as in TDM, and the trailing edge on the last bit's low time isn't needed or expected or required.

 

The ending edge of the low part of the bit transmission only has a leading edge because the NEXT bit's information starts with the High portion of the PWM bit signal.

 

It is a crummy data sheet, but the system works.

 

JC

 

Edit: Typo

  

Last Edited: Mon. Jul 27, 2015 - 08:51 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

DocJC wrote:

-1

 

How does one end a low interval without a rising edge?

I think you are missing the entire encoding concept, (albeit from a poorly written data sheet).

Being poorly written doesn't make it right.

The spec sheet authors seem to have missed it also.

 

I accept, from the results of others experiments that the device works as you describe.

The spec sheet says that it should work in a way that it does not.

The spec sheet is therefore wrong.

Not just vague.  Not just poorly written. Wrong.

 

That the device accepts pulse width modulation and the spec in the sheet somewhat resembles pulse width modulation does not make the spec sheet right.

It makes the spec sheet wrong.

Someone who fed the device only signals endorsed by the spec sheet would never get the device to work.

Quote:

 

This is essentially Pulse Width Modulation.

Within each Bit Time the High interval is either short for a "O", or long for a "1".

The duration for the High Level, and for the entire Bit Time is spec'd.

(Hence the Low bit time is also spec'd, but this duration is redundant given the other info.)

'Tain't.

The low time cannot be determined from the other given data.

 

Clearly the device works.

Clearly the spec sheet is wrong.

Moderation in all things. -- ancient proverb

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
Not just vague.  Not just poorly written. Wrong.
Vague and poorly written, oh my goodness yes.

 

Wrong?:

DocJC wrote:
the trailing edge on the last bit's low time isn't needed or expected or required.

joeymorin wrote:
... suggests that the end of a bit must always result in a low-to-high transition.  It does not.  As you say, when there is a bit to follow, it does.  After the last bit of the last LED the line may be left in whichever state you wish i.e. you may keep it low and reset the comm line right away (after 50 us), or you can bring it high.  Since there are no LEDs after the last one to be confused by a high-idling line, and since all previous LEDs have already decoded and latched their RGB payloads and are now merely mirroring DI on DO while they wait for a reset, this should be fine but is by no means necessary.

js wrote:
The last TxL CAN be stretched but no other, 50 us low latches the data and reset the counters so anything after that you will be addressing the 1st LED.

 

I can find nothing in the datasheet which refutes this.

 

As previously mentioned, I will run some tests when I can.

 

BTW, no need to buy 5m of these things:

https://www.adafruit.com/products/1426

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

'Tain't.

 

The low time cannot be determined from the other given data.

 ?

 

The Bit Time, (Data transfer time), is defined as 1.25 uS +/- 600 nS right in the data sheet.

The "0" High Time, T0H is defined as 0.4 uS, (in the data sheet).

The "1" High Time, T1H is defined as 0.8 uS, (in the data sheet).

 

It is a simple PWM data bit stream, and the inclusion of the low time is redundant.

 

Nobody is arguing it is not a great data sheet.

But it isn't the worst I've ever seen, and it is certainly sufficient to light up the LEDs.

 

JC

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I got my assembler code working from the datasheet info but my brain works in mysterious ways if it does at all..... devil

 

It does say

 

RES  Low voltage time ABOVE 50us
 

 Which means (to me at least) that the last low transition can be 50us or longer including infinity.

John Samperi

Ampertronics Pty. Ltd.

https://www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

joeymorin wrote:
I will run some tests when I can.

 

So I did a bit of fiddling with some WS2812 (not the 'B' variant).  Here's what I found.

 

As posited by cpldcpu, parameters T0L, T1H, and T1L can be stretched quite a bit.  I don't have access to a DSO or an LA so I can't show any pictures or give authoritative figures, but it seems that each of these can be stretched such that the total bit time can be as much as 7125 ns i.e. (T0H + T0L) <= 7125 ns and (T1H + T1L) <= 7125 ns.  Note that 7125 ns is far longer than the max 1850 ns spec'd (which should probably have been spec'd as max 1550 ns, based on the specs for TxH/TxL).

 

Beyond 7125 ns and the behaviour of the LEDs becomes erratic.

 

A T0L or T1L stretched beyond 8625 ns triggered a reset.  Note that this is far short of the 50 us spec'd in the datasheet. 

 

In addition, I tested the use of an idle high condition, and got a curious result.  There are no seriously ill effects to doing so, however it did in fact confirm what js said in post #55:

 

js wrote:

The last TxL CAN be stretched but no other, 50 us low latches the data and reset the counters so anything after that you will be addressing the 1st LED.

In other words, an LED will not update the PWM drive of its R, G, and B elements until a reset condition is seen.  Keeping DI high will postpone that update.

 

The curious part is what happens to DO under these conditions.  While keeping high the DI pin on the first LED in a string will postpone the latching and PWM update of that first LED, the 'idle-high' condition is not replicated on DO.  An LED who's DI is kept high for too long will nevertheless bring its DO pin low.  How long is too long is unknown to me.  A DSO or LA would be helpful in this regard, but the lesson is still clear:  Keeping DI high or low beyond a threshold will reset and latch all down-string LEDs.  Only the first LED (directly driven by the mcu) can be forced to postpone a PWM update by keeping DI high after a transfer.  All down-string LEDs will update almost immediately, as they will see a reset condition almost immediately.

 

This doesn't resemble a feature so much as it does a design flaw.  Or at least an oversight.  It's hard to guess at the designers' intent from such a poorly written datasheet, but it seems clear enough to me that an idle-high condition is not handled well, whereas an idle low condition is.  There is some support from the datasheet in this regard:

 

 

The figure shows that the reset comes immediately after the last RGB word.  Had a high idle condition been intended, I would expect the figure would have looked something like this:

 

 

Of course the datasheet has already proven to be lacking, so that is perhaps not a reasonable expectation ;-)

 

@skeeve has pointed out that interrupts need to be disabled 'for a rather long time'.  Based on the apparent max bit time of 7125 ns and a nominal bit time of 1250 ns, there appear to be about 5875 ns available to service interrupts between bits.  At 8 MHz, that's only 47 cycles.  Opening a window for a pending interrupt would take 3 cycles (sei/nop/cli or out/nop/cli).  Vectoring and returning would take 4 cycles each, leaving 36 cycles for a hand-assembled ISR in the vector table.  If the ISR is outside the vector table, lose another 2 or 3 cycles for a jmp or rjmp, down to 33 cycles.  If the ISR is written in C, lose another 15 cycles for just the minimal prologue and epilogue.  That leaves 18 cycles for a C ISR before you've even touched a single bit or preserved any other state.  Not much, but perhaps enough for a very short, very time critical ISR.  Running at 16 MHz improves this somewhat (83/80/65 cycles).

 

While this may seem promising, there are two problems.  One is that you must guarantee the worst-case execution time of all enabled ISRs, or the WS2812 data stream will be corrupted.  Second, and more importantly IMHO, is that regardless of the quality of the datasheet, you would be driving the WS2812s out of spec.  Fine for a one-off.  Bad for production.  A change by the manufacturer could break later production runs of your product.

 

I did not explore the minimum/maximum times for T0H, nor the minimum time for T1H.  I also did not explore whether bit times could be stretched more or less on byte boundaries or RGB word boundaries.  I based my testing on kk6gm's code mentioned in post #14 running at 8 MHz, where T0H is 375 ns (3 cycles) and T1H is 875 ns (7 cycles).  Testing was done by modifying the code to extend T0L/T1L, and T1H with a granularity of 125 ns (1 cycle).

 

Only WS2812 were tested.  WS2812B were not.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

Last Edited: Thu. Jul 30, 2015 - 04:27 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

parameters T0L, T1H, and T1L can be stretched quite a bit. 

If the WS2812 keeps backward compatibility with it's predecessor WS2811 (low speed mode) then it should accept a lower clock of 400KHz instead of 800KHz, so pretty much twice as long.

Don't really know as everyone always want FASTER>>>>>>>>>>

 

John Samperi

Ampertronics Pty. Ltd.

https://www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
If the WS2812 keeps backward compatibility with it's predecessor WS2811 (low speed mode) then it should accept a lower clock of 400KHz instead of 800KHz,
To my knowledge they are not backwards compatible per se.

 

The WS2811 has a pin called SET used to select the mode (400 kHz or 800 kHz).  The WS2812 has no such pin.  It operates at 800 kHz exclusively.  However as discussed, the only critical timing parameter is T0H.  Whereas the WS2812 specs that as 200-500 ns, the WS2811 @ 400 kHz specs it at 350-650 ns, so there is some overlap.  Code could be written to drive both using a value for T0H within the overlapping range.

 

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

Last Edited: Thu. Jul 30, 2015 - 09:51 PM