MIDI.sendControlChange() to toggle a button in Ableton

morning folks,

I'm trying to use MIDI.sendControlChange(); in the 'MIDI library' to toggle a button on and off (let's say a 'MUTE' button for argument's sake) inside Ableton via Hiduino (USB connection). However, all i can manage to do so far is control it momentarily. So when I press the button it becomes 'ON' in Ableton but then when I let go it becomes 'OFF' again. What I want is to press the button once and the 'MUTE' in ableton becomes 'ON' and then press it a second time and the 'MUTE' becomes 'OFF'.

The appoach i've been attempting is by creating an integer variable called toggleState and then incorperating that into the conditions in my 'if' statements as you can see in my code below. However for some reason this code isn't actually sending anything at all. Even though When I did the exact same code minus the 'toggleState' variable and conditions it actually does send the signal only as a momentary instead of a toggle.

#include <MIDI.h>
#include <midi_Defs.h>
#include <midi_Message.h>
#include <midi_Namespace.h>
#include <midi_Settings.h>
MIDI_CREATE_DEFAULT_INSTANCE();

const int buttonPin = 2;    
int buttonState = 0;        
int lastButtonState = 0;
int toggleState = 0;    

void setup() {

MIDI.begin(1);
pinMode(buttonPin, INPUT_PULLUP);  

}

void loop() {

buttonState = digitalRead(buttonPin);

    if(buttonState != lastButtonState && buttonState == 1 && toggleState == 0) { 
      MIDI.sendControlChange(1, 127, 1); 
    lastButtonState = buttonState; 
    toggleState = 1;
    }
    if(buttonState != lastButtonState && buttonState == 1 && toggleState == 1) { 
      MIDI.sendControlChange(1, 0, 1); 
    lastButtonState = buttonState; 
    toggleState = 0;
    }
    delay(50);
}

There is nothing complicated about the hardware side of things so I'm guessing there is nothing wrong there but just in case here's a fritzing image for your reference.

Thanks a lot

lastButtonState = buttonState;

Must be outside both those two if statements.

Just have it once under the unnecessary delay call.

ahh right...
yeah that makes sense.
I'll give it a go when i get a minute.
Thanks

hmm... that doesn't seem to have worked.

it's just working as a momentary again

This is what I've uploaded: -

#include <MIDI.h>
#include <midi_Defs.h>
#include <midi_Message.h>
#include <midi_Namespace.h>
#include <midi_Settings.h>
MIDI_CREATE_DEFAULT_INSTANCE();

const int buttonPin = 2;
int buttonState = 0;
int lastButtonState = 0;
int toggleState = 0;

void setup() {
  MIDI.begin(1);
  pinMode(buttonPin, INPUT_PULLUP);
}

void loop() {
  buttonState = digitalRead(buttonPin);

  if(buttonState != lastButtonState && buttonState == 1 && toggleState == 0) {
    MIDI.sendControlChange(1, 127, 1);
  toggleState = 1;
  }
  if(buttonState != lastButtonState && buttonState == 0 && toggleState == 1) {
    MIDI.sendControlChange(1, 0, 1);
  toggleState = 0;
  }
  lastButtonState = buttonState;
}

The button state should be the same in both if statements. This is because you are looking to do something different on each push, not something on a push and something on a release.

okay so now it switches the mute button off but not back on again. And if i click it back on with the mouse and press then press the hardware button again it switches it off again. But still does not switch it back on afterwards.

current code with the buttonState conditions the same.

#include <MIDI.h>
#include <midi_Defs.h>
#include <midi_Message.h>
#include <midi_Namespace.h>
#include <midi_Settings.h>
MIDI_CREATE_DEFAULT_INSTANCE();

const int buttonPin = 2;
int buttonState = 0;
int lastButtonState = 0;
int toggleState = 0;

void setup() {
  MIDI.begin(1);
  pinMode(buttonPin, INPUT_PULLUP);
}

void loop() {
  buttonState = digitalRead(buttonPin);

  if(buttonState != lastButtonState && buttonState == 1 && toggleState == 0) {
    MIDI.sendControlChange(1, 127, 1);
  toggleState = 1;
  }
  if(buttonState != lastButtonState && buttonState == 1 && toggleState == 1) {
    MIDI.sendControlChange(1, 0, 1);
  toggleState = 0;
  }
  lastButtonState = buttonState;
}

thanks a lot for your help by the way

Okay I've got it sussed...

I ran it all through the serial monitor and noticed it was reading both if's at the same time resulting in me getting a '1' and a '0' simultaneously on each press of the button.

so i changed the second 'if' for an 'else if' allowing it to only read one or the other and it worked. Toggles buttons in ableton and everything.

Thanks a lot for your help again Mike

:slight_smile:

Hello! I realize this thread might be old, but I was wondering if you could send the Arduino code that you fixed, as I have it working, but it's a button just turning things on and off (still very exciting). Also, this is all very new and exciting for me! Thank you! and thank you to Gustavo Silveira for the Udemy course!