Introduction: Arduino Programable 5 Pedal Switcher

Picture of Arduino Programable 5 Pedal Switcher

Searching for a simple programable pedal switcher over the net I was
amazed about the overpriced gear around there... so I came out with DIY solution and found several great projects but found 'em too complicated (PCB etching...) or maybe too overpriced for my needs. All I needed at that time was the simplest possible programable true bypass relay switcher for 4 pedals but found a way to switch up to 5 pedals with the "nano" version of arduino UNO. With 2 Arduino nanos (thru serial communication) you can surely extend this as up to 8 switchers! (to see: second part of this instructable...). Posibility to add MIDI program change out on pin 1.

Addendum: connect a led in parallel of one of these little on the relay board (caution: check the polarity!). This manner you'll know which relay is on or off when programing. Tip: I 've used the hole of the screw near the inboard led to drill thru the chassis and put it the parallel one on. (see pictures on my second instructable )

After noob searching for the "code-part" of this project over internet and spent hours and hours of led debuging (hey, I'm NOT a coder, just a r'n'r guitar player!) I got out with an amazing library named "keypad.h". Initially intended to manage secret code doors within a keypad, we'll see how simple is to "fool" the code with a 3 way selector, so with only 5 momentary switches we'll can access up to 15 functions and store 5 presets on internal EEPROM! The hardware parts are current sees over Ebay / Google so please don't ask me "how and where can I buy this thing or this other..." ! Google is your friend and Ebay too!

Caution: some noise issues where experienced by some builders (me included). I suspect those cheap and chinese relays aren't made for audio signals. The ideal relays should be some called DPDT but for instance few advices can be followed: use shielded cables all along the signal path, ensure all the circuit in a metallic box use caps (usually 10u) for decoupling and/or add some high resistances to all in and outs jacks. Adding a booster pedal in front of the input may strongly reduce these noise...

------------------------------------------------------------------------------------

USE:

-position "A" (select switches) from the selector (cases 'a' 'b' 'c' 'd' 'e' on the sketch) -> select wich pedal to loop ON (1,2... 5). When finished, turn the selector to ->

-position "B" (preset memory mode -cases 'f' 'g' 'h' 'i' 'j') -> select the number of the preset (1 to 5) where you want to preserve the loops (the led of the preset you choose will lit 2 times. Caution: don't press the switch more than once because you'll reset the preset (all ' 0,0,0,0,0')!

-Rotate the selector back to position 'A', select another pedal combination and store it on next free preset on position "B". You can repeat this procedure 5 times. Once you have your 5 combination stored, rotate to->

-position "C" (cases 'k' 'l' 'm' 'n' 'o')-> read the preset (1 to 5) you memorized previously

-enjoy the art of rocking pedals with one footpress !!!


Step 1: Arduino Programable 5 Pedal Switcher

Picture of Arduino Programable 5 Pedal Switcher

So here are the parts:

-1 x arduino Nano with Atmega328 built-in (~4 to 5$)

-1 x 5 volt/2 amp power supply (~10 $)

-3 x ways rotary selector (~4$)

-5 x SPST Momentary Footswitches (~15$)

-5 x double relay modules (~ 15$)

-12 x chassis 6.3 female jack (~20$)

-10 x leds (half of a different color)

-5 x 220 to 560 ohms resistor (peanuts...)

-some spare cable (...)

~70$ if you don't have any of these as spare

(not included: metal chassis or woodbox or whatever...)

------------------------------------------------------------------------------------

and here are the tools:

-plyers

-soldering station

-eventually some tools for wood/metal/plastic working

------------------------------------------------------------------------------------

Here's the code part: (many thanks to Anton Efremoff for his feedback and suggestions) Tip: don't forget to add "//" on these two lines if you want to save your preset after booting it up!

//for (int =0;i<512;i++)
//EEPROM.write(i,0); It's here just for initialize EEPROM memory in case of debugging

You''l have first to download and install the keypad.h library here:

A big THANK YOU to Armando Colangelo aka 4Knobs Effects for this code . Note his project is based on a different approach that ommit the 3 positions switch and therefore adds 1 more selecting switch (6 instead of 5).

A video is available on youtube showing his awesome work.

Comments

Hein66 (author)2017-08-21

hi CarraN, i am not sure to find the right instruction in this here.

I want to create a 4 way looper for 1 instrument,

it means , at one side 1 input jacket, at the other side 1 output jacket.

in the middle my arduino mega board with different switches, different LED, in the best way to serv the switches with my foot.

is your work suitable for me ?

kindly regards

Hein66

CarraN (author)Hein662017-08-21

Hey

yes you're at the right place among others. This project is designed for 5 pedals with an arduino uno. If you have the Mega more options can be build.

cheers

livewir3 made it! (author)2017-10-09

hi CarraN,

thanks for the fun project and great instructions. I made some changes/updates to the code to use a click/hold button to substitute the 3way switch so the control can be done by foot (one click = bank control, presshold = go through A,B,C stages you had) i will add the code below if someone wants to use it. i have a prototype built waiting in hardware for the final thing. cheers again.

code here

==============================

/* programable stompbox looper. Original design and sketch by CarraN. Corrected, updated and upgraded by Pascal Paquay */
/* programable stompbox looper. Original design and sketch by CarraN. updated and upgraded by EltonO 09/10/17 */

#define LCDSCREEN 1 //#define LCDSCREEN 0 if not using lcd display

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

#if LCDSCREEN == 1
#include <LiquidCrystal_I2C.h>
/**********************************************************/
LiquidCrystal_I2C lcd(0x3F, 16, 2); // set the LCD address to 0x3f for a 16 chars and 2 line display
/*********************************************************/
#endif

const int ctrlButton = A6; //Pin for controll Button
const byte rows = 5;
const byte cols = 1;
char keys [rows][cols] = {'0','1','2','3','4'};
byte rowPins[rows] = {2,3,4,5,6};
byte colPins[cols] = {7};
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, rows, cols);
int ledPin[5] = {A3,A2,A1,A0,13};
int relayPin[5] = {8,9,10,11,12};
byte midiChannel = 0;
int i;
int readOut;
int numberOfPedal = 5; /*adapt this number to your needs = number of loop pedals */
int bankVariable = 5;
int numberOfBanks = 5;
int bank = 0; //Starting Bank Number
int presetSelect = 3;
int preset = 0;
int loop1 = 0;
int loop2 = 0;
int loop3 = 0;
int loop4 = 0;
int loop5 = 0;
int bounceTime = 20;
int holdTime = 1000;
int doubleTime = 1000;
int lastReading = HIGH;
int hold = 0;
int single = 0;

long onTime = 0;
long lastSwitchTime = 0;
boolean currentRead = LOW;
boolean lastRead = LOW;

void setup() {
for(i=0; i<numberOfPedal; i++)
{
pinMode(ctrlButton, INPUT_PULLUP);
pinMode(relayPin[i], OUTPUT);
pinMode(ledPin[i], OUTPUT);
digitalWrite(relayPin[i],LOW); //pullup all relay outputs in case off low level relayboard
digitalWrite(ledPin[i],HIGH); //pullup all relay outputs in case off low level relayboard
delay(100);
digitalWrite(relayPin[i],HIGH); //pullup all relay outputs in case off low level relayboard
digitalWrite(ledPin[i],LOW); //pullup all relay outputs in case off low level relayboard

}

Serial.begin(31250); /* for midi communication - pin 1 TX */
//Serial.begin(9600); /* for serial communication - pin RX/ TX */

// *for (int i = 0; i < 512; i++) // erase eeprom (optional)
// EEPROM.write(i, 0); */

#if LCDSCREEN == 1
lcd.clear();
lcd.init(); //initialize the lcd
lcd.backlight(); //open the backlight
lcd.print("| DIY FX 5 |");
lcd.setCursor(0,1);
lcd.print("| LOOPER |");
delay(3000);
lcd.setCursor(0,0);
lcd.print(" | |: ");
lcd.setCursor(0,1);
lcd.print(" | |: ");
lcd.setCursor(5,0);
lcd.print("Pset");
lcd.setCursor(0,0);
lcd.print("Bank");
lcdprint ();
#endif
}

/*********************************************************/
boolean debounce(boolean last,int ctrlButton) {
boolean current = analogRead(ctrlButton);
if (last != current) {
delay(50);
current = analogRead(ctrlButton);
}
return current;
}
/*********************************************************/

void loop() {

currentRead = debounce(lastRead,ctrlButton);
// int currentRead = digitalRead(ctrlButton);

//first pressed
if (currentRead == LOW && lastRead == HIGH ) {
onTime = millis();
}
singlePress();

if (currentRead == LOW && lastRead == LOW ) {
if ((millis() - onTime) > holdTime) {
hold = 1;
}
}

if (currentRead == HIGH && lastRead == LOW ) {

if (((millis() - onTime) > bounceTime) && hold != 1) {

doublePress();
}

holdPress();
}

char key = keypad.getKey();

if((key)&&(preset == 1)) // Check for a valid key.
{

switch (key)
{
case '0': // a to x
writeOut(0); // relay
break;
case '1':
writeOut(1);
break;
case '2':
writeOut(2);
break;
case '3':
writeOut(3);
break;
case '4':
writeOut(4);
break;

}
}
/****************************** STORE PRESET MODE */
if(key && preset == 2) // Check for a valid key.
{

switch (key)
{
case '0':
memory(100+(bank*bankVariable),0); //addr, led
break;
case '1':
memory(200+(bank*bankVariable),1);
break;
case '2':
memory(300+(bank*bankVariable),2);
break;
case '3':
memory(400+(bank*bankVariable),3);
break;
case '4':
memory(500+(bank*bankVariable),4);
break;
}

}
/****************************** READ PRESET MODE */
if(key && preset == 3||preset == 0) // Check for a valid key.
{

switch (key)
{
case '0':
readPreset(100+(bank*bankVariable), 1, 0); // addr, pcNum, relay
break;
case '1':
readPreset(200+(bank*bankVariable), 2, 1);
break;
case '2':
readPreset(300+(bank*bankVariable), 3, 2);
break;
case '3':
readPreset(400+(bank*bankVariable), 4, 3);
break;
case '4':
readPreset(500+(bank*bankVariable), 5, 4);
break;
}
}

delay (100);
lastRead = currentRead;

}

void singlePress() {

if (single == 1 && (millis() - lastSwitchTime) > doubleTime) {

// Serial.println("single press");
bank++;

#if LCDSCREEN == 1
lcdprint ();
#endif


if (bank == 1) { ledtoggle(8); }
if (bank == 2) { ledtoggle(9); }
if (bank == 3) { ledtoggle(10); }
if (bank == 4) { ledtoggle(11); }
if (bank == 5||bank == 0) { ledtoggle(12); }

if (bank >= numberOfBanks) {
bank = 0;

}
single = 0;
}
}
void doublePress() {

if ((millis() - lastSwitchTime) >= doubleTime) {
single = 1;
lastSwitchTime = millis();
return;
}

if ((millis() - lastSwitchTime) < doubleTime) {
// Serial.println("double press");

digitalWrite(8, LOW);
digitalWrite(10, LOW);
digitalWrite(12, LOW);

#if LCDSCREEN == 1
lcdprint ();
#endif


single = 0;
lastSwitchTime = millis();
}

}
void holdPress() {

if (hold == 1) {
preset++;
if (preset == 1) {

ledtoggle(A3);
#if LCDSCREEN == 1
lcd.setCursor(5,0);
lcd.print("Set ");
#endif

}
if (preset == 2) {
ledtoggle(A2);
#if LCDSCREEN == 1
lcd.setCursor(5,0);
lcd.print("Prog");
#endif


}
if (preset == 3||preset == 0) {

ledtoggle(A1);

#if LCDSCREEN == 1
lcd.setCursor(5,0);
lcd.print("Pset");
#endif

}


if (preset >= presetSelect) {
preset = 0;

}
hold = 0;
}
}
/*********************************************************/
void midiProg(byte status, int data)
{
Serial.write(status);
Serial.write(data);
}

/*********************************************************/

void memory(int addr, int led)
{
for(i=0; i<numberOfPedal; i++)
{
EEPROM.write((addr) + i, digitalRead(relayPin[i]));
digitalWrite(ledPin[i], LOW);

}
ledtoggle(ledPin[led]);
#if LCDSCREEN == 1
lcd.setCursor(8,1);
lcd.print(led + 1);
#endif

}

/*********************************************************/

void writeOut(int relay)
{
digitalWrite(relayPin[relay], !digitalRead(relayPin[relay]));
digitalWrite(ledPin[relay], !digitalRead(relayPin[relay]));

#if LCDSCREEN == 1
lcdprint ();
#endif


}

/*********************************************************/

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);
}

#if LCDSCREEN == 1
lcdprint ();
lcd.setCursor(8,1);
lcd.print(led + 1);
#endif


midiProg(0xC0, pcNum +1); /* send midi change program 1 */
}

void ledtoggle(int led)
{
digitalWrite(led, !digitalRead(led));
delay(100);
digitalWrite(led, !digitalRead(led));
delay(100);
digitalWrite(led, !digitalRead(led));
delay(100);
digitalWrite(led, !digitalRead(led));
delay(100);
digitalWrite(led, !digitalRead(led));
delay(100);
digitalWrite(led, !digitalRead(led));
delay(100);

}

void lcdprint() {
#if LCDSCREEN == 1
loop1 = !digitalRead (8);
loop2 = !digitalRead (9);
loop3 = !digitalRead (10);
loop4 = !digitalRead (11);
loop5 = !digitalRead (12);

lcd.setCursor(3,1);
lcd.print(bank);
lcd.setCursor(8,1);
lcd.print(">");
lcd.setCursor(11,0);
lcd.print("Loops");
lcd.setCursor(11,1);
lcd.print(loop1);
lcd.setCursor(12,1);
lcd.print(loop2);
lcd.setCursor(13,1);
lcd.print(loop3);
lcd.setCursor(14,1);
lcd.print(loop4);
lcd.setCursor(15,1);
lcd.print(loop5);
#endif


}

CarraN (author)livewir32017-10-10

Armando did that yet (see the loopino code here) but thanks mate!

cheers

livewir3 (author)CarraN2017-10-11

I did check armondos interestning work but i wanted something simple for what i needed to do and get to speed with arduino :)

Hein66 made it! (author)2017-08-23

that is my plan

hein66

CarraN (author)Hein662017-08-23

OKAAYYY... you're not in the right place, I'm affraid! What you're searching for is a PHRASE LOOPER not a pedal switcher. This project is for creating presets among 5 external pedals like distortion -> chorus or distortion -> delay-> comp...

sorry

Hein66 (author)CarraN2017-08-24

yes , i am afraid too.
thx for your comments. do you suppose there is a way to realize my plan with an ardiuno or an raspberry pi ?

CarraN (author)Hein662017-08-24

nope

cheers

Hein66 (author)2017-08-23

Hi CarraN, Ok, that is a good idea,So I have made a short image. Additional
I will mention, that always must be a connect through between input jack
and output jack.

Is your
solution suitable for me ?

Hein66

Hein66 (author)2017-08-21

Hi CarraN, thank you for your quickly response.

what i dont understand is, why do you use 5 pedals ?

For my 1 instrument ( = 1 input jacket ) , i should need 1 double relay, is'n it ?

I understand partially your sketch, but in the image, i cannot find out the relay connections of the relay and the mega board.

what can i do now ?

regards

hein66

CarraN (author)Hein662017-08-21

5 pedals is the max that can manage Arduino uno. But if you want less -4 in your case- just ignore the fifth relay. That said you don't even need a mega for that purpose. So well, the input jack is connected on the pin 2 of the first relay board and the out jack is connected to the pin 5 of the last realy board like in the schematic. You don't need to cable the ground, just the live cable. The connections between the Uno and relay boards is as you wish, just pay attention to select the good digital pins in your sketch. Hope it'll help you.

Hein66 (author)CarraN2017-08-22

Hi CarraN,
thank you for your patience with me. It is possible that we have a different wording and understanding of this issue ?
I am confused about the word “pedal” . In your schematic input jack is marked as “to pedal IN” , output jack as “to pedal OUT” .
What do you mean with this ? what is the function of your "pedal" ?

“to pedal IN” must be in my understanding “instrument IN” .
And “to pedal OUT” must be “to amplifier”
The only “pedal” I have are the foot switches to change the loop channel.
My plan is to have one input and one output jack.
Do I need for every couple of in/out jacks one relay
Or for every loop channel ?
What is correct ?
Sorry but I am musican, no specially technic freak.
Hein66

CarraN (author)Hein662017-08-22

what do you want to do?

Hein66 (author)CarraN2017-08-23

Hi CarraN,

Ok, that is a good idea,

So I have made a short image.

Additional
I will mention, that always must be a connect through between input jack
and output jack.

Is your
solution suitable for me ?

Hein66

Fever2112 (author)2017-03-05

In this picture you have a lighted LED ring around the foot switch.... where did you get these?

MachineClash (author)Fever21122017-03-10

Try this: https://guitarpedalparts.com/product/3pdt-foot-switch-with-led-ring-red/ or search "footswitch led ring"

NikolayZ6 (author)2017-01-28

I don't recommend to put relays on D13, because potential jumps few times on this pin when arduino starts. Check it with any light diode, you don't need to make changes in your code, it will blink anyway.

besiek2510 (author)2016-11-26

part where you connect DPDT? 3 rotary switch? One wire from DPDT Connecting to the plates and the other to 3 rotary switch. please help. I still question how to connect LED understand from one leg to the plates and the other leg of the resistor and what else? please scheme of connecting or photo

xenophontis (author)2016-10-06

This is my build of the 5 pedal switcher.

I couldn't find the right size of enclosure. This one was hard to fit everything in. but i got it all to fit anyhow.

I've added an extra footswitch / LED to add an extra feature, like a boost or bypass all. I just havn't hooked it up yet. But the switcher is done for now.

CarraN (author)xenophontis2016-10-06

cool! yes it seem pretty little !
Do you observe some noise issues with your pedals on (mostly with overdrives)?
Did you use the Armando's code or mine?
cheers

xenophontis (author)CarraN2016-10-15

I used your code for this project. This looper only has a little noise from the relays as you mentioned, but this goes away with a buffer before. I didn't use any decoupling capacitors either. one of my distortion pedals creates a very small going noise, but it's too quiet to warrant using decoupling caps. Thanks for posting this project, it so much fun and very hand to have. On my pedal board.

LidioR (author)2016-10-05

Dear CarraN, congrats, wonderful project.

Can you please send me the final code, including this correction to make sure the memory will be there when boot it up?

Thanks in advance, Lidio (Brazil)

CarraN (author)LidioR2016-10-05

Hi

just place // before these two lines:

//for (int =0;i<512;i++)
//EEPROM.write(i,0);

that's all

ArmandoC26 (author)2016-10-05

Thx CarraN!!

Also the code has a different approach to the keypad library. I've found that in a normal setup the standard keypad function is checking the pins for H/L too often and, being this digital and audio together, I was experiencing clicking on the audio path. Slowing down the loop with a delay of 500ms, I could hear about 2 clicks almost every second, so after searching for a solution, I've found on the net this different approach to keyboard reading, that looks like has solved the ticking issue (see byte keypad() function toward the end of the code)

CarraN (author)ArmandoC262016-10-05

Hi Armando!
I've never experienced these clicks but I know some builders have done. On the other hand, I have some noise issue when engaging my OCD on the signal path. I think this is due to the bad quality of these chinese relay board but I'm not sure... Anyway, good job coding and building! I've seen your pedals page: nice!
ciao!

ArmandoC26 (author)2016-10-05

... and sorry, it looks like I've 2 accounts ArmandoC26 and ArmandoC42... it's me in both case ;)

ArmandoC42 (author)2016-10-03

thanks

xenophontis

of course I can share the code, though it's about 900 line, don't wont to mess this board. I'll see if I can send it you via pm.

CarraN (author)ArmandoC422016-10-04

Yo!

can you share your code with all? it's an instructable in the end...

thanks!

ArmandoC42 (author)CarraN2016-10-04

Yes I can and will, just don't know how to attach a file here to be shared to all. Or should I post the whole programm as a reply? That's about 1000 lines!

See if you can access this link

http://media.wix.com/ugd/914253_e98e388d1ef14535b948603821d10bec.pdf

ArmandoC42 (author)ArmandoC422016-10-04

Better ?

https://drive.google.com/drive/folders/0ByzWvdNvN7jDRjh4cFlkM25BNTg?usp=sharing

ArmandoC42 (author)2016-10-02

Hi! just to say thanks !!! I've based on this project my 6 channels looper. A video of it in action....

https://youtu.be/FT50IPzZUDc

xenophontis (author)ArmandoC422016-10-03

well done! can you please share your arduino code? i like how you can program the preset without using a rotary switch. thanks!

CarraN (author)ArmandoC422016-10-02

Hi Armando!

cool! can I include your link to this instructable?

cheers

ArmandoC42 (author)CarraN2016-10-02

absolutely yes!

Thanks!

CarraN (author)ArmandoC422016-10-02

thank you too!

xenophontis (author)2016-09-24

One more question for you. After programming a preset to footswitches, should the relays go into bypass after hitting the switch again? Or does one of the present have to be set to all pedals off, to get a bypass mode?

xenophontis (author)2016-09-22

CarraN, how hard would it be to change this project, so that there is no read / write / select switch. But instead another momentary on/off footswitch. That would change from read mode to select mode. And the method of storing the preset was holding down the desired footswitch for 3 seconds?

CarraN (author)xenophontis2016-09-22

hi!

in the filosophy of this project here, this is not possible. My first attempt was on the way you want today but I didn't achieve it with arduino. Though I'm pretty sure it must be a way to do it... Ask about it on arduino forums.

ProjectL (author)2016-09-12

can I ask where did you get this cool looking switches?

ProjectL (author)2016-09-10

hi, I have build this on project board (replaced relays just with LED's) and every thing seems to be ok. I only have to sort out how to tweak it a bit. I will use only 4 effect loops, but need to have more presets... any ideas how to do it?

CarraN (author)ProjectL2016-09-11

It depens on how many presets you want... If there are equal to the number of switch you want to add the sketch is straight forward. If you want sort of bank you'll must do add two buttons and few changes on the sketch.

cheers

CarraN (author)2015-12-11

Ok! it seems like the onboard smd leds act as reverse as they should!
Have you tried with additional external leds as in the schem ? If your answer is yes, maybe you should add

for (int =0;i<512;i++){
EEPROM.write(i,0);}

in the setup() void of your code to initialize EEPROM. Because, by default all addresses are value 255 . Don't ask me why...

DaniP8 (author)2015-12-11

Well, I've no checked with a multimeter the outputs, but just connecting Arduino UNO (Low cost imitation) to 8-Relay Board, it stands all onboard smd red Leds light on, and when I select switches ('A' position ), selected ones turns off smd Led!

DaniP8 (author)2015-12-10

hey! I'm trying it as first Arduino project, an it's working at first tests! Thank's for the work and sharing knowledge!

in order to solve some aspects, why are the relays initialy open? onboard Led relays are HIGH!

CarraN (author)DaniP82015-12-10

Hi Dany!
are you saying me that all is working at reverse function?
Leds are normally lit and the relays on? I don't really understand

your question...

CarraN (author)2015-10-29

Hi all!

for persons with light arduino skills: to retain presets after boot up, just add "//" or delete these 2 setup lines

//for (int =0;i<512;i++)

//EEPROM.write(i,0);

It's here just for initialize EEPROM memory in case of debugging

JordanL6 (author)2015-04-06

Awesome project, dude! congrats!!
You considered using this relays " http://www.mouser.com/ProductDetail/NEC-Tokin/EC2-... " ?

Another question... i have an arduino Mega, if i need 10 or 14 channels?

cheers!

CarraN (author)JordanL62015-04-06

Hi jordan and thank you for your comment!

sure you can add more I/O depending on the patform you're using. Just adapt the code considering you'll need 3 inputs + 1/3 for tap input, 1/3 for output leds and the last 1/3 for output relays to keep it simple as previously wanted. Sadly with the Mega you'll can manage only 9 presets at max! Another solution is to combine 2 arduinos thru I2C communication but I still don't have a code solution for that ... (see my second instructable).

You can use any relays you want for this project, personaly I don't have found any cheaper than those on ebay ...

http://www.ebay.com/sch/i.html?_from=R40&_trksid=m...

cheers!

CarraN (author)2015-02-23

february 23- edit: changed configuration of relay connections, it works now!