I've had to deal with this myself recently on a leonardo, the issue here is that the analogue inputs will have noise, so what you have to do is introduce a method for filtering out that noise and only outputting real movement. First things first, make sure that all other unused analog pins are tied to ground, that will get rid of some noise.
As for the code, I would start by setting up an array containing the pin numbers that you want to read and a couple of variables to store the last reading you took and the current one. so it will look something like this:
#include <MIDI.h>
// define the number of pots you want to use here, then all you have to do is change this if you want to add more
#define NUM_POTS 3 // make sure you change the analogueInputMapping array below
#define MIDI_CC 1 // use this so that we can set a base CC value and change it later
byte analogueInputMapping[NUM_POTS] = {A0,A1,A2}; // put the pins you want to use here
int16_t lastVal[NUM_POTS]; // We use this to store the last value that wasn't noise here
int16_t tempAnalogueInput; // we use this to take the current reading from each pot
void setup(){
MIDI.begin();
Serial.begin(115200);
for (i = 0; i < NUM_POTS; i++)
{
// Set the pin direction to input.
pinMode(analogueInputMapping[i], INPUT);
}
}
void loop(){
for (i = 0; i < NUM_POTS; i++)
{
// Read the analogue input pin
tempAnalogueInput = analogRead(analogueInputMapping[i]);
if (abs(tempAnalogueInput - lastVal[i]) >= 8) { // check that it's a real reading and not just noise on the 10bit value
lastVal[i] = tempAnalogueInput; // make sure we keep a record of the last real reading we have taken
MIDI_TX(176, MIDI_CC + i, tempAnalogueInput >> 3); // shift our 10bit value to 7bits, then output it as a CC
}
}
}
That's about all you need really :-)
Essentially, all the magic happens in a couple of lines, this is the first one of note:
if (abs(tempAnalogueInput - lastVal[i]) >= 8) {
At that point we've taken a reading from the analog pin, so we compare the reading with the last reading (which will be initialised to something random, it doesn't really matter) essentially, if the new reading and the last reading is +-8 or bigger, then it's a real reading, the code will store the current reading into the last reading variable, output the midi message and continue through the for loop. It should be noted that the value 8 should not really be changed, if you do you'll probably get noise (random midi messages) or you'll thin the data out and won't get 0-128 in single steps.
the 2nd line of note is the actual MIDI_TX command:
MIDI_TX(176, MIDI_CC + i, tempAnalogueInput >> 3);
Specifically this 'tempAnalogueInput >> 3' what that does is converts our 10bit analog value into 7 bits by shifting it 3 bits, which gives us a nice 7bit value without needing to do any maths.
The code is super simple, doesn't need any delays and as long as you've tied all the unused analogue inputs to ground, it should be super clean, fast, with full 0-128 range from top to bottom and it is easy to expand, just change the NUM_POTS value and add the pin numbers to analogueInputMapping array.
HTH.
Bookmarks