Display circularly scrolling text on the LCD

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

The aim of my experiment is to display circularly scrolling text received from main function on the LCD.The text should be displayed scrolling from first row first column to first row sixteenth column of the LCD. The text coming out from first row sixteenth column should start appearing again in first row first column.

iam getting the text is scrolling from first row first column to first row sixteenth column of LCD. but iam not getting the text coming out from first row sixteenth column should start appearing again in first row first column.

pls help me to solve this.

Attachment(s): 

This topic has a solution.

ranju

Last Edited: Thu. Mar 15, 2018 - 04:36 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Does the lcd_cursor() call really accept "-5" as a valid location?

 

Anyway the way I would do it is probably just to shuffle the array and keep printing in in the same place. In untested psuedo code something like:

char text[17] = "Hello Good World";
char c;

for (n=0 n < 16; n++) {
    lcd_goto(0,0);
    lcd_printstring(text);
    // do the string shuffle
    c = text[0]; // take copy of the left most character
    // shuffle all the others one place to the left
    for (i = 0; i < 16; i++) {
        text[i] = text[i + 1];
    }
    // put the saved character on the end
    text[15] = c;
    // just in case it's disturbed
    text[16] = 0; // end of string marker
}

If you want to scroll it the other way then:

    // do the string shuffle
    c = text[15]; // take copy of the right most character
    // shuffle all the others one place to the right
    for (i = 15; i > 0; i--) {
        text[i] = text[i - 1];
    }
    // put the saved character at the start
    text[0] = c;
    // just in case it's disturbed
    text[16] = 0; // end of string marker

I haven't tried this or thought it through so I could well have got the boundary conditions wrong but the idea is there.

 

Bottom line shuffle the text itself - before you do copy the character that is about to "disappear" - at end put that character back on the other end.

 

Then just keep printing the text at the same location.

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

OK so I had to give that a go:

D:\c>type lcd.c
#include <stdio.h>

char text[17] = "Hello Good World";
char c;

int main(void)  {
        int i, n;
        for (n = 0; n < 16; n++) {
                printf("%s\n", text);
                // do the string shuffle
                c = text[0]; // take copy of the left most character
                // shuffle all the others one place to the left
                for (i = 0; i < 16; i++) {
                        text[i] = text[i + 1];
                }
                // put the saved character on the end
                text[15] = c;
                // just in case it's disturbed
                text[16] = 0; // end of string marker
        }
}
D:\c>cl lcd.c
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.40219.01 for 80x86
Copyright (C) Microsoft Corporation.  All rights reserved.

lcd.c
Microsoft (R) Incremental Linker Version 10.00.40219.01
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:lcd.exe
lcd.obj

D:\c>lcd
Hello Good World
ello Good WorldH
llo Good WorldHe
lo Good WorldHel
o Good WorldHell
 Good WorldHello
Good WorldHello
ood WorldHello G
od WorldHello Go
d WorldHello Goo
 WorldHello Good
WorldHello Good
orldHello Good W
rldHello Good Wo
ldHello Good Wor
dHello Good Worl

D:\c>

I believe that if these strings had all been printed at the same place on an LCD (with a delay after each to give a chance for it to be seen) this would have given the impression of scrolling.

 

For completeness here's the "other" version going in the opposite direction:

D:\c>type lcd.c
#include <stdio.h>

char text[17] = "Hello Good World";
char c;

int main(void)  {
        int i, n;
        for (n = 0; n < 16; n++) {
                printf("%s\n", text);
                // do the string shuffle
                c = text[15]; // take copy of the right most character
                // shuffle all the others one place to the right
                for (i = 15; i > 0; i--) {
                        text[i] = text[i - 1];
                }
                // put the saved character at the start
                text[0] = c;
                // just in case it's disturbed
                text[16] = 0; // end of string marker
        }
}
D:\c>lcd
Hello Good World
dHello Good Worl
ldHello Good Wor
rldHello Good Wo
orldHello Good W
WorldHello Good
 WorldHello Good
d WorldHello Goo
od WorldHello Go
ood WorldHello G
Good WorldHello
 Good WorldHello
o Good WorldHell
lo Good WorldHel
llo Good WorldHe
ello Good WorldH

As this demonstrates it is ASTRONOMICALLY easier to prototype this kind of thing in a PC program - when you have the mechanism worked out only THEN move to your AVR+LCD (and a few tweaks as printf() no longer works)

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

PS I notice the time difference between #2 and #3 is 5 minutes. So this went from idea/design to implementation and test in less than 5 minutes. That is why you do this kind of experimenting on a PC!

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

my aim of the project is to convert the analog values of the three white line sensors and the front sharp sensor into digital value

here i have attached the code, my problem is in lcd_print(), show the error as "undefined reference to lcd_print".

Attachment(s): 

ranju

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

You haven’t shown us the code for lcd_print or the errors. I think you need to do some detective work.
It also would’ve been nice to mark Cliff’s excellent work as the solution.

Last Edited: Thu. Mar 15, 2018 - 07:13 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Kartman wrote:
It also would’ve been nice to mark Cliff’s excellent work as the solution.
I don't think the OP even took notice of Cliff's work.  Not even an acknowledgement, comment, or thanks was offered. :\

"I may make you feel but I can't make you think" - Jethro Tull - Thick As A Brick

"void transmigratus(void) {transmigratus();} // recursio infinitus" - larryvc

"It's much more practical to rely on the processing powers of the real debugger, i.e. the one between the keyboard and chair." - JW wek3

"When you arise in the morning think of what a privilege it is to be alive: to breathe, to think, to enjoy, to love." -  Marcus Aurelius

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

“We reap what we sow”

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

The "solution" appears to be a new homework assignment to me, with no apparent connection to any scrolling.

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

I had a similar issue just this evening, actually, although I was shuffling data around programmable LED chips (Adafruit NeoPixel 24 chip ring, if you care) instead of characters on an LCD and I decided the array shuffle was much too expensive computationally, and went with loopy pointers to stable RAM instead.

 

One problem with prototyping on a PC (many kudoes to clawson!) is that you can write very expensive functions and not know it, because PCs are stupid fast and have vast tracts of RAM, while AVR's don't (Tiny2313A, 128 bytes, again in case you care, and I'm working for fun on old scrap boards, so picking a newer chip is right out).

 

S.

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

To a certain extent I write replies to broaden my own understanding (never done the LCD shuffle thing before!) so I don't actually care too much if no one listens anyway :-)

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

theusch wrote:
The "solution" appears to be a new homework assignment to me, with no apparent connection to any scrolling.

Time for a split, then!

 

laugh

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

RANJANASHANKER wrote:
my problem is in lcd_print(), show the error as "undefined reference to lcd_print".
That's because the "project" has to build (and then link together) both experiment-1.c and lcd.c (or whatever the file that contains your LCD functions is called). If you are using a "makefile" then add the LCD source file to the list of sources.

Time for a split, then!

Oh dear God no.

Last Edited: Thu. Mar 15, 2018 - 01:35 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

RANJANASHANKER wrote:
my problem is in lcd_print(), show the error as "undefined reference to lcd_print".

Same as: https://www.avrfreaks.net/commen...

 

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

I was shuffling around 96 bytes (four bytes per LED chip, it's an GRBW ring) and although this would work to walk through the SRAM pattern:

for (i = 15; i > 0; i--) {
                        text[i] = text[i - 1];

you want my lil' tiny2313 AVR to do HOW MANY load and stores?  At four cycles each?  And when that 15 becomes 96?  Urf!!  I think not.

 

The Neopixel rings have timing requirements.  I wound up putting delay loops in anyhow to make them look prettier, but I think my point stands.

 

S.

 

PS - I may have found a way to use the <> code window.  It doesn't work when I click on the icon, but it DOES work when I paste SOMEONE ELSE's code.  Bizarre.  S.

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

PS - I may have found a way to use the <> code window.  It doesn't work when I click on the icon, but it DOES work when I paste SOMEONE ELSE's code.  Bizarre.  S.

Log out.

Clear your browser's cache.

Log in.

 

If that doesn't fix it, clear your browser's cookies as well.  If you'd rather not clear all your cookies, you can clear just those cookies associated with avrfreaks.net and jsdelivr.net.

 

you want my lil' tiny2313 AVR to do HOW MANY load and stores?  At four cycles each?  And when that 15 becomes 96?  Urf!!  I think not.

4 x 96 = 384.  At 8 MHz (at which you're likely running for the WS2812 updates), that's only 48 us.  Is that really too much?  Even if you're running at 2 MHz (I have WS2812 code which does), then it's still only 192 us.  How often are you shuffling this data?  After all, it's for human eyeballs, which are pretty slow.

 

The Neopixel rings have timing requirements.  I wound up putting delay loops in anyhow to make them look prettier, but I think my point stands.

The timing requirements are handled by the update routine, likely by disabling interrupts during the update.  Your main code need not concern itself with that.

 

Your point may stand, but it also eludes me.

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

"Read a lot.  Write a lot."

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

 

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

Me and the <> code window have a long history, thank you.  As far as we know there is no simple fix.

 

joeymorin wrote:

PS - I may have found a way to use the <> code window.  It doesn't work when I click on the icon, but it DOES work when I paste SOMEONE ELSE's code.  Bizarre.  S.

Log out.

Clear your browser's cache.

Log in.

 

If that doesn't fix it, clear your browser's cookies as well.  If you'd rather not clear all your cookies, you can clear just those cookies associated with avrfreaks.net and jsdelivr.net.

 

you want my lil' tiny2313 AVR to do HOW MANY load and stores?  At four cycles each?  And when that 15 becomes 96?  Urf!!  I think not.

 

4 x 96 = 384.  At 8 MHz (at which you're likely running for the WS2812 updates), that's only 48 us.  Is that really too much?  Even if you're running at 2 MHz (I have WS2812 code which does), then it's still only 192 us.  How often are you shuffling this data?  After all, it's for human eyeballs, which are pretty slow.

 

 

 

I am running at 8MHz.  I wish this dumb board had pads for an external crystal, but it doesn't.  I'd love to run at 20MHz. 

 

I should let you know also that the minimum reset time for the WS2812 chips is 50us.  If I want to rewrite the chips with a new pattern, and spend 48us just shoveling memory around, that gives me only 2uS to calculate a new pattern (if I want to animate them at full speed), time that I would much rather use for getting creative with new values for the next "frame" (next patch of data sent to the LEDs).  I put in delay loops to give the NeoPixels smooth movement, but 48us for a memory move is right out.

 

If I want to animate fast, I cannot afford to wait that long.

 

joeymorin wrote:

The Neopixel rings have timing requirements.  I wound up putting delay loops in anyhow to make them look prettier, but I think my point stands.

The timing requirements are handled by the update routine, likely by disabling interrupts during the update.  Your main code need not concern itself with that.

 

Your point may stand, but it also eludes me.

 

Point being that 48uS is a bloody eternity and I'm not willing to sit around for that.

 

The individual timing for each LED chip driver could be more efficient too, but the main code has to animate the different patterns as fast as the chips can handle it, and farting around with a 48us memory move will just not do.

 

Thanks,  S.

 

PS - This is my own custom board and my own code, written entirely in assembler.  I left out the entire interrupt table (except rjmp RESET, which may itself be redundant since RESET, aside from the jmp table, is 0x0000)  to save on flash RAM.  This is not an Arduino.  S.

 

PPS - This is not interrupt timing, this is careful use of the occasional NOP.  I don't have time to get into and return from an interrupt routine.  S.

Last Edited: Sat. Mar 17, 2018 - 03:43 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

 

 

I should let you know also that the minimum reset time for the WS2812 chips is 50us

That's the spec, but in reality the LEDs will interpret any low pulse longer than about 9us as a reset.

 

Still, I don't see how that's relevant.  The reset pulse simply ends a bit stream and triggers an update of the PWM drive with the newly latched values.

 

What's more, it takes 30 us per LED for an update, so a string of 96 will take 2.93 ms, during which interrupts are disabled.  How is 48 us to reshuffle an array too much?

 

I think you've conflated the 50 us reset pulse as a maximum rather than a minimum spec.  You can wait forever between bitstreams and the LEDs will hold and show the most recently latched values, until you send them new ones, and then trigger an update with the next reset pulse.

 

If you took 7 ms to do all of your new computations, added to the 2.93 ms LED update, you'd still be able to maintain a 100 Hz update rate on your string of 96 LEDs.  Surely that's enough for most any human eyeball.  So I still don't know what the issue is with 48 us.

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

"Read a lot.  Write a lot."

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

 

Last Edited: Sat. Mar 17, 2018 - 05:42 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I calculate about 920us for updating my ring of 24 LEDs (at four bytes per - it's an GRBW ring).  Not quite 2,930us.

 

While bitbanging the stream to the LEDs timing precision is important.

 

Interrupts are very much disabled - for the whole program.  There are no interrupts at all (I deleted the whole table).

 

It's true that the 50uS low is a minimum spec, and it's possible the chips are better than that.  But cheating on the specs doesn't help me have any confidence in the reliability thereof.

 

Point being (here I go again) that while updating the LEDs timing precision is important (+/- 150 nanoseconds).  I will take all the time I need to do that carefully.  The reset time is my free time to have fun with what's going to be written the next time.  And that can get elaborate, and the last thing I want to be doing with it is shoveling memory around.

 

Ever heard of antialiasing? 

 

S.

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

PS - In a way you've defeated your own argument there.

 

joeymorin wrote:

I should let you know also that the minimum reset time for the WS2812 chips is 50us

That's the spec, but in reality the LEDs will interpret any low pulse longer than about 9us as a reset.

 

 

So why should I muck about for 48us moving memory around if I can rewrite the chips in 9us?  S.

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

I calculate about 920us for updating my ring of 24 LEDs (at four bytes per - it's an GRBW ring).  Not quite 2,930us.

I was calculating based on 96 GRB LEDs, rather than 96 bytes (24 GRBW LEDs), but the arithmetic is the same.

 

Since you're talking GRBW, I assume that means the SK6812 or similar.  Some are RGBW, not GRBW, but other than the colour order the specs are the same.  That's 32 bits per LED, and the bit times are spec'd at a nominal 1.25 us, so one LED takes 40 us to update.  With 24 LEDs, that's 960 us, plus the 80 us nominal reset pulse for a total of 1040 us.  So I still don't see how 48 us kills you given that the update bitstream takes 20 times that long to send, even though there is a quite a bit of tolerance for the bit times.

 

While bitbanging the stream to the LEDs timing precision is important.

Not nearly as important as you think.  The critical parameter is T0H, which is spec'd at 200ns-500ns for both the WS2812, and the newer WS2812B.  There is far greater latitude in T0L, T1H, and T1L.  The SK6812 specs 150ns-450ns, and I expect it has similarly flexible timings.

 

Have a look at:

https://www.avrfreaks.net/forum/how-generate-pulse-under-1us?page=all

 

I've found that for GRB/RGB you can stretch the bit times all the way to 7125 ns, far longer than the nominal 1250 ns.  The only real (as opposed to spec'd) timing values are that T0H be less than about 500 ns, and that T1H be greater than about 500 ns.  As long as T0H+T0L and T1H+T1L is between about 1000 ns and 7125 ns, it will work, although T1L likely has a simlar constraint to T0H.  Low times longer than about 8625 ns are seen as a reset.

 

PS - In a way you've defeated your own argument there.

So why should I muck about for 48us moving memory around if I can rewrite the chips in 9us?  S.

How did you arrive at that conclusion?  It is only the reset pulse which has a real threshold of about 9us, rather than the 50 us quoted in the datasheet.  You cannot update the LED in 9us.

 

The 'update' consists of sending new values for the RGB (or GRB, RGBW, or GRBW, depending on the part) bitstream.  Once received, that value is buffered internally.  The reset serves only to latch those values to the PWM drivers.  Were you to send an unending bitstream i.e. no reset pulse, the LEDs would receive and buffer the new values, but would not update their PWM outputs to match.  It is the reset pulse which is used to trigger a simultaneous PWM update across all connected LEDs (subject to the propagation delay between DI and DO of about 300 ns).

 

You seem to be arguing that you have to make your calculations within a 50 us window in order to meet spec, and that's simply not true.  You can update the LEDs at whichever rate you want, 1000 times per second (provided you have a small enough number of LEDs i.e. (1000us-50us) / 40us[GRBW] = 23 LEDs), or once per second, or once every 7 years.  You are not bound to a 50 us reset, except as a minimum (and the 50 spec is quite conservative).  It is not a maximum.

 

As I've mentioned, your 24 LEDs will take 1040 us to update (to spec... you can get away with a little bit faster, or quite a bit slower).  How is 48 us a deal-breaker?

 

This is now thoroughly OT, and we should continue this in another thread if you want.

 

 

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

"Read a lot.  Write a lot."

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

 

Last Edited: Sat. Mar 17, 2018 - 07:14 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Oh, but awneil suggesting splitting it already, and that got nixed.

 

I don't want to stretch the writing times.  I want to run the whole Adafruit ring (as I mentioned before, and yeah, they're probably SK6812s) as fast as I can as long as I'm within the specifications.

 

If I had a new frame (by "frame" I mean "new data for all the LEDs on the ring) in 9ms I'd be thrilled to bits.  But I don't have enough SRAM or Flash to store the patterns I want, so instead of just loading them from somewhere I have to arithmetically generate them.  That takes processing time that I don't want to use throwing memory around. 

 

The chip updates were carefully shaven with a NOP here and there to precisely meet the minimum timing requirements (or as close as I could reasonably get with my 8MHz clock).  With a bit of clever interleaving I could do mathematics during the chip update time, but that's why I want a 20MHz clock not an 8MHz one.

 

You're perfectly right that I can go a lot slower if I want to, but I don't want to.  I also really don't like the idea of sloppy timing outside what the chip specification says I can do.

 

Think of it this way:  It takes me 920 us of carefully timed bitbanging to get the correct data to the correct chips.  Fine.  There is some possibility of doing useful mathematical work during that time, but most of it is going to be firing out bits - it's going to be a mess.  Most of the useful mathematical time is going to be during the reset cycle, because during that time the AVR doesn't have to do anything else.  And that, according to the spec, is 50us.

 

And shoveling a data array around for 48us of that 50us I would like to use kinda occupies the whole space.  Besides, my loopy pointers are much faster.

 

I think your point is that 'faster' in this context is trivially small.  I hold that's the only really unoccupied time to do my math.

 

S.

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

And that, according to the spec, is 50us.

 Again, that's a >>minimum<<.  You are within spec if you take 51 us, or 9 ms, or 7 years.

 

as fast as I can

Updating an array of LEDs 1000 times a second is pointless.  Even if the PWM frequency of the LEDs was that high (for the SK6812 it's 1.2 kHz, but for most WS2812 varieties, it's 400 Hz or lower), you will never perceive updates that fast.

 

Even HFR video is only 48 fps.  Video games are quite happy at 60 or 70 fps.  Anything else is a complete waste of time and resources.  Let's be even more ambitious and say you want 100 Hz.  That means 10 ms updates.  You need a fraction over 1 ms for the bitstream to the LEDs, leaving you nearly 9 ms for your computations.  If you are so close to the edge that 48 us (representing 0.6% of available time) makes or breaks you, then I'd say you have lower-hanging fruit than a data moving loop.  At 8 MHz, 9 ms is 72,000 cpu cycles.  What on earth are you doing to 24 GRBW LEDs that could require that kind of juice?

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

"Read a lot.  Write a lot."

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

 

Last Edited: Sat. Mar 17, 2018 - 08:23 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

joeymorin wrote:

What on earth are you doing to 24 GRBW LEDs that could require that kind of juice?

 

Signalling to fast photosensors.  This is not entirely for human vision.  S.

 

Edited to add:  Yeah, some of it is.  But some of it isn't.  Think intelligent machine-to-machine communication that also has a human visible component, like taillights on a car that can tell the car behind it how hard the driver pushed on the brakes as well as telling the driver of the car behind it that the brake lights just came on.  It's not that, but it's a metaphor for the general idea.  And no, this might not be the best way to go about it, but it's the gizmos I have and I thought it would be fun to play with.  S.

Last Edited: Sat. Mar 17, 2018 - 08:24 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Signalling to fast photosensors.  This is not entirely for human vision.  S.

An important point you failed to mention until now ;-)

 

Please elaborate.

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

"Read a lot.  Write a lot."

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

 

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

See edit.  S.

 

Edited to add:  PS - It does turn out that the chips are a lot faster than rated, but I'm still reluctant to push them.  Besides, my AVR can't do the necessary math that fast.  S.

Last Edited: Sat. Mar 17, 2018 - 08:29 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm still reluctant to push them

As would I be, for a commercial product.  For one-offs and hobby projects, no problem.

 

The specs in the datasheet (indeed the datasheet as a whole) are a little hard to have faith in to begin with.  The authors can't seem get basic arithmetic right (see the tolerances for pulses and bit times... they don't add up).

 

In reality, these things very likely use a simple counter to decode the bitstream.  A rising edge resets a running counter, and the falling edge triggers a decode.  The value of the counter determines the value of the bit which has just been decoded.  Lower than a certain threshold, it's a zero.  At or above that threshold, it's a one.  A shift register clocks in 24 (32 for GRBW) decoded bits.  After the 24th bit, the DIN pin is routed to the DOUT pin for downstream LEDs.

 

An overflow on the counter triggers a reset, which latches the bits in the shift register to the PWM units, reinitialises the 24-bit shift register, and drives the DOUT pin low to propagate the reset signal to all downstream LEDs.

 

An interesting consequence of this design (if that is indeed how they're designed) is that a high pulse of the same length as a low pulse would still trigger a reset, because the counter will still overflow without a new rising edge to reset it.  This is in fact how the LEDs I've tested behave.  Sort of.  A long high pulse (>9us) causes DOUT to go low triggering a reset in all downstream LEDs, but does not cause the 1st LED to latch the shift register to the PWM units.

 

 

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

"Read a lot.  Write a lot."

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

 

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

joeymorin wrote:

The specs in the datasheet (indeed the datasheet as a whole) are a little hard to have faith in to begin with.  The authors can't seem get basic arithmetic right (see the tolerances for pulses and bit times... they don't add up).

 

This is true.  Adafruit themselves put in their instructions for using these rings their own timing, for exactly the above reason.

 

Thanks for reporting your experiments. 

 

They're wonderful little chips.  I like 'em.  I hadn't considered leaving the data line high.  I have left it low for hours on end, and yes, they maintain the latched data just fine.  (They also (2/3rds (ish) of them) light up something fierce when I program the AVR, because the nature of the board has the LED data line on the SCK line from the ISP...  laugh  Probably says something about my programming baud rate, that)  S.