Originally Posted by
MiL0
Ideally, what would be perfect, is if someone could write some Arduino code that will allow x number of potentiometers/buttons and that everyone can use on their controllers (without having to go the HID/midi route or hack a joypad to pieces!)
There is a minor problem with achieving this with regards to the analog inputs for faders and knobs, and I had to solve it when developing my 64 I/O dedicated ArduinoMIDI board. The problem is making the code versatile, so one bit of code works no matter how many inputs are used.
As you repeatedly scan the analog inputs, you check the value to see if it has changed since the last time the input was read ie has the POT moved? That way if the POT has moved the MIDI is outputted, if the POT hasn't moved no MIDI is sent. If this system is not implemented and you just output a MIDI value when the POT is read then a) bombarding the other device with lots of unnecessary MIDI may cause latency and b) 'MIDI learn' functions of programs like Traktor and Ableton will not work properly.
...so here's the problem. It would be quite easy to write a bit of code that scanned all the analog inputs on an Arduino, checked to see if they were different to the last time and if so, output the MIDI data on a different CC number for each analog input. The problem is getting the code to work with different combinations of POTS connected... for example if I wrote the code to read all 6 analog inputs of the Arduino UNO board and you only connected 4 POTS there would be random MIDI messages flying about for the disconnected inputs.... why? ...if you read an analog input that is 'floating' (nothing connected) you will find the analog values fluctuate all over the place. As this is seen by the code as 'a changing value' it will fire out MIDI messages of random values which is not what you want!
So the code has to take in to account which inputs are connected and which inputs are not. The user can then adjust a variable in the code to state which inputs are used and which are not before uploading to their Arduino.
Here is some code that should work with any Arduino with 1 - 6 analog inputs connected. If anyone finds this useful or anyone thinks it would be worth me adding digital intputs to the code, let me know and ill make some time to add it! To suit your needs, just change the very bit at the top...
This bit needs to be changed to how many POTs you have connected to the Arduino, entering 6 means all 6 inputs will be scanned for POTs. If you only want to use 3 POTs, change this number to 3. NOTE: Consecutive inputs must be used from the first analog pin, for 3 POTs, use A0, A1, A2.
number_of_analog_connections = 6;
This bit can be changed if you want specific CC numbers for each POT. The numbers 50 .. 55 correspond to the CC numbers for analog inputs 1 - 6 on the Arduino. If you want the second input to be CC07, change '51' to '7' as shown below
control_change_numbers[6] = { 50, 7, 52, 53, 54, 55 };
You can also change the MIDI channel the CC data is outputted on with this line..
midi_channel = x;
..and the LED pin if you are using a custom Arduino board...
led_pin = 13;
Be warned I have thrown this code together pretty quickly and have only tested it a little bit!! So apologies if there is a prob with it, let me know and ill fix
PHP Code:
// BASIC ANALOG INPUTS --> MIDI OUT CODE - SIYTEK - siy@btinternet.com
// YOU MUST USE CONSECUTIVE ANALOG PINS AND BEGIN FROM A0!!!
// IF YOU WANT TO CONNECT 3 POTS, CONNECT TO A0, A1, A2 AND SET 'number_of_analog_connections' to '3'
//////////////////////////////////////////////////////
//////////////////////////////////////////////////////
//////////////////////////////////////////////////////
////// USER EDITS THESE VARIABLES
int number_of_analog_connections = 6; //NUMBER OF ANALOG INPUTS USED FROM 1 to 6
int control_change_numbers[6] = { 50, 51, 52, 53, 54, 55 }; //CONTROL CHANGE NUMBERS FOR ANALOG OUTPUTS A0, A1, A2, A3, A4, A5 - SO 'A1' WILL OUTPUT TO 'CC51' etc...
int midi_channel = 1; //MIDI CHANNEL
int led_pin = 13; //ARDUINO BOARDS USUALLY USE PIN 13, SO MOST LIKELY NO NEED TO CHANGE
//////////////////////////////////////////////////////
//////////////////////////////////////////////////////
//////////////////////////////////////////////////////
//////////////////////////////////////////////////////
//////////////////////////////////////////////////////
//////////////////////////////////////////////////////
int MIDIReading;
int last_analog_reading[6] = { 0,0,0,0,0,0 };
int current_analog_reading[6] = { 0,0,0,0,0,0 };
void setup() {
pinMode(led_pin, OUTPUT); //INITIALIZE LED PIN
digitalWrite(led_pin, HIGH);
Serial.begin(31250); // INITIALIZE SERIAL PORT, 31,250 bps FOR MIDI
Serial.flush();
}
void loop(){
for (int x=0; x < number_of_analog_connections; x++){ //CREATES A LOOP THAT SCANS A0 - A6 DEPENDING ON NUMBER OF INPUTS SELECTED
current_analog_reading[x] = analogRead(x); //READS ANALOG INPUT PIN
if (current_analog_reading[x] != last_analog_reading[x]){ //CHECKS TO SEE IF ITS THE SAME AS THE PREVIOUS READING (IF ITS THE SAME, NO MIDI IS TRANSMITTED)
MIDIReading = current_analog_reading[x] >> 3; //CONVERTS THE 10-BIT READING FROM ARDUINOS ADC TO 7-BIT FOR MIDI
transmit_MIDI(MIDIReading, control_change_numbers[x]); //TRANSMITS THE VALUE OF THE ANALOG READING TO THE CC NUMBER FOR THE RELEVANT INPUT
}
last_analog_reading[x] = current_analog_reading[x]; //STORES THE READING AS A PREVIOUS VALUE REFERENCE FOR NEXT TIME INPUT IS SCANNED
}
}
void transmit_MIDI(byte the_out_value, byte cc_output){ //TRANSMIT MIDI ROUTINE
digitalWrite(led_pin, LOW); //BLINKS LED TO SHOW MIDI IS BEING SENT
Serial.print((0xB0 | midi_channel) , BYTE); //SENDS MIDI CC MESSAGE AND CHANNEL NUMBER
Serial.print((cc_output & 0x7F), BYTE); //SENDS THE CC NUMBER RELEVANT TO THE ANALOG INPUT
Serial.print((the_out_value & 0x7F), BYTE); //SENDS THE ACTUAL VALUE OF THE ANALOG INPUT
digitalWrite(led_pin, HIGH); //SWITCH LED BACK ON AFTER TRANSMISSION
}
Bookmarks