gzweigle / open-hybrid-piano

Building a hybrid MIDI digital piano
https://www.youtube.com/@gzpiano88
GNU General Public License v3.0
44 stars 3 forks source link

DOC: how to proceed in debugging sensor data #109

Open davidedelvento opened 7 hours ago

davidedelvento commented 7 hours ago

With my sensors and my action (which you know are both very different than yours), I have a problem finding the appropriate calibration. I'm not asking for a fish, but to be taught to fish, which I can then make it into a PR for the documentation, so others can benefit too. I'm describing my problem just as an example: I speculate you went through something similar and so the actual question is "what steps would you suggest performing to debug similar issues". I know some people are mulling the option to use the system with different kind of sensors (maybe not even optical ones), so this would greatly help them too.

It feels like I am stuck at a note-on velocity of almost always 16. See for example this MIDI and corresponding ADC capture

note_on channel=1 note=24 velocity=16 time=0
note_off channel=1 note=24 velocity=23 time=0

note_on channel=1 note=24 velocity=16 time=0
note_off channel=1 note=24 velocity=50 time=0

note_on channel=1 note=24 velocity=16 time=0
note_off channel=1 note=24 velocity=84 time=0

note_on channel=1 note=24 velocity=16 time=0
note_off channel=1 note=24 velocity=79 time=0
note_off channel=1 note=24 velocity=4 time=0
note_off channel=1 note=24 velocity=0 time=0
note_off channel=1 note=24 velocity=2 time=0

note_on channel=1 note=24 velocity=16 time=0
note_on channel=1 note=24 velocity=34 time=0
note_off channel=1 note=24 velocity=10 time=0

hammer

In this example (which I unfortunately I forgot to separately timestamp on the MIDI capture part, given that real-time MIDI has no inherent timestamps) I had:

and the following problems:

I speculate that the hammers move too fast (my sensors are right under the felt, as compared to yours near the flange) and therefore something in the code is too slow to keep pace and measure them fast enough for sensing velocities faster than MIDI 16. Perhaps something else (e.g. some integer conversion) forces the velocity to not be slower than 16 either (given the range of ADC measurements), and so it's stuck there.... unless I move an hammer with my hand, which is slower enough to be measured and hence other velocity values are generated. Pure speculation here, which I could confirm if there is a quick debug setting somewhere to stop the multiplexing and go "full throttle" on one note only. Is there such an option?

Probably confirming the speculation above, but I tried changing various constants with _scaling and _threshold and the algorithm (0 or 1). None of those changes modified anything with regard to this behavior.

gzweigle commented 5 hours ago

I always debugged with calibration off. One less variable.

Here is some data that could help. I moved a sensor to be over the hammer.

Attached is:

(1) A picture of the test setup.

(2) Measured values (received over Ethernet) for a very slow (manual move hammer), slow (keypress), and fast (keypress) hammer strike.

(3) A picture of plot of position and velocity.

Observations:

(A) The sensor does not pick up the hammer until it is close to the sensor. So the hammer position data is very nonlinear.

(B) There are less samples due to the faster motion (traveling 40mm at hammer vs 5 mm at flange). But back-of-the-envelope and looking at this attached data, the 300us sample rate may be ok.

(C) The velocity in attached plot is about 2X for the fast strike compared to the slow strike. This quick test didn't test if I actually played with 2X the velocity.

a0_fast_strike.txt a0_manual.txt a0_slow_strike.txt

plotted_results sensor_at_hammer

gzweigle commented 5 hours ago

The results I just shared is with calibration off.

gzweigle commented 5 hours ago

Octave code to recreate my plots. The zeros in the filter are just to smooth things out. They aren't necessary.

clear;

x_slow = load("a0_slow_strike.txt"); x_fast = load("a0_fast_strike.txt");

v_slow = filter([1 0 0 0 0 0 0 0 -1],[1],x_slow); v_fast = filter([1 0 0 0 0 0 0 0 -1],[1],x_fast);

t = [0:length(x_slow)-1]*300e-6;

figure(1); subplot(2,2,1); plot(t, x_slow); grid; title('position, slow'); xlabel('seconds');

subplot(2,2,3); plot(t, x_fast); grid; title('position, fast'); xlabel('seconds');

subplot(2,2,2); plot(t, v_slow, 'k', t, v_slow, 'ok'); grid; title('velocity, slow'); xlabel('seconds');

subplot(2,2,4); plot(t, v_fast, 'k', t, v_fast, 'ok'); grid; title('velocity, fast'); xlabel('seconds');

gzweigle commented 4 hours ago

With respect to my observation (B) and this comment in op - "...something in the code is too slow to keep pace and measure them fast enough..." After thinking about it. At both hammer and flange, the motion start time and end time are the same. All that differs is a numerical value. Therefore, the 300us sample rate is ok for both. In other words, the "code speed" is ok for measuring at hammer. The problem is somewhere else.