Go Down

Topic: Different MIDI data from pot (Read 895 times) previous topic - next topic

sarma

Jun 23, 2011, 01:16 pm Last Edit: Jun 23, 2011, 04:00 pm by sarma Reason: 1
I'm using 10k pot to send MIDI data. The issue that I'm having is that when I try to map that pot in my DJ software (Traktor Pro), it reads different values like:

Ch02.CC.032
Ch02.CC.021
Ch02.CC.000

Why is that? I've tried using 2 codes, first one I found on instructables (with some edits) and 2nd is mine. Same issues are appearing, with code 2 giving even more values:

Code 1:
Code: [Select]
//#define DEBUG

#define FILTER_AMOUNT 7

// Timeout is in microseconds
#define ANALOGUE_INPUT_CHANGE_TIMEOUT 250000


// Contains the current value of the analogue inputs.
int analogueInputs[6];

// Variable to hold temporary analogue values, used for analogue filtering logic.
int tempAnalogueInput;

// for loop
int i = 0;

// Variable to hold difference between current and new analogue input values.
int analogueDiff = 0;

// This is used as a flag to indicate that an analogue input is changing.
boolean analogueInputChanging[6];

// Time the analogue input was last moved
unsigned long analogueInputTimer[6];


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

 

 
 // Initialise each analogue input channel.
 for (i = 0; i < 1; i++)
 {
   // Set the pin direction to input.
   pinMode(i, INPUT);
   
   // Initialise the analogue value with a read to the input pin.
   analogueInputs[i] = analogRead(i);
   
   #ifdef DEBUG
   Serial.print("read in setup: ");
   Serial.println(analogueInputs[i]);
   #endif
   
   // Assume no analogue inputs are active
   analogueInputChanging[i] = false;
   analogueInputTimer[i] = 0;
 }
 
}


void loop()
{
 
 
 /*
  * Analogue input logic:
  * The Arduino uses a 10-bit (0-1023) analogue to digital converter (ADC) on each of its analogue inputs.
  * The ADC isn't very high resolution, so if a pot is in a position such that the output voltage is 'between'
  * what it can detect (say 2.505V or about 512.5 on a scale of 0-1023) then the value read will constantly
  * fluctuate between two integers (in this case 512 and 513).
  *
  * If we're simply looking for a change in the analogue input value like in the digital case above, then
  * there will be cases where the value is always changing, even though the physical input isn't being moved.
  * This will in turn send out a constant stream of MIDI messages to the connected software which may be problematic.
  *
  * To combat this, we require that the analogue input value must change by a certain threshold amount before
  * we register that it is actually changing. This is good in avoiding a constantly fluctuating value, but has
  * the negative effect of a reduced input resolution. For example if the threshold amount was 2 and we slowly moved
  * a slider through it's full range, we would only detect every second value as a change, in effect reducing the
  * already small 7-bit MIDI value to a 6-bit MIDI value.
  *
  * To get around this problem but still use the threshold logic, a timer is used. Initially the analogue input
  * must exceed the threshold to be detected as an input. Once this occurs, we then read every value coming from the
  * analogue input (not just those exceeding a threshold) giving us full 7-bit resolution. At the same time the
  * timer is started. This timer is used to keep track of whether an input hasn't been moved for a certain time
  * period. If it has been moved, the timer is restarted. If no movement occurs the timer is just left to run. When
  * the timer expires the analogue input is assumed to be no longer moving. Subsequent movements must exceed the
  * threshold amount.
  */
 
 for (i = 0; i < 1; i++)
 {
   // Read the analogue input pin, dividing it by 8 so the 10-bit ADC value (0-1023) is converted to a 7-bit MIDI value (0-127).
   tempAnalogueInput = analogRead(i);
   
   #ifdef DEBUG
   Serial.print("read in loop: ");
   Serial.println(tempAnalogueInput);
   #endif
   
   
   
 
   // Take the absolute value of the difference between the curent and new values
   analogueDiff = abs(tempAnalogueInput - analogueInputs[i]);
   #ifdef DEBUG
   Serial.print("difference: ");
   Serial.println(analogueDiff);
   Serial.print("\n");
   delay(2000);
   #endif
   
   
   // Only continue if the threshold was exceeded, or the input was already changing
   
   if ((analogueDiff > 0 && analogueInputChanging[i] == true) || analogueDiff >= FILTER_AMOUNT)
   {
     // Only restart the timer if we're sure the input isn't 'between' a value
     // ie. It's moved more than FILTER_AMOUNT
     
     if (analogueInputChanging[i] == false || analogueDiff >= FILTER_AMOUNT)
     {
       // Reset the last time the input was moved
       analogueInputTimer[i] = micros();
       
       // The analogue input is moving
       analogueInputChanging[i] = true;
     }
     
     else if (micros() - analogueInputTimer[i] > ANALOGUE_INPUT_CHANGE_TIMEOUT)
     {
       analogueInputChanging[i] = false;
     }
     
     
     
     
     
     // Only send data if we know the analogue input is moving
     if (analogueInputChanging[i] == true)
     {
       // Record the new analogue value
       analogueInputs[i] = tempAnalogueInput;
       #ifdef DEBUG
       Serial.print("Value to send: ");
       Serial.println(analogueInputs[i]/8);
       #endif
       
     
       // Send the analogue value out on the general MIDI CC (see definitions at beginning of this file)
       controlChange(177, 21+i, analogueInputs[i]/8);
       
     }
   }
   
 }
 
}





// Send a MIDI control change message
void controlChange(int channel, int control, int value)
{
 

     Serial.print(channel, BYTE);
     Serial.print(control, BYTE);
     Serial.print(value, BYTE);

}


Code 2:
Code: [Select]
//current reading from pot
int sendval[2] = {0, 0};

//previous reading from pot
int last[2] = {0, 0};

//difference between current and previous reading
int diff[2] = {0, 0};

//for loop variable
int i = 0;

void setup() {

 Serial.begin(31250);
}


void loop() {
 
 
for (i=0; i<1; i++) {
 sendval[i]=analogRead(i);
 
 
 diff[i]=abs(sendval[i]-last[i]);
 



 if ( (sendval[i]/8 != last[i]/8 ) && (diff[i]>7) )


 {

   //Serial.println(sendval[i]/8, DEC);
   midiCC(177, 21, sendval[i]/8);

   // update last variable
   last[i] = sendval[i];

 }
} }



// this function sends a Midi CC.
void midiCC(char CC_data, char c_num, char c_val){
 Serial.print(CC_data, BYTE);
 Serial.print(c_num, BYTE);
 Serial.print(c_val, BYTE);

}




Oh and for the record, I'm using this scheme also: http://shiftmore.blogspot.com/2010/01/quick-and-dirty-arduino-midi-over-usb.html

Any help is appreciated.

Grumpy_Mike

Quote
it reads different values like

What do you mean by this? The values look fine to me what are you expecting to see?

sarma

#2
Jun 23, 2011, 03:05 pm Last Edit: Jun 23, 2011, 03:08 pm by sarma Reason: 1
It should be constant, ie. when I map pot to selected function (we are talking about ONE pot whole time by the way) in Traktor it should read it as a specific command. The command changes in my case which is making it unusable.

It's like you want to map key on your keyboard to function "A" and your software tries to map it to functions "A" and "B".

Funny thing is, If I set the baud rate to 9600 and use Serial-to-MIDI converter it works just fine. But with the setup I'm using it doesn't.

Grumpy_Mike

Quote
we are talking about ONE pot whole time by the way

But the code is reading two analogue inputs if there is nothing connected to one of them then you have a floating input and you will get random numbers.

sarma

You're right, but that was the issue only in 2nd code. I fixed it and I'm getting same results again.

Go Up