Набирал тут недавно в одном интернет магазинчике комплектуху, для будущих поделок и случайно зацепился взглядом за такую штуку
Теория работы с устройством: на вход TRIG подается импульс 10мкс, датчик посылает ультразвуковой сигнал 40кГц, который отражается от препятствий и поступает обратно на датчик. На выходе ECHO формируется импульс, длительность которого пропорциональна расстоянию до объекта. Пересчитываем полученную длительность в сантиметры/метры по формуле из даташита
Test distance = (high level time×velocity of sound(340M/S) / 2,
или uS / 58 = centimeters
По подключению все просто, импульс формировать можно любой ножкой для примера PD3, а вот чтобы не пропустить ответный импульс, заведем эхо на ножку внешнего прерывания.
После того как был послан импульс, смотрим в прерывании что пришло — если передний фронт, то обнуляем таймер, если задний фронт, то считываем время от начала импульса до конца. Полученное время, пересчитываем в сантиметры и выводим в Uart на скорости 9600.
#include <mega8.h> #include <delay.h> // Standard Input/Output functions #include <stdio.h> volatile unsigned char status; volatile int tim = 0; // External Interrupt 0 service routine interrupt [EXT_INT0] void ext_int0_isr(void) { //проверяем уровень синала PD2( ECHO ) if(PIND.2 == 1 ) { //передний фронт - сбрасываем в 0 таймер TCNT1 = 0; status = 1; //измерение } else { //задний фронт - запоминаем значение таймера tim = TCNT1; status = 2; //окончание измерения } } void main(void) { // Port D initialization // Func7=In Func6=In Func5=In Func4=In Func3=Out Func2=In Func1=In Func0=In // State7=T State6=T State5=T State4=T State3=0 State2=T State1=T State0=T PORTD=0x00; DDRD=0x08; // Timer/Counter 1 initialization // Clock source: System Clock // Clock value: 1000,000 kHz // Mode: Normal top=0xFFFF TCCR1A=0x00; TCCR1B=0x02; TCNT1=0x00; // USART initialization // Communication Parameters: 8 Data, 1 Stop, No Parity // USART Receiver: Off // USART Transmitter: On // USART Mode: Asynchronous // USART Baud Rate: 9600 UCSRA=0x00; UCSRB=0x08; UCSRC=0x86; UBRRH=0x00; UBRRL=0x33; // External Interrupt(s) initialization // INT0: On // INT0 Mode: Any change // INT1: Off GICR|=0x40; MCUCR=0x01; GIFR=0x40; // Timer(s)/Counter(s) Interrupt(s) initialization TIMSK=0x00; #asm("sei") while (1) { //начало измерений status = 0; //генерируем импульс 10 мкс на входе trig PORTD.3 = 1; delay_us( 10 ); PORTD.3 = 0; //ждем окончания измерения while( status != 2 ); //переводим в сантиметры и выводим в юарт printf("%d\r\n",tim/58); delay_ms(1000); } } |
Максимальное измеряемое расстояние, заявленное производителем 4м, мне удалось протестировать в диапазоне до 3м, все в точности соответствует. Только нужно понимать, что если отражаемая поверхность неровная то датчик будет показывать все что угодно.
Прошивка, исходники
мегагерц