Midi Controller HELP

Status
Not open for further replies.

cackland

Well-known member
Hi Guys,

New to the world of custom controllers. Using teensy 3.2

Trying to build and code a simply 8 linear potentiometer midi controller.

Currently using a custom code however doesn't seem to be the absolute correct thing for my needs. Wondering if anyone can help.

8 Faders
A0 - A7 (analog inputs on teensy 3.2)
Need to be able to customise each input for a different CC value. (Eg A0 = CC1, A1 = CC7) Etc. Customisable. (Change midi channel etc)
Also, using 100 mm linear potentiometers. The current range only works till half of the length of the fader. Need to be able to utilise the full range of the 100 mm. (1 - 127 = 100 mm of the fader) if that makes sense.

Please help anyone. Trying to read and learn code, and got no idea.

Thanks in advance.

Corey
 
I am a total noob but I could help with the code and tell you what the real guys will tell you immediately: post the schematics (have you connected everything properly?) and particularly post the code you are using, otherwise it's impossible to tell!
How do you plan to change the channel and cc? Updating the software or with user interaction (buttons on a device?)
 
Apologies... here is the code i'm using: Its the code from a tutorial i found online. However i'm unfamiliar with this.
View attachment DJTT_DIY_MIDI.ino

All i'm doing is creating a simple 8 fader controller. They are being soldered from A0 - A7 on a Teensy 3.2. Ground and Power are all connected.

This code works, however I don't know how to change the midi cc message. Like I need A0 = CC 1. Also need to change the midi channel.

Also, using 100mm slide potentiometers, are causing me a problem. As can't utilise the full range, as it seems to reach 1023 value half way up the fader. If that makes sense.

Plan on changing it all inside Arduino, not hardware based.
 
Last edited:
GRD and PWR on the Teensy 3.2

All i'm trying to accomplish is 8 analog inputs that send CC messages over usb.
Midi Channel 1
(Analog Inputs)
A0 = CC 1
A1 = CC 11
A2 = CC 7
Etc. These need to be customisable depending on the program i'm assigning them to. But you get the gist.
 
Last edited:
Determining the cc is pretty simple, in

Code:
usbMIDI.sendControlChange(i, ccValue[i], 1);

the first is the cc, the second the value, the third the channel. In your file the channel is hardcoded to 1 (the last one, change it at wish), the "i" in first position is using the loop index (if you are not familiar with programming search it up).
Your best solution is to declare an array in the beginning (I put random numbers):

Code:
int ccs[] = {1,11,7,30,25,64,3,4};

and change

Code:
usbMIDI.sendControlChange(i, ccValue[i], 1);

to

Code:
usbMIDI.sendControlChange(ccs[i], ccValue[i], 1);


That it reads 1024 at half could be for a number of reasons, all very simple, to debug just start adding

Code:
analogReadRes(10);

after

Code:
void setup() {

and see if anything changes.
 
Thank you for your response. Still a little over my head.

So if start a new sketch... Do I just paste this in?
 
Yes, it does.
Make sure to check the pin configuration of your specific teensy compared to the 2.0 that the tutorial is using.
And understand when it explains how to chen cc and channel inside usbMIDI.sendControlChange( ) function.
 
Ok so i used this code.

/* USB MIDI AnalogControlChange Example

You must select MIDI from the "Tools > USB Type" menu
http://www.pjrc.com/teensy/td_midi.html

This example code is in the public domain.
*/

#include <Bounce.h>

// the MIDI channel number to send messages
const int channel = 1;

// the MIDI continuous controller for each analog input
const int controllerA0 = 1; // 10 = pan position
const int controllerA1 = 11; // 11 = volume/expression


void setup() {
}

// store previously sent values, to detect changes
int previousA0 = -1;
int previousA1 = -1;


elapsedMillis msec = 0;

void loop() {
// only check the analog inputs 50 times per second,
// to prevent a flood of MIDI messages
if (msec >= 20) {
msec = 0;
int n0 = analogRead(A0) / 8;
int n1 = analogRead(A1) / 8;
// only transmit MIDI messages if analog input changed
if (n0 != previousA0) {
usbMIDI.sendControlChange(controllerA0, n0, channel);
previousA0 = n0;
}
if (n1 != previousA1) {
usbMIDI.sendControlChange(controllerA1, n1, channel);
previousA1 = n1;
}
}

// MIDI Controllers should discard incoming MIDI messages.
// http://forum.pjrc.com/threads/24179-Teensy-3-Ableton-Analog-CC-causes-midi-crash
while (usbMIDI.read()) {
// ignore incoming messages
}
}

It works for a second, but afterwards its jumps and isn't stable.

Also, the range of the potentiometer still peaks around half way up the fader.
 
OK so this code works. However same issue before regarding the fader range. It peaks half way up the fader.

Any idea how to make the range from 0 - 127 reach the full range of the fader length?

#include <Bounce.h>

/*
PacMod DJ Controller 002
*/

// pin definitions
const int analog_pin[] = { A0, A1 };

// variables for the states of the controls
boolean digital_stored_state[19];
int analog_stored_state[2];

// amount of change that constitutes sending a midi message
const int analog_threshold = 2;
const int analog_scale = 8;



// MIDI settings
int midi_ch = 1;
int midi_vel = 127;

const int analog_control[] = { 1, 11 };

void setup() {
Serial.begin(38400);

// set the pin modes && zero saved states
int b = 0;


// analog pins
for (b = 1; b>= 0; b--) {
analog_stored_state = 0;
}
}


void loop() {
fcnProcessButtons();
}

//Function to process the buttons
void fcnProcessButtons() {
int b = 0;



// analog pins
for (b = 1; b >= 0; b--) {
int analog_state = analogRead(analog_pin);
if (analog_state - analog_stored_state >= analog_scale || analog_stored_state - analog_state >= analog_scale) {
int scaled_value = analog_state / analog_scale;
usbMIDI.sendControlChange(analog_control, scaled_value, midi_ch);
Serial.print("analog value ");
Serial.print(b);
Serial.print(": ");
Serial.print(analog_state);
Serial.print(" scaled: ");
Serial.println(scaled_value);
analog_stored_state = analog_state;
}
}
}
 
... Any idea how to make the range from 0 - 127 reach the full range of the fader length?...

What does the serial monitor read as you pass the point where the fader change stops changing the MIDI?

It looks like it the code outputs what you need to troubleshoot.

Have you verified the contacts on the faders are as you expect? The wiper on a rotary is always in the middle but I think it might not be so obvious on a linear.

Do you have any other hardware in the circuit? Some people add naïve low-pass filtering to tame a perceived noise problem from the data and if its done incorrectly perhaps it could lead to not getting the full voltage swing from the fader movement.

Are you sure you have the faders connected to the correct power and ground sources?

A photo of your breadboard or whatever hardware setup might be in order if the above code functions for others doesn't work for you.


By-the-way... If you're going to post the serial output or additional code attempts here...
Code:
 please use a code block.
Use the advanced editor and look for the # button... code and machine data is so much easier to read in a mono-space font
 
GRD and PWR on the Teensy 3.2

All i'm trying to accomplish is 8 analog inputs that send CC messages over usb.
Midi Channel 1
(Analog Inputs)
A0 = CC 1
A1 = CC 11
A2 = CC 7
Etc. These need to be customisable depending on the program i'm assigning them to. But you get the gist.
You need to power the voltage dividers (faders) with 3.3 v to keep the voltage at the analog pin under the maximum of 3.3 volts (even though it's 5V tolerant).

I don't have direct experience with using the 5v tolerance with the 3.2 but I would think the behaviour you're getting is consistent with this (especially if 'half-way up the fader' is actually two-thirds).
 
Last edited:
Hi Oddson, thanks for your response. Apologies about the code format, new to this forum and how to express it.

I have used the serial monitor - once i hit 1023 half way up(two thirds) of the fader (100mm) nothing changes in the serial monitor.

All contacts are soldered correctly on the linear potentiometers.

No other hardware, simply 8 linear potentiometers in the circuit. Super simply. All ground and power is daisy-chained for obvious reasons. Each potentiometer is soldered from A0 - A07.

I just want some simply code that picks up the analog input of the each fader and sends it across USB (midi).
 
I test the voltage output using a the ReadAnalogVoltage template, and it shows the output maxing at 5 volts (two thirds up the fader). 0 Volts at 0 positon(all the way down) the fader.
 
right... see the second of my two posts above

edit three... I'm not really sure what your message means but I'm pretty sure the supply voltage to the pots is the issue.
 
Last edited:
All the code i have used seems to be a lot of mess, when all i need is 8 analog inputs sending midi over usb.

Regarding the voltage, I have no idea. Totally new to all of this.
 
Ok so I reverted back to this code I was using in the beginning. Change some lines of code to reflect the array (Change of CC for each potentiometer) - advised in the beginning. That works.

Still the voltage is maxing at 5 volts (two thirds) up the fader. Any ideas?

Code:
// define how many pots are active up to number of available analog inputs
#define analogInputs 2
// make arrays for input values and lagged input values
int inputAnalog[analogInputs];
int iAlag[analogInputs];
// make array of cc values
int ccValue[analogInputs];
// index variable for loop
int i;
int ccs[] = {1,11,7,30,25,64,3,4};

void setup() {
  

}

void loop() {
  // loop trough active inputs for knobs
  for (i=0;i<analogInputs;i++){
    // read current value at i-th input
    inputAnalog[i] = analogRead(i);
    // if magnitude of difference is 8 or more...
    if (abs(inputAnalog[i] - iAlag[i]) > 7){
      // calc the CC value based on the raw value
      ccValue[i] = inputAnalog[i]/8;
      // send the MIDI
      usbMIDI.sendControlChange(ccs[i], ccValue[i], 1);
      // set raw reading to lagged array for next comparison
      iAlag[i] = inputAnalog[i];
    }
  delay(5); // limits MIDI messages to reasonable number
  }
  
}
 
Still the voltage is maxing at 5 volts (two thirds) up the fader.
How are you measuring voltage? If it's by any means other than an external voltage meter I think I can explain.
 
Last edited:
Measuring via the sketch - ReadAnalogVoltage

Code:
/*
  ReadAnalogVoltage
  Reads an analog input on pin 0, converts it to voltage, and prints the result to the serial monitor.
  Attach the center pin of a potentiometer to pin A0, and the outside pins to +5V and ground.

 This example code is in the public domain.
 */

// the setup routine runs once when you press reset:
void setup() {
  // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);
}

// the loop routine runs over and over again forever:
void loop() {
  // read the input on analog pin 0:
  int sensorValue = analogRead(A0);
  // Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 5V):
  float voltage = sensorValue * (5.0 / 1023.0);
  // print out the value you read:
  Serial.println(voltage);
}
 
Then the fact that it is reading 5 volts at the two-thirds mark is happening for the same reason that you can't read changes above that point... your code expects 5 volts when the analog reading maxes-out at 1023 (ten bits of ones as an integer).

But you are using a 3.3 volt based board. Only the incoming power is at 5 volts but luckily the inputs are 5 volt tolerant so it doesn't mess up completely.

A potentiometer acts as a voltage divider with the wiper's voltage equal to a fraction of the supply voltage. At two-thirds the way up your fader, when powered by a 5 volt supply, the output hits 3.3 volts and the analog-to-digital converter (ADC) will read it's maximum of 1023.

But if you have code that tries to report the input voltage but assumes a 5 volt supply it will report 5 volts at the two-thirds mark because it doesn't know the pin is being compared with a 3.3 volt source and so a maximum reading is interpreted as 5 volts even though it's only 3.3.
 
So the fix is to power the voltage dividers (faders) from a 3.3 volt source. I believe you want to use the 3.3 volt source at the third pin off the same side as the Vin you must be using now.
 
Last edited:
Sorry, i don't understand. My fader is powered off the 3.3 volt source on the Teensy 3.2
 
Last edited:
Status
Not open for further replies.
Back
Top