MIDI_controller icon indicating copy to clipboard operation
MIDI_controller copied to clipboard

Faders jump when I push through 50%

Open mkothencz opened this issue 6 years ago • 17 comments

Hello,

I built a big MIDI controller with 16 faders, 150 buttons and 8 rotary encoders. I used Tennsy 3.5 and 10k faders.

I have a little problem: when I push the faders through 50% they jump to maximum (or minimum depend on push direction) for a very short time.

How could I solve this? With programing or this is hardware problem?

mkothencz avatar Jun 16 '18 09:06 mkothencz

If you use the AnalogReadSerial example of the IDE, do you experience the same problem?

tttapa avatar Jun 16 '18 09:06 tttapa

No, I can't find any problem if I monitor with serial monitor.

mkothencz avatar Jun 16 '18 10:06 mkothencz

That's very strange. Are you using release 3.0.1 or the latest version from the master branch?

tttapa avatar Jun 16 '18 11:06 tttapa

Yes, I use the latest version.

mkothencz avatar Jun 16 '18 14:06 mkothencz

There could be a problem with implicit type conversions from unsigned to signed integer types, IIRC, they can be different on ARM.

I have exams at the moment, so I don't have time to look into it right now. If you want to debug yourself, I'd start by looking at src/Helpers/EMA.h, src/Helpers/Hysteresis.h and src/Helpers/Hysteresis.cpp.

tttapa avatar Jun 16 '18 14:06 tttapa

potmeter

This is what I get, when I move the faders up-down.

I don't really know how I could debug.

What about changing refresh/analog reading rate? How could I try this out?

mkothencz avatar Jun 22 '18 08:06 mkothencz

Could you post your exact code?

tttapa avatar Jun 22 '18 10:06 tttapa

#define USE_ROTARY_ENCODER
#include <MIDI_Controller.h>
const int speedMultiply = 1;


//BUTTONS
AnalogMultiplex multiplexer1(4, {0,1,2,3} );
AnalogMultiplex multiplexer2(5, {0,1,2,3} );
AnalogMultiplex multiplexer3(6, {0,1,2,3} );
AnalogMultiplex multiplexer4(7, {0,1,2,3} );
AnalogMultiplex multiplexer5(8, {0,1,2,3} );
AnalogMultiplex multiplexer6(9, {0,1,2,3} );
AnalogMultiplex multiplexer7(10, {0,1,2,3} );
AnalogMultiplex multiplexer8(11, {0,1,2,3} );
AnalogMultiplex multiplexer9(12, {0,1,2,3} );

Digital button1(53, 0x1, 15, 127);
Digital button2(26, 0x2, 15, 127);
Digital button3(27, 0x3, 15, 127);
Digital button4(28, 0x4, 15, 127);
Digital button5(29, 0x5, 15, 127);
Digital button6(30, 0x6, 15, 127);
Digital button7(31, 0x7, 15, 127);

Digital buttons1[] = {
  {multiplexer1.pin(0), 0x1, 1},
  {multiplexer1.pin(1), 0x2, 1},
  {multiplexer1.pin(2), 0x3, 1},
  {multiplexer1.pin(3), 0x4, 1},
  {multiplexer1.pin(4), 0x5, 1},
  {multiplexer1.pin(5), 0x6, 1},
  {multiplexer1.pin(6), 0x7, 1},
  {multiplexer1.pin(7), 0x8, 1},
  {multiplexer1.pin(8), 0x9, 1},
  {multiplexer1.pin(9), 0xA, 1},
  {multiplexer1.pin(10), 0xB, 1},
  {multiplexer1.pin(11), 0xC, 1},
  {multiplexer1.pin(12), 0xD, 1},
  {multiplexer1.pin(13), 0xE, 1},
  {multiplexer1.pin(14), 0xF, 1},
  {multiplexer1.pin(15), 0x10, 1},
};
Digital buttons2[] = {
  {multiplexer2.pin(0), 0x1, 2},
  {multiplexer2.pin(1), 0x2, 2},
  {multiplexer2.pin(2), 0x3, 2},
  {multiplexer2.pin(3), 0x4, 2},
  {multiplexer2.pin(4), 0x5, 2},
  {multiplexer2.pin(5), 0x6, 2},
  {multiplexer2.pin(6), 0x7, 2},
  {multiplexer2.pin(7), 0x8, 2},
  {multiplexer2.pin(8), 0x9, 2},
  {multiplexer2.pin(9), 0xA, 2},
  {multiplexer2.pin(10), 0xB,2},
  {multiplexer2.pin(11), 0xC,2},
  {multiplexer2.pin(12), 0xD, 2},
  {multiplexer2.pin(13), 0xE, 2},
  {multiplexer2.pin(14), 0xF, 2},
  {multiplexer2.pin(15), 0x10,2},
};
Digital buttons3[] = {
  {multiplexer3.pin(0), 0x1, 3},
  {multiplexer3.pin(1), 0x2, 3},
  {multiplexer3.pin(2), 0x3, 3},
  {multiplexer3.pin(3), 0x4, 3},
  {multiplexer3.pin(4), 0x5, 3},
  {multiplexer3.pin(5), 0x6, 3},
  {multiplexer3.pin(6), 0x7, 3},
  {multiplexer3.pin(7), 0x8, 3},
  {multiplexer3.pin(8), 0x9, 3},
  {multiplexer3.pin(9), 0xA, 3},
  {multiplexer3.pin(10), 0xB,3},
  {multiplexer3.pin(11), 0xC, 3},
  {multiplexer3.pin(12), 0xD, 3},
  {multiplexer3.pin(13), 0xE, 3},
  {multiplexer3.pin(14), 0xF, 3},
  {multiplexer3.pin(15), 0x10,3},
};
Digital buttons4[] = {
  {multiplexer4.pin(0), 0x1, 4},
  {multiplexer4.pin(1), 0x2, 4},
  {multiplexer4.pin(2), 0x3, 4},
  {multiplexer4.pin(3), 0x4, 4},
  {multiplexer4.pin(4), 0x5, 4},
  {multiplexer4.pin(5), 0x6, 4},
  {multiplexer4.pin(6), 0x7, 4},
  {multiplexer4.pin(7), 0x8, 4},
  {multiplexer4.pin(8), 0x9, 4},
  {multiplexer4.pin(9), 0xA, 4},
  {multiplexer4.pin(10), 0xB, 4},
  {multiplexer4.pin(11), 0xC, 4},
  {multiplexer4.pin(12), 0xD, 4},
  {multiplexer4.pin(13), 0xE, 4},
  {multiplexer4.pin(14), 0xF, 4},
  {multiplexer4.pin(15), 0x10, 4},
};
Digital buttons5[] = {
  {multiplexer5.pin(0), 0x1, 5},
  {multiplexer5.pin(1), 0x2, 5},
  {multiplexer5.pin(2), 0x3, 5},
  {multiplexer5.pin(3), 0x4, 5},
  {multiplexer5.pin(4), 0x5, 5},
  {multiplexer5.pin(5), 0x6, 5},
  {multiplexer5.pin(6), 0x7, 5},
  {multiplexer5.pin(7), 0x8, 5},
  {multiplexer5.pin(8), 0x9, 5},
  {multiplexer5.pin(9), 0xA, 5},
  {multiplexer5.pin(10), 0xB, 5},
  {multiplexer5.pin(11), 0xC, 5},
  {multiplexer5.pin(12), 0xD, 5},
  {multiplexer5.pin(13), 0xE, 5},
  {multiplexer5.pin(14), 0xF, 5},
  {multiplexer5.pin(15), 0x10, 5},
};
Digital buttons6[] = {
  {multiplexer6.pin(0), 0x1, 6},
  {multiplexer6.pin(1), 0x2, 6},
  {multiplexer6.pin(2), 0x3, 6},
  {multiplexer6.pin(3), 0x4, 6},
  {multiplexer6.pin(4), 0x5, 6},
  {multiplexer6.pin(5), 0x6, 6},
  {multiplexer6.pin(6), 0x7, 6},
  {multiplexer6.pin(7), 0x8, 6},
  {multiplexer6.pin(8), 0x9, 6},
  {multiplexer6.pin(9), 0xA, 6},
  {multiplexer6.pin(10), 0xB, 6},
  {multiplexer6.pin(11), 0xC, 6},
  {multiplexer6.pin(12), 0xD, 6},
  {multiplexer6.pin(13), 0xE, 6},
  {multiplexer6.pin(14), 0xF, 6},
  {multiplexer6.pin(15), 0x10, 6},
};
Digital buttons7[] = {
  {multiplexer7.pin(0), 0x1, 7},
  {multiplexer7.pin(1), 0x2, 7},
  {multiplexer7.pin(2), 0x3, 7},
  {multiplexer7.pin(3), 0x4, 7},
  {multiplexer7.pin(4), 0x5, 7},
  {multiplexer7.pin(5), 0x6, 7},
  {multiplexer7.pin(6), 0x7, 7},
  {multiplexer7.pin(7), 0x8, 7},
  {multiplexer7.pin(8), 0x9, 7},
  {multiplexer7.pin(9), 0xA, 7},
  {multiplexer7.pin(10), 0xB, 7},
  {multiplexer7.pin(11), 0xC, 7},
  {multiplexer7.pin(12), 0xD, 7},
  {multiplexer7.pin(13), 0xE, 7},
  {multiplexer7.pin(14), 0xF, 7},
  {multiplexer7.pin(15), 0x10, 7},
};
Digital buttons8[] = {
  {multiplexer8.pin(0), 0x1, 8},
  {multiplexer8.pin(1), 0x2, 8},
  {multiplexer8.pin(2), 0x3, 8},
  {multiplexer8.pin(3), 0x4, 8},
  {multiplexer8.pin(4), 0x5, 8},
  {multiplexer8.pin(5), 0x6, 8},
  {multiplexer8.pin(6), 0x7, 8},
  {multiplexer8.pin(7), 0x8, 8},
  {multiplexer8.pin(8), 0x9, 8},
  {multiplexer8.pin(9), 0xA, 8},
  {multiplexer8.pin(10), 0xB,8},
  {multiplexer8.pin(11), 0xC, 8},
  {multiplexer8.pin(12), 0xD, 8},
  {multiplexer8.pin(13), 0xE, 8},
  {multiplexer8.pin(14), 0xF, 8},
  {multiplexer8.pin(15), 0x10, 8},
};
Digital buttons9[] = {
  {multiplexer9.pin(0), 0x1, 9},
  {multiplexer9.pin(1), 0x2, 9},
  {multiplexer9.pin(2), 0x3, 9},
  {multiplexer9.pin(3), 0x4, 9},
  {multiplexer9.pin(4), 0x5, 9},
  {multiplexer9.pin(5), 0x6, 9},
  {multiplexer9.pin(6), 0x7, 9},
  {multiplexer9.pin(7), 0x8, 9},
  {multiplexer9.pin(8), 0x9, 9},
  {multiplexer9.pin(9), 0xA, 9},
  {multiplexer9.pin(10), 0xB,9},
  {multiplexer9.pin(11), 0xC, 9},
  {multiplexer9.pin(12), 0xD, 9},
  {multiplexer9.pin(13), 0xE, 9},
  {multiplexer9.pin(14), 0xF, 9},
  {multiplexer9.pin(15), 0x10, 9},
};

//POTENTIOMETERS
Analog potentiometer0 (A9,0x1,11);
Analog potentiometer1 (A8,0x2,11);
Analog potentiometer2 (A7,0x3,11);
Analog potentiometer3 (A6,0x4,11);
Analog potentiometer4 (A5,0x5,11);
Analog potentiometer5 (A20,0x6,11);
Analog potentiometer6 (A19,0x7,11);
Analog potentiometer7 (A17,0x8,11);
Analog potentiometer8 (A18,0x9,11);
Analog potentiometer9 (A16,0xA,11);
Analog potentiometer10 (A4,0xB,11);
Analog potentiometer11 (A3,0xC,11);
Analog potentiometer12 (A2,0xD,11);
Analog potentiometer13 (A1,0xE,11);
Analog potentiometer14 (A0,0xF,11);
Analog potentiometer15 (A15,0x10,11);


//ROTARY ENCODERS
RotaryEncoder enc0 = {48, 47, 0x1, 12, speedMultiply, NORMAL_ENCODER, TWOS_COMPLEMENT};// Create a new instance of class 'RotaryEncoder' called enc, on pins 1 and 0, controller number 0x2F, on MIDI channel 1, at normal speed, using a normal encoder (4 pulses per click/step), using the TWOS_COMPLEMENT sign option
RotaryEncoder enc1 = {50, 49, 0x2, 12, speedMultiply, NORMAL_ENCODER, TWOS_COMPLEMENT};
RotaryEncoder enc2 = {45, 43, 0x3, 12, speedMultiply, NORMAL_ENCODER, TWOS_COMPLEMENT};
RotaryEncoder enc3 = {46, 44, 0x4, 12, speedMultiply, NORMAL_ENCODER, TWOS_COMPLEMENT};
RotaryEncoder enc4 = {52, 51, 0x5, 12, speedMultiply, NORMAL_ENCODER, TWOS_COMPLEMENT};
RotaryEncoder enc5 = {41, 42, 0x6, 12, speedMultiply, NORMAL_ENCODER, TWOS_COMPLEMENT};
RotaryEncoder enc6 = {55, 54, 0x7, 12, speedMultiply, NORMAL_ENCODER, TWOS_COMPLEMENT};
RotaryEncoder enc7 = {57, 56, 0x8, 12, speedMultiply, NORMAL_ENCODER, TWOS_COMPLEMENT};

int mapCalibrated(int val) {

  if (val <= 88)
  {
    return map(val, 0, 88, 0, 0);
  }
  if (val > 88 && val < 1001)
  {
    return map(val, 89, 1000, 0, 1023);
  }
  if (val >= 1001 )
  {
    return map(val, 1001, 1023, 1023, 1023);
  }
  
}

void setup() {  
  potentiometer0.map(mapCalibrated); // apply the 'mapCalibrated' function on the analog input of 'potentiometer'
  potentiometer1.map(mapCalibrated); // apply the 'mapCalibrated' function on the analog input of 'potentiometer'
  potentiometer2.map(mapCalibrated); // apply the 'mapCalibrated' function on the analog input of 'potentiometer'
  potentiometer3.map(mapCalibrated); // apply the 'mapCalibrated' function on the analog input of 'potentiometer'
  potentiometer4.map(mapCalibrated); // apply the 'mapCalibrated' function on the analog input of 'potentiometer'
  potentiometer5.map(mapCalibrated); // apply the 'mapCalibrated' function on the analog input of 'potentiometer' 
  potentiometer6.map(mapCalibrated); // apply the 'mapCalibrated' function on the analog input of 'potentiometer'
  potentiometer7.map(mapCalibrated); // apply the 'mapCalibrated' function on the analog input of 'potentiometer'
  potentiometer8.map(mapCalibrated); // apply the 'mapCalibrated' function on the analog input of 'potentiometer'
  potentiometer9.map(mapCalibrated); // apply the 'mapCalibrated' function on the analog input of 'potentiometer'
  potentiometer10.map(mapCalibrated); // apply the 'mapCalibrated' function on the analog input of 'potentiometer'
  potentiometer11.map(mapCalibrated); // apply the 'mapCalibrated' function on the analog input of 'potentiometer'
  potentiometer12.map(mapCalibrated); // apply the 'mapCalibrated' function on the analog input of 'potentiometer'
  potentiometer13.map(mapCalibrated); // apply the 'mapCalibrated' function on the analog input of 'potentiometer'
  potentiometer14.map(mapCalibrated); // apply the 'mapCalibrated' function on the analog input of 'potentiometer'
  potentiometer15.map(mapCalibrated); // apply the 'mapCalibrated' function on the analog input of 'potentiometer' 
  
}
void loop() {MIDI_Controller.refresh();}

mkothencz avatar Jul 22 '18 12:07 mkothencz

There is no way I can ever try that code, because I don't have the same hardware you have.

Could you please try to post a minimal example that shows the behaviour you mentioned?

tttapa avatar Jul 26 '18 16:07 tttapa

https://www.youtube.com/watch?v=qbX7qgLZIo0&feature=youtu.be In this video you can see when I push up fader 1,5,6,9,10.

mkothencz avatar Jul 26 '18 17:07 mkothencz

I see. Is it always on the same faders? Or is it just random?

The strange thing is that I haven't been able to reproduce it, so I don't really have a clue where to start debugging.
I'll check the mathematics behind the analog input circuitry, tonight. They should be alright, but who knows, maybe there's an overflow somewhere.

tttapa avatar Jul 26 '18 17:07 tttapa

It is just random.

I tried use capacitor on analog inputs, but only slowed the faders down, but jumps at same speed happens.

mkothencz avatar Jul 26 '18 18:07 mkothencz

I feel so stupid right now.
The version I have locally on my computer has a filter factor of 2, so the intermediate values are 10 + 2*2 bits wide and fit in a 16-bit int. However, the version on GitHub has a filter factor of 3, so the values are 10 + 2*3 bits wide, and don't fit in a 16-bit int.

The solution: just change the filter factor to 2, or make the int_t for the filter 32 bits wide instead of 16. The latter will come at a performance and memory cost.

tttapa avatar Jul 26 '18 23:07 tttapa

Thank you! I can test it next week, but I am sure it will solve my problem.

mkothencz avatar Jul 27 '18 17:07 mkothencz

This two change options solved my problem, thanks! :)

Now I have only bit noise problem between 0-20% and 80-100%. Do you have any idea, what I can try to make a bit smoother?

mkothencz avatar Jul 30 '18 16:07 mkothencz

There are two options:

  1. Increase the filter factor again (note that this will also increase the latency if you make it too high), and change the filter type from int16_t to int32_t.
  2. Filter the input before applying the map function. This is the best approach, I think, and it's the default in the next release. Move up this line two lines.

tttapa avatar Jul 30 '18 17:07 tttapa

ola, precisava ajuda, tenho nocçao basica de arduino mega 2560, queria criar algo com 10 fader, 3 encoder e 40 botao poderiam me ajudar???

davidgauze avatar Mar 05 '19 21:03 davidgauze