Controlling a Guitar Effect (DigiTech Whammy) with MIDI

I am trying use my Arduino to control a guitar pedal, a DigiTech Whammy via MIDI, the pedal has a single MIDI In that can be used to control every funtion of the pedal. On the pedal there is a mode select dial, this sweeps through 17 different modes of pitch shift. So far I have found a sketch that has given me the ability to sweep through each mode continuously. Or I can create sequences for the mode change to follow.

Want I want, is a circuit and sketch that will allow me to choose when it advances to the next mode with a momentary footswitch. I have searched a lot to try and find a sketch that will allow me to use a single footswitch to control the Whammy in this way without success, I have attached a second code at the bottom which gave me A result, but not the correct result. Instead of advancing through each mode, it only jumps back and forth between two modes.

If anyone can help that would be amazing, I am still new to Arduino so I apologise if the problem is quite simple to fix.

Thanks!!

Here is the sketch that simply sweeps through each mode:

#define DLY 90
#define MIN 0
#define MAX 125
 
void setProgram(uint8_t p) {
 Serial.write((uint8_t)0xC0);
 Serial.write((uint8_t)p);
}
 
void setup() {
 Serial.begin(31250);
 
}
void loop() {
 setProgram(0);        //This loop simply sweeps through each mode that the pedal has.
 delay(DLY);
 setProgram(1);
 delay(DLY);
 setProgram(2);
 delay(DLY);
 setProgram(3);
 delay(DLY);
 setProgram(4);
 delay(DLY);
 setProgram(5);
 delay(DLY);
 setProgram(6);
 delay(DLY);
 setProgram(7);
 delay(DLY);
 setProgram(8);
 delay(DLY);
 setProgram(9);
 delay(DLY);
 setProgram(10);
 delay(DLY);
 setProgram(11);
 delay(DLY);
 setProgram(12);
 delay(DLY);
 setProgram(13);
 delay(DLY);
 setProgram(14);
 delay(DLY);
 setProgram(15);
 delay(DLY);
 setProgram(16);
 delay(DLY);
}

The code that gave almost the correct results, it switches between two modes, the switching is also quite flaky and if the button is held down it switches between the two modes erratically:

//Button 1
int ledPin = 12; //led output
int buttonPin = 10; //button input pin
int buttonVal = 0; //variable for reading the button status
int buttonState = 0; //variable to hold the buttons current state
int bounceCheck = 0; //variable for debouncing

void setup() {
pinMode(ledPin, OUTPUT); //declare LED as output
pinMode(buttonPin, INPUT); //declare pushbutton as input
Serial.begin(31250); //MIDI communicates at 31250 baud
}

void loop()
{
////////////////////////////TOGGLE////////////////////////////////////
buttonVal = digitalRead(buttonPin); //read input value from button
delay(5); //wait 10ms
bounceCheck = digitalRead(buttonPin); //check again

if(buttonVal == bounceCheck){ //if val is the same then not a bounce
if (buttonVal == HIGH && buttonState == 1) { //check if the input is HIGH
digitalWrite(ledPin, HIGH); //turn LED OFF
midiOUT(0xC0, 0, 1); //Note ON (CH 1), C1, velocity 127
buttonState = 0;
}
if(buttonVal == LOW && buttonState == 0){
digitalWrite(ledPin, LOW); //turn LED ON
midiOUT(0xC0, 0, 0); //Note ON (CH 1), middle C1, velocity 0
buttonState = 1;
}
}

}
void midiOUT(char command, char value1, char value2) {
Serial.print(command);
Serial.print(value1);
Serial.print(value2);

}

Can anyone help with where I am going wrong with this?

The guitar pedal's manual says the the presets (mode) can be selected using MIDI Program Change commands. The Program Changes recognised by the pedal are #1 -> #34. Although, I'm only interested in modes #1 -> #17 as 18# ->#34 are with the effect turned off.

How do I tell it to use the button to cycle through each mode one by one with each press?

I can't see how your first code that you posted does much of anything.

Your second code could be improved by modifying it to use state change detection.

Look in the examples in the digital tab for "statechangedetection". EDIT: USE the code that you got from the "bounce" example and add the state change detection method.

I reformatted your second code to make it easier to read. Make some changes and I will try to help you if you still have trouble.

//Button 1
int ledPin = 12;                      //led output
int buttonPin = 10;                   //button input pin             
int buttonVal = 0;                    //variable for reading the button status
int buttonState = 0;                  //variable to hold the buttons current state
int bounceCheck = 0;                  //variable for debouncing

void setup() {
  pinMode(ledPin, OUTPUT);            //declare LED as output
  pinMode(buttonPin, INPUT);          //declare pushbutton as input
  Serial.begin(31250);                //MIDI communicates at 31250 baud
}

void loop()
{
  ////////////////////////////TOGGLE////////////////////////////////////
  buttonVal = digitalRead(buttonPin);     //read input value from button
  delay(5);                              //wait 10ms
  bounceCheck = digitalRead(buttonPin);   //check again


    if(buttonVal == bounceCheck)
  { //if val is the same then not a bounce
    if (buttonVal == HIGH && buttonState == 1) 
    {    //check if the input is HIGH
      digitalWrite(ledPin, HIGH);         //turn LED OFF
      midiOUT(0xC0, 0, 1);              //Note ON (CH 1), C1, velocity 127
      buttonState = 0;
    }

    if(buttonVal == LOW && buttonState == 0)
    {
      digitalWrite(ledPin, LOW);       //turn LED ON
      midiOUT(0xC0, 0, 0);           //Note ON (CH 1), middle C1, velocity 0
      buttonState = 1;
    }
  }
}
//////////////////////////////////YOUR FUNCTION/////////////
void midiOUT(char command, char value1, char value2)
{
  Serial.print(command);
  Serial.print(value1);
  Serial.print(value2);
}

I have managed to get my circuit working. I found a different sketch to use as a starting point and also got some help from someone on IRC.

I have attached the sketch I am using, should anyone else ever want to do something similar. I'm sure someone will find a better way to write it but it does exactly what I want it to do. I also cleaned up the sketch and removed references to an LED, it was never my intention to add an LED as there are already LEDs on the guitar pedal itself which I can use to see which preset I am using.

When I press on the momentary switch the pedal advances to the next preset. If I press + hold the switch down, the pedal cycles continuously until I let go of the switch. This will be useful if I want to switch from preset 1 to preset 13 without having to press the switch 12 times.

Cyclegadget, thanks for your help. I tried your sketch, but it only switches from one preset to the other momentarily. I don't know if my explanation in previous posts was clear enough, hopefully this post has cleared that up.

    // DigiTech Whammy IV - MIDI Controller.
    // MichaelJGuitar 2013
    // Switch allows changing of Whammy preset.
    // Configured to cycle through all modes in active mode, an option for bypassing the effect is not required as there is already a switch on the unit for that.
    
    #include <MIDI.h>
     
    #define KEY 8 // The switch is connected to PIN 8.
     
    int keyispressed = 0; // Variable. Is the key currently pressed?
    int currentprogram = 0;

    void  setup()
    {
      pinMode(KEY, INPUT);
      MIDI.begin(); // Initialise midi library
      setProgram(currentprogram);
    }
    //---------------------------------------------
    void loop() //the main loop
    {
      keyispressed = digitalRead(KEY); // Read pin 8
     
      if (keyispressed == LOW){
        currentprogram++;
        delay (175); // When footswitch is pressed, the preset will change and then wait the amount specified before moving on to the next preset.
        if(currentprogram > 16) currentprogram = 0; // The Whammy has 16 presets, 0 - 16 are all active.
        setProgram(currentprogram);
      }
      else{
        
      }
    }
    
    void setProgram(uint8_t p) {
    Serial.write((uint8_t)0xC0);
    Serial.write((uint8_t)p);}

uniquebeef, thank you for your post, I was looking for MIDI + Arduino on the web and found very little useful things.

The reason I'm into this MIDI now is exactly the same as yours, the Digitech Whammy 4.

I really didn't get this part of your final code:

    void setProgram(uint8_t p) {
    Serial.write((uint8_t)0xC0);
    Serial.write((uint8_t)p);}

Could you please break it for me? What is this uint8_t? and this p? The 0xC0 I believe is the channel you're communicating through, right? Could you use any other one?

Thanks again!

Resurrecting this thread to ask OP further questions. I'm trying to do the same thing, for a Bass Whammy (pretty much the same as the Whammy V) and I'm wondering about the hardware. Does your pedal's output go from the Arduino's USB port to a MIDI socket, then to the Whammy's MIDI in? Or can a MIDI port be wired onto some prototyping board just using the Arduino as a processor? Hope someone sees this, at least.