Ableton receive midi from my Arduino Leonardo midi controller but I can´t map

Hi there!

I´m trying to build a midi controller based in Arduino Leonardo and I´m getting a bit desperated with this problem... I hope maybe you have any idea about...

I´m using a code that I found in internet and I did a few modifications to adapt him to my requeriments. Anyways the code seems to works fine, I can conect my prototipe with a slide potenciometer to my computer throught USB and I can see in a Midi Translate software that I receive midi signal.

Then I go to Ableton, and everything seems to works fine, I receive midi signal, Arduino Leonardo is recognized as a midi controller, I selected: Input: Arduino Leonardo (Track ON; Remote ON) and Ouput: Arduino Leonardo (Remote on). But when I press "MIDI" to make a midi mapping I can´t map anything coming from arduino... and I really don´t get why...

I attach you a few pictures, I hope you can help me
Thanks in advance,
Daniel Lozano

Please post your full code.
The first data byte shouldn't be changing like that, only the second data byte. Did the code expect more potentiometers than you have wired up?
B1 is MIDI channel 2, not channel 1, which might not be what you expected.

You could try this example of the Control Surface library I maintain, it is known to work correctly: Control-Change-Potentiometer.ino

Pieter

Hi PieterP

Thank you for your reply! the code is done for 10 potenciometer and 5 buttons but right now i´m only testing in a protoboard with one slide potenciometer and a normal potenciometer…

This is the full code:

/////////////////////////////////////////////
// Choosing your board
// Define your board, choose:
// "ATMEGA328" if using ATmega328 - Uno, Mega, Nano...
// "ATMEGA32U4" if using with ATmega32U4 - Micro, Pro Micro, Leonardo...
// "TEENSY" if using a Teensy board
// "DEBUG" if you just want to debug the code in the serial monitor
// you don't need to comment or uncomment any MIDI library below after you define your board


#define ATMEGA32U4 1 //* put here the uC you are using, like in the lines above followed by "1", like "ATMEGA328 1", "DEBUG 1", etc.


/////////////////////////////////////////////


// if using with ATmega328 - Uno, Mega, Nano...
#ifdef ATMEGA328
#include <MIDI.h> // by Francois Best
//MIDI_CREATE_DEFAULT_INSTANCE();


// if using with ATmega32U4 - Micro, Pro Micro, Leonardo...
#elif ATMEGA32U4
#include "MIDIUSB.h"


#endif
// ---- //


/////////////////////////////////////////////
// BUTTONS
const int N_BUTTONS = 5; //*  total numbers of buttons
const int BUTTON_ARDUINO_PIN[N_BUTTONS] = {7, 2, 3, 4, 5}; //* pins of each button connected straight to the Arduino


int buttonCState[N_BUTTONS] = {};        // stores the button current value
int buttonPState[N_BUTTONS] = {};        // stores the button previous value


//#define pin13 1 //* uncomment if you are using pin 13 (pin with led), or comment the line if not using
byte pin13index = 12; //* put the index of the pin 13 of the buttonPin[] array if you are using, if not, comment


// debounce
unsigned long lastDebounceTime[N_BUTTONS] = {0};  // the last time the output pin was toggled
unsigned long debounceDelay = 50;    //* the debounce time; increase if the output flickers


/////////////////////////////////////////////
// POTENTIOMETERS
const int N_POTS = 10; //* total numbers of pots (slide & rotary)
const int POT_ARDUINO_PIN[N_POTS] = {6, 9, 10, 11, 13, A4, A3, A2, A1, A0}; //* pins of each pot connected straight to the Arduino


int potCState[N_POTS] = {0}; // Current state of the pot
int potPState[N_POTS] = {0}; // Previous state of the pot
int potVar = 0; // Difference between the current and previous state of the pot


int midiCState[N_POTS] = {0}; // Current state of the midi value
int midiPState[N_POTS] = {0}; // Previous state of the midi value


const int TIMEOUT = 300; //* Amount of time the potentiometer will be read after it exceeds the varThreshold
const int varThreshold = 10; //* Threshold for the potentiometer signal variation
boolean potMoving = true; // If the potentiometer is moving
unsigned long PTime[N_POTS] = {0}; // Previously stored time
unsigned long timer[N_POTS] = {0}; // Stores the time that has elapsed since the timer was reset


/////////////////////////////////////////////
// MIDI
byte midiCh = 1; //* MIDI channel to be used
byte note = 1; //* Lowest note to be used
byte cc = 1; //* Lowest MIDI CC to be used


/////////////////////////////////////////////
// SETUP
void setup() {


 // Baud Rate
 // use if using with ATmega328 (uno, mega, nano...)
 // 31250 for MIDI class compliant | 115200 for Hairless MIDI
 Serial.begin(115200); //*


#ifdef DEBUG
Serial.println("Debug mode");
Serial.println();
#endif


 // Buttons
 // Initialize buttons with pull up resistors
 for (int i = 0; i < N_BUTTONS; i++) {
   pinMode(BUTTON_ARDUINO_PIN[i], INPUT_PULLUP);
 }


#ifdef pin13 // inicializa o pino 13 como uma entrada
pinMode(BUTTON_ARDUINO_PIN[pin13index], INPUT);
#endif


}


/////////////////////////////////////////////
// LOOP
void loop() {


 buttons();
 potentiometers();


}


/////////////////////////////////////////////
// BUTTONS
void buttons() {


 for (int i = 0; i < N_BUTTONS; i++) {


   buttonCState[i] = digitalRead(BUTTON_ARDUINO_PIN[i]);  // read pins from arduino


#ifdef pin13
if (i == pin13index) {
buttonCState[i] = !buttonCState[i]; // inverts the pin 13 because it has a pull down resistor instead of a pull up
}
#endif


   if ((millis() - lastDebounceTime[i]) > debounceDelay) {


     if (buttonPState[i] != buttonCState[i]) {
       lastDebounceTime[i] = millis();


       if (buttonCState[i] == LOW) {


         // Sends the MIDI note ON accordingly to the chosen board
#ifdef ATMEGA328
// use if using with ATmega328 (uno, mega, nano...)
MIDI.sendNoteOn(note + i, 127, midiCh); // note, velocity, channel


#elif ATMEGA32U4
// use if using with ATmega32U4 (micro, pro micro, leonardo...)
noteOn(midiCh, note + i, 127);  // channel, note, velocity
MidiUSB.flush();


#elif TEENSY
//do usbMIDI.sendNoteOn if using with Teensy
usbMIDI.sendNoteOn(note + i, 127, midiCh); // note, velocity, channel


#elif DEBUG
Serial.print(i);
Serial.println(": button on");
#endif


       }
       else {


         // Sends the MIDI note OFF accordingly to the chosen board
#ifdef ATMEGA328
// use if using with ATmega328 (uno, mega, nano...)
MIDI.sendNoteOn(note + i, 0, midiCh); // note, velocity, channel


#elif ATMEGA32U4
// use if using with ATmega32U4 (micro, pro micro, leonardo...)
noteOn(midiCh, note + i, 0);  // channel, note, velocity
MidiUSB.flush();


#elif TEENSY
//do usbMIDI.sendNoteOn if using with Teensy
usbMIDI.sendNoteOn(note + i, 0, midiCh); // note, velocity, channel


#elif DEBUG
Serial.print(i);
Serial.println(": button off");
#endif


       }
       buttonPState[i] = buttonCState[i];
     }
   }
 }
}


/////////////////////////////////////////////
// POTENTIOMETERS
void potentiometers() {




 for (int i = 0; i < N_POTS; i++) { // Loops through all the potentiometers


   potCState[i] = analogRead(POT_ARDUINO_PIN[i]); // reads the pins from arduino


   midiCState[i] = map(potCState[i], 0, 1023, 0, 127); // Maps the reading of the potCState to a value usable in midi


   potVar = abs(potCState[i] - potPState[i]); // Calculates the absolute value between the difference between the current and previous state of the pot


   if (potVar > varThreshold) { // Opens the gate if the potentiometer variation is greater than the threshold
     PTime[i] = millis(); // Stores the previous time
   }


   timer[i] = millis() - PTime[i]; // Resets the timer 11000 - 11000 = 0ms


   if (timer[i] < TIMEOUT) { // If the timer is less than the maximum allowed time it means that the potentiometer is still moving
     potMoving = true;
   }
   else {
     potMoving = false;
   }


   if (potMoving == true) { // If the potentiometer is still moving, send the change control
     if (midiPState[i] != midiCState[i]) {


       // Sends the MIDI CC accordingly to the chosen board
#ifdef ATMEGA328
// use if using with ATmega328 (uno, mega, nano...)
MIDI.sendControlChange(cc + i, midiCState[i], midiCh); // cc number, cc value, midi channel


#elif ATMEGA32U4
//use if using with ATmega32U4 (micro, pro micro, leonardo...)
controlChange(midiCh, cc + i, midiCState[i]); //  (channel, CC number,  CC value)
MidiUSB.flush();


#elif TEENSY
//do usbMIDI.sendControlChange if using with Teensy
usbMIDI.sendControlChange(cc + i, midiCState[i], midiCh); // cc number, cc value, midi channel


#elif DEBUG
Serial.print("Pot: ");
Serial.print(i);
Serial.print(" ");
Serial.println(midiCState[i]);
//Serial.print("  ");
#endif


       potPState[i] = potCState[i]; // Stores the current reading of the potentiometer to compare with the next
       midiPState[i] = midiCState[i];
     }
   }
 }
}


/////////////////////////////////////////////
// if using with ATmega32U4 (micro, pro micro, leonardo...)
#ifdef ATMEGA32U4


// Arduino (pro)micro midi functions MIDIUSB Library
void noteOn(byte channel, byte pitch, byte velocity) {
 midiEventPacket_t noteOn = {0x09, 0x90 | channel, pitch, velocity};
 MidiUSB.sendMIDI(noteOn);
}


void noteOff(byte channel, byte pitch, byte velocity) {
 midiEventPacket_t noteOff = {0x08, 0x80 | channel, pitch, velocity};
 MidiUSB.sendMIDI(noteOff);
}


void controlChange(byte channel, byte control, byte value) {
 midiEventPacket_t event = {0x0B, 0xB0 | channel, control, value};
 MidiUSB.sendMIDI(event);
}
#endif

Please edit your post to include [code][/code] tags around your code so it doesn't mess up the formatting and turn everything italics.

The code you posted is way too complicated, I'd highly recommend having a look at the link I posted previously.
Otherwise, remove the code for the 8 potentiometers you're not using, these input pins are floating and are just sending random values that prevent you from mapping it correctly.

Sorry I didn´t know about that option for the code... edited!

The code is a little bit long but because is implemented for use it with differents boards... but essentially I think it's not that long as looks like!
About the 10 potenciometers, it´s because the real midi controller I want to build needs 10 potenciometer, that´s why I had the code like that, anyways I did right now the try and change it just to 1 potenciometer and upload the software in to arduino and same problems in ableton...

If you're confident that your Arduino code is correct, you might want to ask this question on the forums for Ableton or the MIDI translate software you're using.

I´m not sure about my code for sure, that why I´m asking.
Thank you for the help!
Did somebody have also problems with Ableton and Arduino ? Or has any idea where I can continue trying around ?

Thanks

Apart from the off-by-one error with the channel I mentioned, it should work.

I'm trying exactly the same thing right now. I have a very simple C3 note being sent to Ableton via Hairless Midi and LoopMidi. It plays a note in Operator easy enough. I just tried to get it to play a sample in a midi channel (midi from the loopmidi port) with Simpler loaded and it does it automatically: the sample plays for the duration of the note. I didn't midi map it as such, it seems to be default behaviour.
Playing around with it today, will let you know if I find a way to midi map directly.

Have you watched this? Arduino & Ableton Live - How to connect an Arduino MIDI Controller to Ableton Live 9 on Windows - YouTube
In Ableton preferences you go to Link MIDI section, your virtual midi port should be referenced there, you have to enable both the 1st and the 3rd option 'Remote'.
My Arduino was generating a C2 note every 5 seconds. I setup an audio track to play a Star Trek sound effect wav. I hit the top-right MIDI button to map, and quickly clicked on the 'play' button of the sample.
Then when the Arduino sent the C3 note Ableton detected it and it appeared as a midi mapping.
Hit the MIDI button again to exit mapping mode and the sample plays every time the Arduino sends the note.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.