Replace 3-way selector switch with 3 buttons that uses KEYPAD library...

Hi everyone! Fair warning: noob alert!

I've been wracking my brain on this one. I'm working through this project: 8-loop switch

#include <Key.h>
#include <Keypad.h>
#include <EEPROM.h>
#include <Wire.h>
#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

const int BTN1 = 30; //Pin for Button 1
const int BTN2 = 31; //Pin for Button 2
const int BTN3 = 32; //Pin for Button 3
const int LED1 = 50; //Pin for LED1 (for Button 1)
const int LED2 = 51; //Pin for LED2 (for Button 2)
const int LED3 = 52; //Pin for LED3 (for Button 3)
const int bankButton = 53; //Pin for Bank Button

const byte rows = 8; 
const byte cols = 3;
char keys[rows][cols] = {
{'a','i','q'},
{'b','j','r'},
{'c','k','s'},
{'d','l','t'},
{'e','m','u'},
{'f','n','v'},
{'g','o','w'},
{'h','p','x'} 
};

byte rowPins[rows] = {22, 23, 24,25, 26,27, 28, 29}; /*switch pins*/
byte colPins[cols] = {50, 51, 52}; /*3-way selector pins*/
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, rows, cols);
int relayPin[8] = {33,34,35,36,37,38,39,40}; /*relay/loop pins*/
int ledPin[8] = {41,42,43,44,45,46,47,48}; /*LED pins*/
byte midiChannel = 0;
int i;
int readOut;
int numberOfPedal = 8;

int bank = 0; //Starting Bank Number

boolean lastBTN1 = LOW;
boolean currentBTN1 = LOW;
boolean lastBTN2 = LOW;
boolean currentBTN2 = LOW;
boolean lastBTN3 = LOW;
boolean currentBTN3 = LOW;
boolean lastBankButton = LOW;
boolean currentBankButton = LOW;

/*  Setup  */

void setup()
{
  for(i=0; i<numberOfPedal; i++)
   {
    pinMode(relayPin[i], OUTPUT);
    pinMode(ledPin[i], OUTPUT);
    digitalWrite(relayPin[i],HIGH); //pullup all relay outputs
   }
Serial.begin(31250); /* for midi communication - pin 1 TX */
/*for (int i = 0; i < 512; i++) // erase eeprom (optional)
// EEPROM.write(i, 0); */
  pinMode(BTN1, INPUT); //Button 1 as INPUT
  pinMode(BTN2, INPUT); //Button 2 as INPUT
  pinMode(BTN3, INPUT); //Button 3 as INPUT
  pinMode(LED1, OUTPUT); //LED1 (for Button 1) as OUTPUT
  pinMode(LED2, OUTPUT); //LED2 (for Button 2) as OUTPUT
  pinMode(LED3, OUTPUT); //LED3 (for Button 3) as OUTPUT
  pinMode(bankButton, INPUT); //Bank Button as INPUT
  
  bank ++;
  digitalWrite(LED1, LOW); //Write LOW to Pin for LED1
  digitalWrite(LED2, HIGH); //Write HIGH to Pin for LED2
  digitalWrite(LED3, HIGH); //Write HIGH to Pin for LED3

  lcd.begin(16, 2); 
  lcd.print("You are trying"); 
  lcd.setCursor(0,1); 
  lcd.print("way too hard"); 
  delay(3000); 
  
  lcd.clear();
  lcd.print("Bank ");
  lcd.print(bank);
  lcd.setCursor(0,1);
  lcd.print("Normal Mode");
}


boolean BTN1debounce(boolean last) { //for Set Button
  boolean current = digitalRead(BTN1);
  if (last != current) {
    delay(5);
    current = digitalRead(BTN1);
  }
  return current;
}

boolean BTN2debounce(boolean last) { //for Switch Button
  boolean current = digitalRead(BTN2);
  if (last != current) {
    delay(5);
    current = digitalRead(BTN2);
  }
  return current;
}

boolean BTN3debounce(boolean last) { //for Loop Button
  boolean current = digitalRead(BTN3);
  if (last != current) {
    delay(5);
    current = digitalRead(BTN3);
  }
  return current;
}

boolean bankdebounce(boolean last) { //for Bank Button
  boolean current = digitalRead(bankButton);
  if (last != current) {
    delay(5);
    current = digitalRead(bankButton);
  }
  return current;
}

/*  */

void midiProg(byte status, int data)
{
Serial.write(status);
Serial.write(data);
}

/*  Switch select and store preset  */

void memory(int addr, int led)
{
  for(i=0; i<numberOfPedal; i++)
    {
      EEPROM.write((addr) + i, digitalRead(relayPin[i]));
      digitalWrite(ledPin[i], LOW);
    }
lcd.clear();lcd.print("Stored at ");
lcd.print(led + 1);
delay(100);
digitalWrite(ledPin[led], HIGH);
delay(100);
digitalWrite(ledPin[led], LOW);
delay(100);
digitalWrite(ledPin[led], HIGH);
delay(100);
digitalWrite(ledPin[led], LOW);
delay(100);
digitalWrite(ledPin[led], HIGH);
delay(100);
digitalWrite(ledPin[led], LOW);
delay(100);
digitalWrite(ledPin[led], HIGH);
lcd.clear();
}


/*  Loop select  */

void writeOut(int relay)
{
  digitalWrite(relayPin[relay], !digitalRead(relayPin[relay]));
  digitalWrite(ledPin[relay], !digitalRead(relayPin[relay]));
  lcd.clear();
  lcd.print(" loop FX ");
  lcd.print(relay + 1);

}
/*  Normal use/read mode  */

void readPreset(int addr, int pcNum, int led)
{
  for(i=0; i<numberOfPedal; i++)
  {
    digitalWrite(relayPin[i], EEPROM.read((addr)+i));
    digitalWrite(ledPin[i], LOW);
    digitalWrite(ledPin[led], HIGH);
   }
   lcd.clear();
   lcd.print(" Preset ");
   lcd.print(led + 1);
   midiProg(0xC0, pcNum +1); /* send midi change program 1 */

}

/*  Debounce and program stuff  */

void loop()
{

  currentBankButton = bankdebounce(lastBankButton); 
  if (lastBankButton == LOW && currentBankButton == HIGH) {
    bank ++;
    lcd.clear();
    lcd.print("Bank ");
    lcd.print(bank);
    lcd.setCursor(0,1);
    lcd.print("Hit Set/Play");
    if (bank >= 5) {
      bank = 0;
    }
  }
  lastBankButton = currentBankButton;


  currentBTN1 = BTN1debounce(lastBTN1); 
  if (lastBTN1 == LOW && currentBTN1 == HIGH) {
    digitalWrite(LED1, LOW); 
    digitalWrite(LED2, HIGH); 
    digitalWrite(LED3, HIGH); 
    lcd.clear();
    lcd.print("Bank ");
    lcd.print(bank);
    lcd.setCursor(0,1);
    lcd.print("Preset #");
  }
  lastBTN1 = currentBTN1;


  currentBTN2 = BTN2debounce(lastBTN2); 
  if (lastBTN2 == LOW && currentBTN2 == HIGH) {
    digitalWrite(LED1, HIGH); 
    digitalWrite(LED2, LOW); 
    digitalWrite(LED3, HIGH); 
    lcd.clear();
    lcd.print("Bank ");
    lcd.print(bank);
    lcd.setCursor(0,1);
    lcd.print("Choose Switch");
  }
  lastBTN2 = currentBTN2;


  currentBTN3 = BTN3debounce(lastBTN3); 
  if (lastBTN3 == LOW && currentBTN3 == HIGH) {
    digitalWrite(LED1, HIGH);
    digitalWrite(LED2, HIGH);
    digitalWrite(LED3, LOW); 
    lcd.clear();
    lcd.print("Bank ");
    lcd.print(bank);
    lcd.setCursor(0,1);
    lcd.print("Choose Loops");
  }
  lastBTN3 = currentBTN3;

char key = keypad.getKey();
if(key) // Check for a valid key.
  {
   switch (key)
    {
/*  LOOP SELECT MODE - 'a' to 'h' for 8 pedals; (relay number or led)  */
      case 'a': 
      writeOut(0);
      break;
     case 'b':
      writeOut(1);
      break;
     case 'c':
      writeOut(2);
      break;
     case 'd':
      writeOut(3);
      break;
     case 'e':
      writeOut(4);
      break;
     case 'f':
      writeOut(5);
      break;
     case 'g':
      writeOut(6);
      break;
     case 'h':
      writeOut(7);
      break;
/*  STORE PRESET MODE - (EEPROM address, led) */
      case 'i': 
      memory(11,0);
      break;
     case 'j':
      memory(21,1);
      break;
     case 'k':
      memory(31,2);
      break;
     case 'l':
      memory(41,3);
      break;
     case 'm':
      memory(51,4);
      break;
     case 'n':
      memory(61,5);
      break;
     case 'o':
      memory(71,6);
      break;
     case 'p':
      memory(81,7);
      break;
/*  READ PRESET MODE (EEProm address,PcNum,led number)  */
      case 'q':
      readPreset(11, 1, 0); 
      break;
     case 'r':
      readPreset(21, 2, 1);
      break;
     case 's':
      readPreset(31, 3, 2);
      break;
     case 't':
      readPreset(41, 4, 3);
      break;
     case 'u':
      readPreset(51, 5, 4);
      break;
     case 'v':
      readPreset(61, 6, 5);
      break;
     case 'w':
      readPreset(71, 7, 6);
      break;
     case 'x':
      readPreset(81, 8, 7);
      break;
      }
    }
}

It is a switch board to control guitar pedals: audio from guitar > 8 loops (send/return to pedals via relays). You select your loops (8 loops total) and program them to a preset button/switch.

This tutorial has this set up with a 3-way selector: Select loops, Select Preset & save to EEPROM, and Read from EEPROM the stored setting.

I'd like to replace the 3-way selector with 3 push buttons; however, since the selector manually cuts off the signal of the other 2 pins, when I replace the switch with LEDs, the KEYPAD library has all 3 selectors on at once.

I was able to get the LCD display and debounce function working for 3 buttons to call 3 LEDs either HIGH or LOW, but can't figure out how to make the keypad call only the LED that's LOW for the respective setting.

Is there a way to replace the 3-way selector with 3 push buttons for use with the keypad?

Thank you in advance!

Is there a way to replace the 3-way selector with 3 push buttons for use with the keypad?

Replacing a 3 way switch with 3 switches is possible. Making them emulate a 24 button keypad is not.

As I read your response (which is the response I was both dreading and expecting), I immediately thought about how to use footswitches with this... Then I thought about maybe using 2 non-momentary footswitches in place of the 3 way switch...

first switch, center pin: from momentary footswitches
first switch, position 1: read/normal mode (pin 50 from arduino)
first switch, position 2: connect to center pin of second switch

second switch, center pin: first switch, position 2 (momentary switches)
second switch, position 1: select loops (pin from 51 arduino)
second switch, position 2: select preset & save (pin 52 from arduino)

This way, there's always only one position in use at a time, and I may even be able to use LEDs to see which setting is on, as well as the LCD display to reinforce instructions. It would also take up a pin or 2 less on the arduino board.

I'll have to breadboard it up, but let me know if you see issues with the logic. :slight_smile:

Thanks for the quick response! :slight_smile:

Actually, with multi-position switches, you will more than likely have a momentary open circuit while the devices switches from one position to another. There are special switches that are called "make before break", but that is another bunch of problems.

Paul

Just FYI, I got it breadboarded up, and my 2 stomp switches replacing the 3-way rotary actually worked... The "problem" now is that the UI requires the user (aka, me) to hit the second switch once more AFTER I've programmed the preset in order to start the process again. This isn't the end of the world, as I can setup LEDs to the stomp switches to let me know what's active or not...

BUT, maybe 3 relays could work? This way I can control them with the arduino and code them to automatically default back to normal mode. By using delay(100), I could also ensure there's no overlap, too...

I don't have any spst relays around... I'll have to make an order soon and see.

So far, that would put me at 69 pins of the 70 available to me. The 70th one, I think with this code, is set aside for midi communication with itself (pin 0 for TX, but i could be reading the code wrong)...

My next step will be banking the presets - AKA, right now there's one back of 8 presets - I'd like to try and get anywhere from 5 to 8 banks of 8 presets each.

If anyone has any insight on how that can work with the keypad library, I'm all ears. Initial thought is writing to EEPROM based on bank number, and reading based on bank number, or using the bank number as an if/then statement in the cases to write to different memory locations, and reading a similar way. Thoughts?

Thanks again for the help, guys!