joshnishikawa / MIDIcontroller

A library for creating Teensy MIDI controllers with support for hold or latch buttons, potentiometers, encoders, capacitive sensors, Piezo transducers and other velocity sensitive inputs with aftertouch.
223 stars 19 forks source link

Inout Range & Threshold #25

Closed digitalelements closed 1 year ago

digitalelements commented 1 year ago

Hi Josh,

I'm trying to confirm that since the input range parameters have been implemented, I not longer need the threshold in my sketches ? It's been a while since I've looked at things and the threshold doesn't appear to have any effect at the moment.

Pad0.setThreshold(960);

Pad0.inputRange(400, 850);

Kind Regards,

Chris

joshnishikawa commented 1 year ago

That works for some things but I can't tell which class you're using. Can you post the source code?

digitalelements commented 1 year ago

Sorry ! .. I should have posted more code.

`#include "MIDIcontroller.h"

// digitalelements FSR USB Module 10

byte MIDIchannel = 10;

const int pressPin [10] = {A0,A1,A2,A3,A4,A5,A6,A7,A8,A9}; // ANALOG pin

// Pin & Note number MIDIdrum Pad0(A0, 36); MIDIdrum Pad1(A1, 38); MIDIdrum Pad2(A2, 42); MIDIdrum Pad3(A3, 71); MIDIdrum Pad4(A4, 69); MIDIdrum Pad5(A5, 67); MIDIdrum Pad6(A6, 65); MIDIdrum Pad7(A7, 96); MIDIdrum Pad8(A8, 101); MIDIdrum Pad9(A9, 75);

void setup(){

// Threshold

Pad0.setThreshold(960); Pad1.setThreshold(10); Pad2.setThreshold(200); Pad3.setThreshold(200); Pad4.setThreshold(200); Pad5.setThreshold(200); Pad6.setThreshold(200); Pad7.setThreshold(200); Pad8.setThreshold(200); Pad9.setThreshold(200);

// Input Range

Pad0.inputRange(400, 850); Pad1.inputRange(60, 995); Pad2.inputRange(80, 900); Pad3.inputRange(80, 900); Pad4.inputRange(80, 900); Pad5.inputRange(80, 900); Pad6.inputRange(80, 900); Pad7.inputRange(80, 900); Pad8.inputRange(80, 900); Pad9.inputRange(80, 900);

// Velocity Output

Pad0.outputRange(1,127); Pad1.outputRange(1,127); Pad2.outputRange(1,127); Pad3.outputRange(1,127); Pad4.outputRange(1,127); Pad5.outputRange(1,127); Pad6.outputRange(1,127); Pad7.outputRange(1,127); Pad8.outputRange(1,127); Pad9.outputRange(1,127);

//WaitTime

Pad0.setWaitTime(100); Pad1.setWaitTime(6); Pad2.setWaitTime(10); Pad3.setWaitTime(10); Pad4.setWaitTime(10); Pad5.setWaitTime(10); Pad6.setWaitTime(10); Pad7.setWaitTime(10); Pad8.setWaitTime(10); Pad9.setWaitTime(10);

}

void loop(){ Pad0.send(); Pad1.send(); Pad2.send(); Pad3.send(); Pad4.send(); Pad5.send(); Pad6.send(); Pad7.send(); Pad8.send(); Pad9.send();

// Crash Protection while(usbMIDI.read()){}

} `

joshnishikawa commented 1 year ago

Sorry I couldn't respond earlier. I was in the middle of a move. At first glance, using setThreshold is redundant when using inputRange. The inputRange function sets the threshold and max reading in one function. So on Pad0 for example, you're telling the threshold to be 960 but then you're telling it to be 400. Try it without any of the setThreshold function calls.

digitalelements commented 1 year ago

Hi Josh, No worries !! And, sorry to have bothered you during your move. Yes ... 960 is the value I left in my sketch which prompted me to reach out to you. The threshold doesn't appear to work at all 0 or 960. SO I will try removing all the threshold function calls. Pad0 is my kick drum. and I'm trying to solve an issue that occurs when a drummer leaves the beater against the head ( FSR sensor) in between actual played notes. it may take some fancy programming to eliminate this one.

Thanks for responding and hope all went well with your move :)

joshnishikawa commented 1 year ago

I know exactly what you're saying about the beater resting on the kick drum until the drummer lifts their foot for the next beat. The code accounts for that. After a trigger, the input will be ignored until the input signal drops BELOW the threshold again. Unfortunately, it looks like I made a very silly mistake. I used an unsigned int type where I needed just int. I don't want to create a new release unless I know that the problem is solved so...could you remove the word 'unsigned' from line #47 of MIDIdrum.cpp and let me know if that fixes it.

Incidentally, 960 is a very high threshold. There aren't even 127 possible values between 960 and the max analog reading of 1023. You might try some extra padding between the FSR and beater. It's very tricky to get perfect though.

digitalelements commented 1 year ago

Hey Josh, Thanks for the quick reply. I will absolutely work on this today. The 960 was just a drastic value test. So, not a value I would ever really use. All my FSR sensors are very well padded. I'd love to show you .. just have to decide where how to post the images. not sure this message system supports images ?

digitalelements commented 1 year ago

Never mind it appears it does support images :)

Kick Molds KickPad1 KickPad2

digitalelements commented 1 year ago

Hi Josh,

I did as you suggested and change the 'unsigned int' to 'int' however, it had no effect on the issue. I did happen to notice at line #146 that there was another reference to the threshold that was also 'unsigned' wasn't sure if this one also needs to be changed or?

Regards

joshnishikawa commented 1 year ago

I'm back in the workshop again. Can you post your current sketch using either setThreshold(xxx) or inputRange(xxx, xxx) (not both) for each drum pad?

digitalelements commented 1 year ago

Hi Josh,

welcome back ! .. hope the move went well and smoothly : ) ..


// digitalelements FSR USB Module 10

byte MIDIchannel = 10;

const int pressPin [10] = {A0,A1,A2,A3,A4,A5,A6,A7,A8,A9}; // ANALOG pin

  // Pin & Note number
  MIDIdrum Pad0(A0, 36);
  MIDIdrum Pad1(A1, 38);
  MIDIdrum Pad2(A2, 42);
  MIDIdrum Pad3(A3, 71);
  MIDIdrum Pad4(A4, 69);
  MIDIdrum Pad5(A5, 67);
  MIDIdrum Pad6(A6, 65);
  MIDIdrum Pad7(A7, 96);
  MIDIdrum Pad8(A8, 101);
  MIDIdrum Pad9(A9, 75);

void setup(){

  // Threshold

  // Input Range

  Pad0.inputRange(550, 800);
  Pad1.inputRange(60, 995);
  Pad2.inputRange(80, 900);
  Pad3.inputRange(80, 900);
  Pad4.inputRange(80, 900);
  Pad5.inputRange(80, 900);
  Pad6.inputRange(80, 900);
  Pad7.inputRange(80, 900);
  Pad8.inputRange(80, 900);
  Pad9.inputRange(80, 900);

  // Velocity Output

  Pad0.outputRange(24,127);
  Pad1.outputRange(1,127);
  Pad2.outputRange(1,127);
  Pad3.outputRange(1,127);
  Pad4.outputRange(1,127);
  Pad5.outputRange(1,127);
  Pad6.outputRange(1,127);
  Pad7.outputRange(1,127);
  Pad8.outputRange(1,127);
  Pad9.outputRange(1,127);

  //WaitTime

  Pad0.setWaitTime(50);
  Pad1.setWaitTime(6);
  Pad2.setWaitTime(10);
  Pad3.setWaitTime(10);
  Pad4.setWaitTime(10);
  Pad5.setWaitTime(10);
  Pad6.setWaitTime(10);
  Pad7.setWaitTime(10);
  Pad8.setWaitTime(10);
  Pad9.setWaitTime(10);

}

void loop(){
  Pad0.send();
  Pad1.send();
  Pad2.send();
  Pad3.send();
  Pad4.send();
  Pad5.send();
  Pad6.send();
  Pad7.send();
  Pad8.send();
  Pad9.send();

// Crash Protection
  while(usbMIDI.read()){}

}
joshnishikawa commented 1 year ago

Your sketch looks okay. I wired my FSR up and tested it using inputRange(). Changing the threshold (the first argument) did seem to have an effect. I was just tapping the naked FSR with my finger which is quite different than your setup but I did get a much better result using a 1k resistor instead of a 10k and using inputRange(300, 700).

I doubt those numbers would be ideal with your setup but the code seems to be working as expected for me. You might try some different resistor values.

digitalelements commented 1 year ago

Thank you !

I'll go ahead an experiment with a few new resistor values. I have a feeling this scenario will require some other type of programming to eliminate this trigger event. If the bass drum beater is just resting against the playing surface ( FSR + Silicone) and enough pressure is applied it will trigger. it's just an odd " drummer " thing I guess. :)

joshnishikawa commented 1 year ago

I have a feeling this scenario will require some other type of programming to eliminate this trigger event. If the bass drum beater is just resting against the playing surface ( FSR + Silicone) and enough pressure is applied it will trigger.

I think you're right. I mean it works as the programmer intends but, if it doesn't work like the musician expects, it's kind of pointless.

The way it works now is that, once the threshold is breached, it keeps track of the highest value over the next ten milliseconds and then sends it. Maybe I should try to adapt the traditional approach. Most keyboards use dual switches for each key. The sooner the second switch is triggered after the first switch, the higher the note velocity.

To do it with an FSR, I think dual thresholds would have to be set somehow. But I'll have to put some serious thought into exactly how...maybe just hard-code a minimum traversal time (to eliminate notes that aren't the result of a strike), dynamically set the first threshold to be halfway between the min and max input. Then the higher user-set threshold could be used to set the sensitivity of the pad while velocity is still time-based. It would be more responsive too.

I'm on this!

digitalelements commented 1 year ago

Josh,

Thats outstanding news ! ... I'm ready and able to test anything you come up with and provide feedback.

joshnishikawa commented 1 year ago

Well, I've been working on this for about a week and, although the dual-trigger solution isn't going to work, at least I figured out a way to prevent non-hit triggers. You can now add Pad0.sensitivity(99) in your setup and that will require at least some velocity. You can put anything between 1 and 100 (100 is default) but even as low as 90 seems useless. I need to fine tune this but I'd like to hear how it works for you before I do.

Please install version 2.6.5 and see how it responds. It's pre-release so you won't find it in the Arduino library manager (in fact the latest version you'll find there is broken. I'm trying to get it removed.) You'll have to get 2.6.5 from github.

Details about what didn't work and why... Analog range is 0-1023 but you won't necessarily be able to make use of that whole range. For example, my setup only uses the 20-720 range. If using dual thresholds, some of that usable range needs to be used as space between the two thresholds: more than 10 (because even quiescent readings could jump that far) but as little as possible because it cuts into the usable analog range. So, say a low threshold of 20 and a high threshold of 120. The time it takes to traverse both of those thresholds with a hit is on the order of tens of microseconds. The problem is that an analog reading takes something like 15-20 microseconds to perform. Your finger/beater could be anywhere in transition when the reading comes through so many of the triggers get missed. The problem would be compounded with any additional analogReads in your loop.

Details about what might have worked... sensitivity() sets what percentage of your usable analog range should trigger MIDI. The remainder is used to determine what percentage of that range should be traversed in 1 millisecond (not microsecond) to trigger a hit. For example, my setup with sensitivity 99 would require a reading of 27 within 1 millisecond of a reading of 20 to trigger MIDI. sensitivity 50 would require a reading of 370 within 1 millisecond of a reading of 20. That's already pretty difficult to do and eats up a huge part of the analog range. Dual trigger has the same problem but at least this way it's a percentage of that range set by the user and not just a 'magic number'.

digitalelements commented 1 year ago

Hey Josh,

This is great news ! I'll dive in to have a close look and report back. Thank you kindly for the work :)

digitalelements commented 1 year ago

Hey Josh,

I've had a little bit of time with the 2.6.5 still trying to get things dialed in. The first attempt was with your newest example sketch. it was pretty erratic with playing. i'd get a few soft notes and then the pad would stop. Also after loading the sketch to the Teensy I get a fair bit of warning which I'll include below. Btw is it still ok to use the velocity out put range and wait time in the sketches ?

Thanks,

Pad0.outputRange(24,127); Pad0.setWaitTime(50);


/Users/chrisryan/Documents/Arduino/libraries/MIDIcontroller/src/MIDIdrum.cpp:62:27: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
           peak = newValue > peak ? newValue : peak;
                           ^
/Users/chrisryan/Documents/Arduino/libraries/MIDIcontroller/src/MIDIdrum.cpp:73:22: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
         if (newValue > peak) {
                      ^
In file included from /Users/chrisryan/Library/Arduino15/packages/teensy/hardware/avr/1.57.1/cores/teensy4/WProgram.h:45:0,
                 from /private/var/folders/w4/q9lkszhj4k16dnhj8l7ctbgc0000gn/T/arduino-sketch-0610778C469B2D548A07C0A351B11B5E/pch/Arduino.h:6,
                 from /Users/chrisryan/Documents/Arduino/libraries/MIDIcontroller/src/MIDIdrum.h:4,
                 from /Users/chrisryan/Documents/Arduino/libraries/MIDIcontroller/src/MIDIdrum.cpp:1:
/Users/chrisryan/Library/Arduino15/packages/teensy/hardware/avr/1.57.1/cores/teensy4/wiring.h:172:9: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   (_amt < _low) ? _low : ((_amt > _high) ? _high : _amt); \
         ^
/Users/chrisryan/Documents/Arduino/libraries/MIDIcontroller/src/MIDIdrum.cpp:78:22: note: in expansion of macro 'constrain'
           newValue = constrain(peak, upperThreshold, inHi);
                      ^
/Users/chrisryan/Documents/Arduino/libraries/MIDIcontroller/src/MIDIdrum.cpp:79:31: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
           newValue = newValue >= inHi ? outHi : map(peak,upperThreshold,inHi,outLo,outHi);
                               ^
/Users/chrisryan/Documents/Arduino/libraries/MIDIcontroller/src/MIDIdrum.cpp:89:22: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
         if (newValue > threshold) {
                      ^
/Users/chrisryan/Documents/Arduino/libraries/MIDIcontroller/src/MIDIdrum.cpp:103:22: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
         if (newValue >= threshold) {
                      ^
/Users/chrisryan/Documents/Arduino/libraries/MIDIcontroller/src/MIDIswitch.cpp: In member function 'int MIDIswitch::read()':
/Users/chrisryan/Documents/Arduino/libraries/MIDIcontroller/src/MIDIswitch.cpp:60:17: warning: 'bool Bounce::fallingEdge() const' is deprecated [-Wdeprecated-declarations]
     if (Bounce::fallingEdge()){    // If the button's been pressed,
                 ^
In file included from /Users/chrisryan/Documents/Arduino/libraries/MIDIcontroller/src/MIDIswitch.h:5:0,
                 from /Users/chrisryan/Documents/Arduino/libraries/MIDIcontroller/src/MIDIswitch.cpp:1:
/Users/chrisryan/Documents/Arduino/libraries/Bounce2/src/Bounce2.h:246:7: note: declared here
  bool fallingEdge() const { return fell(); }
       ^
/Users/chrisryan/Documents/Arduino/libraries/MIDIcontroller/src/MIDIswitch.cpp:60:29: warning: 'bool Bounce::fallingEdge() const' is deprecated [-Wdeprecated-declarations]
     if (Bounce::fallingEdge()){    // If the button's been pressed,
                             ^
In file included from /Users/chrisryan/Documents/Arduino/libraries/MIDIcontroller/src/MIDIswitch.h:5:0,
                 from /Users/chrisryan/Documents/Arduino/libraries/MIDIcontroller/src/MIDIswitch.cpp:1:
/Users/chrisryan/Documents/Arduino/libraries/Bounce2/src/Bounce2.h:246:7: note: declared here
  bool fallingEdge() const { return fell(); }
       ^
/Users/chrisryan/Documents/Arduino/libraries/MIDIcontroller/src/MIDIswitch.cpp:63:22: warning: 'bool Bounce::risingEdge() const' is deprecated [-Wdeprecated-declarations]
     else if (Bounce::risingEdge()){// If the button has been released,
                      ^
In file included from /Users/chrisryan/Documents/Arduino/libraries/MIDIcontroller/src/MIDIswitch.h:5:0,
                 from /Users/chrisryan/Documents/Arduino/libraries/MIDIcontroller/src/MIDIswitch.cpp:1:
/Users/chrisryan/Documents/Arduino/libraries/Bounce2/src/Bounce2.h:241:7: note: declared here
  bool risingEdge() const { return rose(); }
       ^
/Users/chrisryan/Documents/Arduino/libraries/MIDIcontroller/src/MIDIswitch.cpp:63:33: warning: 'bool Bounce::risingEdge() const' is deprecated [-Wdeprecated-declarations]
     else if (Bounce::risingEdge()){// If the button has been released,
                                 ^
In file included from /Users/chrisryan/Documents/Arduino/libraries/MIDIcontroller/src/MIDIswitch.h:5:0,
                 from /Users/chrisryan/Documents/Arduino/libraries/MIDIcontroller/src/MIDIswitch.cpp:1:
/Users/chrisryan/Documents/Arduino/libraries/Bounce2/src/Bounce2.h:241:7: note: declared here
  bool risingEdge() const { return rose(); }
       ^
/Users/chrisryan/Documents/Arduino/libraries/MIDIcontroller/src/MIDIdrum.cpp:126:10: warning: 'newValue' may be used uninitialized in this function [-Wmaybe-uninitialized]
   return newValue;
          ^
/Users/chrisryan/Documents/Arduino/libraries/MIDIcontroller/src/MIDIdrum.cpp: In member function 'int MIDIdrum::send()':
/Users/chrisryan/Documents/Arduino/libraries/MIDIcontroller/src/MIDIdrum.cpp:51:7: warning: 'newValue' may be used uninitialized in this function [-Wmaybe-uninitialized]
   int newValue;
       ^
/Users/chrisryan/Documents/Arduino/libraries/MIDIcontroller/src/MIDIdrum.cpp: In member function 'int MIDIdrum::send(int)':
/Users/chrisryan/Documents/Arduino/libraries/MIDIcontroller/src/MIDIdrum.cpp:143:10: warning: 'newValue' may be used uninitialized in this function [-Wmaybe-uninitialized]
   return newValue;
          ^
Memory Usage on Teensy 4.0:
  FLASH: code:13760, data:5168, headers:8716   free for files:2003972
   RAM1: variables:6400, code:12056, padding:20712   free for local variables:485120
   RAM2: variables:17568  free for malloc/new:506720```
joshnishikawa commented 1 year ago

Thanks for that. I've cleaned up most of those errors. The ones about deprecated risingEdge/fallingEdge happened because the Bounce2 library (used for MIDIswitch) changed the function names to rose/fell and I hadn't yet. I fixed the ones about newValue being possibly uninitialized too.

As for the ones about comparing signed and unsigned integers, I fixed a few. I'll fix the rest at some point but they shouldn't cause problems (It's not like that time I told an unsigned int to be -1).

About the sketch, could you post the whole thing please? I know you mention starting with my example and it looks like you're setting the output range and wait time but you don't mention setting the sensitivity. Anyway, it's just clearer if I can see the whole sketch. One other thing I thought is that maybe the threshold is just too high to begin with. I suggest using the lowest possible value that is the result of making contact with the pad.

Thanks for your help!

digitalelements commented 1 year ago

Hey Josh,

my apologies for the delay .. I tried to spend a good amount of time tweaking and testing things.

here's is the sketch that I'm working with. ( default example) with wait time added. the wait time is necessary especially for kick drum. it helps eliminate double triggers.

#include "MIDIcontroller.h"

/*This is an example of how to set up
  a velocity sensitive input using a
  force sensitive resistor.
  It's wired like so:

  3.3v--(FORCE RESISTOR)---\
                            )---Analog Pin
  GND--------/\/\/---------/
              10k
*/

byte MIDIchannel = 5;
const int pressPin = A0; // Change this to the correct ANALOG pin

// Note Parameters are: pin, note number
MIDIdrum myPad(pressPin, 36);

void setup(){
  // Set the threshold where you want notes to trigger.
  // And the analog reading that will trigger the maximum velocity.
  myPad.inputRange(60, 850);

 myPad.sensitivity(99); // Omit this to trigger MIDI even without hitting the pad.

 myPad.setWaitTime(10);
}

void loop(){
  myPad.send();

// This prevents crashes that happen when incoming usbMIDI is ignored.
  while(usbMIDI.read()){}

// Also uncomment this if compiling for standard MIDI
//  while(MIDI.read()){}
}

My pad input ranges are quite a bit different than yours. SO, it took my a bit to get them playable.

My Kick FSR is 60-850 and my snare is 100-950.

I assembled a dynamics plotter sketch to observe my FSR low and high ranges to help dial things in.

#include "MIDIcontroller.h"

byte MIDIchannel = 10;

const int pressPin [10] = {A0,A1,A2,A3,A4,A5,A6,A7,A8,A9}; // ANALOG pin

// Pin & Note number
MIDIdrum Pad0(A0, 36);
MIDIdrum Pad1(A1, 38);

void setup(){

Serial.begin(38400);

  // Threshold

  Pad0.setThreshold(10);
  Pad1.setThreshold(10);

  Pad0.inputRange(400, 900);
  Pad1.inputRange(60, 995);

  // Velocity Output

  Pad0.outputRange(24,127);
  Pad1.outputRange(1,127);

  //WaitTime
  Pad0.setWaitTime(80);
  Pad1.setWaitTime(6);

}

void loop(){

 int sensorValue = analogRead(A0);
  // print out the value you read:
Serial.print(60);// To freeze the lower limit
Serial.print(" "); 
Serial.print(" ");
Serial.print(900);// To freeze the upper limit
Serial.print(" ");
Serial.println(sensorValue);  // To send all three 'data' points to the plotter
  delay(1);        // delay in between reads for stability

  Pad0.send();
  Pad1.send();

// Crash Protection
  while(usbMIDI.read()){}

}

The settings for my kick drum ( in the first sketch ) seem tp play the best sofar. From time to time it does miss a few notes when playing soft to loud. still chasing that. it does however eliminate the triggered note if the FSR is pressed. The sensitivity must remain at 99. anything lower and the playability gets a bit whacky.

Best,

Chris

joshnishikawa commented 1 year ago

Thanks for putting time in on this! It sounds like the main issue now is missed triggers at lower velocities? I'm getting a bit of that too. I'll try to pin it down. And yeah, calling setWaitTime is very helpful for debouncing. I should probably put that in the example.

By the way I wrapped your code blocks in triple backticks ``` to render as preformatted text instead of HTML. Single backticks only work inline.

Also, there are some problems with the second sketch. This array never gets used.

const int pressPin [10] = {A0,A1,A2,A3,A4,A5,A6,A7,A8,A9}; // ANALOG pin

This has the same problem where you set the thresholds to 10 and then reset them to 400 and 60.

  Pad0.setThreshold(10);
  Pad1.setThreshold(10);

  Pad0.inputRange(400, 900);
  Pad1.inputRange(60, 995);

I think this would render the same as Serial.print(" ") but wouldn't function any differently than Serial.print(" ").

Serial.print(" "); 
Serial.print(" ");

Cheers! I'll see if I can find those missing triggers.

digitalelements commented 1 year ago

Hey Josh,

Thanks for that and sorry for the sloppy programming and code blocks. I'll clean things up :) The Serial Plotter sketch is intended for a single input. I was hoping to build the Sketch so that I could read and view all inputs at once. juts haven't gotten that far. I'm still pretty new to a lot of this code and programming.

digitalelements commented 1 year ago

Hey Josh,

I had a question regarding the MIDIswitch. Is it possible to bring the setThreshold forward into my sketch ? I'm attempting to use one of my FSR pads as the switch. The behavior works great when I press my FSR but it will not respond to a strike from a drum stick.( my FSR is covered with a 6mm silicone layer) I'm using the FSR straight in to a digital pin ( 10 which is in the example sketch). I have not included a 10K resistor or 3.3v from the Teensy. I'm only guessing that it would take a threshold adjustment to make this work.

Thanks!

joshnishikawa commented 1 year ago

There's a way to do that but could you open a new issue? I want to close this one when the too many/few triggers problem is resolved.

digitalelements commented 1 year ago

Understood .. and Sorry ... I should have just done that to begin with :)

joshnishikawa commented 1 year ago

I think I found those missing triggers. I was looking in the wrong place. Instead of changing the distance between thresholds, I needed to increase the time it had to traverse both thresholds. 1ms wasn't enough so I made it 2ms. (If that doesn't make sense, don't worry about it. It's mainly a note to self.)

I also set a default sensitivity of 90% to prevent triggers when the pad is not being struck. This can be set to anything between 0~100 using the improved sensitivity() function. (100 always triggers. 0 requires a pretty hard hit).

Finally, I made the default waitTime 30ms to prevent subsequent triggers. That may be high but 3ms was clearly too low.

So, if you would be so kind, update to 2.6.8 and try a new sketch WITHOUT using the setWaitTime() or sensitivity() functions. I'd like to know if the defaults are workable. Then, of course, fine tune it however you like. Thanks in advance!

digitalelements commented 1 year ago

Hey Josh,

I updated things to 2.6.8 and tested as requested without changing any settings. I used the MIDIdrum_FSR example sketch to do so. I think things are good and certainly workable as your default settings. I did notice in the example that the sensitivity was still set to 99 even though you mentioned changing it to 90% ? I do believe the 30ms wartime is a good middle of the road for a "Drum" It's a bit to high for a snare for intricate playing. ( rolls, drags and close flams) but a bit short for kick. Especially for folks that might bury the beater. But again .. a good starting point for all. You have some great notes inside the examples sketches maybe you could provide some copy that explains advanced tweaks ? .. just a thought. And then of course ... I had to go super nutty with tweaks after my homework :) I spent a few hours and, will do so for a few days. The numbers are wildly different so far. I'm sure it has everything to do with the difference in our respective FSR sensors. I invested in a custom sensor from china that is 9.5 inches in diameter. I use a silicone pad on top that is a centimeter at the thickest point. Can you tell me more about the sensor you are using ? any playing surface ? I'll share the numbers after more time with this build.

joshnishikawa commented 1 year ago

I did notice in the example that the sensitivity was still set to 99 even though you mentioned changing it to 90%

Yeah, I haven't updated the examples yet. I just figured you had a sketch you were working with.

I do believe the 30ms wartime is a good middle of the road

Thanks for that! We'll stick with 30 then.

maybe you could provide some copy that explains advanced tweaks

Good idea! Now that we have something workable. I'll go through and update all the sketches etc. and put out another release.

Can you tell me more about the sensor you are using ?

Well, since you asked, I use mostly Piezos for drums. The only thing I use an FSR for is my hat pedal. It's not one of the fancy ones - just a repurposed KORG PS-1. That wedge of foam allows a wider range of readings over the very short travel that the pedal has. As you press, the area of the foam that makes contact with the FSR gradually increases. 2023-03-15 11 15 39 Here's an explanation of what it do. TeensyDrumController Anyway, for testing, I just leave it open like this and tap it with my finger. Not ideal. So, your input has been much appreciated!

digitalelements commented 1 year ago

Awesome !

Thats a fantastic idea with the wedge foam. That pedal is on my "Next to experiment" list I'll have to try it with wedge and cone shapes. I'm always happy to help test and refine things. So, I appreciate you letting me do so. btw is it ok to correspond via the e-mail listed on the library? .. I'd like to share some things without flooding your GitHub :/

joshnishikawa commented 1 year ago

Sure thing👍

digitalelements commented 1 year ago

Thank you !! .. and have a good night :)

digitalelements commented 1 year ago

Some recent findings. I finally took the time to try some different resistor values other than 10k I worked with a hand full of values spanning more and less resistance. I settled on 1k which gave what feels like the most natural dynamic range. I worked till my soft hits could almost reach zero MIDI velocity and a solid range with a bit of headroom to reach 127 on accented hits.

joshnishikawa commented 1 year ago

This seems to be working well enough to close. If it needs fine-tuning, we can make that a new issue. Thanks!