Witam, napisałem kod do obsługi tego czujnika. Wysyłam wartość zmierzonego czasu przez usart do terminala.
Jeżeli zbliżę przeszkodę na odległość 2 cm to otrzymuję w odpowiedzi wartość "40" co po podzieleniu przez 20 da mi 2 cm. Wyczytałem tutaj na forum w jakimś starym artykule, że to należy tak skalować. Chciałbym się jednak dowiedzieć dlaczego akurat dzielimy przez "20".
W nocie katalogowej czujnika mamy wzór:
odl = (czas stanu wysokiego * 340[m/s] ) / 2
Z tego wzoru nie wynika, że mamy stan wysoki dzielić przez "20" chyba że nie potrafię sobie tego przekształcić. Czas wysoki mierzę Timer2 w mikrosekundach, więc po przekształceniu wzoru powinienem czas stanu wysokiego mnożyć razy "0,017".
Dodatkowo zauważyłem, że czujnik kiedy jest skierowany w stronę sufitu to maksymalnie daje mi wartość 1800, co po podzieleniu przez "20" daje "90", a do sufitu z blatu biurka mam zdecydowanie więcej.
Kod programu:
#define F_CPU 8000000ul
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <stdio.h>
#include "uart/uart.h"
volatile int odl0 = 0;
volatile int licznik = 0;
char flaga = 0;
char bufor[20];
void sonar_init()
{
DDRC = 0x02;
MCUCR |=(1<<ISC00)|(1<<ISC01);
GICR |= (1<<INT0);
TCNT2 |= 0x00;
TCCR2 |= (1<<WGM21)|(1<<CS20);
OCR2 = 0x08;
sei();
}
ISR(TIMER2_COMP_vect)
{
licznik++;
}
ISR(INT0_vect)
{
if(flaga==0)
{
TIMSK = (1<<OCIE2);
GICR &= ~(1<<INT0);
MCUCR = 0x00;
MCUCR = (1<<ISC01);
GICR = (1<<INT0);
flaga=1;
}
else if(flaga==1)
{
TIMSK &= ~(1<<OCIE2);
GICR &= ~(1<<INT0);
MCUCR = 0x00;
MCUCR = (1<<ISC01)|(1<<ISC00);
GICR = (1<<INT0);
odl0=licznik;
//odl0/=20;
licznik=0;
flaga=0;
}
}
int l_pomiar(void)
{
//odl0=0;
GICR |= (1<<INT0);
PORTC |= (1<<PINC1);
_delay_us(15);
PORTC &= ~(1<<PINC1);
_delay_ms(8);
GICR &= ~(1<<INT0);
return odl0;
}
int main(void)
{
sonar_init();
USART_Init();
uart_puts(" start ");
while(1)
{
_delay_ms(1000);
sprintf(bufor, "D: %d",l_pomiar());
uart_puts(bufor);
}
}