Sketch works 99% although curious response - any assistance?

I have a spring-return SPDT rocker switch, GND and to pins 10 and 11. Also RGB led. LED is blue in switch open state, on switching one way, LED goes red fine. On switching the other way (switch on/green) I can see in the serial monitor that it alternates from switch on / neither switch on / switch on / neither switch on etc. and the LED flashes green / blue / green / blue etc. Not sure why as exact same code as per switch off % RED which works perfectly? Any thoughts?

I have played with different permutations of the code, ie just If switch1 on etc but this didn't work well, I would have thought the arduino would be able to see if switch 1 on, then do routine 1 and if switch2 on do routine 2 else do nothing routine, but this didn't work either, eventually I found that if switch 1 on && switch2 off, then do routine 1 etc. Not sure why as to any of the above to be honest. This is the first sketch/arduino I've done so very much a beginner

// Prior to Setup
int green_light_pin = 5; ;// Green pin connected to digital pin 5
int blue_light_pin = 6; // Blue pin connected to digital pin 6
int red_light_pin = 7; // Red pin connected to digital pin 7


int switch_on_pin = 11; // switch on pin connected to digital pin 11
int switch_off_pin = 10; // switch off pin connected to digital pin 10


int switch_on_val = 0; // value used to store the state of the input pin
int switch_off_val = 0; // value used to store the state of the input pin


// Setup
void setup() {
  pinMode(green_light_pin, OUTPUT); // sets the greenPin as an output
  pinMode(blue_light_pin, OUTPUT); // sets the bluePin as an output
  pinMode(red_light_pin, OUTPUT); // sets the redPin as an output


pinMode(switch_on_pin, INPUT_PULLUP);    // declare on switch as input + activate internal pull-up resistor
pinMode(switch_off_pin, INPUT_PULLUP);    // declare off switch as input + activate internal pull-up resistor


// turn LED cyan 
  RGB_color(0, 255, 255); 

// initialize serial communication:
  Serial.begin(9600);

} // close void setup







// Loop
void loop() {

  switch_on_val = digitalRead(switch_on_pin); // read the state


  switch_off_val = digitalRead(switch_off_pin); // read the state
delay(10); // small delay to prevent switch bounce


// check whether if condition is true
  if (switch_on_val == HIGH && switch_off_val == LOW) {

switch_on();

  } // closing if statement

  

if (switch_on_val == LOW && switch_off_val == HIGH) {

switch_off();


  } // closing else if statement






else {

RGB_color(0, 0, 255); // turn blue

Serial.println("LED is blue neither switch on ");

  } // closing else if statement






}

// this following void command is like a DEFINE FUNCTION command in that it defines rgb color as a command consisting of 3 integers and then as specified in the curly brackets, analogwrites to each of these as specified


void RGB_color(int red_light_value, int green_light_value, int blue_light_value)
{
  analogWrite(red_light_pin, red_light_value);
  analogWrite(green_light_pin, green_light_value);
  analogWrite(blue_light_pin, blue_light_value);

  }



void switch_on()  //switch on subroutine function
{
RGB_color(0, 255, 0); // turn green

Serial.println("LED is green for switch on ");

}

void switch_off()  //switch off subroutine function
{
RGB_color(255, 0, 0); // turn red

Serial.println("LED is red for switch on ");

}
Serial.println("LED is blue neither switch on ");

But that's not true, switch_off_val could be HIGH or LOW.

Well hi again Paul. Same project, I am still getting bits working before combining. That bit of the sketch seems to work. serial monitor shows that it's only printing that line when rocker switch is in neutral position.

It should print that when either
1: switch_on_val == HIGH && switch_off_val == LOW
2: switch_on_val == HIGH && switch_off_val == HIGH

(It would also print that when switch_on_val == LOW && switch_off_val == LOW, but that can't happen for mechanical reasons)

This is the serial output.

LED is red for switch on <--- correct for switch in position 1
LED is red for switch on
LED is red for switch on
LED is red for switch on
LED is red for switch on
LED is red for switch on
LED is red for switch on
LED is blue neither switch on <--- correct for switch in neutral position
LED is blue neither switch on
LED is blue neither switch on
LED is blue neither switch on
LED is blue neither switch on
LED is blue neither switch on
LED is blue neither switch on
LED is green for switch on <--- seems to vascillate when switch in position 2
LED is blue neither switch on
LED is green for switch on
LED is blue neither switch on
LED is green for switch on
LED is blue neither switch on
LED is green for switch on
LED is blue neither switch on
LED is green for switch on
LED is blue neither switch on
LED is green for switch on
LED is blue neither switch on
LED is green for switch on
LED is blue neither switch on
LED is green for switch on
LED is blue neither switch on
LED is green for switch on
LED is blue neither switch on
LED is green for switch on
LED is blue neither switch on
LED is blue neither switch on
LED is blue neither switch on
LED is blue neither switch on

Let me give you some tips.

I suspect you are missing an "else". See if you can figure out where.

You can simplify your logic. Both pins can't be LOW at the same time. If one is LOW, the other must be HIGH.

  if (switch_on_val == HIGH && switch_off_val == LOW)

You don't need to check the state of both inputs because you are using a rocker switch. You don't even need two input pins as by using only one you can tell whether the switch is open or closed,

Well, my word. I added 'else' to the second if and it works perfectly. I originally wrote this like that as I understand the logic is that first if is false, then the code doesn't check it again. Well thanks again - it now works :slight_smile: I had been playing with if's and else ifs on and off all day as getting different results.

Glad it works. Now simplify it by reading only a single inpu

The switch has 3 pins, so can be on in two positions so surely this must require two inputs?

Hi,

I gather the OP is using a centre OFF rocker.

So we have

Position Pin 10 Pin 11 LED Binary
sw_on LOW HIGH RED 1
centre HIGH HIGH BLUE 3
sw_off HIGH LOW GREEN 2

Tom.... :grinning: :+1: :coffee: :australia:

1 Like

A SPDT switch can only be in 2 positions

Perhaps you don't actually have an SPDT switch but a 3 position switch with centre off

exactly. You table that well. Curiously if I just use 'if switch 1 high' or of switch 2 high, it doesn't work, which was why I added the 'if switch 1 high and switch 2 low' in the code which made it work.

Yes, a 3 position switch with centre off.

In your table, centre you have high high, is that because the pinmode is input_pullup? pulling them high?

In my view these lines are not "technically" correct.

You used a delay to avoid bouncing, but it is after the button has already been read
and will no longer change the value of the variable.

Here the button is read:
"switch_on_val = digitalRead (switch_on_pin); // read the state"
and after he has read it, you write:
"delay (10); // small delay to prevent switch bounce"
but what was the entry level at the time of reading?

I normally use it like this:

if (digitalRead (switch_on_pin) == HIGH) // If pressed
{
      delay (10); // Debouncing
      if (digitalRead (switch_on_pin) == HIGH) // If still pressed
     {
          switch_on_val = HIGH;
     }
}

RV mineirin

that makes good sense. I'll incorporate in to the code. thanks :slight_smile:

Hi,
Try this code, it uses switch.. case to select the appropriate LED colour by assigning your switching combinations a discrete value.

// Prior to Setup
int green_light_pin = 5; ;// Green pin connected to digital pin 5
int blue_light_pin = 6; // Blue pin connected to digital pin 6
int red_light_pin = 7; // Red pin connected to digital pin 7


int switch_on_pin = 11; // switch on pin connected to digital pin 11
int switch_off_pin = 10; // switch off pin connected to digital pin 10


int switch_on_val = 0; // value used to store the state of the input pin
int switch_off_val = 0; // value used to store the state of the input pin

int switchon_valbin = 0; // value used to store the state of the input pin
int switchoff_valbin = 0; // value used to store the state of the input pin
int LEDVal = 0;

// Setup
void setup() {
  pinMode(green_light_pin, OUTPUT); // sets the greenPin as an output
  pinMode(blue_light_pin, OUTPUT); // sets the bluePin as an output
  pinMode(red_light_pin, OUTPUT); // sets the redPin as an output


  pinMode(switch_on_pin, INPUT_PULLUP);    // declare on switch as input + activate internal pull-up resistor
  pinMode(switch_off_pin, INPUT_PULLUP);    // declare off switch as input + activate internal pull-up resistor


  // turn LED cyan
  RGB_color(0, 255, 255);

  // initialize serial communication:
  Serial.begin(9600);

} // close void setup

// Loop
void loop() {

  switch_on_val = digitalRead(switch_on_pin); // read the state
  if (switch_on_val)  // Assign a value to switch position
  {
    switchon_valbin = 1;
  }
  else
  {
    switchon_valbin = 0;
  }

  switch_off_val = digitalRead(switch_off_pin); // read the state
  if (switch_off_val)  // Assign a value to switch position
  {
    switchoff_valbin = 2;
  }
  else
  {
    switchoff_valbin = 0;
  }
  LEDVal = switchon_valbin + switchoff_valbin;  // Calculate the LED display Value

  switch (LEDVal)    // Select the RGB colour according to switch value
  {
    case 1:  // Red
      RGB_color(255, 0, 0);
      Serial.println("Switch in RED position");
      break;
    case 2:  // Green
      RGB_color(0, 255, 0);
      Serial.println("Switch in GREEN position");
      break;
    case 3:  // Blue
      RGB_color(0, 0, 255);
      Serial.println("Switch in CENTRE BLUE position");
    default:
      RGB_color(0, 0, 0);
      Serial.println("Switch in UNDEFINED position");
      break;
  }
delay(250);  // delay to slow the monitor update down
}

// this following void command is like a DEFINE FUNCTION command in that it defines rgb color as a command consisting of 3 integers and then as specified in the curly brackets, analogwrites to each of these as specified


void RGB_color(int red_light_value, int green_light_value, int blue_light_value)
{
  analogWrite(red_light_pin, red_light_value);
  analogWrite(green_light_pin, green_light_value);
  analogWrite(blue_light_pin, blue_light_value);

}

/*

  void switch_on()  //switch on subroutine function
  {
  RGB_color(0, 255, 0); // turn green

  Serial.println("LED is green for switch on ");

  }

  void switch_off()  //switch off subroutine function
  {
  RGB_color(255, 0, 0); // turn red

  Serial.println("LED is red for switch on ");

  }
*/

Tom... :grinning: :+1: :coffee: :australia:

Based on what we know from @awesomness99 so far, there is no need and no point debouncing at all.

However, given the fact that this is a spring-return switch, @awesomness99 may reveal what its true purpose is, in their next post, and it wouldn't be a surprise to learn that debouncing will be needed after all.

Hi, I'm trying Wokwi, and I put your project in Wokwi.
@TomGeorge, did you test your sketch ? I had to make a few changes and made a few more to my liking.
In the upper-middle is the start-button to start the simulation. I had to use two pushbuttons instead of the rocker switch.

Hi TG, thats brilliant. thank you. It works, when switch is depressed either way it glows red or green as expected...except when switch in neutral position the LED flashes weakly. Serial monitor reports this:

Switch in UNDEFINED position
Switch in CENTRE BLUE position
Switch in UNDEFINED position
Switch in CENTRE BLUE position
etc

Getting rid of the DEFAULT case (undefined) fixed this though,

What you have done is great. Was thinking perhaps the Switch / case statement is best as ultimately, the below table is what I want to do, so there will be more cases

Case Amplifier Door Switch 1 Switch 2 Action
1 On Closed Open / green
2 On Open Magenta
3 Off Open Close / red
4 Off Closed Off / blue
5 HIGH Open / green
6 HIGH Close / red

Hi Koepel, I tried the sketch and it didn't work However uploaded some of my code and got it to work