View previous topic :: View next topic |
Author |
Message |
aaronik19
Joined: 25 Apr 2011 Posts: 297
|
Curve followup |
Posted: Tue Jan 07, 2014 3:25 pm |
|
|
Dear Friends,
Is there a way how I can output on a curve behaviour as shown in the image below? I am right if I use table-lookup? Does CCS has an example show this technique?
[/url] |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9246 Location: Greensville,Ontario
|
|
Posted: Tue Jan 07, 2014 3:53 pm |
|
|
You could enter in several data points into either eXcel or Matlab and have the program 'reverse engineer' to solve for the equation. Then simply code the PIC with the equation. Run a complete test of 0 to 255 to confirm the math is right.
The other way is to just have a simple lookup table of 255 elements.
My 'gut' feeling is that the lookup table might be faster than the algorithm.Although integer math is fast on a PIC. It'd be interesting to see though.
Should be a simple task for anyone in college or university. Let's me out as I graduated in 1974.
hth
jay |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Jan 07, 2014 4:31 pm |
|
|
Use the forum's search page to search for this:
Quote: | sine* lookup table |
Set it to: Search For All Terms |
|
|
aaronik19
Joined: 25 Apr 2011 Posts: 297
|
|
Posted: Tue Jan 07, 2014 4:38 pm |
|
|
thanks to all my friends |
|
|
gpsmikey
Joined: 16 Nov 2010 Posts: 588 Location: Kirkland, WA
|
|
Posted: Tue Jan 07, 2014 7:46 pm |
|
|
Ah, another '74 graduate !! Just out of Vacuum tubes (or "valves" for that side of the pond). I used a lookup table with a Z-80 (lots slower than the PIC) some years ago to simulate a fairly complex curve (flap and slat simulator for the 757 aircraft) and it worked well. The advantage to the table lookup is being able to easily tweak the curve. You can either use all 255 data points for a 8 bit value or for more complex, you create a table of "segments" where the table entry has a base value and then a incremental value listed used to calculate the desired output as a function of "base+(incremental*diff_from_base)" -- you find the closest entry for a given "value", that gives you the base value and you take the difference between the pointer to the base value and your current variable and multiply that times the "increment" from the table then add that to the base value you obtained. You can define some "segments" fairly close together for rapidly changing curves and longer segments where the curve approximates a straight line. Not sure I said that quite right, but you get my meaning :-)
Recognize that lights and eyes have non-linear responses (50% power is not 50% brightness) so your actual table (depending on what you are controlling to "dim" the lighting) may indeed have a strange looking curve to make the lighting appear as desired. _________________ mikey
-- you can't have too many gadgets or too much disk space !
old engineering saying: 1+1 = 3 for sufficiently large values of 1 or small values of 3 |
|
|
aaronik19
Joined: 25 Apr 2011 Posts: 297
|
|
Posted: Wed Jan 08, 2014 3:20 am |
|
|
Thanks for your ideas. Suppose i need to dim for example 80% to 40%, in customized time such as 6 seconds, i was going to implement this routine:
(80-40)/6 = 6.667 steps/second ~ 7 steps/second
Now i will make a for...loop of 7 loops to decrease the level. I am right? Any suggestions please how i can improve the fade time dimming? The fade time should be customized by the client and could be up to 1 hour to have like "sunrise / sunset" dimming effect. |
|
|
RF_Developer
Joined: 07 Feb 2011 Posts: 839
|
|
Posted: Wed Jan 08, 2014 4:47 am |
|
|
aaronik19 wrote: | Suppose i need to dim for example 80% to 40%, in customized time such as 6 seconds, i was going to implement this routine:
(80-40)/6 = 6.667 steps/second ~ 7 steps/second
Now i will make a for...loop of 7 loops to decrease the level. I am right? Any suggestions please how i can improve the fade time dimming? |
I did this sort of thing many years ago (err... pretty much 30 years ago in fact!) on a 6809 for which I hand assembled all my code - no CCS C then! That was for a transparency projector controller project. The lookup table is the simplest, most flexible and fastest way to go.
My fade algorithm was different: I had fixed time updates and therefore I worked out how much I had to change the level in each update. There was clearly a limit to how slowly I could fade, in other words I couldn't do less than one step per time slot. My time slots (16 per second if I remember right) were related to a data frames on a controlling audio tape, but it would work the same way with a PIC timer and interrupt. As this was for things like cross-fades between projectors, my longest fade times are no more than a few tens of seconds and worked pretty well.
To extend the time range you'd maybe extend the resolution of the brightness range, say to 16 bit, but only use the top eight bits to drive the look-up table. Another trick, the one I used, was to skip some intervals and change every second/third tick etc. That way the fading is capable of being interrupt driven and timed by hardware. I did get this working with a tape and pair of transparency projectors, and got acceptably linear dimming with tape controlled automated fading, but I never completed the project. I had done the difficult bit; the rest was GUI and HMI stuff which was not all that interesting for me, and while cool, gave what I thought was relatively little reward for the rather large effort required in those pre-Windows days. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19553
|
|
Posted: Wed Jan 08, 2014 5:12 am |
|
|
First, don't get too neurotic about the shape of the table!.....
The human eye is very variable in how it measures 'brightness', and curves like this are only rough approximations.
A look up table is by far the easiest/quickest way to do this (not exactly rocket science, just an array).
However if you look at the curve as posted, it is pretty close to a quadrant of a circle. As such the 'y' value can be solved by simple Pythagoras.
So y=sqrt(10000-((100-x)^2)) * 2.55
On the loop, keep simple. Work in some standard like mSeconds.
Then have:
start_level (0-100)
end_level (0-100)
time (in mSec for the ramp - say int32)
tick
Have the tick also count in mSec (even if it only updates ten times/second say). Updated by an interrupt
Since you are not looking to change at a great rate, the 'sloth' of fp maths won't matter, so you can do:
Code: |
int32 local_tick;
float temp;
do
{
while (local_tick!=tick)
local_tick=tick; //get a local copy of the timer tick
temp=(float)time/local_tick;
//0 to 1 for how far through the time you are
temp=(temp*(start-end))+start;
//now the required light level required (in percent)
update_light(level);
}
while (local_tick<time);
|
If start_level is above end_level, this will ramp the other way.
Best Wishes |
|
|
aaronik19
Joined: 25 Apr 2011 Posts: 297
|
|
Posted: Wed Jan 08, 2014 5:09 pm |
|
|
Thanks telmah. Just to understand better the variable tick is the fade time? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19553
|
|
Posted: Thu Jan 09, 2014 2:04 am |
|
|
The fade time is 'time' (as I say, in mSec).
Tick is a 'tick' counting in mSec (as I say 'being updated in an interrupt').
So while 'tick' is less than 'time', it ramps.
Best Wishes |
|
|
aaronik19
Joined: 25 Apr 2011 Posts: 297
|
|
Posted: Fri Jan 10, 2014 4:59 am |
|
|
Thanks, i went through the code you sent me and i am understanding why you used the temp variable. Can you please explain in further detail. Really appreciate |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19553
|
|
Posted: Fri Jan 10, 2014 5:28 am |
|
|
Generally because CCS has problems if arithmetic is done with too many variables per statement. There is a tendency for scratch values 'half way through', to get overwritten. It'll probably be OK without here, but generally it always seems to have less problems if you keep the number of statements/line relatively small.....
Best Wishes |
|
|
|