0

I am currently doing part 2: Pedestrian Mode of my project below:

  1. Regular Mode: This is the regular mode of operation. In this mode the three lights (Red, Yellow and Green LEDs) should operate in the following order. The Red LED lights for 2 seconds, followed by the Yellow LED for 1 second, the Green LED for 2 seconds and then the Yellow LED again for 1 second. The cycle should repeat until the mode changes.
  2. Pedestrian Mode: This mode uses the SRF05 Ultrasonic Range Finder to detect the proximity of any object. The lights should operate as defined in the regular mode UNTIL an object is detected less than 10 cm from the TLC. The buzzer should then beep and the Yellow LED must blink ON/OFF (flashing intervals of 0.1 sec) repeatedly 10 times. The buzzer should then stop beeping and the operation of the lights (not the system) must behave as it would in the regular mode. The operation stays the same until the mode changes

My code works, however it waits for the entire regular cycle to finish before sensing a pulse with the ultrasonic range sensor to determine if an object is near or not. Therefore, when I put my hand near the sensor, it has to finish running the regular mode before it detects my hand and switches to pedestrian mode. What I would like is for the range finder to continuously fire the pulse and immediately switch to pedestrian mode when it detects an object less than 10 cm away.

Code below:

int red_light = 12;
int yellow_light = 10;
int green_light = 8;
int ECHOPIN = 3;
int TRIGPIN = 5;
int buzzer = 7;
float distance;

void setup() {
  Serial.begin(9600);
  pinMode(red_light, OUTPUT);
  pinMode(yellow_light, OUTPUT);
  pinMode(green_light, OUTPUT);
  pinMode(ECHOPIN, INPUT);
  pinMode(TRIGPIN, OUTPUT);
  pinMode(buzzer, OUTPUT);
}    

void loop() {
  range_finder();
  if (distance < 10) {
    pedestrian_mode();
  } else {
    regular_mode();
  }
}

void regular_mode() {
  digitalWrite(red_light, HIGH); 
  delay(2000);
  digitalWrite(red_light, LOW);
  digitalWrite(yellow_light, HIGH);
  delay(1000);
  digitalWrite(yellow_light, LOW);
  digitalWrite(green_light, HIGH);
  delay(2000);   
  digitalWrite(green_light, LOW);
  digitalWrite(yellow_light, HIGH);
  delay(1000);
  digitalWrite(yellow_light, LOW);
}

void range_finder() {
  digitalWrite(TRIGPIN, LOW);
  delayMicroseconds(2);
  digitalWrite(TRIGPIN,HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIGPIN,LOW); 
  distance = pulseIn(ECHOPIN, HIGH);
  // return 0 if no high pulse in 1 sec
  distance = distance/58;
  Serial.print(distance);
  Serial.println("cm");
  delay(200);
}

void pedestrian_mode() {
  digitalWrite(buzzer, HIGH);
  digitalWrite(yellow_light, HIGH);
  delay(100);
  digitalWrite(yellow_light, LOW);
  delay(100);
  digitalWrite(yellow_light, HIGH);
  delay(100);
  digitalWrite(yellow_light, LOW);
  delay(100);
  digitalWrite(yellow_light, HIGH);
  delay(100);
  digitalWrite(yellow_light, LOW);
  delay(100);
  digitalWrite(yellow_light, HIGH);
  delay(100);
  digitalWrite(yellow_light, LOW);
  delay(100);
  digitalWrite(yellow_light, HIGH);
  delay(100);
  digitalWrite(yellow_light, LOW);
  delay(100);
  digitalWrite(yellow_light, HIGH);
  delay(100);
  digitalWrite(yellow_light, LOW);
  delay(100);
  digitalWrite(yellow_light, HIGH);
  delay(100);
  digitalWrite(yellow_light, LOW);
  delay(100);
  digitalWrite(yellow_light, HIGH);
  delay(100);
  digitalWrite(yellow_light, LOW);
  delay(100);
  digitalWrite(yellow_light, HIGH);
  delay(100);
  digitalWrite(yellow_light, LOW);
  delay(100);
  digitalWrite(yellow_light, HIGH);
  delay(100);
  digitalWrite(yellow_light, LOW);
  delay(100);
  digitalWrite(yellow_light, HIGH);
  delay(100);
  digitalWrite(yellow_light, LOW);
  delay(100);
  digitalWrite(yellow_light, HIGH);
  delay(100);
  digitalWrite(yellow_light, LOW);
  delay(100);
}

Also I have a feeling some parts of my code may be unnecessarily long and could be shortened. If so, I would appreciate any advice and how to do that. Thank you.

1
   digitalWrite(yellow_light, HIGH);
   delay(100);
   digitalWrite(yellow_light, LOW);
   delay(100);

   digitalWrite(yellow_light, HIGH);
   delay(100);
   digitalWrite(yellow_light, LOW);
   delay(100);

...

You really need to read up on "for" loops. Make a loop that does it 10 times, don't copy and paste 10 times.

As for your other issue, at the very least you could test the proximity sensor after each delay. Read up on millis. Just imagine how you might do it in real life. Would you really delay for two seconds? Or would you check the clock to see if two seconds had elapsed and also check if a pedestrian had arrived?

And better still, replace delay with a loop which tests elapsed time, and also tests the distance sensor.


I'm not writing more specific code because clearly the exercise is for you to learn how to do this. I already know how to do it, and if I just posted the exact answer you wouldn't have learned how to do it.

  • 1
    As a short addition: The BlinkWithoutDelay example in the Arduino IDE is a good starting point for learning this principle – chrisl Mar 20 '18 at 8:23
0

You should use an interrupt pin.

Interrupt pins can operate outside the normal void loop().

So you can have a normal loop going on. If an interrupt pin is triggered - it performs a function immediately.

https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/

Or you could consider using a switch case.

  • However that function should be brief. What the OP seems to want is to switch modes (regular mode to pedestrian mode). It might be better to check for the conditions for a mode change to occur, while a particular mode is in operation. – Nick Gammon Mar 21 '18 at 0:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.