#include <Servo.h>
const int GREEN_PIN = 11;
const int YELLOW_PIN = 12;
const int RED_PIN = 13;
const int BUZZER_BUTTON = 8;
const int PUSH_BUTTON = 4;
const int TRIG = 6; //..We are setting the TRIG on the ultrasonic sensor to port 23
const int ECHO = 5;
const int ledPin1L = 3; // the number of the 1st Indicator LED Left pin
const int ledPin1R = 2; // the number of the 1st Indicator LED Right pin
const int ledPin2L = A0; // the number of the 2nd Indicator LED Left pin
const int ledPin2R = A1; // the number of the 2nd Indicator LED Right pin
const int servo1Pin = 9;
const int servo2Pin = 10; // the number of the 2nd Crossong Guard Servo pin
// create servo objects
Servo myServo1;
Servo myServo2;
long previousMillis = 0;
long interval = 500; // First length of time I want the buzzer to stay on set tone
void setup() {
// put your setup code here, to run once:
pinMode(GREEN_PIN, OUTPUT);
pinMode(YELLOW_PIN, OUTPUT);
pinMode(RED_PIN, OUTPUT);
pinMode(BUZZER_BUTTON, OUTPUT);
// initialize the LED pins as an output:
pinMode(ledPin1L, OUTPUT);
pinMode(ledPin1R, OUTPUT);
pinMode(ledPin2L, OUTPUT);
pinMode(ledPin2R, OUTPUT);
// set inital crossing guard positions
CrossingGuardsUp();
myServo1.attach(servo1Pin);
myServo2.attach(servo2Pin);
pinMode(TRIG, OUTPUT); // TRIG pin as output
pinMode(ECHO, INPUT); // ECHO pin as input
Serial.begin(9600);
Serial.println("Train Crossing Active!");
}
void CrossingGuardsDown(){
// Bring the Crossing Guard arms to the down state
myServo1.write(180);
myServo2.write(0);
}
void CrossingGuardsUp(){
// Bring the Crossing Guard arms to the up state
myServo1.write(90);
myServo2.write(80);
}
void FlashLEDs(int flashTimes, int flashDelay, bool beep) {
// Flash the crossing guard warning indicators for xx period of time
int ctr1 = 0;
for (ctr1 = 0; ctr1 < flashTimes; ctr1 += 1) {
// Outer lights on, inner lights off
digitalWrite(ledPin1L, HIGH);
digitalWrite(ledPin2R, HIGH);
digitalWrite(ledPin2L, LOW);
digitalWrite(ledPin1R, LOW);
//if beep is true buzz the buzzer only on this cycle
if (beep == true) {
digitalWrite(BUZZER_BUTTON, HIGH);
}
delay(flashDelay);
// if beep is true stop the buzzer
if (beep == true) {
digitalWrite(BUZZER_BUTTON, LOW);
}
// Inner lights on, outer lights off
digitalWrite(ledPin2L, HIGH);
digitalWrite(ledPin1R, HIGH);
digitalWrite(ledPin1L, LOW);
digitalWrite(ledPin2R, LOW);
delay(flashDelay);
}
// all lights off at end of sequence
digitalWrite(ledPin1L, LOW);
digitalWrite(ledPin2R, LOW);
digitalWrite(ledPin2L, LOW);
digitalWrite(ledPin1R, LOW);
}
//define a function that is called get distance gets distance of ultrasonic wave that is sent
long getDistance()// #define a function that is called get distanc
{
digitalWrite(TRIG, HIGH); // Start the ultrasonic pulse
delayMicroseconds(10); // Send a 10-microsecond pulse
digitalWrite(TRIG, LOW); // Stop the pulse
unsigned long startTime = 0;
unsigned long endTime = 0;
// Wait for ECHO to go HIGH and record the start time
unsigned long timeout = millis();
while (digitalRead(ECHO) == LOW) {
startTime = micros();
if (millis() - timeout > 50) return -1; // Exit if timeout (no response)
}
// Wait for ECHO to go LOW and record the end time
timeout = millis();
while (digitalRead(ECHO) == HIGH) {
endTime = micros();
if (millis() - timeout > 50) return -1; // Exit if timeout
}
// Calculate the duration in microseconds
long duration = endTime - startTime;
// Convert duration to distance in centimeters
long distance_cm = duration / 58; // 58 us per cm for sound in air
return distance_cm;
}
//This is what the output should be when the function green light is to be run
void greenLight()
{
digitalWrite(GREEN_PIN, HIGH); //turn will turn on green light
digitalWrite(YELLOW_PIN, LOW); //turn the yellow led off
digitalWrite(RED_PIN, LOW); //turn the red led off
}
void yellow_light()
{
digitalWrite(GREEN_PIN, LOW); // Turn off green light
digitalWrite(YELLOW_PIN, HIGH); // Turn on yellow light
digitalWrite(RED_PIN, LOW); // Turn off red light
}
void red_light()
{
digitalWrite(GREEN_PIN, LOW); // Turn off green light
digitalWrite(YELLOW_PIN, LOW); // Turn off yellow light
digitalWrite(RED_PIN, HIGH); // Turn on red light
}
void no_light()
{
// Ensure all lights and buzzer are off
digitalWrite(GREEN_PIN, LOW);
digitalWrite(YELLOW_PIN, LOW);
digitalWrite(RED_PIN, LOW);
digitalWrite(ledPin1L, LOW);
digitalWrite(ledPin1R, LOW);
digitalWrite(ledPin2L, LOW);
digitalWrite(ledPin2R, LOW);
}
bool buttonPressed = false;
// delay(flashDelay)
void loop()
{
if (digitalRead(PUSH_BUTTON) == HIGH && !buttonPressed) {
buttonPressed = true; // Track that the button was pressed
}
if(buttonPressed)
{
// put your main code here, to run repeatedly:
long distance = getDistance();
// start the crossing guard actions
if(distance >=90)
{
no_light();
noTone(BUZZER_BUTTON);
}
else if(distance > 40 && distance < 90)
{
greenLight();
FlashLEDs(2, 200, false);
CrossingGuardsUp();
noTone(BUZZER_BUTTON);
}
else if(distance > 16 && distance < 40)
{
// flash the LEDs x number of times for YY milliseconds
yellow_light();
noTone(BUZZER_BUTTON);
}
else if(distance <=15)
{
red_light();
FlashLEDs(2, 200, true);
CrossingGuardsDown();
// flash the LEDs x number of times for YY milliseconds
if(millis() - previousMillis > interval)
{
tone(BUZZER_BUTTON, 500);
previousMillis = millis(); // Reset the timer
}
}
// Check if the buzzer should be turned off
}
}