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

calculation in CCS C

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



Joined: 23 May 2004
Posts: 48

View user's profile Send private message

calculation in CCS C
PostPosted: Thu Jun 24, 2004 3:47 pm     Reply with quote

I would like to compute this formular in 16F876:

Code:
delta = (pos_motion*acceleration/velo_motion)*(pos_motion*acceleration/velo_motion) - 4*pos_motion*acceleration;


pos_motion, velo_motion are SIGNED LONG numbers, and acceleration is defined as 5.

delta is forced as float number, and I gave constants to pos_motion and velo_motion to printf to pC for testing. However, I get wrong results.

pos_motion = 10000;
velo_motion = 50;

the result should be 800,000; but I cannot get it.

May someone explain me about this? How the C code compute in this case? will it be overflow as computing?
rnielsen



Joined: 23 Sep 2003
Posts: 852
Location: Utah

View user's profile Send private message

PostPosted: Thu Jun 24, 2004 4:00 pm     Reply with quote

You're probably getting hit by the priorities that these calculations are using. Try:

delta = (((pos_motion*acceleration)/velo_motion)*((pos_motion*acceleration)/velo_motion)) - (4*pos_motion)*acceleration;

Note where the parenthesis are located.
falleaf



Joined: 23 May 2004
Posts: 48

View user's profile Send private message

PostPosted: Thu Jun 24, 2004 4:19 pm     Reply with quote

Thanks rnielsen, I'll try.

by the way,

what will happen if I force the format number as:

beta = (signed long) delta;???

will it save the high bytes of result as normal, or what will it do?
Neutone



Joined: 08 Sep 2003
Posts: 839
Location: Houston

View user's profile Send private message

PostPosted: Thu Jun 24, 2004 5:14 pm     Reply with quote

Technically what you are attempting to do should work but it's a good practice to spread the computation over several lines. Use signed math only where you have to. You might as well declare and use some intermediate variables. If you don't you the compiler will it has to.
falleaf



Joined: 23 May 2004
Posts: 48

View user's profile Send private message

PostPosted: Thu Jun 24, 2004 5:35 pm     Reply with quote

I have to compute in signed format number because it's the motion control, and it may take negative values.

as using asm, to express a negative number, I take out a bit of direction, and compute with positive ones. But if do this with C, i'm afraid that it will generate longer codes, and no need to do so.

Code:
velocity_temp = (((pos_motion*acceleration)/velo_motion) - sqrt(delta))/2;


in this case, delta should be float, and velocity_temp should be float. I would like to get LONG format, and give it

velocity = (signed long) velocity_temp;
falleaf



Joined: 23 May 2004
Posts: 48

View user's profile Send private message

PostPosted: Fri Jun 25, 2004 1:26 am     Reply with quote

with pos_motion = 10000, velo_motion = 50; I got this

Code:
delta = 2.875000delta = 2.875000delta = 2.875000delta = 2.875000delta = 2.875000
delta = 2.875000delta = 2.875000delta = 2.875000delta = 2.875000delta = 2.875000
delta = 2.875000delta = 2.875000delta = 2.875000delta = 2.875000delta = 2.875000
delta = 2.875000delta = 2.875000delta = 2.875000


I use hyperterminal to get these results. I'm confused :((
Ttelmah
Guest







PostPosted: Fri Jun 25, 2004 2:31 am     Reply with quote

falleaf wrote:
with pos_motion = 10000, velo_motion = 50; I got this

Code:
delta = 2.875000delta = 2.875000delta = 2.875000delta = 2.875000delta = 2.875000
delta = 2.875000delta = 2.875000delta = 2.875000delta = 2.875000delta = 2.875000
delta = 2.875000delta = 2.875000delta = 2.875000delta = 2.875000delta = 2.875000
delta = 2.875000delta = 2.875000delta = 2.875000


I use hyperterminal to get these results. I'm confused :((


Remember that a 'signed long', only has a range of +32767 to -32768.
The very first part of the maths:
(pos_motion*acceleration/velo_motion)

starts by taking 10000*5 = 50000 -> allready overflowed.....

As others have said, _split_ the maths, and consider working only with unsigned values. If the motion is -ve, test for this before starting, and set a flag to say that this is true. Then you can perform this part of the arithmetic, with something like:
Code:

if (pos_motion<0) {
    pos_motion=-pos_motion;
    neg=true;
}
else neg=false;
temp=(int16)pos_motion*acceleration/velo_motion;
if (neg) temp=-temp;

Now in this case, I am assuming that only 'pos_motion' can be -ve, and the other values are allready declared as 'int16', with 'temp' declared as 'signed long'. Then the arithmetic is performed using unsigned maths, and the sign bit put back after the calculation has finished.
If you split the arithmetic up like this, you can work through the sections, and print the resuls to find which parts are causing problems.

Best Wishes
falleaf



Joined: 23 May 2004
Posts: 48

View user's profile Send private message

PostPosted: Fri Jun 25, 2004 3:51 am     Reply with quote

Oh, I tested with the program, and this is my code:
Code:

 float velocity_temp=0;
   float delta=0;
   signed long delta1=0;
   float delta2=0;

   if (velo_motion < 0)
   {
      velo_motion = - velo_motion;           // gan gia tri duong vao de tinh toan
      pwm_direction = 0;                     // cho quay theo chieu nguoc
   }
   else
   {
      pwm_direction = 1;                     // quay theo chieu thuan
   }

   printf("pos_motion = %ld", pos_motion);
   printf("acceleration = %u", acceleration);
   delta1 = (pos_motion* acceleration);
   delta2 = (float)delta1;
   delta2 = delta2/5;
   printf("delta2 = %f", delta2);
   delta = delta1*delta1 - delta2;

  printf("delta = %f",delta);


I change pos_motion = 1000;
and acceleration = 2
velo_motion = 30;

delta1 is right, and the result is 2000;
delta2 at the upper line is right, and it results 1999.9999991 (but not good)
but as I compute with division operator, it gets wrong values, and returns all stuff.. blah.. blah... cannot read.

I think this is the problem inside the compiler???

I'm using version 3.094 :(
falleaf



Joined: 23 May 2004
Posts: 48

View user's profile Send private message

PostPosted: Fri Jun 25, 2004 6:28 am     Reply with quote

I found the problem. We cannot do it with local variables, as I put it out as global variables, the program worked very good.

Thanks for all.
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