Revision 1475
linearize_distance() uses new LUT mapped for (4-30cm) rangefinders. Accuracy +/- 10mm. Need more testing to increase accuracy -- should be able to get +/- 5mm.
rangefinder.c | ||
---|---|---|
36 | 36 |
/* |
37 | 37 |
Authors: James Kong and Greg Tress |
38 | 38 |
|
39 |
Last Modified: 10/07/09 by Dan Shope
|
|
39 |
Last Modified: 10/30/09 by Dan Shope
|
|
40 | 40 |
-Revised LUT to match GP2D120X Sensors (4-30cm) |
41 | 41 |
-range_read_distance() now returns -1 for below lower bound, -2 for beyond upper bound |
42 | 42 |
|
... | ... | |
46 | 46 |
|
47 | 47 |
----------------- |
48 | 48 |
rangefinder.c |
49 |
Using Sharp GP2D120X IR Rangefinder
|
|
49 |
Using Sharp GP2D02 IR Rangefinder
|
|
50 | 50 |
|
51 | 51 |
Vin is the input to the rangefinder, designated RANGE_CTRL. |
52 | 52 |
Vout is the output from the rangefinder, designated RANGE_IN# where # is the rangefinder you are reading from |
... | ... | |
61 | 61 |
4.) Set Vin high for 2ms or more to turn off rangefinder |
62 | 62 |
|
63 | 63 |
*/ |
64 |
#include <avr/pgmspace.h> |
|
64 | 65 |
|
65 |
#include "dragonfly_lib.h" |
|
66 |
#include "dragonfly_defs.h" |
|
67 |
#include "analog.h" |
|
68 |
#include "dio.h" |
|
66 | 69 |
#include "rangefinder.h" |
67 | 70 |
|
71 |
unsigned char range_initd=0; |
|
72 |
|
|
68 | 73 |
/* |
69 | 74 |
read_distance returns the 8-bit reading from the rangefinder |
70 | 75 |
parameters: |
... | ... | |
89 | 94 |
10cm from the detector. See the datasheet for more information. |
90 | 95 |
*/ |
91 | 96 |
|
92 |
static int IR_dist_conversion[72] = { |
|
97 |
static int IR_dist_conversion[72] PROGMEM = {
|
|
93 | 98 |
327,315,303,291,281,271,262,253,245,238,231,224,218,212,206,200, |
94 | 99 |
195,190,185,181,177,173,168,165,161,158,155,151,148,145,143,140, |
95 | 100 |
137,134,132,130,127,125,123,121,119,117,115,114,111,110,108,106, |
... | ... | |
112 | 117 |
* |
113 | 118 |
* @see range_read_distance |
114 | 119 |
**/ |
115 |
void range_init(void)
|
|
120 |
int range_init(void)
|
|
116 | 121 |
{ |
122 |
if(range_initd) |
|
123 |
return ERROR_INIT_ALREADY_INITD; |
|
124 |
|
|
117 | 125 |
digital_output(_PIN_B4,0); |
126 |
|
|
127 |
range_initd=1; |
|
128 |
return 0; |
|
118 | 129 |
} |
119 | 130 |
|
120 | 131 |
/** |
... | ... | |
124 | 135 |
* @param range_id the rangefinder to use. This should be one |
125 | 136 |
* of the constants IR1 - IR5. |
126 | 137 |
* |
127 |
* @return the distance measured by the rangefinder |
|
138 |
* @return the distance measured by the rangefinder, or an error code
|
|
128 | 139 |
* |
129 | 140 |
* @see range_init |
130 | 141 |
**/ |
131 | 142 |
int range_read_distance(int range_id) { |
143 |
if(!range_initd) |
|
144 |
return -3; |
|
145 |
|
|
132 | 146 |
return linearize_distance(analog8(range_id)); |
133 | 147 |
} |
134 | 148 |
|
... | ... | |
136 | 150 |
* Transforms distance readings from logarithmic to linear scale. |
137 | 151 |
* This probably isn't the function you are looking for. |
138 | 152 |
* |
153 |
* Note: pgm_read_word() needs additional testing |
|
154 |
* |
|
139 | 155 |
* @param value the 8-bit analog value from rangefinder |
140 | 156 |
* |
141 | 157 |
* @return linearized distance reading from rangefinder (integer in [78,327]) |
142 |
* @return (-1) if below MIN_IR_ADC8
|
|
143 |
* @return (-2) if beyond MAX_IR_ADC8
|
|
158 |
* @return (-2) if below MIN_IR_ADC8
|
|
159 |
* @return (-1) if beyond MAX_IR_ADC8
|
|
144 | 160 |
**/ |
145 | 161 |
int linearize_distance(int value) { |
146 | 162 |
if(value < MIN_IR_ADC8) { |
163 |
return -2; |
|
164 |
} else if(value > MAX_IR_ADC8) { |
|
147 | 165 |
return -1; |
148 |
} else if(value > MAX_IR_ADC8) { |
|
149 |
return -2; |
|
150 | 166 |
} else { |
151 |
return IR_dist_conversion[value - MIN_IR_ADC8];
|
|
167 |
return pgm_read_word(&(IR_dist_conversion[value - MIN_IR_ADC8]));
|
|
152 | 168 |
} |
153 | 169 |
} |
154 | 170 |
|
171 |
|
|
155 | 172 |
/** @} **/ //end defgroup |
Also available in: Unified diff