Landing : Athabascau University

Circuit 3C: Motion Alarm

I did not have any major issues building the circuit, but I had trouble attaching my paper clip to the servo arm because my paper clip is too thick to fit into the small holes on the servo arm. I solved this problem by using tape to attach the paperclip, but it is a little bit flimsy. Ideally, I would have found a way to attach the paperclip more securely, but the tape is holding up for now. I modified the example program so instead of being a motion alarm it is an automatic door opener. When an object gets within five inches of the sensor, the LED and buzzer simultaneously play a message in morse code that spells out the greeting “Hi”. I got the morse code encoding information from the Morse Code Wikipedia article. When an object gets within three inches of the sensor and the morse code greeting has finished, the door opens and the LED turns green and the buzzer buzzes to help alert the user that the door has opened. After the object moves away from the sensor, the door stays open for three seconds to allow the object to get through it before closing. If the object comes within five inches of the sensor, but not three, the message plays but the door does not open. If there are no objects within five inches of the sensor the LED remains red. Here is the code:

#include <Servo.h> //include the servo library
const int trigPin = 11; //connects to the trigger pin on the distance sensor
const int echoPin = 12; //connects to the echo pin on the distance sensor
const int redPin = 3; //pin to control the red LED inside the RGB LED
const int greenPin = 5; //pin to control the green LED inside the RGB LED
const int bluePin = 6; //pin to control the blue LED inside the RGB LED
const int buzzerPin = 10; //pin that will drive the buzzer
float distance = 0; //stores the distance measured by the distance sensor
Servo myservo; //create a servo object
void setup()
{
pinMode(trigPin, OUTPUT); //the trigger pin will output pulses of electricity
pinMode(echoPin, INPUT); //the echo pin will measure the duration of pulses coming back from the distance sensor
//set the RGB LED pins to output
pinMode(redPin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);
pinMode(buzzerPin, OUTPUT); //set the buzzer pin to output
myservo.attach(9); //use pin 9 to control the servo
}
void loop() {
distance = getDistance(); //variable to store the distance measured by the sensor
if (distance <= 5) { //if the object is less than or equal to five inches away
greetingSequence();
} else { //if the object is too far away
//make the RGB LED red
analogWrite(redPin, 255);
analogWrite(greenPin, 0);
analogWrite(bluePin, 0);
}
distance = getDistance(); //variable to store the distance measured by the sensor
while (distance <= 3) { //while the object is less than or equal to three inches away
openDoor();
distance = getDistance(); //variable to store the distance measured by the sensor
if(distance > 3){
closeDoor();
}
}
}
//------------------FUNCTIONS-------------------------------
void greetingSequence(){
letterH();
longSpace();
letterI();
longerSpace();
}
void letterH(){
dit();
space();
dit();
space();
dit();
space();
dit();
}
void letterI(){
dit();
space();
dit();
}
void dit(){
tone(buzzerPin, 272); //buzz the buzzer pin

//make the RGB LED yellow
analogWrite(redPin, 255);
analogWrite(greenPin, 50);
analogWrite(bluePin, 0);

delay(100);
}
void space(){
ledsOff();
delay(100);
}
void longSpace(){
ledsOff();
delay(300);
}
void longerSpace(){
ledsOff();
delay(700);
}
void ledsOff(){
analogWrite(redPin, 0);
analogWrite(greenPin, 0);
analogWrite(bluePin, 0);
noTone(buzzerPin); //turn the buzzer off
}
void openDoor(){
myservo.write(20); //move the servo
tone(buzzerPin, 272); //buzz the buzzer pin
//make the RGB LED green
analogWrite(redPin, 0);
analogWrite(greenPin, 255);
analogWrite(bluePin, 0);
}
void closeDoor(){
delay(3000);
myservo.write(90); //move the servo
noTone(buzzerPin); //turn the buzzer off
}
//RETURNS THE DISTANCE MEASURED BY THE HC-SR04 DISTANCE SENSOR
float getDistance()
{
float echoTime; //variable to store the time it takes for a ping to bounce off an object
float calculatedDistance; //variable to store the distance calculated from the echo time
//send out an ultrasonic pulse that's 10ms long
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
echoTime = pulseIn(echoPin, HIGH); //use the pulsein command to see how long it takes for the
//pulse to bounce back to the sensor
calculatedDistance = echoTime / 148.0; //calculate the distance of the object that reflected the pulse (half the bounce time multiplied by the speed of sound)
return calculatedDistance; //send back the distance that was calculated
}

Some of the code is from the example program. In my loop() function there is an if-else statement and a while loop. The if-else statement determines whether the object is within five inches of the sensor, and if it is then it calls the greetingSequence() function, otherwise it just makes the LED stay red. The greetingSequence() function is responsible for making the LED and buzzer play the morse code message, and it calls methods for each letter of the morse code alphabet that is required, which in turn call methods for creating the dits and spaces that make up the letters in morse code. After greetingSequence() is finished executing, the while loop inside the loop() function determines whether the object is within three inches of the sensor, and if it is then it calls openDoor(), and continues to call openDoor() until the object moves away from the sensor. Once the object is more than three inches away, closeDoor() is called. The openDoor() and closeDoor() methods are responsible for opening and closing the door. The getDistance() function is exactly the same as the one in the example code.


Here is a video of the code in action:  Speed sensor


I did have some issues with writing this program. The first time I ran the program the door swung the wrong way because openDoor() was actually closing the door, and closeDoor() was opening it. This was because I put myservo.write(90); in the openDoor() function and I put myservo.write(20); in the closeDoor() function. I simply swapped those two statements to solve the problem. The second issue that I ran into was that once the door opened, it would stay open forever. The problem was that I had forgot to update the distance variable inside the while loop in the loop() function. So distance <= 3 was always true, and there was no way to exit the loop. I solved this problem by including the line "distance = getDistance();" inside the while loop.