How to generate a pulse under 1uS ?

Go To Last Post
70 posts / 0 new

Pages

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.

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.

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.

"SCSI is NOT magic. There are *fundamental technical
reasons* why it is necessary to sacrifice a young
goat to your SCSI chain now and then." -- John Woods

  • 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.

"SCSI is NOT magic. There are *fundamental technical
reasons* why it is necessary to sacrifice a young
goat to your SCSI chain now and then." -- John Woods

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.

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.

"SCSI is NOT magic. There are *fundamental technical
reasons* why it is necessary to sacrifice a young
goat to your SCSI chain now and then." -- John Woods

  • 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?

"SCSI is NOT magic. There are *fundamental technical
reasons* why it is necessary to sacrifice a young
goat to your SCSI chain now and then." -- John Woods

  • 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.

"SCSI is NOT magic. There are *fundamental technical
reasons* why it is necessary to sacrifice a young
goat to your SCSI chain now and then." -- John Woods

  • 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.

"SCSI is NOT magic. There are *fundamental technical
reasons* why it is necessary to sacrifice a young
goat to your SCSI chain now and then." -- John Woods

  • 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.

 

"SCSI is NOT magic. There are *fundamental technical
reasons* why it is necessary to sacrifice a young
goat to your SCSI chain now and then." -- John Woods

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.

"SCSI is NOT magic. There are *fundamental technical
reasons* why it is necessary to sacrifice a young
goat to your SCSI chain now and then." -- John Woods

  • 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.

"SCSI is NOT magic. There are *fundamental technical
reasons* why it is necessary to sacrifice a young
goat to your SCSI chain now and then." -- John Woods

  • 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.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

Pages