-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathLeftSensor.ino
110 lines (90 loc) · 3.04 KB
/
LeftSensor.ino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
//New format
//GND -> GND
//Echo -> Pin 13 -> PB5
//Trig -> Pin 12 -> PB4
//VCC -> Pin 11 -> PB3
// HC-SR04 ultrasonic rangefinder demo
// Popular code uses pulseIn to measure echo pulse, pulseIn is a blocking function
// Using interrupts for reading the incoming pulse is better approach because it won't stall your main program
// You are welcome to use this code for the project
// You might need to do additional calibration and data filtering
// Note sources of innacuracies of some components like micros(). It has a small error, check online why this happens
// Pinout:
// VCC (5VDC)
// GND (return)
// TRIG (trigger input)
// ECHO (echo output)
// For sensor operation refer to datasheet:
// https://www.mouser.com/ds/2/813/HCSR04-1022824.pdf
#define TRIG PB4 // trigger pin Arduino Pin 12
#define ECHO PB5 // echo output Arduino Pin 13
#define VCC PB3 //Vcc Arduino Pin 11
// riseTime and fallTime will be modified by interrupt so we need to declare them as volatile
volatile unsigned long riseTime; // timestamp when echo signal goes high
volatile unsigned long fallTime; // timestamp when echo signal goes low
unsigned long pulseTime; // difference between riseTime and fallTime
unsigned long distance; // our range
float getDistance();
void setup()
{
Serial.begin(9600);
// Setting direction for trig and echo pins
DDRB |= (1<<TRIG);
DDRB &= ~(1<<ECHO);
// Setting up pin change interrupt for echo (PB5), PCINT5
PCICR = (1<<PCIE0); // only enabling PCIE0
PCMSK0 = (1<<PCINT5); // only enabling PCINT5
DDRB |= (1<<VCC); //Set as output
PORTB |= (1<<VCC); //Turn on pin 11
}
void loop()
{
float range = getDistance();
if (range < 80){
beep();
}
Serial.println(range);
delay(100);
}
// function to calculate the distance
float getDistance()
{
// clear trig pin
PORTB &= ~(1<<TRIG);
delayMicroseconds(2);
// send out 10 us pulse
PORTB = (1<<TRIG);
delayMicroseconds(10);
PORTB &= ~(1<<TRIG);
// sound travels at 343 m/s which is 0.0343 cm/us
// distance = time*velocity
// we need to divide result by 2 because sound travels
// to object and back so the incoming pulse is twice longer
distance = pulseTime*0.0343/2; // result in cm
return distance;
}
// Interrupt service vector for pin change:
// ISR (PCINT0_vect) pin change interrupt for D8 to D13
// ISR (PCINT1_vect) pin change interrupt for A0 to A5
// ISR (PCINT2_vect) pin change interrupt for D0 to D7
// We need PCINT0_vect because we are using PB5 as input (echo)
ISR(PCINT0_vect)
{
if ((PINB & (1<<ECHO)) == (1<<ECHO)) // check if pin PB5 is high
{ // Measure time when echo pin goes high
riseTime = micros(); // micros() calculates the run time in us since the program's start
}
else
{
// measure the time when echo pin goes low
fallTime = micros();
pulseTime = fallTime - riseTime; // this is our echo pulse, its length is proportional to the measured distance
}
Serial.println("ISR");
}
void beep(){
tone(A0, 80, 200);
delay(100);
// stop the tone playing:
noTone(A0);
}