simple_ping.pde (1585Bytes)
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?
** First of all, I’have never**
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 ’ inches100
and you have 2 digits precision.
Ah, thanks Runaround. The
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
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.
"" on arduino ?**
guys at parallax are using the ** operator, which is a multiplication by 1/65536 in one operation
is there any equivalent on arduino?
bitwise division
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.
Rik
Thanks Rik, nice explanation
Thanks Rik, nice explanation of what the bit shifting can do. Im 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.