This shows you the differences between two versions of the page.
| pt:examples:sensor:ir_distance [2015/12/16 14:07] – Criação deste novo documento. artica | pt:examples:sensor:ir_distance [2020/07/20 12:00] (current) – external edit 127.0.0.1 | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| + | ====== Sensor de distância de infra-vermelhos ====== | ||
| + | // | ||
| + | [HW] [[pt: | ||
| + | [AVR] [[pt: | ||
| + | [LIB] [[pt: | ||
| + | |||
| + | ===== Teoria ===== | ||
| + | |||
| + | [{{ : | ||
| + | |||
| + | Para a medição da distância a um objecto, existem sensores ópticos que usam o método de medição por triangulação. A empresa " | ||
| + | |||
| + | [{{ : | ||
| + | |||
| + | A saída dos sensores de distância da " | ||
| + | |||
| + | ===== Prática | ||
| + | |||
| + | [{{ : | ||
| + | |||
| + | O conjunto de sensores HomeLab inclui o sensor de distância IR SHARP GP2Y0A21YK. A gama de valores do sensor é de 10 cm - 80 cm. A voltagem de saída deste sensor é, de acordo com a distância medida, até 3 V. O sensor de distância pode ser ligado a qualquer ADC (conversor analógico-digital) de canal do módulo HomeLab. Com base nos exercícios de sensores anteriores, é fácil escrever um programa que mede a tensão de saída dos sensores de distância, mas, além disso, este exercício inclui a conversão desta tensão de saída para distância. | ||
| + | |||
| + | Na datasheet do GP2Y0A21YK é mostrado o gráfico da relação entre a tensão de saída e distância medida. Este gráfico não é linear, porém o gráfico de valores inversos de tensão de saída e distancia são quase, e a partir dele é bastante fácil encontrar a fórmula para a conversão de tensão em distância. Para encontrar a fórmula, os pontos do mesmo gráfico devem ser inseridos numa folha de cálculo e, em seguida, gerar um novo gráfico. Em programas de folhas e cálculo é possível calcular automaticamente a linha de tendência. De seguida, o gráfico da relação entre os valores inversos da tensão de saída corrigido do GP2Y0A21YK e o valor corrigido inverso da distância medida com linha de tendência linear é apresentado. Para simplificar, | ||
| + | |||
| + | [{{ : | ||
| + | |||
| + | Como pode ser visto no gráfico, a linha de tendência (azul) sobrepõe-se com bastante precisão aos pontos do gráfico. Tal sobreposição é conseguida através da ajuda da constante de correcção. Esta constante de correcção é descoberta usando o método de tentativa e erro - muitas variáveis são testadas até ser encontrada a que faz o gráfico de linha de tendência sobrepor-se o mais possível. Esta constante de correcção do presente gráfico é +2; isto significa que, para todas as distâncias reais é adicionado o valor 2. Desta forma, o gráfico é muito semelhante para a linha de tendência linear e uma generalização pode ser feita e dizer-se que a relação entre a distância e a tensão é a seguinte: | ||
| + | |||
| + | 1 / (d + k) = a * ADC + b | ||
| + | |||
| + | onde | ||
| + | |||
| + | * d - distância em centímetros. | ||
| + | * k - constante de correcção (encontrada por tentativa e erro). | ||
| + | * ADC - valor de tensão digitalizado. | ||
| + | * a - membro linear (o valor é determinado pela equação da linha de tendência). | ||
| + | * b - membro livre (o valor é determinado pela equação da linha de tendência). | ||
| + | |||
| + | |||
| + | A distância pode ser expressa pela fórmula: | ||
| + | |||
| + | d = (1 / (a * ADC + B)) - k | ||
| + | |||
| + | Agora é possível, basicamente, | ||
| + | |||
| + | d = (1 / a) / (ADC + B / a) - k | ||
| + | |||
| + | Ao introduzir a constante de correcção na fórmula assim como o membro linear e o membro livre calculado a partir da equação de linha de tendência, a fórmula para calcular a distância será: | ||
| + | |||
| + | d = 5461 / (ADC - 17) - 2 | ||
| + | |||
| + | Esta fórmula é calculável com inteiros de 16 bits e completamente adequada ao AVR. Antes de calcular, deve ser assegurado que o valor do ADC é superior a 17, de outra forma estaremo a dividir por 0 e distâncias negativas podem ocorrer. | ||
| + | |||
| + | A seguir mostra-se a função para converter os valores do ADC para centímetros, | ||
| + | |||
| + | |||
| + | <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; | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Para fazer a conversão, a função // | ||
| + | |||
| + | <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); | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | /* | ||
| + | ===== Materiais extra ===== | ||
| + | |||
| + | * {{: | ||
| + | * [[http:// | ||
| + | |||
| + | */ | ||