Design Con 2015
Breaking News
Comments
Newest First | Oldest First | Threaded View
<<   <   Page 3 / 3
Max The Magnificent
User Rank
Blogger
Re: Maybe just add 1
Max The Magnificent   10/25/2013 2:52:19 PM
NO RATINGS
@Wnderer: I might be missing something but why not just add or subtract 1?

I've not tried this yet, but I think that if I try to fade the LEDs up over 256 increments / levels then this will consume a lot of processing cycles and may be overkill (changes not discernable to the human eye). Even if I transition the color using say 16 steps with 100 milliseconds (0.1 seconds) between each step, this still equates to 1.6 seconds.

My idea of being able to specify the "howMany" increments value and the delay between incremnents will let me experiment a bit. Also, setting the "howMany" parameter to 1 should make the LED immediately turn hard on or hard off. The idea is that I can vary the pace of the display either randomly or in a controlled manner...

I'm having a lot of fun with this.

Wnderer
User Rank
CEO
Maybe just add 1
Wnderer   10/25/2013 10:54:12 AM
NO RATINGS
I might be missing something but why not just add or subtract 1?

 

if (modColor > 0) modColor = (modColor + 1) / howMany

else if (modColor < 0) modColor = (modColor - 1)/howMany

 

if modColor is either 0, 255 or -255 and howMany is always even then you end up with a couple of compares, an increment, a decrement and some bit shifts. If I recall correctly that switch statement will create a jump table, so you're better off with if statements if you're looking for compact assembly code.

 

 

Garcia-Lasheras
User Rank
Blogger
Re: Alternative implementation
Garcia-Lasheras   10/25/2013 10:19:34 AM
NO RATINGS
@Max: Yes, you are compltely right -- I was using modColor variable too and then I realized that I didn't need that, so I quickly changed the code.

In addition, about the timing coherence, I was assuming that delay(howLong) dominates the fading, so I was not thinking on exactly matching the number of CPU cycles -- I just love symmetry ;-)

The code could be then:


void lightLEDs (int howMany,
                int howLong)
{
    int tmpColor = oldColor;

    for (int i = 1; i <= howMany; i++)
    {
        if (newColor != oldColor)
        {
            tmpColor = 255 * i;
            tmpColor = tmpColor / howMany;
            
            if (newColor < oldColor)
                tmpColor = 255 - tmpColor;
        }

        // Use current tmpColor to drive LED
        delay(howLong);
    }
}

Max The Magnificent
User Rank
Blogger
Re: Alternative implementation
Max The Magnificent   10/25/2013 10:10:12 AM
NO RATINGS
Re the part of your code that says:

 

            if (newColor > oldColor)

                tmpColor = 0 + tmpColor;

            else

                tmpColor = 255 - tmpColor;

 

Isn't the first part of this redundant? Couldn't we just say:

 

            if (newColor < oldColor)

                tmpColor = 255 - tmpColor;

 

Or are we doing it your way to keep the time pretty much consistent for fade-ups and fade-downs by performing roughy the same number/type of calculations each way?

 

Max The Magnificent
User Rank
Blogger
Re: Alternative implementation
Max The Magnificent   10/25/2013 10:02:01 AM
NO RATINGS
@salbayeng: It's also useful to see whether  "negative zero" can appear in your algorithm

Now you are making my brain ache -- surely one of the main points about the twos complement form of representation is that you cannot get negative zero...


Max The Magnificent
User Rank
Blogger
Re: Alternative implementation
Max The Magnificent   10/25/2013 9:58:34 AM
NO RATINGS
@Garcia: Interesting ... I will try both techniques (mine and yours) and report back on the results.

salbayeng
User Rank
Rookie
Re: Alternative implementation
salbayeng   10/25/2013 1:10:56 AM
NO RATINGS
I'm thinking similar to Garcia.

I use the delta addition approach in Servo systems as well as LED drivers.

I call it "phase accumulation" , the idea has been around for years , embodied in DDS chips. 

In your case I would set up an integer "phase accumulator" and then overlay the "led brightness" byte on the high 8 bits. You then add "ramping speed" to "phase accumulator" 

All of the accumulating is done in an interrupt routine, so you can do multiple LED's , and other system timers at once , and can have long fade times. You can also interrupt a fade and fade smoothly off to something else.

--------------------------

Re  the "missing bit"  , yeh you get this issue with fixed point multiply (and divide) .  From memory if you do it in assembler you can keep track of the missing bit, something like this:  (plucked from code I wrote years ago, and the detail forgotton)

 mulsu r23, r20
 SBC r19, _zero
          ADD r17, r0
          ADC r18, r1 
  ADC r19, _zero

I can't remember exactly how this works , this piece is transferring the partial results from a multiply into the result.  Note the SBC r19, _zero , this seems to be pointlessly subtracting zero from a register, but its actually propagating the missing bit. Note the Atmel chips have 6 flavors of multiply

MUL Rd, Rr Multiply Unsigned R1:R0 ← Rd x Rr    
MULS Rd, Rr Multiply Signed R1:R0 ← Rd x Rr      
MULSU Rd, Rr Multiply Signed with Unsigned R1:R0 ← Rd x Rr     
FMUL Rd, Rr Fractional Multiply Unsigned R1:R0 ← (Rd x Rr) << 1     
FMULS Rd, Rr Fractional Multiply Signed R1:R0 ← (Rd x Rr) << 1      
FMULSU Rd, Rr Fractional Multiply Signed with Unsigned R1:R0 ← (Rd x Rr) << 1 

So if you go to the trouble of writing in assembler,and pick and choose the type of MUL you use, you can make 255/256=1 , It's also useful to see whether  "negative zero" can appear in your algorithm and whether it is handled correctly  typically -255/-256 = 1 while 255/256=0 but what about 0/-256 ??

A possible fix to your problem is to use a condition test like <= in one direction and > in the other

Garcia-Lasheras
User Rank
Blogger
Alternative implementation
Garcia-Lasheras   10/24/2013 8:07:50 PM
NO RATINGS
As you note, in order to use a constant incremental step or delta, the ideal choice would be using "float". The problem is that this is not very handy for a 8 bits machine.

But there are a lot of problems in using integers for this purpose too, as we cannot deal with decimal values. One of them is that the LED intensity increase/decrease is not going to be linear along the cycles -- it may reach the final value far before the for loop ends.

I propose you a bit more computational intensive solution, but I believe the LED regulation may be nicer:


void lightLEDs (int howMany,
                int howLong)
{
    int tmpColor = oldColor;

    for (int i = 1; i <= howMany; i++)
    {
        if (newColor != oldColor)
        {
            tmpColor = 255 * i;
            tmpColor = tmpColor / howMany;
            
            if (newColor > oldColor)
                tmpColor = 0 + tmpColor;
            else
                tmpColor = 255 - tmpColor;
        }

        // Use current tmpColor to drive LED
        delay(howLong);
    }
}

 

<<   <   Page 3 / 3


Top Comments of the Week
Flash Poll
Like Us on Facebook

Datasheets.com Parts Search

185 million searchable parts
(please enter a part number or hit search to begin)
EE Life
Frankenstein's Fix, Teardowns, Sideshows, Design Contests, Reader Content & More
<b><a href=Betajet">

The Circle – The Future's Imperfect in the Present Tense
Betajet
Post a comment
The Circle, a satirical, dystopian novel published in 2013 by San Francisco-based writer Dave Eggers, is about a large, very powerful technology company that combines aspects of Google, ...

Max Maxfield

Recommended Reads From the Engineer's Bookshelf
Max Maxfield
2 comments
I'm not sure if I read more than most folks or not, but I do I know that I spend quite a lot of time reading. I hate to be idle, so I always have a book or two somewhere about my person -- ...

Martin Rowe

No 2014 Punkin Chunkin, What Will You Do?
Martin Rowe
2 comments
American Thanksgiving is next week, and while some people watch (American) football all day, the real competition on TV has become Punkin Chunkin. But there will be no Punkin Chunkin on TV ...

Rich Quinnell

Making the Grade in Industrial Design
Rich Quinnell
15 comments
As every developer knows, there are the paper specifications for a product design, and then there are the real requirements. The paper specs are dry, bland, and rigidly numeric, making ...

Special Video Section
The LT8640 is a 42V, 5A synchronous step-down regulator ...
The LTC2000 high-speed DAC has low noise and excellent ...
How do you protect the load and ensure output continues to ...
General-purpose DACs have applications in instrumentation, ...
Linear Technology demonstrates its latest measurement ...
10:29
Demos from Maxim Integrated at Electronica 2014 show ...
Bosch CEO Stefan Finkbeiner shows off latest combo and ...
STMicroelectronics demoed this simple gesture control ...
Keysight shows you what signals lurk in real-time at 510MHz ...
TE Connectivity's clear-plastic, full-size model car shows ...
Why culture makes Linear Tech a winner.
Recently formed Architects of Modern Power consortium ...
Specially modified Corvette C7 Stingray responds to ex Indy ...
Avago’s ACPL-K30T is the first solid-state driver qualified ...
NXP launches its line of multi-gate, multifunction, ...
Doug Bailey, VP of marketing at Power Integrations, gives a ...
See how to ease software bring-up with DesignWare IP ...
DesignWare IP Prototyping Kits enable fast software ...
This video explores the LT3086, a new member of our LDO+ ...
In today’s modern electronic systems, the need for power ...