View previous topic :: View next topic |
Author |
Message |
hayee
Joined: 05 Sep 2007 Posts: 252
|
Calculations are too long,how to reduce it |
Posted: Wed Mar 02, 2011 6:11 am |
|
|
I want to do some kg calculations using pulses at interrupt.
Total kg should look like that
Code: |
total_kg_i=kg8i+kg7i+kg6i+kg5i+kg4i+kg3i+kg2i+kg1i;
|
what i am currently doing is that whenever interrupt comes it increament the variable kg1,when kg1>9 then kg1 becomes 0 and there is an increament in kg2 variable. when kg1 again >9,kg1 becomes 0 and increament in kg2 and it continues,when kg2>9, kg2 becomes 0 and kg3 increamented and it continues till kg8>9
then i am calculating total kg like that
Code: |
kg1i=kg1*1;
kg2i=kg2*10;
kg3i=kg3;
kg3i=kg3i*100;
kg4i=kg4;
kg4i=kg4i*1000;
kg5i=kg5;
kg5i=kg5i*10000;
kg6i=kg6;
kg6i=kg6i*100000;
kg7i=kg7;
kg7i=kg7i*1000000;
kg8i=kg8;
kg8i=kg8i*10000000;
total_kg_i=(kg8i)+(kg7i)+(kg6i)+(kg5i)+(kg4i)+(kg3i)+(kg2i)+(kg1i);
|
i declared variables like that
Code: |
int kg1=0,kg2=0,kg3=0,kg4=0,kg5=0,kg6=0,kg7=0,kg8=0;
int kg1i,kg2i;
long kg4i,kg3i;
int32 kg5i,kg6i,kg7i,kg8i;
int32 total_kg_i=0;
|
But it takes too much memory.Is there anyother way to calculate the total kg
Hope you guys understand wht i wrote above. |
|
|
Wayne_
Joined: 10 Oct 2007 Posts: 681
|
|
Posted: Wed Mar 02, 2011 6:19 am |
|
|
Why arn't you just incrementing total_kg_i in the interrupt ?
total_kg_i++; |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9244 Location: Greensville,Ontario
|
|
Posted: Wed Mar 02, 2011 6:24 am |
|
|
Maybe I'm not looking at it right but isn't the total kg EQUAL to the number of pulses ? |
|
|
hayee
Joined: 05 Sep 2007 Posts: 252
|
|
Posted: Wed Mar 02, 2011 6:24 am |
|
|
I am not using it because whenever kg2>9, i have to give pulse
Thats why. |
|
|
hayee
Joined: 05 Sep 2007 Posts: 252
|
|
Posted: Wed Mar 02, 2011 6:32 am |
|
|
@temtronic
Its a sort of totalizer.
the first two variables kg1 and kg2 are the fractional part and rest of the variables are integer part.i am dealing the kg1 and kg2 also in interger.
whenever kg2 overflow then the pulse is generated,which indicates that 1 kg is filled
Total kg is like that for example=758963.28
But i using the format =75896328 merge the fractional part. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9244 Location: Greensville,Ontario
|
|
Posted: Wed Mar 02, 2011 6:41 am |
|
|
If I read it right and think of it as a car's odometer, everytime it goes exactly xxxx1.99 to xxxx2.00, xxxx2.99 to xxxx3.00, you want to send a pulse.
If so, you can still just increment the kgtotal in the isr.
Do the following comparison
in 'pseudo code'
If(int(kgtotal)/100= kgtotal/100) then sendpulse()
There's probably some C function that'll do this,but I've done this for years in Quickbasic.
hth
Jay |
|
|
SherpaDoug
Joined: 07 Sep 2003 Posts: 1640 Location: Cape Cod Mass USA
|
|
Posted: Wed Mar 02, 2011 6:47 am |
|
|
Could you keep all the kgx and kgxi numbers as ints and use:
total_kg_i=((((((((((((((int32)kg8i*10)+kg7i)*10)+kg6i)*10)+kg5i)*10)+kg4i)*10)+kg3i)*10)+kg2i)*10)+kg1i;
This way only one value is an int32, which should save space and might save time too. _________________ The search for better is endless. Instead simply find very good and get the job done. |
|
|
hayee
Joined: 05 Sep 2007 Posts: 252
|
|
Posted: Wed Mar 02, 2011 6:50 am |
|
|
i am increamenting mechanical counter by sending pulse.
Quote: |
If(int(kgtotal)/100= kgtotal/100) then sendpulse()
|
I didnt understand it,Plz tell me again.
totalkg is a 32 bit interger.as you can see in the declared variables. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9244 Location: Greensville,Ontario
|
|
Posted: Wed Mar 02, 2011 7:34 am |
|
|
Hmm.. oops, I'm so used to FP numbers in bigger processors....
Ok, how about something like...
using the DIV(); function
See the CCS C manual on it's use,
div_t idiv;
ldiv_t lidiv;
idiv=div(3,2);
//idiv will contain quot=1 and rem=1
lidiv=ldiv(300,250);
//lidiv will contain quot=1 and rem=50
something like
lidiv=ldiv(kgreading,100);
if(rem==0) sendpulse();
may work for you.
Basically you want a function and test that if kgreading/100 does NOT have a remainder, send a pulse? |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Wed Mar 02, 2011 7:35 am |
|
|
Quote: | This way only one value is an int32, which should save space and might save time too. |
You mean, there's only one explicite int32 variable, but all calculations are 32 bit anyway. They don't need
to be, because values up to the fourth digit fit int16, as the original poster had already in his code.
For this reason, the original code is executing 1/3 faster than yours. It can be still speeded up by removing
intermediate variables and by using shift left/add instead of library multiply with constant 10, which takes
most of the execution time. |
|
|
SherpaDoug
Joined: 07 Sep 2003 Posts: 1640 Location: Cape Cod Mass USA
|
|
Posted: Wed Mar 02, 2011 8:08 am |
|
|
The original post said he was primarily running out of memory. Using
total_kg_i=((((((((((((((int32)kg8i*10)+kg7i)*10)+kg6i)*10)+kg5i)*10)+kg4i)*10)+kg3i)*10)+kg2i)*10)+kg1i;
should only take one or two 32 bit variables, which SHOULD save quite a few bytes or RAM. _________________ The search for better is endless. Instead simply find very good and get the job done. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19545
|
|
Posted: Wed Mar 02, 2011 8:08 am |
|
|
Realistically, why not just have two variables.
A main 'counter', and a counter for the pulse.
So:
Code: |
int32 total_kg=0;
//Then in the int
static int8 pulse_ctr=9;
if (pulse_ctr) --pulse_ctr;
else {
//generate pulse here
pulse_ctr=9;
}
total_kg++;
|
Decrementing an 8 bit counter, takes a couple of machine cycles. Testing it for zero about the same. Incrementing an int32, only about 15 machine cycles. A single division by ten, takes nearly 1200 machine cycles, and a multiplication 354...
Alternatively, you can code '*10', much more efficiently, as
val*2+val*8
The compiler 'knows' to code binary multiplications (*2,4,8 etc.), as shifts, and doing *10 this way is probably about 5* as fast as the simple multiplication.
Best Wishes |
|
|
Wayne_
Joined: 10 Oct 2007 Posts: 681
|
|
Posted: Wed Mar 02, 2011 8:52 am |
|
|
Ttelmah wrote: | Realistically, why not just have two variables.
A main 'counter', and a counter for the pulse.
So:
Code: |
int32 total_kg=0;
//Then in the int
static int8 pulse_ctr=9;
if (pulse_ctr) --pulse_ctr;
else {
//generate pulse here
pulse_ctr=9;
}
total_kg++;
|
|
I totally agree but I think it needs to be changed so
pulse_ctr = 99;
in both places as the pulse is on the role over of kg2. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19545
|
|
Posted: Wed Mar 02, 2011 3:34 pm |
|
|
Agreed. I thought he was looking for a pulse every ten counts, but looking though, it is when the hundredth of Kg rolls over as you say.
Best Wishes |
|
|
hayee
Joined: 05 Sep 2007 Posts: 252
|
|
Posted: Wed Mar 02, 2011 10:50 pm |
|
|
Thanks alot guys for your suggestions.
Why I am not incrementing it in a single variable because I am also showing that result on 7-segment LCD like use in fuel dispensers. (7-segment LCD consist of 6-digit and I require 8 so I use 2 7-segment LCD).
The design of the LCD is like that I can't send a whole variable total kg, I have to break it into 8 variables and send, that's why I am using this pattern also I have to store the value in eeprom after the process finish.
Why I am calculating total kg is because I want to do like that
total kg = total kg -1
Then again break the new total kg into 8 variables and send it to LCD and after completing the process store it into eeprom.
total kg = total kg -1 is not requires always but at certain conditions.
Maybe I fail to tell you guys the exact theme of the project.
I have done all the processing and it is working fine and I am going to minimize the code because it is consuming lot of ROM.
Any suggestions. |
|
|
|