This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| en:examples:sensor:ir_distance [2015/11/10 12:46] – heikopikner | en:examples:sensor:ir_distance [2020/07/20 12:00] (current) – external edit 127.0.0.1 | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| + | ====== Infrared distance sensor ====== | ||
| + | //Necessary knowledge: | ||
| + | [HW] [[en: | ||
| + | [AVR] [[en: | ||
| + | [LIB] [[en: | ||
| + | |||
| + | ===== Theory ===== | ||
| + | |||
| + | [{{ : | ||
| + | |||
| + | For measuring the distance to an object there are optical sensors using triangulation measuring method. Company “Sharp” produces most common infra-red (IR) wavelength using distance sensors which have analogue voltage output. The sensors made by “Sharp” have IR LED equipped with lens, which emits narrow light beam. After reflecting from the object, the beam will be directed through the second lens on a position-sensible photo detector (PSD). The conductivity of this PSD depends on the position where the beam falls. The conductivity is converted to voltage and if the voltage is digitalized by using analogue-digital converter, the distance can be calculated. The route of beams reflecting from different distance is presented on the drawing next to the text | ||
| + | |||
| + | [{{ : | ||
| + | |||
| + | The output of distance sensors by " | ||
| + | |||
| + | ===== Practice | ||
| + | |||
| + | [{{ : | ||
| + | |||
| + | The HomeLab set of sensors includes IR distance sensor SHARP GP2Y0A21YK. Measuring range of the sensor is 10 cm – 80 cm. The output voltage of this sensor is, depending on the distance measured, up to 3 V. The distance sensor can be connected to any ADC (the analogue-digital converter) channel of the HomeLab module. On the basis of previous exercises of sensors, it is easy to write a program which measures the output voltage of the distance sensors, but in addition, this exercise includes converting this output voltage to distance. | ||
| + | |||
| + | On the datasheet of the GP2Y0A21YK is graph of relation between its output voltage and measured distance. This graph is not a linear one, however the graph of inverse values of output voltage and distance almost is, and from that is quite easy to find the formula for converting voltage to distance. To find the formula, the points of the same graph must be inserted to any kind of spreadsheet application and then generate a new graph. In spreadsheet programs is possible to calculate automatically the trend-line. Next, the graph of GP2Y0A21YK corrected output voltage inverse value’s relation to the corrected inverse value of measured distance with linear trend-line is presented. To simplify, the output voltage is already converted to 10 bit +5 V values of analogue-digital converter with comparison voltage. | ||
| + | |||
| + | [{{ : | ||
| + | |||
| + | As seen on the graph, the trend-line (blue) overlaps quite precisely with the points of the graph. Such overlapping is achieved by using the help of the corrective constant. This corrective constant is discovered by using the trial-and-error method – many variables were tested until such was found which made the graph overlap the trend-line the most. This corrective constant of present graph is +2; this means that to all real distances +2 is added. This way the graph is very similar to the linear trend line and a generalization can be made and | ||
| + | say that the relation between the distance and the voltage is following: | ||
| + | |||
| + | 1 / (d + k) = a * ADC + b | ||
| + | |||
| + | where | ||
| + | |||
| + | * d - distance in centimeters. | ||
| + | * k - corrective constant (fund using tial-and-error method) | ||
| + | * ADC - digitalized value of voltage. | ||
| + | * a - linear member (value is determined by the trend line equation) | ||
| + | * b - free member(value is determined by the trend line equation) | ||
| + | |||
| + | |||
| + | Distance d can be expressed from the formula: | ||
| + | |||
| + | d = (1 / (a * ADC + B)) - k | ||
| + | |||
| + | Now it is basically possible to calculate the distance by using this formula, but this requires floating-point calculations, | ||
| + | |||
| + | d = (1 / a) / (ADC + B / a) - k | ||
| + | |||
| + | When introducing the corrective constant to the formula and also the linear-member and the free-member from the trend-line equation, the formula for calculating the distance will be: | ||
| + | |||
| + | d = 5461 / (ADC - 17) - 2 | ||
| + | |||
| + | This formula is computable with 16-bit integers and completely suitable to AVR. Before calculating, | ||
| + | |||
| + | Following is the function for converting the values of ADC to centimeters, | ||
| + | |||
| + | |||
| + | <code c> | ||
| + | // The structure of the parameters of the IR distance sensors | ||
| + | typedef const struct | ||
| + | { | ||
| + | const signed short a; | ||
| + | const signed short b; | ||
| + | const signed short k; | ||
| + | } | ||
| + | ir_distance_sensor; | ||
| + | |||
| + | // The object of the parameters of GP2Y0A21YK sensor | ||
| + | const ir_distance_sensor GP2Y0A21YK = { 5461, -17, 2 }; | ||
| + | |||
| + | // Converting the values of the IR distance sensor to centimeters | ||
| + | // Returns -1, if the conversion did not succeed | ||
| + | signed short ir_distance_calculate_cm(ir_distance_sensor sensor, | ||
| + | unsigned short adc_value) | ||
| + | { | ||
| + | if (adc_value + sensor.b <= 0) | ||
| + | { | ||
| + | return -1; | ||
| + | } | ||
| + | |||
| + | return sensor.a / (adc_value + sensor.b) - sensor.k; | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | To make the conversion the function // | ||
| + | |||
| + | <code c> | ||
| + | // The example program of the IR distance sensor of the HomeLab | ||
| + | // Measured results in centimeters is displayed on the LCD | ||
| + | #include < | ||
| + | #include < | ||
| + | #include < | ||
| + | #include < | ||
| + | #include < | ||
| + | |||
| + | #define ADC_CHANNEL 0 | ||
| + | |||
| + | // Main program | ||
| + | int main(void) | ||
| + | { | ||
| + | signed short value, distance; | ||
| + | char text[16]; | ||
| + | |||
| + | // Robotic HomeLab II external sensors pin of Sensor module | ||
| + | //pin ex_sensors = PIN(G, 0); | ||
| + | // | ||
| + | // | ||
| + | |||
| + | // Initialization of LCD | ||
| + | lcd_gfx_init(); | ||
| + | lcd_gfx_clear(); | ||
| + | lcd_gfx_goto_char_xy(1, | ||
| + | lcd_gfx_write_string(" | ||
| + | |||
| + | // Setup of the ADC | ||
| + | adc_init(ADC_REF_AVCC, | ||
| + | |||
| + | // Endless loop | ||
| + | while (1) | ||
| + | { | ||
| + | // Reading the 4 times rounded value of output voltage | ||
| + | value = adc_get_average_value(ADC_CHANNEL, | ||
| + | |||
| + | // Conversing ADC value to distance | ||
| + | distance = ir_distance_calculate_cm(GP2Y0A21YK, | ||
| + | |||
| + | lcd_gfx_goto_char_xy(1, | ||
| + | |||
| + | // Was the calculation successful? | ||
| + | if (distance >= 0) | ||
| + | { | ||
| + | // Conversing distance to text | ||
| + | sprintf(text, | ||
| + | } | ||
| + | else | ||
| + | { | ||
| + | // Creating the text for unknown distance | ||
| + | sprintf(text, | ||
| + | } | ||
| + | |||
| + | lcd_gfx_goto_char_xy(1, | ||
| + | lcd_gfx_write_string(text); | ||
| + | sw_delay_ms(500); | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | /* | ||
| + | ===== Extra materials ===== | ||
| + | |||
| + | * {{: | ||
| + | * [[http:// | ||
| + | |||
| + | */ | ||