C code review for SF02 Laser Rangefinder to Propeller
Ken Gracey
Posts: 7,392
Hello,
If anybody ever felt afraid to post, I'm here to pave the way for you. From time to time I show off my own programming "skills" on behalf to the many people I encounter who might be afraid to post on our forums. I've only learned to program a little bit of C thanks to Andy's tutorials and a couple of recommended books, but I never make enough time to evolve the skill. I do have the interest, however.
I decided to work from home today and experiment with the SF02 Laser Rangefinder (http://www.lightware.co.za/shop/en/lrf-modules/7-sf02f.html), a 0-40m sensor that seems to work flawlessly. Little seems to bother this sensor: smoke, wind, angle of reflection, or sunlight. Considering limitations of ultrasonic, infrared, beacons and everything else I've used, this is the cat's meow and I can imagine it being useful on UAVs and outdoor robots. I'm just a little concerned that Erco won't be buy one at $349, however. But for those willing, this sensor appears to be worth every dollar!
The Lightware Terminal software lets me configure the hardware's analog output, so I made 0.0 m = 0.0V and 40.0 m = 3.3V.
I need some review of my C code. I'm trying to produce a simple analog input example with the Propeller Activity Board's A/D converter. My code is below:
The datasheet states the resolution to be 1 cm, 12 readings/second with accuracy of +/-(0.1 +1%) m. In my code example I'm claiming a huge number of significant digits and I'd like the example to show the right calculation, which I think is to a hundredth of a meter. Is this correct, and what's the right way to show the math routine in C with only two sig digits?
By the way, I really love having access to the floating point library.
Thanks,
Ken Gracey
If anybody ever felt afraid to post, I'm here to pave the way for you. From time to time I show off my own programming "skills" on behalf to the many people I encounter who might be afraid to post on our forums. I've only learned to program a little bit of C thanks to Andy's tutorials and a couple of recommended books, but I never make enough time to evolve the skill. I do have the interest, however.
I decided to work from home today and experiment with the SF02 Laser Rangefinder (http://www.lightware.co.za/shop/en/lrf-modules/7-sf02f.html), a 0-40m sensor that seems to work flawlessly. Little seems to bother this sensor: smoke, wind, angle of reflection, or sunlight. Considering limitations of ultrasonic, infrared, beacons and everything else I've used, this is the cat's meow and I can imagine it being useful on UAVs and outdoor robots. I'm just a little concerned that Erco won't be buy one at $349, however. But for those willing, this sensor appears to be worth every dollar!
The Lightware Terminal software lets me configure the hardware's analog output, so I made 0.0 m = 0.0V and 40.0 m = 3.3V.
I need some review of my C code. I'm trying to produce a simple analog input example with the Propeller Activity Board's A/D converter. My code is below:
[FONT=courier new]/* SF02 Distance - Analog.c Display analog output voltage and distance from SF02 Laser Rangefinder connected to Propeller Activity Board (PAB). SF02 configured using Lightware software 0.0V = 0.00 m and 3.3V = 40.0 m. SF02 PAB ==== ==== 2 GND 3 5V 4 GND 7 A/D0 */ #include "simpletools.h" // Include simpletools #include "adcDCpropab.h" // Include adcDCpropab int main() // main function { adc_init(21, 20, 19, 18); // CS=21, SCL=20, DO=19, DI=18 float v0, meters; // Voltage and distance variables while(1) // Repeat { v0 = adc_volts(0); // Check A/D 0 meters = 12.12*v0; // 40.00m / 3.3V = 12.12V/m putChar(HOME); // Cursor -> top-left "home" print("Lightware SF02 to Propeller Activity Board \n"); print("A/D0 = %f V%c\n", v0, CLREOL); // Display volts print("Distance = %f m%c\n", meters, CLREOL); pause(100); // Wait 1/10 s } }[/FONT]
The datasheet states the resolution to be 1 cm, 12 readings/second with accuracy of +/-(0.1 +1%) m. In my code example I'm claiming a huge number of significant digits and I'd like the example to show the right calculation, which I think is to a hundredth of a meter. Is this correct, and what's the right way to show the math routine in C with only two sig digits?
By the way, I really love having access to the floating point library.
Thanks,
Ken Gracey
Comments
Unfortunate, I do not speak C, (yet), but it looks like a great potential product, (hang it off the bottom of a Elev-8 for precise landings).
Ken Gracey
You never took a C programming class?
Thanks Cody! If I could paraphrase what your example does, would this be correct?
- with a 0-5V A/D and 12-bit A/D, we get 2703 samples over 0-3.3V
- you worked in all positive numbers, fixed point, multiplying by 10,000
- whole digit and remainder were handled separately, so no floating point library required
But, what if I wanted to use floating point and I want to display the output to only two significant digits? Is there a way to format the output in this line:
print("Distance = %f m%c\n", meters, CLREOL);
To include only two significant digits?
Thanks,
Ken Gracey
Oh, you're back with that question again. . .how do I reply to this inquiry? No, but I bought this little colorful book http://ineasysteps.com/products-page/all_books/c-programming-in-easy-steps-4th-edition-2/ and it seemed to be suitable for my goal of developing enough background to be barely functional. While nobody should discount the value of an actual course, I really need to learn this on my own with web resources around me. I can't make the time to go to and from a college to take such a class at this stage.
Ken Gracey
Thanks Dave! Now I have two ways of doing the same thing, with and without floating point. This little example is very useful to me.
Ken Gracey
That way you get to test the Parallax offering to see if it helps you as an entry level student.
You've done pretty good so far.
It's nice that Cody (SRLM) demonstrates floating point is not really necessary in such an application. People tend to jump on floating point only because it's possible.
Yeah, people like me. For such an application I'm happy to waste resources as much as I want to make it simple.
Bloated code oinker I am.
Ken Gracey
What it does is assume that the number in the `meters` variable is in units of 1/10,000th of a meter. We've fixed the point at 4 decimal places. Therefore, to extract the characteristic (the portion before the point) we get rid of the first 4 digits of the number. To the decimal portion we get rid of the characteristic.
An example. Suppose that the reading came back as 1274. If each bit represents 0.014798m, then the current distance reading is 18.852m. But rather than multiply by the float 0.014798, we multiply by 148 to get 188552. This number is now in units of 1/10000th of a meter. For human consumption we can extract the characteristic by dividing by 10000 (=18) and the decimal remainder by taking the modulus (=8552). For algorithm consumption we might as well leave it as an integer.
Note that the entire distance value is handled in a single number. Normally, when we work with integers, we assume that the decimal place is on the right hand side after the last digit. But, with fixed point, we treat it as if the decimal place is some number of digits to the left.
Remember that significant digits has a specific scientific meaning. What I think you're really asking for is how to limit it to a specific number of digits after the decimal point. In that case, you would simply take the decimal portion and divide by 10,100, or 1000 for 1,2, or 3 digits.
ps: Are you going to carry their products in your store?
Thanks Cody. Now I understand the example completely.
Yes, we have these SF02 units in stock at Parallax and they'll be available in the web shop this week.
Ken Gracey