1

I am trying to create a Traffic Light Controller.
There are three modes to the controller:
Mode 1 - the traffic light operates RED-YELLOW-GREEN-YELLOW and should repeat
* (The other modes are not necessary apart from knowing the user can select the mode.)*

I want to loop the function of the mode until I receive an input from the serial monitor. If no input is detected, then it should continue with the current mode.
At the moment I am using Serial.read() at the start of the main loop function before my switch statement to select the mode. However, this needs an input, but I want the switch cases to loop until an input is received.

All help will be much appreciated.

  • 2
    use a variable to store the mode ..... run the display sequence depending on the value of the variable ..... update the variable when a command is received – jsotola Feb 26 '19 at 18:42
  • 2
    Show us the sketch that you have so far. Do you know what a finite state machine is? majenko.co.uk/blog/finite-state-machine – Jot Feb 26 '19 at 18:43
1

Use something like this (it is pseudo code so convert it to your sketch):

enum EState { NORMAL, SPECIAL } _state; // States
enum ENormalState { RED, YELLOW1, GREEN, YELLOW2 } _normalState; // State only valid when _state == NORMAL 
unsigned long _time; // _time only valid when _state == NORMAL

void loop() 
{
   if ('serial input available')
   {
      if ('input == ...')
      {
         _state = NORMAL;
      }
      else if ('input == ...')
      {
         _state = SPECIAL;
      }
      ...
   }

   switch (_state)
   {
   case NORMAL:
       if (_time + ... > time())
       {
          // Change to next state
          switch (_normalState)
          {
          case RED:
              _normalState = YELLOW1;
              _time = time();
              break;

          case YELLOW1:
              _normalState = GREEN;
              _time = time();
              break;
          ...
          }

       setLight(_normalState); // Change the light according to the _normalState
       break;



   case SPECIAL:
       ...
       break;

   ...
   }
}

Ideas to improve/explain:

  • Try to make some specific functions for setting the light according to the current state
  • You do not need a delay
  • Split functions (like above, make a separate function for normal state, and specific state
| improve this answer | |
1

thankyou for your responses.
I managed to solve this myself by using a while loop to store the code inside each switch case, my working code is below, utilising Serial.peek() and by changing the input ending in the serial monitor to no line ending.

while ((Serial.peek() == -1)){
          regularMode(ledRed, ledYellow, ledGreen);
}

Serial.peek() gets the next item from the serial stack, if there is nothing there, it returns '-1' so i can check against that as shown above.

| improve this answer | |
  • Yes, you need a non-blocking operation to check if there is pending chars in the stream. peek() is correct, but Serial.available() is more stream-related. – caligari Feb 28 '19 at 10:00

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.