CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Efficient and fast math?

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
astus



Joined: 17 Nov 2003
Posts: 12
Location: Australia

View user's profile Send private message Visit poster's website

Efficient and fast math?
PostPosted: Mon Jul 19, 2004 12:44 am     Reply with quote

Hi,
Currently I'm trying to measure the RPM of a turbine. I am setup to use the capture mode on the pic16f877. I have the period of the turbine rotation but how do I determine the RPM so I can display it on an LCD display? The math is

RPM = 60 / ( CCP_Value * Ts) where Ts is timer period.

Do I have to convert to floating point or is there a sneaky method that I'm not aware of ?

Thanks

Adam Cool
kypec



Joined: 20 Sep 2003
Posts: 54

View user's profile Send private message

PostPosted: Mon Jul 19, 2004 2:22 am     Reply with quote

Maybe we could give you some suggestions but you have
to let us know what values of RPM you expect/need to measure.
What is your supposed range? 100 - 1000 rpm?
Or is it 1000-10000 rpm?

I did a sort of DC motor regulation with feedback of optical tacho
encoder. The basic I needed to know was how many pulses
I am able to capture at minimum speed and at maximum speed.
Given that I could determine my measurement period and
eventually all necessary calculations as well.

kypec
Ttelmah
Guest







Re: Efficient and fast math?
PostPosted: Mon Jul 19, 2004 2:43 am     Reply with quote

astus wrote:
Hi,
Currently I'm trying to measure the RPM of a turbine. I am setup to use the capture mode on the pic16f877. I have the period of the turbine rotation but how do I determine the RPM so I can display it on an LCD display? The math is

RPM = 60 / ( CCP_Value * Ts) where Ts is timer period.

Do I have to convert to floating point or is there a sneaky method that I'm not aware of ?

Thanks

Adam Cool

Quite a few possible ways to approach this. First comment, integer arithmetic is always faster than FP. Second comment, multiplication is quicker than division. Third comment, limit the number of maths operations involved. Fourth comment, on unsigned integers, multiplication/division by a binary multiple, is done using shifting, and is fast.
Now, taking the 'third' comment first, 'Ts' is a constant for a particular setup, so it is quicker to evaluate:
(60/Ts), and store this as the constant used for the arithmetic. So if (for instance), Ts is 1uSec, and the counter is reading 1000, the sum could be converted to:
60000000.0/(float)CCP_value
Next, the 'second comment' then applies, and you could instead use:
1.666667E-8 * (float)CCP_value.
Now the first comment applies. This operation, could potentially be 'scaled', so that it uses an integer. How easy this is, depends on the frequency of the sample clock chosen, so it can be worth considering using a different crystal, to give a nice simple binary multiple. Whether this is practical, depends on the sample intervals you can select, and the accuracy you need on the results. What is done, is to select the interval, so that the CCP_value itself, times some integer constant, gives a value that is a binary multiple of the required number. Then comment four applies, and the result can be scaled by shifting, or just selecting the upper bytes from the 32bit integer you would have to use. If (for example), the 'constant', was 1, and the final division was by 65536, then the result would be being multiplied by 1/65536, and if this matched the factor needed above, everything would be great. In general, this is a 'nice' way to work, but unfortunately, the size of the factor you need (probably in the 'order' of 1E-8), makes it unlikely that you can do this, since to have rotational speeds available up to 65536RPM, using a 32bit integer (the largest available), only allows a division factor of 65536...
So, multiplication by the reciprocal factor, is probably going to be the most practical solution for you.

Best Wishes
SherpaDoug



Joined: 07 Sep 2003
Posts: 1640
Location: Cape Cod Mass USA

View user's profile Send private message

Re: Efficient and fast math?
PostPosted: Mon Jul 19, 2004 6:52 am     Reply with quote

Most of Ttelmah's ideas are good. I would definately scale things so I could use fixed point arithmatic. But he lost me at
[quote="Ttelmah]
60000000.0/(float)CCP_value
Next, the 'second comment' then applies, and you could instead use:
1.666667E-8 * (float)CCP_value.
[/quote]
(maybe it is just Monday morning). But the important thing is to make sure YOU understand the code you are using.
_________________
The search for better is endless. Instead simply find very good and get the job done.
Not yet registered
Guest







PostPosted: Mon Jul 19, 2004 7:16 am     Reply with quote

When I learned at uni we looked at the amount of processes involved in Math functions, a division takes somewhere aound two - four times as many clock cycles to complete, so a multiplication is more efficient,

if the turbine is high speed these few extra milli seconds might make all the difference.

I'm not sure of the exact capabilities of the 16f877 but we did something simillar for a uni project on a motorolla 16hc11.

as a low speed we measured Timer over flow flags an made a heart rate monitor, (rate is circa 60 - 150 BPM anything over or under is measured for a while and critical status can be reported, but in extreemes no measurement takes place)
as a high speed application we made a fuel injection system taking throttle positions on an ADC and measuring engine speed to determine a duty cycle, in this case there were two possible ways to complete the task.
The first was to use the Timer output capture to make an interrrput driven system, in this way when a pulse comes from the crank shaft a timer is stopped and a speed can be measured, this can only measure high speeds.

a second method is to count both clock over flows and clock ticks, in this way both fast and slow speeds can be measured (0 - ~2Mhz).

depending on the speed of theo turbine will depend on the speeds that the code needs to excecute.

(i'm thinking of registering, I've been posting as a guest for a week now, and everyone seems quite nice and helpfull here abouts!)
Not yet registered
Guest







PostPosted: Mon Jul 19, 2004 7:17 am     Reply with quote

that should have said motorolla 68HC11.
(getting confused with the Microchip PICS I'm using now)
Definitly must register so I can at least edit my own posts!
Ttelmah
Guest







Re: Efficient and fast math?
PostPosted: Mon Jul 19, 2004 8:39 am     Reply with quote

SherpaDoug wrote:
Most of Ttelmah's ideas are good. I would definately scale things so I could use fixed point arithmatic. But he lost me at
[quote="Ttelmah]
60000000.0/(float)CCP_value
Next, the 'second comment' then applies, and you could instead use:
1.666667E-8 * (float)CCP_value.

(maybe it is just Monday morning). But the important thing is to make sure YOU understand the code you are using.[/quote]
Sorry.
I was missing out part of my 'thinking' here, and it made a right b*&%'s up of what I posted. :-)
It depends massively on the chip, and the algorithms used. I happened to be working a while ago, on a chip that had a very efficient 'reciprocal' function. On this, it was more efficient to code as:
1/(1/x*y), than to code for x/y.
I carefully managed to leave out the reciprocal, and have not looked at the relative efficiency of this function in CCS C. I doubt if they seperately code it, so in which case the gain will not exist...

Best Wishes
astus



Joined: 17 Nov 2003
Posts: 12
Location: Australia

View user's profile Send private message Visit poster's website

PostPosted: Mon Jul 19, 2004 11:15 pm     Reply with quote

Thanks for the helpful responses

I was actually using the first method suggested by Ttelmah, it takes about 1.3ms (depending on values) at a clock spped of 4Mhz (1us clock). I haven't tried the double reciprocal thing I will test it and get back to you on that one. The integer method seems interresting but I'd have to change my clock freq or add a new oscillator in to drive the timer 1 module (Possibility in next revision).

Oh, Kypec the turbine runs from ~1000 to 150,000 RPM (Fast) currently I use the ccp and timer 1 module. After the turbine reaches idle (~35000 RPM) I then capture every 16th edge from the shaft. To keep the resolution high I only use the RPM function on the LCD screen. The turbine control algorithm uses the captured value from the ccp.

If anybody was wondering I'm working on a turbine controller for a small jet engine used in the hobby model aircraft area.

Thanks Again

Adam
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group