Lights - machine state

Hello,

I try to control the light to turn on/off with 2 instant buttons (named b1, b2), N.O (normal opened).
These 2 buttons install on the line to limit a pointer moving in 2 directions (b2 on the left, b1 on the right). In the beginning, both lights turns OFF, the buttons are opened (as N.O).

When a pointer from the middle of line moving on the right direction, it hits b1 button (b1 closed), the Yellow light turns ON (during b2 is closed).
When the pointer leaving (changes direction to the left side), the b1 button releases (b1 is opened now), the RED light turns ON, until it hits the b2 button, the RED light turns OFF.

My problem is I can not turns OFF the RED light after the pointer living b2 button (b2 is opened) to start as beginning (all lights turns OFF). The RED light turns OFF ONLY when the b2 button is pressed.

Could you please tell me why ?

Here is my code:

/*
 * Arduino Uno R3
 * 2 pushed buttons + 2 lights (Yellow, Red)
 * 
 */
 
const unsigned int yellowPin = A4;  
const unsigned int redPin    = A5;         

const unsigned int b1Pin = 11;      // Buttons (with INPUT_PULLUP resistors). 
const unsigned int b2Pin = 12;      // Reset (no lights turn ON)   
           

int b1, b2;                         // Values read from b1Pin, b2Pin pins

enum indState_t : int {
  YELLOW_ON = 1,          // State during yellow lights ON
  RED_ON = 2,             // State during red lights ON
  NONE = 3                // State resetting (no lights turn ON)
} indState;

void setup() {
  pinMode(yellowPin, OUTPUT);
  pinMode(redPin, OUTPUT);

  pinMode(b1Pin, INPUT_PULLUP);
  pinMode(b2Pin, INPUT_PULLUP);
}
  
void loop() {
  
  // read switches
  b1 = digitalRead(b1Pin);      // Read b1 button states
  b2 = digitalRead(b2Pin);      // Read b2 button states

  YR_Process();
  YR_States();
}

void YR_Process (){

  switch (indState) {
     
    case YELLOW_ON:
      digitalWrite(redPin, HIGH);
      digitalWrite(yellowPin, LOW);  // Yellow ON
      break ;
   
    case RED_ON:
      digitalWrite(redPin, LOW);    // Red ON
      digitalWrite(yellowPin, HIGH);
      break ;

    case NONE:
      digitalWrite(redPin, HIGH);
      digitalWrite(yellowPin, HIGH);
      break ;
  }
}

void YR_States(){

  if (b1 == LOW){           // b1 button pressed
    indState = YELLOW_ON;
    }
  else {
    indState = RED_ON;      // b1 button released
    }
  
  if (b2 == LOW){           // b2 button pressed
    if (indState = RED_ON){
    indState = NONE;        // RED light turns OFF !
    }
  }
}

void Sleep() {                      // Set ALL 2 lights turn OFF
  digitalWrite(redPin, HIGH);
  digitalWrite(yellowPin, HIGH);
}
    if (indState = RED_ON)

Whoops

A diagram:

TIme
image hosting

OP's image

Have you fixed the problem with the comparison operator ?

Hello Bob,

Thanks for reply.

I have the same problem after correction to: if (indState == RED_ON)

Regards,

It might seem unnecessary but please post your program as it is now

Here is the code updated:

 /*
 * Arduino Uno R3
 * 2 pushed buttons (b1, b2) + 2 lights (Yellow, Red)
 * 
 */
 
const unsigned int yellowPin = A4; 
const unsigned int redPin    = A5;         

const unsigned int b1Pin = 11;      // Buttons (with INPUT_PULLUP resistors).
const unsigned int b2Pin = 12;      // Reset (no lights turn ON)   
           

int b1, b2;                         // Values read from b1Pin, b2Pin pins

enum indState_t : int {
  YELLOW_ON = 1,          // State during yellow lights ON
  RED_ON = 2,             // State during red lights ON
  NONE = 3                // State resetting (no lights turn ON)
} indState;

void setup() {
  pinMode(yellowPin, OUTPUT);
  pinMode(redPin, OUTPUT);

  pinMode(b1Pin, INPUT_PULLUP);
  pinMode(b2Pin, INPUT_PULLUP);
}
 
void loop() {
 
  // read switches
  b1 = digitalRead(b1Pin);      // Read b1 button states
  b2 = digitalRead(b2Pin);      // Read b2 button states

  YR_Process();
  YR_States();
}

void YR_Process (){

  switch (indState) {
     
    case YELLOW_ON:
      digitalWrite(redPin, HIGH);
      digitalWrite(yellowPin, LOW);  // Yellow ON
      break ;
   
    case RED_ON:
      digitalWrite(redPin, LOW);    // Red ON
      digitalWrite(yellowPin, HIGH);
      break ;

    case NONE:
      digitalWrite(redPin, HIGH);
      digitalWrite(yellowPin, HIGH);
      break ;
  }
}

void YR_States(){

  if (b1 == LOW){           // b1 button pressed, yellow light turns ON
    indState = YELLOW_ON;
    }
  else {
    indState = RED_ON;      // b1 button released, yellow light turns OFF, red light turns ON immidiately
    }
 
  if (b2 == LOW){           // b2 button pressed
    if (indState == RED_ON){
    indState = NONE;        // RED light turns OFF while b2 is pressed by pointer. 
                            // When b2 opened, RED light turns OFF                          
    }
  }
}

void Sleep() {                      // Set ALL 2 lights turn OFF
  digitalWrite(redPin, HIGH);
  digitalWrite(yellowPin, HIGH);
}

UKHeliBob:

    if (indState = RED_ON)

Whoops

I always try to write if code like this:

if(RED_ON == indState) {...}

because if you forget one = in the code, you (should) get a compilation error. Always put the constant before the ==, not after.

Also, if it is a function:

if (someFunction(args) == indState) {...}

thehardwareman:
I always try to write if code like this:

if(RED_ON == indState) {...}

because if you forget one = in the code, you (should) get a compilation error. Always put the constant before the ==, not after.

If I could remember to write it that way, I could remember to write == in the first place :wink:

Hi,
Where in your timing diagram do you press b2?
Let get the logic understood first.


And a schematic would help.
Tom... :slight_smile:

Hi Tom,

b2 buton (closed/pressed) when the pointer hits b2 to turn OFF the RED light. The RED light continues turning OFF after the pointer changes direction: b2 opened/released as Initial state (YELLOW and RED lights: OFF, b1 and b2 button: opened).

Thanks for helps,

Just simplify, I have removed the statement: if (indState == RED_ON) {...} from the program.

The program is OK at b1 button position. It can make Yellow light:ON when b1 closed, and Red light: ON (yellow: OFF) when b1 opened.

But I don't know HOW to make the Red light: OFF after the pointer hits b2 button and release, meaning the program goto initial state where the Yellow&Red lights: OFF, b1&b2 buttons: OPENED as the beginning.

Thanks for your advice,

Here is the code updated:

 /*
 * Arduino Uno R3
 * 2 pushed buttons (b1, b2) + 2 lights (Yellow, Red)
 *
 */
 
const unsigned int yellowPin = A4;
const unsigned int redPin    = A5;         

const unsigned int b1Pin = 11;      // Buttons (with INPUT_PULLUP resistors).
const unsigned int b2Pin = 12;      // Reset (no lights turn ON)   
           

int b1, b2;                         // Values read from b1Pin, b2Pin pins

enum indState_t : int {
  YELLOW_ON = 1,          // State during yellow lights ON
  RED_ON = 2,             // State during red lights ON
  NONE = 3                // State resetting (no lights turn ON)
} indState;

void setup() {
  pinMode(yellowPin, OUTPUT);
  pinMode(redPin, OUTPUT);

  pinMode(b1Pin, INPUT_PULLUP);
  pinMode(b2Pin, INPUT_PULLUP);
}
 
void loop() {
 
  // read switches
  b1 = digitalRead(b1Pin);      // Read b1 button states
  b2 = digitalRead(b2Pin);      // Read b2 button states

  YR_Process();
  YR_States();
}

void YR_Process (){

  switch (indState) {
     
    case YELLOW_ON:
      digitalWrite(redPin, HIGH);
      digitalWrite(yellowPin, LOW);  // Yellow ON
      break ;
   
    case RED_ON:
      digitalWrite(redPin, LOW);    // Red ON
      digitalWrite(yellowPin, HIGH);
      break ;

    case NONE:
      digitalWrite(redPin, HIGH);
      digitalWrite(yellowPin, HIGH);
      break ;
  }
}

void YR_States(){

  if (b1 == LOW){           // b1 button pressed, yellow light turns ON
    indState = YELLOW_ON;
    }
  else {
    indState = RED_ON;      // b1 button released, yellow light turns OFF, red light turns ON immidiately
    }
 
  if (b2 == LOW){           // b2 button pressed
    indState = NONE;        // RED light turns OFF at the moment b2 is hits/pressed by pointer.                         
    }
}

void Sleep() {                      // Set ALL 2 lights turn OFF
  digitalWrite(redPin, HIGH);
  digitalWrite(yellowPin, HIGH);
}

It would have been better if you answered Tom's diagram with another diagram. It really helps to see it in a picture.

I think I understand your request in replies 11 and 12 to mean that it can only enter the red state if it was yellow previously. Then the code would look like this...

if (b1 == LOW){           // b1 button pressed, yellow light turns ON
    indState = YELLOW_ON;
    }
  else if (indState == YELLOW_ON) {
    indState = RED_ON;      // b1 button released, yellow light turns OFF, red light turns ON immidiately
    }

Hello MorganS,

It's helped ! Thanks a lot for your advice.

It works now (as what I want)

Here is the final code:

 /*
 * Arduino Uno R3
 * 2 pushed buttons (b1, b2) + 2 lights (Yellow, Red)
 *
 */
 
const unsigned int yellowPin = A4;
const unsigned int redPin    = A5;        

const unsigned int b1Pin = 11;      // Buttons (with INPUT_PULLUP resistors).
const unsigned int b2Pin = 12;      // Reset (no lights turn ON)  
          

int b1, b2;                         // Values read from b1Pin, b2Pin pins

enum indState_t : int {
  YELLOW_ON = 1,          // State during yellow lights ON
  RED_ON = 2,             // State during red lights ON
  NONE = 3                // State resetting (no lights turn ON)
} indState;

void setup() {
  pinMode(yellowPin, OUTPUT);
  pinMode(redPin, OUTPUT);

  pinMode(b1Pin, INPUT_PULLUP);
  pinMode(b2Pin, INPUT_PULLUP);
}
 
void loop() {
 
  // read switches
  b1 = digitalRead(b1Pin);      // Read b1 button states
  b2 = digitalRead(b2Pin);      // Read b2 button states

  YR_Process();
  YR_States();
}

void YR_Process (){

  switch (indState) {
    
    case YELLOW_ON:
      digitalWrite(redPin, HIGH);
      digitalWrite(yellowPin, LOW);  // Yellow ON
      break ;
  
    case RED_ON:
      digitalWrite(redPin, LOW);    // Red ON
      digitalWrite(yellowPin, HIGH);
      break ;

    case NONE:
      digitalWrite(redPin, HIGH);
      digitalWrite(yellowPin, HIGH);
      break ;
  }
}

void YR_States(){

  if (b1 == LOW){           // b1 button pressed, yellow light turns ON
    indState = YELLOW_ON;
    }
  else if (indState == YELLOW_ON) {
    indState = RED_ON;      // b1 button released, yellow light turns OFF, red light turns ON immidiately
    }
 
  if (b2 == LOW){           // b2 button pressed
    indState = NONE;        // RED light turns OFF at the moment b2 is hits/pressed by pointer.                        
    }
}

void Sleep() {                      // Set ALL 2 lights turn OFF
  digitalWrite(redPin, HIGH);
  digitalWrite(yellowPin, HIGH);
}

[/quote]

TomGeorge:
Hi,
Where in your timing diagram do you press b2?
Let get the logic understood first.


And a schematic would help.
Tom... :slight_smile:

Hi Tom,

I can not display the URL image attached between "img" tags as in your reply.

Could you please show me ?

Thanks,

[img]https://ibb.co/vs6V9NS[/img]

Took me a bit to see why you don't need to debounce either button, hope you know that there are times when it's necessary.

viet5d:
Hi Tom,

I can not display the URL image attached between "img" tags as in your reply.

Could you please show me ?

Thanks,

[img]https://ibb.co/vs6V9NS[/img]
  • You post the image as an attachment to your post,
  • save your post,
  • then right click the attachment name and save the URL,
  • then select modify your post,
  • place the URL of the attached image into the img tags.

Tom... :slight_smile:

Testing...

draft.jpg

Steps 2&3:

draft.jpg

Thanks Tom !