Go Down

Topic: Floating point math (Read 2777 times) previous topic - next topic

skyjumper

Hi All...

I'm working on an application that requires a lot of floating point math, in particular the use of trig functions like sin(), cos(), tan() and so on. The Arduino Duemilanove seems to meet my requiremens from some other perspectives. For example, it runs on a 12VDC battery and I can get one with a DB9 connector and RS232 serial.

I see it has either an ATmega168 or ATmega328 CPU. I don't need to do my caculations super fast. I'll be reading a serial data stream at 4800 baud. Will these CPUs be able to handle something like this? Iys a lot of math, but I have a lot of time to do it.

Thanks...


jraskell

The Arduinos are capable of both floating point math and trig functions.  They are relatively slow, but if you have the time, they will work.

skyjumper

That's great news, thanks! I need to do several dozen caculations in a second, so I probably have the time, and lots more to spare.

jraskell


That's great news, thanks! I need to do several dozen caculations in a second, so I probably have the time, and lots more to spare.



You could easily do several thousand calculations per second more than likely.

cachehiker

Even when programming far more powerful processors, I bend over backwards to arrange my algorithms to minimize floating point due to it's relative impact on speed, especially trig and log functions. It's an old school habit. Heck, you'll even see division involving two long integers minimized in much of my code.

Several dozen per second ? 14 milliseconds each. I could see the Arduino handling that. I could also see the Arduino struggling to handle any other tasks being performed at the same time.

Several thousand per second ? 170 microseconds each. I'm from Missouri. Show me.

I, for one, hope SJ posts his results. They could come in very handy for one of my upcoming projects. If the floating point division doesn't carry as much of a penalty as I'm suspecting, I won't have to resort to clever tactics to reduce a near real time speed measurement problem to long integer division.

gardner

I think people underestimate the speed of Arduino.  At 16Mhz and mostly one instruction per cycle, Arduino will run rings around an old Apple 2 or CPM box or even a PDP-11 that folks did all kinds of significant work on.  The limits of Arduino as a compute platform are mainly due to the amount of RAM available, which is puny in the extreme.

The good folks who built AVR-GCC and AVR-LIBC didn't bother to give us long floats though, so you have to make do with single floats.  If you are REALLY in a hurry, it's possible to do a lot with fixed point, and I have seen some nice work on fixed point libraries for AVR. http://sourceforge.net/projects/avrfix/

westfw

Enough philosophy.  There are a thousands of people with Arduino reading these postings; give us a better idea what your calculations need to be, and someone will try it out.

I get about 2300 "cos()" and associated operations with the following example:
Code: [Select]

volatile float d;
void loop (void)
{
  unsigned long opcount = 0;
  unsigned long starttime = millis();

  while (millis() - starttime < 1000) {
    float b,c;

    b = (float) random(100);
    c = (float) random(72);
    d = cos(b/c);
    opcount++;
  }
  Serial.println(opcount);
}

PaulS

Quote
give us a better idea what your calculations need to be, and someone will try it out.

The baud rate mentioned (4800) is typical for a GPS. Looks to me like OP is trying to read from a GPS and determine direction and distance to a target with some degree of speed.

pluggy

Think similar similar order of magnitude power to what put man on the moon in 1969......  (Primitive and slow in other words.)
http://pluggy.is-a-geek.com/index.html

cachehiker

#9
Feb 02, 2011, 07:09 pm Last Edit: Feb 02, 2011, 09:01 pm by cachehiker Reason: 1
I get about 2300 "cos()" and associated operations with the following example: ...


That's fast! Thanks for the info. I was personally expecting something around 500.

Still, 2300/several dozen operations = about a 30ms floor for the loop execution speed. Add some string processing, serial communications, or an LCD display could easily slow things up quite a bit more.

My upcoming project will require an overall loop speed below 10ms, a little interrupt driven pulse timing accurate to within 250┬Ás, and just a few floating point operations to calculate results for the display. I think this puts that well within reach.

Arduino will run rings around an old Apple 2 or CPM box or even a PDP-11 that folks did all kinds of significant work on.


Hehe, I cut my teeth programming on the successor to the PDP-11.  XD

BetterSense

#10
Feb 02, 2011, 07:49 pm Last Edit: Feb 02, 2011, 07:51 pm by BetterSense Reason: 1
For the benefit of us noobulars, what are some techniques for converting floating point calculations into integer? Simply multiply the floats by 10^(number of decimal places desired), truncate them, and then go to town with integer math?

What about avoiding trig functions? I know that for many tasks, you can use the small angle approximation, and you can also break the trig  function into its series and use the first couple terms.

I'm just confused about arranging algorithms to avoid using floats because it seems like if you are using floats, you need them.

Fletcher Chr

Hi

For raw cos(x) I get around 8900 loops/sec preformance.

Code:
Code: [Select]
float a=0.5;
long bigNumber = 100000;
unsigned long time1, time2, diff;

void setup(){
  Serial.begin(9600);
  time1 = millis();
  for (int i=0; i<bigNumber;i++){
    a = cos(a);
  }
  time2 = millis();
  diff = time2-time1;
  Serial.print(diff);Serial.print(" millisec for numbers of loops: ");Serial.println(bigNumber);
  a = 1.0*bigNumber/diff*1000;
  Serial.print(a); Serial.println(" loops/sec");
}

void loop(){
}


Output:
11229 millisec for numbers of loops: 100000
8905.51 loops/sec


I guess there is a convagens to a=0.739... but the cos() calculation is still forced at every loop.

-Fletcher

Go Up