Go Down

Topic: Problem with performing fractions with Arduino UNO R3 (Read 1 time) previous topic - next topic

Cristian_C

Hello everyone,
I tried to perform some calculations, in particular fractions, to evaluate the speed knowing the position (from a sensor) at different times.

Code: [Select]
CurrentTime=millis();
  float Vobst= long(PrevDist-CurrDist)/(long(CurrentTime-PrevTime))*1000;
  Serial.print ("ingresso= ");
  Serial.println(analogRead(A0));
  //Serial.println(pow(analogRead(A0),(-1,26)));
  Serial.print ("Distanza= ");
  Serial.print (CurrDist);
  Serial.print("[mm] \t Velocità=");
  Serial.print(Vobst);
  Serial.println("[mm/s]");
  Serial.print("current time=");
  Serial.print(CurrentTime);
  Serial.print("[ms]  previous time=");
  Serial.print(PrevTime);
  Serial.println("[ms]");
  Serial.print(long(PrevDist-CurrDist));Serial.print("/");Serial.print(CurrentTime-PrevTime);
  if((PrevDist-CurrDist)<0){
    calc=-1.0*((float(CurrDist-PrevDist))/long((CurrentTime-PrevTime)));
  } else {calc=(float(PrevDist-CurrDist))/long((CurrentTime-PrevTime));}
  Serial.print("=");Serial.println(calc);
   Serial.print("0-1="); Serial.println(0-1);
 
  Serial.println("");
[/size]

As it is possible to see in the following print out of serial monitor, if the 2 operands are both positive, there are no problems. If one is negative, it seems to go in overflow and gives unreliable values.
Quote
ingresso= 106

Distanza= 609[mm]     Velocità =191000.00[mm/s]

current time=5000[ms]  previous time=4999[ms]

191/1=191.00

0-1=-1



ingresso= 111

Distanza= 617[mm]     Velocità =0.00[mm/s]

current time=10071[ms]  previous time=5000[ms]

-8/5071=846966.56

0-1=-1



ingresso= 113

Distanza= 551[mm]     Velocità =0.00[mm/s]

current time=15142[ms]  previous time=10071[ms]

66/5071=0.01

0-1=-1



ingresso= 95

Distanza= 741[mm]     Velocità =0.00[mm/s]

current time=20210[ms]  previous time=15142[ms]

-190/5068=847467.87

0-1=-1
[/size]

Anyone had the same problem?
I tried several times to change formats from long to float and to double. But I didn't notice any improvement or different results. Everytime one operand becomes negative, the value is positive and very high.

If anyone had and solved this problem, could please help me?[/size]

marco_c

You need to post all the code because you probably have problems with your variable definitions. For a start you are casting to long and float when you are printing and calculating, which may give you diferent results.
Arduino Libraries http://arduinocode.codeplex.com
Parola for Arduino http://parola.codeplex.com

Tom Carpenter

#2
Jul 25, 2012, 11:24 am Last Edit: Jul 25, 2012, 11:25 am by TCWORLD Reason: 1
Code: [Select]
calc=-1.0*((float(CurrDist-PrevDist))/long((CurrentTime-PrevTime)));
You are doing a float divided by a long. In which case it won't use floating point division. Try something like this:
Code: [Select]
unsigned long timeDifference = CurrentTime - PrevTime;
unsigned long distanceChage = CurrDist - PrevDist;
calc = -((float)distanceChage/(float)timeDifference);


The same goes for this one:
Code: [Select]
float Vobst= long(PrevDist-CurrDist)/(long(CurrentTime-PrevTime))*1000;
And this one:
Code: [Select]
calc=(float(PrevDist-CurrDist))/long((CurrentTime-PrevTime));

As you are doing pretty much the same calculation 3 times, you could simplify the calculation by finding 'calc' at the start, just after millis. Then 'Vobst' is simply 1000.0 times it.
~Tom~

PaulS

Quote
You are doing a float divided by a long. In which case it won't use floating point division.

Yes, it will. What makes you think it won't?

Tom Carpenter

I guess I misunderstood how it decides whether or not to use floating point division. Nevermind.
~Tom~

gardner


if the 2 operands are both positive, there are no problems. If one is negative, it seems to go in overflow and gives unreliable values.
Quote

-190/5068=847467.87



This is a clue.  -190 is 2^32 - 190 + 1, if you were to cast it to an unsigned long.  (2^32 - 190 + 1) / 5068 = 847,467.8 as you get here.  Given we can't see your code, my guess is that wherever -190 comes from, it is being converted to an unsigned long somewhere before being cast to a float for the division.

Cristian_C

Hello everybody,
I'm quite new with Arduino and programming with C-like code. So probably I made some mistakes in assigning of variables formats.

Following the complete code. I know that is performing 3 times the same calculation, but during the test of the distance sensor I noticed that something was wrong, so I decided to print out as much as possible and see where the problem arises.
So I started with declaring all variables unsigned long. And then after seeing that the results had no sense I decided to declare variables as float.

Code: [Select]
unsigned long CurrDist;
unsigned long PrevDist;
unsigned long CurrentTime;
unsigned long PrevTime;
unsigned long Vobst;
float calc;

void setup() {
  Serial.begin(9600);
  Serial.println("Ready");
  delay(5000);
  PrevDist=800;
  PrevTime=millis();
}
void loop(){
    int in=analogRead(A0);
  if (in<=81) {CurrDist=800;}
  else if (in<=122){CurrDist=800-0.7317*(in-81)*10;}
  else if (in<=143){CurrDist=500-0.4762*(in-122)*10;}
  else if (in<=184){CurrDist=400-0.2439*(in-143)*10;}
  else if (in<=225){CurrDist=300-0.1220*(in-184)*10;}
  else if (in<=266){CurrDist=250-0.1220*(in-225)*10;}
  else if (in<=327){CurrDist=200-0.0820*(in-266)*10;}
  else if (in<=471){CurrDist=150-0.0347*(in-327)*10;}
  else if (in<=563){CurrDist=100-0.0217*(in-471)*10;}
  else if (in<=604){CurrDist=80-0.0244*(in-563)*10;}
  else if (in<=645){CurrDist=70-0.0244*(in-604)*10;}
  else {CurrDist=55;}

  CurrentTime=millis();
  float Vobst= long(PrevDist-CurrDist)/(long(CurrentTime-PrevTime))*1000;
  Serial.print ("ingresso= ");
  Serial.println(analogRead(A0));
  //Serial.println(pow(analogRead(A0),(-1,26)));
  Serial.print ("Distanza= ");
  Serial.print (CurrDist);
  Serial.print("[mm] \t Velocità=");
  Serial.print(Vobst);
  Serial.println("[mm/s]");
  Serial.print("current time=");
  Serial.print(CurrentTime);
  Serial.print("[ms]  previous time=");
  Serial.print(PrevTime);
  Serial.println("[ms]");
  Serial.print(long(PrevDist-CurrDist));Serial.print("/");Serial.print(CurrentTime-PrevTime);
  calc=(float(PrevDist-CurrDist))/long((CurrentTime-PrevTime));
  Serial.print("=");Serial.println(calc);
   Serial.print("0-1="); Serial.println(0-1);
 
  Serial.println("");
 
  PrevDist=CurrDist;
  PrevTime=CurrentTime;
  delay(5000);
}


The thing that seem very strange to me is that even for small negatives values the problem occurs:
Quote
-8/5071=846966.56


Thanks in advance[/size]

Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy