tttapa / MIDI_controller

This is a library for creating a MIDI controller using an Arduino or Teensy board.
GNU General Public License v3.0
402 stars 70 forks source link

Faders jump when I push through 50% #48

Open mkothencz opened 6 years ago

mkothencz commented 6 years ago

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?

tttapa commented 6 years ago

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

mkothencz commented 6 years ago

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

tttapa commented 6 years ago

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

mkothencz commented 6 years ago

Yes, I use the latest version.

tttapa commented 6 years ago

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.

mkothencz commented 6 years ago

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?

tttapa commented 6 years ago

Could you post your exact code?

mkothencz commented 6 years ago
#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();}
tttapa commented 6 years ago

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?

mkothencz commented 6 years ago

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.

tttapa commented 6 years ago

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.

mkothencz commented 6 years ago

It is just random.

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

tttapa commented 6 years ago

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.

mkothencz commented 6 years ago

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

mkothencz commented 6 years ago

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?

tttapa commented 6 years ago

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.
davidgauze commented 5 years ago

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???