Let's Make Robots!

Float variables?

Last night I put together a quick demo sketch to test out my shiny new Parallax Ping, which I'll be equipping to my next robot.  I downloaded the code from arduino.cc and with my rusty C programming skills it was easy enough to convert it to a simple demo program that lights up an LED.  However, I make use of floating variables, and I was wondering if that slowed it down significantly enough to matter.  The program works like a champ, which I'm happy about, but I'm also one who likes code to be as optimized as possible.  Can someone take a look at my sketch and let me know if the "float"s are a problem?
simple_ping.pde1.55 KB

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

 First of all, I'have never programmed arduino. But I try to help you, if possible.

pulseIn returns an unsigned long.

ultrasoundValue = (echo / 58.138) * .39

i.e. ultrasoundValue = (echo * 1000 / 58138) * 39 /100 == echo *39000/5813800 == echo *390/58138

 So: declare pulseIn as unsigned long not float and simplify ultrasoundValue expression.

ultrasoundValue can be a int: for example 

ultrasoundValue = echo *39000/58138 ' inches*100

and you have 2 digits precision.

Ah, thanks Runaround.  The original code made it an unsigned long, but I changed it since I thought he was only doing it that way to write to the serial port.

My tip would be to don't do any of those conversions at all. Your bot doesn't need to know how many inches away from a surface it is, it only needs a number proportional to that distance. It may make the code somewhat more involved to write and read, but if you make a graph or table over bits/inch you're set.

For lightning fast code avoid divisions by anything other than a power of 2 at all cost. If theres no way around it consider approximations. I seem to remember the boards at avrfreaks had a good thread on the subject.

Edit: And yes; using floating-point arithmetic will slow down the program by several orders of magnitude. At least when programming a "raw" atMega with C, never used the Arduino bootloader either. But I can't imagine this being any different - the hardware simply isn't there.

guys at parallax are using the ** operator,  which is a multiplication by 1/65536 in one operation

is there any equivalent on arduino? 

The reason dividing by two (or a power of two) is so efficient on a binary computer is the same reason why you and I are so rock steady fast at dividing by ten (or a power of ten) on our decimal brains.

Two in the binary number system is written as "10".

And so is ten in the decimal number system.

All this leads up to this: dividing by "10" is the same as shifting all the digits in a number to the right. Once. Dividing by "100" moves all the digits two positions. And so on. You know the trick. You've been doing it in the decimal system since your first school days. Computers do it the same way, but in a different number system.

Now for the computer bit (dang! punned myself without realising!).

In binary, the position shift has its own operators. In C (and therefore in many Arduino languages) those operators are >> and <<. Just guess which way they shift bits.

Dividing by 65536 (decimal) or 10000000000000000 (binary: that's 16 zeros) would amount to shifting the integer 16 binary positions. Use this code to divide lotsacandy over 65536 kids:

perkid = lotsacandy >> 16

There is no remainder! The result will also be an integer. All spilled bits are wasted. Shifted into oblivion.


Thanks Rik, nice explanation of what the bit shifting can do. I`m starting to delve into programming some avrs with C and didn`t really know what it did or why I would want to use it.
Just to add in here, the floating point library adds another 11kb or so to program size, which is terribly inefficient. I don't know if the arduino has it's own lib for that, but for plain AVR's that's how it goes.