Arduino Uno: 3 Position Switch Code

Hello Forum,
I’m just starting out on programming, and I’ve had to forcefully start a code for a 3-position on-off-on switch with 3 pins. 1,2,3 or L, C and R (Left, Center and Right)
One connects to ground and the other two to two digital pins.

The idea is to send MIDI CC # messages at each switch position.

I still need to define when position 1 is off and position 3 is off, that is, the switch is in position 2, or central, make the code for this.

I was able to assign MIDI CC # to each end position.

The question is how to stop sending the message, when the switch is set to 1 or 3 (L or R)
In Hairless Midi it continues to send the message eternally, depending on the delay you place on it.

This is the code:

 #include <MIDI.h>   
int sw_L = 6;
int sw_C ; // falta definir cuando sw_L =off y sw_R =off, así Center =on
int sw_R = 5;

void setup()
{
  Serial.begin(115200);     //hairless + loop midi (via usb - pc) descargar hairless y loop midi - conecta con PEDALERA gt-1000 a traves de loopmidi


 
//-----------------/ SETUP - INTERRUPTOR 3 POS /--------------------------

pinMode (sw_L, INPUT_PULLUP);
pinMode (sw_R, INPUT_PULLUP);
}

//-----------------/ LOOP - INTERRUPTOR 3 POS /--------------------------
if (digitalRead(sw_L)==LOW){
MIDI.sendControlChange(8, 0, 1);
      delay(200);// no se detiene el envio del mensaje
 
}
if (digitalRead(sw_R)==LOW){
MIDI.sendControlChange(8, 127, 1);
      delay(200);// no se detiene el envio del mensaje
 
}
//-----------------/ end LOOP - INTERRUPTOR 3 POS /--------------------------

}

Not sure what you want, but the state change detection example may be the answer. Look in the IDE digital examples.

please describe very detailed in normal words what you want the program to do.

it is a 3-position switch

left-on-----middle-off-------right-on

what shall happen if switch is in position left-on?

what shall happen if switch is in position middle-off?

what shall happen if switch is in position right-on?

please use normal words. No programming-terms at all.
You are a beginner and might have a misconception about a programming-term.
For sure you are a professional about using normal words.

Your description shal include of your code should send a midi-comand ony once per changening the switching-state or continously

best regards Stefan

If each pin controls one bit in a two bit number, the value of the number (0-3) can be used to determine which of the three positions the switch is in.

#include <MIDI.h>


const byte sw_LPin = 6;
const byte sw_RPin = 5;


//-----------------/ SETUP - INTERRUPTOR 3 POS /--------------------------
void setup()
{
  Serial.begin(115200);    


  pinMode (sw_LPin, INPUT_PULLUP);
  pinMode (sw_RPin, INPUT_PULLUP);
}




//-----------------/ LOOP - INTERRUPTOR 3 POS /--------------------------
void loop()
{
  // 0 = Both LOW.  INVALID
  // 1 = Left LOW,  Right HIGH.  RIGHT position
  // 2 = Left HIGH, Right LOW.  LEFT position
  // 3 = Left HIGH, Right HIGH. CENTER position
  enum positions {INVALID, RIGHT, LEFT, CENTER};
  static positions previousSwitchPosition = INVALID;
  positions switchPosition = (positions) (digitalRead(sw_LPin) * 2 + digitalRead(sw_RPin));


  if (switchPosition != previousSwitchPosition)
  {
    previousSwitchPosition = switchPosition;
    switch (switchPosition)
    {
      case LEFT:  MIDI.sendControlChange(8, 0, 1); break;
      case RIGHT: MIDI.sendControlChange(8, 127, 1); break;
      case CENTER: break;
      case INVALID: break;
    }
  }
}
//-----------------/ end LOOP - INTERRUPTOR 3 POS /--------------------------

Ok, Thanks for your replies.

In normal words:

3 position Switch

LEFT: send just one midi control change value (0) with CC# 8 and channel 1. This conect digital pin 6

CENTER: send just one midi control change value (63) with CC# 8 and channel 1. Don’t have pin… :frowning:

RIGHT: send just one midi control change value (127) with CC# 8 and channel 1. Conect digital pin 5

OH, my code:

#include <MIDI.h>   

int sw_L = 6;
int sw_C ;
int sw_R = 5;
bool L = false;
bool R = false;


void setup() 
{
  Serial.begin(115200);     //hairless + loop midi (via usb - pc) descargar hairless y loop midi - conecta con PEDALERA gt-1000 a traves de loopmidi


 
//-----------------/ SETUP - INTERRUPTOR 3 POS /--------------------------

pinMode (sw_L, INPUT_PULLUP);
pinMode (sw_R, INPUT_PULLUP);
L=false;
R=false;
}

void loop() {


//-----------------/ LOOP - INTERRUPTOR 3 POS /--------------------------
if (digitalRead(sw_L)==LOW){
  L=true; 
  R=false;
  MIDI.sendControlChange(8, 0, 1); //(CC#,Value,Ch)
  delay(200);
  
}
if (digitalRead(sw_R)==LOW){
  R=true;
  L=false;
  MIDI.sendControlChange(8, 127, 1); //(CC#,Value,Ch)
  delay(200);
  
}
  if (digitalRead(sw_R)==HIGH && digitalRead(sw_L)==HIGH){
  MIDI.sendControlChange(8, 63, 1);  //(CC#,Value,Ch)
  delay(200);
}
//-----------------/ end LOOP - INTERRUPTOR 3 POS /--------------------------

Hey mr. Jonh, your code is amazing, I dont understand this part:

enum positions {INVALID, RIGHT, LEFT, CENTER};
  static positions previousSwitchPosition = INVALID;
  positions switchPosition = (positions) (digitalRead(sw_LPin) * 2 + digitalRead(sw_RPin));

The code works really well!

this is the complete code:

#include <MIDI.h>
#include "Controller.h" 

const byte sw_LPin = 9;
const byte sw_RPin = 10;


MIDI_CREATE_DEFAULT_INSTANCE(); //Very important to iniciate

//-----------------/ SETUP - INTERRUPTOR 3 POS /--------------------------
void setup()
{
  Serial.begin(115200);    


  pinMode (sw_LPin, INPUT_PULLUP);
  pinMode (sw_RPin, INPUT_PULLUP);
}




//-----------------/ LOOP - INTERRUPTOR 3 POS /--------------------------
void loop()
{
  // 0 = Both LOW.  INVALID
  // 1 = Left LOW,  Right HIGH.  RIGHT position
  // 2 = Left HIGH, Right LOW.  LEFT position
  // 3 = Left HIGH, Right HIGH. CENTER position
  enum positions {INVALID, RIGHT, LEFT, CENTER};
  static positions previousSwitchPosition = INVALID;
  positions switchPosition = (positions) (digitalRead(sw_LPin) * 2 + digitalRead(sw_RPin));


  if (switchPosition != previousSwitchPosition)
  {
    previousSwitchPosition = switchPosition;
    switch (switchPosition)
    {
      case LEFT:  MIDI.sendControlChange(8, 0, 1); delay(50);
      break;
      case RIGHT: MIDI.sendControlChange(8, 127, 1); delay(50);
      break;
      case CENTER: MIDI.sendControlChange(8, 63, 1); delay(50); //this is the middle set
      break;
      case INVALID: break; 
    }
  }
}
//-----------------/ end LOOP - INTERRUPTOR 3 POS /--------------------------

another thing, how can I add the other two switches?
There are 3 switches in total

Sw_1 pin5, pin6 CC#8, ch1
Sw_2 pin7, pin8 CC#9, ch1
Sw_3 pin9, pin10 CC#10, ch1

barbol_music:
Hey mr. Jonh, your code is amazing, I dont understand this part:

enum positions {INVALID, RIGHT, LEFT, CENTER};

static positions previousSwitchPosition = INVALID;
 positions switchPosition = (positions) (digitalRead(sw_LPin) * 2 + digitalRead(sw_RPin));

The 'enum' (enumeration) is an easy way to assign values to names. By default, it starts as 0 and increments by 1 so:
INVALID = 0, RIGHT = 1, LEFT = 2, and CENTER = 3.
The digitalRead() function returns 0 for LOW and 1 for HIGH. For an INPUT_PULLUP pin and a switch to Ground, a CLOSED switch reads LOW/0 and an OPEN switch reads HIGH/1.
Looks like I got the number order wrong. Since I multiply the LEFT value by 2 the order should be INVALID, LEFT, RIGHT, CENTER. If both switches are OPEN/HIGH/1 the result is 3 (CENTER). If the LEFT side is CLOSED/LOW/0 and the RIGHT side is OPEN/HIGH/1 the result is 1. If the LEFT side is OPEN/HIGH/1 and the RIGHT side is CLOSED/LOW/0 the result is 2.

To add two more switches, define more pins and repeat the code.

Oh Hello mr. *John

ok I understand something, but it works, Im happy…

But I follow this John_lines: “To add two more switches, define more pins and repeat the code.”
ok Im obedient…

#include <MIDI.h>
#include "Controller.h" 

const byte sw1_LPin = 5;
const byte sw1_RPin = 6;
const byte sw2_LPin = 7;
const byte sw2_RPin = 8;
const byte sw3_LPin = 9;
const byte sw3_RPin = 10;

MIDI_CREATE_DEFAULT_INSTANCE();

//-----------------/ SETUP - INTERRUPTOR 3 POS /--------------------------
void setup()
{
  Serial.begin(115200);    


  pinMode (sw1_LPin, INPUT_PULLUP);
  pinMode (sw1_RPin, INPUT_PULLUP);
  
  pinMode (sw2_LPin, INPUT_PULLUP);
  pinMode (sw2_RPin, INPUT_PULLUP);
  
  pinMode (sw3_LPin, INPUT_PULLUP);
  pinMode (sw3_RPin, INPUT_PULLUP);
}




//-----------------/ LOOP - INTERRUPTOR 3 POS /--------------------------
void loop()
{
  // 0 = Both LOW.  INVALID
  // 1 = Left LOW,  Right HIGH.  RIGHT position
  // 2 = Left HIGH, Right LOW.  LEFT position
  // 3 = Left HIGH, Right HIGH. CENTER position
  enum positions1 {INVALID, RIGHT, LEFT, CENTER};
  static positions1 previousSwitchPosition = INVALID;
  positions1 switchPosition = (positions1) (digitalRead(sw1_LPin) * 2 + digitalRead(sw1_RPin));

  if (switchPosition != previousSwitchPosition)
  {
    previousSwitchPosition = switchPosition;
    switch (switchPosition)
    {
      case LEFT:  MIDI.sendControlChange(8, 0, 1); delay(50); break;
      case RIGHT: MIDI.sendControlChange(8, 127, 1); delay(50); break;
      case CENTER: MIDI.sendControlChange(8, 63, 1); delay(50); break;
      case INVALID: break; 
    }
  }
   enum positions {INVALID, RIGHT, LEFT, CENTER};
  static positions previousSwitchPosition = INVALID;
  positions switchPosition = (positions) (digitalRead(sw2_LPin) * 2 + digitalRead(sw2_RPin));

  if (switchPosition != previousSwitchPosition)
  {
    previousSwitchPosition = switchPosition;
    switch (switchPosition)
    {
      case LEFT:  MIDI.sendControlChange(9, 0, 1); delay(50); break;
      case RIGHT: MIDI.sendControlChange(9, 127, 1); delay(50); break;
      case CENTER: MIDI.sendControlChange(9, 63, 1); delay(50); break;
      case INVALID: break; 
    }
  }
  enum positions {INVALID, RIGHT, LEFT, CENTER};
  static positions previousSwitchPosition = INVALID;
  positions switchPosition = (positions) (digitalRead(sw3_LPin) * 2 + digitalRead(sw3_RPin));

  if (switchPosition != previousSwitchPosition)
  {
    previousSwitchPosition = switchPosition;
    switch (switchPosition)
    {
      case LEFT:  MIDI.sendControlChange(10, 0, 1); delay(50); break;
      case RIGHT: MIDI.sendControlChange(10, 127, 1); delay(50); break;
      case CENTER: MIDI.sendControlChange(10, 63, 1); delay(50); break;
      case INVALID: break; 
    }
  }

  
}
//-----------------/ end LOOP - INTERRUPTOR 3 POS /--------------------------

But the part of “repeat the code” throws duplications and multiple declarations and redeclarations …

:frowning:

Maybe I need to put a different number to each code word… ???

The ‘positions’ enum only has to be declared once. Variables that don’t have to be remembered (like switchPosition) should only be declared once and used repeatedly. Variables that are ‘static’ should have one copy per switch so those get a number.

#include <MIDI.h>
// #include "Controller.h"  // Not used here


const byte sw1_LPin = 5;
const byte sw1_RPin = 6;
const byte sw2_LPin = 7;
const byte sw2_RPin = 8;
const byte sw3_LPin = 9;
const byte sw3_RPin = 10;


MIDI_CREATE_DEFAULT_INSTANCE();


//-----------------/ SETUP - INTERRUPTOR 3 POS /--------------------------
void setup()
{
  Serial.begin(115200);


  pinMode (sw1_LPin, INPUT_PULLUP);
  pinMode (sw1_RPin, INPUT_PULLUP);


  pinMode (sw2_LPin, INPUT_PULLUP);
  pinMode (sw2_RPin, INPUT_PULLUP);


  pinMode (sw3_LPin, INPUT_PULLUP);
  pinMode (sw3_RPin, INPUT_PULLUP);
}




//-----------------/ LOOP - INTERRUPTOR 3 POS /--------------------------
void loop()
{
  // 0 = Both LOW.  INVALID
  // 1 = Left LOW,  Right HIGH.  LEFT position
  // 2 = Left HIGH, Right LOW.   RIGHT position
  // 3 = Left HIGH, Right HIGH.  CENTER position
  enum positions {INVALID, LEFT, RIGHT, CENTER};


  static positions previousSwitch1Position = INVALID;
  static positions previousSwitch2Position = INVALID;
  static positions previousSwitch3Position = INVALID;


  positions switchPosition;


  switchPosition = (positions) (digitalRead(sw1_LPin) * 2 + digitalRead(sw1_RPin));


  if (switchPosition != previousSwitch1Position)
  {
    previousSwitch1Position = switchPosition;
    switch (switchPosition)
    {
      case LEFT:  MIDI.sendControlChange(8, 0, 1); delay(50); break;
      case RIGHT: MIDI.sendControlChange(8, 127, 1); delay(50); break;
      case CENTER: MIDI.sendControlChange(8, 63, 1); delay(50); break;
      case INVALID: break;
    }
  }




  switchPosition = (positions) (digitalRead(sw2_LPin) * 2 + digitalRead(sw2_RPin));


  if (switchPosition != previousSwitch2Position)
  {
    previousSwitch2Position = switchPosition;
    switch (switchPosition)
    {
      case LEFT:  MIDI.sendControlChange(9, 0, 1); delay(50); break;
      case RIGHT: MIDI.sendControlChange(9, 127, 1); delay(50); break;
      case CENTER: MIDI.sendControlChange(9, 63, 1); delay(50); break;
      case INVALID: break;
    }
  }




  switchPosition = (positions) (digitalRead(sw3_LPin) * 2 + digitalRead(sw3_RPin));


  if (switchPosition != previousSwitch3Position)
  {
    previousSwitch3Position = switchPosition;
    switch (switchPosition)
    {
      case LEFT:  MIDI.sendControlChange(10, 0, 1); delay(50); break;
      case RIGHT: MIDI.sendControlChange(10, 127, 1); delay(50); break;
      case CENTER: MIDI.sendControlChange(10, 63, 1); delay(50); break;
      case INVALID: break;
    }
  }
}
//-----------------/ end LOOP - INTERRUPTOR 3 POS /--------------------------