Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
de:examples:sensor:ultrasonic [2009/04/09 10:35] – angelegt nierhoffde:examples:sensor:ultrasonic [2020/07/20 09:00] (current) – external edit 127.0.0.1
Line 16: Line 16:
 // //
 // Mikk Leini // Mikk Leini
 +// Department of Mechatronics
 +// Tallinn University of Technology
 +//
 +// NB!
 +// CPU clock has to be 14745600 hz
 // //
 // 2009 // 2009
Line 23: Line 28:
 #include <avr/io.h> #include <avr/io.h>
 #include <avr/interrupt.h> #include <avr/interrupt.h>
-#include <util/delay.h> 
    
 // Include common library // Include common library
-#include "pinops.h" +#include <stdlib.h> 
 +#include "pin.h" 
 +#include "lcd.h" 
 + 
 // Configuration // Configuration
 #define INTEGRATION_STEP 5 #define INTEGRATION_STEP 5
 + 
 // Math operations // Math operations
 #define MIN(a, b)   ((a) < (b) ? (a) : (b)) #define MIN(a, b)   ((a) < (b) ? (a) : (b))
 #define MAX(a, b)   ((a) > (b) ? (a) : (b)) #define MAX(a, b)   ((a) > (b) ? (a) : (b))
 #define INTEGRATE(value, new_value, n)  value = (value * (n - 1) + new_value) / n; #define INTEGRATE(value, new_value, n)  value = (value * (n - 1) + new_value) / n;
 + 
 // Configure pins // Configure pins
-#define SEGMENT_DISPLAY_LATCH      PORTPIN(G, 2) 
-#define SEGMENT_DISPLAY_DATA_OUT   PORTPIN(C, 6) 
-#define SEGMENT_DISPLAY_CLOCK      PORTPIN(C, 7) 
 #define LEDR                       PORTPIN(C, 5) #define LEDR                       PORTPIN(C, 5)
-#define US_TRIGGER                 PORTPIN(B2// blue +#define US_TRIGGER                 PORTPIN(E5
-#define US_ECHO                    PORTPIN(B3// yellow +#define US_ECHO                    PORTPIN(E4
 + 
 // Ultrasonic data structure // Ultrasonic data structure
 struct struct
Line 51: Line 54:
  unsigned short result;  unsigned short result;
 } ultrasonic; } ultrasonic;
 + 
 // 16 bit timestamp // 16 bit timestamp
 volatile unsigned long timestamp = 0; volatile unsigned long timestamp = 0;
- 
-// 
-// 7 segment display initialization 
-// 
-void segment_diplay_init(void) 
-{ 
- // Set latch, data out and clock pins as output 
- setup_output_pin(SEGMENT_DISPLAY_LATCH); 
- setup_output_pin(SEGMENT_DISPLAY_DATA_OUT); 
- setup_output_pin(SEGMENT_DISPLAY_CLOCK);  
-} 
    
-// 
-// Digit writing to 7 segment display 
-// 
-void segment_display_write(unsigned char digit) 
-{ 
- unsigned char map; 
    
- // Decimal to segment map 
- switch (digit) 
- { 
- case 0 : map = 0b00111111; break; // Every bit corresponds to one segment 
- case 1 : map = 0b00000110; break; // "1" 
- case 2 : map = 0b01011011; break; // "2" 
- case 3 : map = 0b01001111; break; // "3" and so on 
- case 4 : map = 0b01100110; break;  
- case 5 : map = 0b01101101; break;  
- case 6 : map = 0b01111100; break;  
- case 7 : map = 0b00000111; break; 
- case 8 : map = 0b01111111; break;  
- case 9 : map = 0b01100111; break;   
- default: map = 0b01111001;        // E like Error 
- }  
-  
- // Latch low 
- clear_pin(SEGMENT_DISPLAY_LATCH); 
-  
- // Send every bit in the byte. MSB (most significant bit) first. 
- for (signed char i = 7; i >= 0; i--) 
- { 
- // If bit is set, sets the data out pin, otherwise not  
- set_pin_to(SEGMENT_DISPLAY_DATA_OUT, IS_BIT_SET(map, i)); 
-  
- // Clock high for certain period 
- set_pin(SEGMENT_DISPLAY_CLOCK) 
- _delay_us(1); 
-  
- // Clock low for certain period  
- clear_pin(SEGMENT_DISPLAY_CLOCK) 
- _delay_us(1); 
- } 
-  
- // Latch high  
- set_pin(SEGMENT_DISPLAY_LATCH); 
-} 
- 
- 
 // //
-// 0.1ms clock Timer1+// Start measuring timer
 // //
 void clock_init(void) void clock_init(void)
Line 120: Line 67:
  TCCR1A = BIT(WGM11);  TCCR1A = BIT(WGM11);
  TCCR1B = BIT(WGM13) | BIT(WGM12) | BIT(CS10);  TCCR1B = BIT(WGM13) | BIT(WGM12) | BIT(CS10);
- +  
- // Top = 1475 + // Adjust timer period so that we get 1cm of 
- // Clock = 14.745600 Mhz 1475 = ~10 kHz + // measured distance every overflow. 
- // Period = 1 Clock 0.1 ms + /
- ICR1 = 1475+ // Formula: 
 + // Timer period clock rate / speed of sound in centimeters * 2 
 + // The period is multiplied by 2 because the sound travels 
 + // forth and back
 + ICR1 = 893
 + 
  // Enable overflow interrupt  // Enable overflow interrupt
  TIMSK = BIT(TOIE1);  TIMSK = BIT(TOIE1);
 } }
 + 
 // //
 // Delay // Delay
-// Time in 0.1 of milliseconds+// Time in ~60 of microseconds
 // //
 void delay(unsigned int time) void delay(unsigned int time)
 { {
  unsigned long end_time, temporary = 0;  unsigned long end_time, temporary = 0;
 + 
  // Interrupt safe timestamp waiting  // Interrupt safe timestamp waiting
  cli();  cli();
  end_time = timestamp + time;  end_time = timestamp + time;
  sei();  sei();
 + 
  while (temporary < end_time)  while (temporary < end_time)
  {  {
Line 151: Line 102:
  }  }
 } }
 + 
 // //
 // Timer1 overflow interrupt // Timer1 overflow interrupt
Line 159: Line 110:
  timestamp++;   timestamp++;
 } }
 + 
 // //
 // Ultrasonic initialization // Ultrasonic initialization
Line 168: Line 119:
  ultrasonic.state  = 0;  ultrasonic.state  = 0;
  ultrasonic.result = 0;  ultrasonic.result = 0;
 + 
  // Setup pins  // Setup pins
- setup_output_pin(US_TRIGGER); + pin_setup_output(US_TRIGGER); 
- setup_input_pin(US_ECHO); + pin_setup_input(US_ECHO); 
 + 
  // External interrupt on any logical change  // External interrupt on any logical change
  EICRB = BIT(ISC40);  EICRB = BIT(ISC40);
 + 
  // Enable external interrupt 4  // Enable external interrupt 4
  EIMSK = BIT(INT4);  EIMSK = BIT(INT4);
 } }
 + 
 // //
 // Trigger ultrasonic pulse // Trigger ultrasonic pulse
Line 188: Line 139:
  if (ultrasonic.state > 0)  if (ultrasonic.state > 0)
  return;  return;
 + 
  // Trigger ultrasonic pulse  // Trigger ultrasonic pulse
  ultrasonic.state = 1;  ultrasonic.state = 1;
- set_pin(US_TRIGGER);+ pin_set(US_TRIGGER);
  delay(1);  delay(1);
- clear_pin(US_TRIGGER); + pin_clear(US_TRIGGER);
 } }
 + 
 // //
 // External interrupt - on echo pulse // External interrupt - on echo pulse
Line 202: Line 153:
 { {
  unsigned char b;   unsigned char b;
- +  
- get_pin_value(US_ECHO, b); + pin_get_value(US_ECHO, b); 
 + 
  // Rising edge ?  // Rising edge ?
  if (b && (ultrasonic.state == 1))  if (b && (ultrasonic.state == 1))
Line 211: Line 162:
  ultrasonic.state = 2;  ultrasonic.state = 2;
  }  }
 + 
  // Falling edge ?  // Falling edge ?
  else if (!b && (ultrasonic.state == 2))  else if (!b && (ultrasonic.state == 2))
Line 219: Line 170:
  }  }
 } }
 + 
 // //
 // Get ultrasonic result // Get ultrasonic result
Line 226: Line 177:
 { {
  unsigned short result;  unsigned short result;
 + 
  // Interrupt safe result reading  // Interrupt safe result reading
  cli();  cli();
Line 232: Line 183:
  sei();  sei();
  asm volatile ("nop");  asm volatile ("nop");
 + 
  return result;  return result;
 } }
 + 
 // //
 // Program entrance function // Program entrance function
Line 241: Line 192:
 int main(void) int main(void)
 {   {  
- volatile unsigned short lowValue  = 0xFFFF; + unsigned short value = 0; 
- volatile unsigned short highValue = 0x0000; + char buffer[8]
- volatile unsigned short value = 0; + 
- volatile unsigned char relativeValue+
  // Initializing  // Initializing
  clock_init();  clock_init();
- ultrasonic_init(); + ultrasonic_init();  
- segment_diplay_init();  + pin_setup_output(LEDR); 
- setup_output_pin(LEDR); +  
 + // Init display 
 + lcd_init(LCD_DISP_ON); 
 + lcd_gotoxy(0, 0);  
 + lcd_puts("Distance: "); 
 + 
  // Enable global interrupts  // Enable global interrupts
  sei();   sei();
 + 
   // Endless loop   // Endless loop
  while (1)  while (1)
  {   {
- // Blink LED every second+ // Blink LED constantly
  cli();  cli();
- set_pin_to(LEDR, (timestamp % 10000) > 1000); + pin_set_to(LEDR, (timestamp % 10000) > 1000);
  sei();  sei();
- +  
- // Constantly try triggering ultrasonic pulses+ // Trigger ultrasonic pulse
  ultrasonic_trigger();  ultrasonic_trigger();
- +  
- // Read ultrasonic result + // Read last ultrasonic result
  INTEGRATE(value, ultrasonic_getresult(), INTEGRATION_STEP);  INTEGRATE(value, ultrasonic_getresult(), INTEGRATION_STEP);
-  +  
- // Check for new lower limit + // Go-to first row and to first character 
- lowValue = MIN(lowValuevalue); + lcd_gotoxy(01);  
- +  
- // Check for new higher limit + // Output text 
- highValue = MAX(highValuevalue); + itoa(valuebuffer, 10);  
- + lcd_puts(buffer); 
- // Calculate relative value + lcd_puts(  "); 
- // Range from lowValue to highValue is converted to 0 to 9  + 
- relativeValue = 9 * (value - lowValue) / (highValue - lowValue); +
- +
- // Write digit +
- segment_display_write(relativeValue);  +
  // Delay a while  // Delay a while
- delay(50);+ delay(200);
  }  }
 } }
 </code> </code>
de/examples/sensor/ultrasonic.1239273309.txt.gz · Last modified: 2020/07/20 09:00 (external edit)
CC Attribution-Share Alike 4.0 International
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0