Conhecimento necessário:
[HW] Módulo de Interface do Utilizador,
[AVR] Contadores/Temporizadores,
[LIB] Temporizadores,
[LIB] LCD Gráfico, [LIB] Sensores
Um sensor de distância por ultra-sons determina a distância a um objecto através da medição do tempo necessário ao som ser reflectido de volta a partir do objecto. A frequência do som está algures no intervalo dos ultra-sons, isto assegura um direcção mais concentrada da onda sonora porque um som com alta frequência dissipa-se menos no ambiente. Um sensor de distância ultra-sónico típico consiste em duas membranas. Uma membrana produz um som, outra captura o seu eco. Basicamente, são uma coluna e um microfone. O gerador de som gera pequenos (o comprimento é um par de períodos) impulsos de ultra-sons e dispara o cronómetro. A segunda membrana regista a chegada do impulso de som e pára o cronómetro. A partir do tempo medido é possível calcular a distância percorrida pelo som. A distância até ao objeto é metade da distância percorrida pela onda sonora.
Os sensores ultra-sónicos têm variados usos na vida quotidiana. São usados para substituir fitas métricas em dispositivos de medição para locais de construção. Os carros são equipados com sensores de estacionamento ultra-sônicos. Além de medir distâncias, podem apenas registar a presença de objetos num determinado alcance ou faixa, por exemplo, em zonas de perigo à volta de máquinas em laboração. Se o transmissor e o receptor de ultra-sons estão separados, a velocidade de fluxo da substância entre elas pode ser medida, pois a onda de som propaga-se mais lentamente a montante e vice-versa.
O HomeLab está equipado com o sensor de distância ultra-sônico Devantech SRF04/SRF05. O SRF04/SRF05 é apenas sensor e não dá informação directa sobre a distância. Além dos pins de alimentação, o sensor tem também um pino de disparo e um pino de eco. Uma diferença importante entre o SRF05 e o SRF04 é que é possível, no caso de SRF05, usar um único conector físico de pins para o disparador e o sinal de eco. Isto permite ao sensor usar o conector de três fios standard (alimentação, terra e sinal). Quando o pin de disparo está definido como high, o sensor gera ondas ultra-sónicas de 40 kHz com 8 períodos de duração. No momento do disparo, o pino de eco vai a high e assim continua até que o som refletido atinge o sensor de volta. Assim, o sinal de eco reflete, basicamente, o tempo durante o qual o som chega ao objeto e volta a partir do mesmo. Ao medir esse tempo, multiplicando-o depois pela velocidade do som e, por fim, dividindo o resultado por dois, é calculada a distância ao objecto.
Para usar o SRF04/SRF05 com o AVR, os pins de disparo e eco devem ser ligados a alguns dos pins AVR. Para medir o tempo, é adequado usar um temporizador de 16 bits, por exemplo o timer3. De seguida é apresentada uma função que é baseada no controlador Atmega2561 que executa todos os processos de medição - gera o sinal do disparador, começa o temporizador, mede o comprimento do sinal de eco e converte-o na distância em centímetros. A função bloqueia o processador, significando que o mesmo é ocupado pela função até que o resultado da medição seja recebido mesmo que a medição demore muito tempo. Quanto mais rápido o eco chegar mais rápido o resultado é retornado. Se o eco não chegar, a função espera por ele durante 36 ms e retorna 0. É importante deixar aproximadamente 20 ms de intervalo entre cada medição, para o som gerado durante a medição anterior se desvanecer e a nova medição não ser afetada por este. É importante notar que as ondas sonoras não se perturbam entre si quando vários sensores ultra-sônicos são usados simultaneamente.
#define ULTRASONIC_SPEED_OF_SOUND 33000 // cm/s // Ultrasonic distance measuring unsigned short ultrasonic_measure_srf05(pin triggerecho) { // Pin setup pin_setup_output(triggerecho); // Set timer 3 to normal mode // with period of F_CPU / 8 timer3_init_normal(TIMER3_PRESCALE_8); // Create trigger pulse pin_set(triggerecho); // Reset timer timer3_overflow_flag_clear(); timer3_set_value(0); // Wait ~10 us while (timer3_get_value() < 18) {} // End trigger pulse pin_clear(triggerecho); //short delay sw_delay_ms(1); //set the pin as input pin_setup_input_with_pullup(triggerecho); // Wait for echo start while (!pin_get_value(triggerecho)) { // Timeout ? if (timer3_overflow_flag_is_set()) { return 0; } } // Reset timer again timer3_set_value(0); // Wait for echo end while (pin_get_value(triggerecho)) { // Timeout ? if (timer3_overflow_flag_is_set()) { return 0; } } // Convert time to distance: // distance = timer * (1 / (F_CPU / 8)) * speed / 2 return (unsigned long)timer3_get_value() * ULTRASONIC_SPEED_OF_SOUND / (F_CPU / 4); }
A função apresentada permite ao utilizador escolher o pin de eco/disparo, de modo que o sensor possa ser ligado onde é mais adequado ou onde existe mais espaço. Além disso, a liberdade de escolher os pins permite utilizar a função também em outros dispositivos que não só no HomeLab. A função apresentada pertence já à biblioteca do HomeLab e não é necessário reescrevê-la. Uma coisa deve ser lembrada: a função na biblioteca do HomeLab está rigidamente ligada à velocidade de relógio do módulo de controlo do HomeLab. Usando a função com outras frequências de relógio, esta gerará resultados incorretos. Para usar a função com outras frequências de relógio, esta deve ser implementada manualmente. O código seguinte demonstra o uso do sensor ultra-sónico SRF04/SRF05 com a biblioteca do HomeLab. Ao ligar o sensor é muito importante observar a polaridade da fonte. Sensores incorretamente ligados ficam irremediavelmente estragados.
// The example program of the ultrasonic distance sensor of the HomeLab // Measuring the distance is blocking. #include <stdio.h> #include <homelab/pin.h> #include <homelab/delay.h> #include <homelab/module/sensors.h> #include <homelab/module/lcd_gfx.h> // Pins of ultrasonic sensor // Robotic HomeLab II //pin pin_pin_trigger_echo = PIN(F, 2); // Robotic HomeLab III pin pin_trigger_echo = PIN(B, 2); // Main program int main(void) { unsigned short distance; char text[16]; // Robotic HomeLab II // Switching to external sensors /* pin ex_sensors = PIN(G, 0); pin_setup_output(ex_sensors); pin_set(ex_sensors); */ // Initialization of LCD lcd_gfx_init(); // Clearing the LCD lcd_gfx_clear(); // Line selection lcd_gfx_goto_char_xy(1,1); // Name of the program lcd_gfx_write_string("Ultrasonic sensor"); // Little delay sw_delay_ms(100); // Endless loop. while (1) { // Measuring distance = ultrasonic_measure_srf05(pin_trigger_echo); // Was the measuring successful ? if (distance > 0) { // converting the distance to text. sprintf(text, "%3d cm ", distance); } // Were there errors during the measuring ? else { // Text of the error. sprintf(text, "Error "); } // Displaying the text on the LCD lcd_gfx_goto_char_xy(3, 3); lcd_gfx_write_string(text); // Little delay sw_delay_ms(500); } }
Para se certificar-se de que o sensor ultra-sónico começou realmente a trabalhar, deve verificar-se se o pequeno LED, que está localizado na parte de trás do sensor, pisca a cada medição.