This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| et:examples:sensor:ultrasonic [2009/09/20 10:54] – mikk.leini | et:examples:sensor:ultrasonic [2009/11/05 13:30] (current) – eemaldatud mikk.leini | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| - | ====== Ultraheli kaugusmõõdik ====== | ||
| - | Kasutatud on SRF 04 kaugusmõõdikut. | ||
| - | |||
| - | {{examples: | ||
| - | |||
| - | <code c> | ||
| - | // | ||
| - | // SFR04 ultrasonic distance measuring | ||
| - | // | ||
| - | // Mikk Leini | ||
| - | // Department of Mechatronics | ||
| - | // Tallinn University of Technology | ||
| - | // | ||
| - | // NB! | ||
| - | // CPU clock has to be 14745600 hz | ||
| - | // | ||
| - | // 2009 | ||
| - | // | ||
| - | |||
| - | // Include avrlibc | ||
| - | #include < | ||
| - | #include < | ||
| - | |||
| - | // Include common library | ||
| - | #include < | ||
| - | #include " | ||
| - | #include " | ||
| - | |||
| - | // Configuration | ||
| - | #define INTEGRATION_STEP 5 | ||
| - | |||
| - | // Math operations | ||
| - | #define MIN(a, b) ((a) < (b) ? (a) : (b)) | ||
| - | #define MAX(a, b) ((a) > (b) ? (a) : (b)) | ||
| - | #define INTEGRATE(value, | ||
| - | |||
| - | // Configure pins | ||
| - | #define LEDR | ||
| - | #define US_TRIGGER | ||
| - | #define US_ECHO | ||
| - | |||
| - | // Ultrasonic data structure | ||
| - | struct | ||
| - | { | ||
| - | unsigned char state; | ||
| - | unsigned long front; | ||
| - | unsigned short result; | ||
| - | } ultrasonic; | ||
| - | |||
| - | // 16 bit timestamp | ||
| - | volatile unsigned long timestamp = 0; | ||
| - | |||
| - | |||
| - | // | ||
| - | // Start measuring timer | ||
| - | // | ||
| - | void clock_init(void) | ||
| - | { | ||
| - | // Fast PWM, Top = ICR, Prescaler = 1 | ||
| - | TCCR1A = BIT(WGM11); | ||
| - | TCCR1B = BIT(WGM13) | BIT(WGM12) | BIT(CS10); | ||
| - | |||
| - | // Adjust timer period so that we get 1cm of | ||
| - | // distance every overflow. | ||
| - | ICR1 = 900; | ||
| - | |||
| - | // Enable overflow interrupt | ||
| - | TIMSK = BIT(TOIE1); | ||
| - | } | ||
| - | |||
| - | // | ||
| - | // Delay | ||
| - | // Time in ~0.06 of milliseconds | ||
| - | // (the time of sound wave travelling 1cm forth and back) | ||
| - | // | ||
| - | void delay(unsigned int time) | ||
| - | { | ||
| - | unsigned long end_time, temporary = 0; | ||
| - | |||
| - | // Interrupt safe timestamp waiting | ||
| - | cli(); | ||
| - | end_time = timestamp + time; | ||
| - | sei(); | ||
| - | |||
| - | while (temporary < end_time) | ||
| - | { | ||
| - | cli(); | ||
| - | temporary = timestamp; | ||
| - | sei(); | ||
| - | asm volatile (" | ||
| - | } | ||
| - | } | ||
| - | |||
| - | // | ||
| - | // Timer1 overflow interrupt | ||
| - | // | ||
| - | ISR(TIMER1_OVF_vect) | ||
| - | { | ||
| - | timestamp++; | ||
| - | } | ||
| - | |||
| - | // | ||
| - | // Ultrasonic initialization | ||
| - | // | ||
| - | void ultrasonic_init(void) | ||
| - | { | ||
| - | // Initial state | ||
| - | ultrasonic.state | ||
| - | ultrasonic.result = 0; | ||
| - | |||
| - | // Setup pins | ||
| - | pin_setup_output(US_TRIGGER); | ||
| - | pin_setup_input(US_ECHO); | ||
| - | |||
| - | // External interrupt on any logical change | ||
| - | EICRB = BIT(ISC40); | ||
| - | |||
| - | // Enable external interrupt 4 | ||
| - | EIMSK = BIT(INT4); | ||
| - | } | ||
| - | |||
| - | // | ||
| - | // Trigger ultrasonic pulse | ||
| - | // | ||
| - | void ultrasonic_trigger(void) | ||
| - | { | ||
| - | // Cannot trigger when listening | ||
| - | if (ultrasonic.state > 0) | ||
| - | return; | ||
| - | |||
| - | // Trigger ultrasonic pulse | ||
| - | ultrasonic.state = 1; | ||
| - | pin_set(US_TRIGGER); | ||
| - | delay(1); | ||
| - | pin_clear(US_TRIGGER); | ||
| - | } | ||
| - | |||
| - | // | ||
| - | // External interrupt - on echo pulse | ||
| - | // | ||
| - | ISR(INT4_vect) | ||
| - | { | ||
| - | unsigned char b; | ||
| - | |||
| - | pin_get_value(US_ECHO, | ||
| - | |||
| - | // Rising edge ? | ||
| - | if (b && (ultrasonic.state == 1)) | ||
| - | { | ||
| - | ultrasonic.front = timestamp; | ||
| - | ultrasonic.state = 2; | ||
| - | } | ||
| - | |||
| - | // Falling edge ? | ||
| - | else if (!b && (ultrasonic.state == 2)) | ||
| - | { | ||
| - | ultrasonic.result = timestamp - ultrasonic.front; | ||
| - | ultrasonic.state = 0; | ||
| - | } | ||
| - | } | ||
| - | |||
| - | // | ||
| - | // Get ultrasonic result | ||
| - | // | ||
| - | unsigned short ultrasonic_getresult(void) | ||
| - | { | ||
| - | unsigned short result; | ||
| - | |||
| - | // Interrupt safe result reading | ||
| - | cli(); | ||
| - | result = ultrasonic.result; | ||
| - | sei(); | ||
| - | asm volatile (" | ||
| - | |||
| - | return result; | ||
| - | } | ||
| - | |||
| - | // | ||
| - | // Program entrance function | ||
| - | // | ||
| - | int main(void) | ||
| - | { | ||
| - | unsigned short value = 0; | ||
| - | char buffer[8]; | ||
| - | |||
| - | // Initializing | ||
| - | clock_init(); | ||
| - | ultrasonic_init(); | ||
| - | pin_setup_output(LEDR); | ||
| - | |||
| - | // Init display | ||
| - | lcd_init(LCD_DISP_ON); | ||
| - | lcd_gotoxy(0, | ||
| - | lcd_puts(" | ||
| - | |||
| - | // Enable global interrupts | ||
| - | sei(); | ||
| - | |||
| - | // Endless loop | ||
| - | while (1) | ||
| - | { | ||
| - | // Blink LED constantly | ||
| - | cli(); | ||
| - | pin_set_to(LEDR, | ||
| - | sei(); | ||
| - | |||
| - | // Trigger ultrasonic pulse | ||
| - | ultrasonic_trigger(); | ||
| - | |||
| - | // Read last ultrasonic result | ||
| - | INTEGRATE(value, | ||
| - | |||
| - | // Go-to first row and to first character | ||
| - | lcd_gotoxy(0, | ||
| - | |||
| - | // Output text | ||
| - | itoa(value, | ||
| - | lcd_puts(buffer); | ||
| - | lcd_puts(" | ||
| - | |||
| - | // Delay a while | ||
| - | delay(200); | ||
| - | } | ||
| - | } | ||
| - | </ | ||