Difference between revisions of "Drumkit notes"

From Helpful
Jump to: navigation, search
m (Muting logic)
m (Hihat logic)
Line 269: Line 269:
Since pedal velocity is not very important,  
Since pedal velocity is not very important,  
so a basic footswitch makes sense (and just a piezo does not).
so a basic footswitch makes sense (and just a piezo does not).
===Two-sensor logic===
rimshot is used to refer to two things
* head+rim simultaneous,
:: a few techniques, including hitting a stick you laid down
* rim-only (or -mostly) for clave-like sound (a.k.a. side stick)
:: e.g. by laying your hand on the middle of the snare, hinging it hinging it from the middle
* the after-a-joke ba-dum-tss thing (snare, snare, cymbals (optional basedrum on the latter))
This is more interesting, because any solution with two sensors on one head
means you may want logic to
: if two events come in at the same time (within ~1ms?) and the same strength, trigger both
: if two events come in at the same time (within ~1ms?) with one lower strength, ignore that one
...so that you don't get both all the time, but how doable this is, and the type and amount of tuning, depends on physical design and the the attachment of sensors.
(you may want to look at how some people add MIDI triggers to real drums)

Revision as of 14:13, 14 June 2020

The idea: build a cheap electronic, velocity-sensitive, MIDI-output drumkit.

There are many simple and cheap DIY ideas out there. Check the video sites.


You may care about a few different things

getting more of the energy to the piezo, to detect it reliably
more makes it easier to reliably measure impact and its velocity
getting velocity sensitivity, and getting it reproducably
getting minimal energy to neigbouring pads - i.e. physical isolation from others
so that we can be more sensitive
allowing fast drumming, without false triggers
we'll discuss why this is a thing later

getting the pads to physically bounce roughly like their real-world counterpart
at least, for drummers that want to practice for real playing
pads that aren't loud
half the reason is fewer complaining neighbours
relevant for stick drumming, not finger drumming

Physical design

A few of those can be solved largely in physical design, making your life easier once you get to the electronics and code.

Also, if you just do finger drumming then it's much easier, because the forces are much smaller, so don't carry as far, so I'd recommend your first version be this.

If you want to play as hard as regular drums this is a little harder to design well.

Say, you probably do still want thing to stay in place, but a very solid construction will carry energy to the other sensors and trigger them as well.

If you don't care about the physical loudness of hitting pads, or the physical bounce, then a piezo on the back of a piece of wood already works fine

If you care about crosstalk and the false triggers that may cause on closeby pads, then the material below such a board matters, for physical isolation. Good physical isolation is slightly harder than you'ld think, if you want an otherwise quite solid thing. (For example, I at one point had a MIDI guitar, which has piezos detecting the picking of each stringalike, which if you pick them hard enough will trigger the next one over even though they're mounted in rubber.) Note that this also dampens the resonance of the pad itself, so the signal strength (and shape), so imply some recalibration in the velocity detection part.

If you care about noise and bounce, then the material on top of such a board matters. This also dampens the hits, though you'll probably find that it's enough.

Many designs use a piezo sensor because they're cheap and work pretty well, on a large surface able to bend and resonate a bit to make it easier to get more energy involved (and because with stick drumming that means not worrying about aim so much), which also makes it a little easier to get a more predictable amount of energy.

Keep in mind that on a board, the main resonant node is typically in the middle, so that's where you get best response.

Also keep in mind that you want to attach it in a way that doesn't fall apart immediately. A dollop of wood glue is likely to fail sooner rather than later.

Also keep in mind that the wires on the piezo also carry shock directly to the piezo, so you may want to guide those away with a bit of foam - depending on your design.


Dealing with the piezo's capacitance

Piezos are essentially are stress sensors, so respond well to impact, and the vibration that causes.

Due to their design, they can be seen as stress-to-voltage sensors in parallel with a capacitor (and a very large resistor, GOhm range(verify))).

That combination means it will hold the generated voltage for a relatively long time, to the point that if you hook up a piezo directly to and ADC, you get what looks like a varying resting voltage between hits. Resting a weight on the pad will give a proportional high value. (You may even get small changes over time and with temperature)

You can write code to deal with such input, but it's messier, and there's more edge cases where you can get wild triggering.

So what many designs do instead is add a resistor across the piezo.

This is essentially a discharge resistor for the capacitive effect, which means the voltage output is now primarily the changes in stress, and will be near 0V the rest of the time, even if there is weight, or slow changes in/on the piezo.

You can quantify the impulse response, because it resembles a lowpass filter(verify). Since a piezo disc's capacitance will probably be in the ballpark of 500pF to few dozen nF, and you probably want dropoff within a few dozen milliseconds, something on the order of 100kΩ makes sense.

More widely something in the range of 10k to 1M can make sense, depending on further component and design choices. (In a more portable design you may wish to add a ~1M trimpot, in series with ~10k as a minimum, so you can easily calibrate this later)

If you are multiplexing a single ADC (example being an arduino, but it's likely given cost of having ~10 distinct ADCs) you are likely to find the signal is cross-bleeding between the channels, giving responses on channels you're not hitting.

This largely because ADCs like the Arduino's are designed to deal best sensing things with lowish impedance. (<10kOhm for AVRs, see section "Analog Input Circuitry" in the datasheet). If the impedance of what you're measuring is more than that, then the ADC's sample-and-hold capacitor starts interacting enough to be part of the sampling.

One thing you can do is lower the discharge resistor. The problem with that is that even with a ~10kOhm discharge resistor, which is a lot better, you still haven't solved it, and it comes at the cost of a weak and faster-dampening signal, making it harder to be sensitive to velocity, and sensitive in general.

A better fix is presenting a low impedance to the ADC via a buffer (which also implies the discharge resistor now only affects the dropoff), such as with a FET or an op amp.

My personal preference is the op amp because the tweaking the gain is a little easier (and it's slightly easier to breadboard, with two or three quad op amps for 8 to 12 channels). That said, op amps come with further considerations, like that the output voltage swing is usually lower than the rail, so try to keep under that effective clipping level.

(Other fixes are dedicated ADCs, or even MCUs per channel, but that makes communication a little harder.)

Protecting your input

Diodes you see in a bunch of circuits seem to typically be ~5V zeners from ground to clip peaks, protecting the ADC/buffer from large piezo voltages - a few dozen volts if hard-coupled and hit hard.

How necessary this is depends on the choice of piezo and resistor, and specs of ADC/buffer, but it's a good idea in that it can help lifetime, and costs a few cents.

Detecting empty sockets


If you don't care about velocity, then you can probably write the code in a few minues.

"Do analogRead, Is it above threshold and have we not triggered this in the last 100ms? Then trigger MIDI note" Goes a long way.

When you want velocity, and smartness to help isolation, then things become a little more interesting.

Isolation and sensitivity

If the physical part of isolation wasn't perfect, you'll still see a little of the force from neigbouring pads.

If nearby hits arrive at much lower intensity, then a little threshold tweaking will help a lot.

Still, the better that the physical isolation is, the lower that threshold can be, so the more we can support softer playing even while you're hitting something nearby harder.

You also have the option of 'if two pads seem to hit less than a few ms apart, and one with rather lower intensity, then then maybe just trigger the strongest'.

This will sometimes ignore actual playing, and punish good timing, so ideally you improve the isolation instead.


Velocity makes things more interesting.

There are various methods. Some are simple, some are complex, some are slightly faster (latencywise), some are more consistent, some are handier for softer playing, etc.

For example, we could watch channels for the initial hit. Once we decide it has been triggered, we keep sampling it as long as the values keep increasing, trigger once it starts falling, with the peak value as the velocity

This is probably the lowest-latency you can get, and it's simple code in that it doesn't need to store much. However, high frequency content makes this sometimes stop too early/low, and using just the first peak may be a little less robust between similar hits depending e.g. on the resonance of your design. If/when (just) that first peak clips, it will always report the same value

Another way is to, once we decide to trigger, keep sampling for another 2-15 milliseconds, and average the values (or e.g. over-threshold time), and use that as the velocity. This fairly robust to any clipping of the initial peak.

Because tiny peaks that were only just enough to trigger the "could this be a hit?" threshold, but the average would be very low, it's a little easier to reject it as probably-crosstalk or noise, while still allowing soft hits.

has a fundamental tradeoff between longer (more consistent velocity) and shorter sampling time (lower latency)
can be done without storing samples in RAM (keep adding magnitudes to a large-typed counter, and divide by sampling time)

Apparently there's some that try to find the envelope of the signal. Probably more accurate, but slower, and harder to do

Since you don't have direct control over what pad voltage should correspond to the softest hardest hits (depends on the size of the piezo and the size of the pad), you may want to calibrate.

A 'play a few sample hits on everything, and store that into EEPROM' is a simple and effective idea.
This also makes it more a lot more modular/portable around varying physical designs.

That also makes it easier to change the curve away from linear by applying a function (e.g. a power).

Fast playing, hard playing, and false re-triggers

Playing harder means the signal is stronger, but also a slightly longer time it takes to taper off the oscillations, up to 40ms or so.

If you're reading fast enough, then after a note trigger you may notice the not-quite-gone peaks from the same hit and may trigger again.

A conceptually simple fix is to add the condition "AND did I not trigger in the last 100ms?" in your note-triggering code. (100ms backoff on a channel is enough for basic playing, as that allows 10beats/second, which is 600bpm and most playing is far slower)

However, things like drumrolls are hits on the order of milliseconds apart, so suddenly you need to tell next-half-waves from new hits. This is harder to get right, and involves some tradeoffs, but seems possible.

One approach is to leave a low threshold for triggers from nothing, but after a note trigger set the threshold based on the last emitted's first strength.

One issue is determining that value reliably - it's higher than the average, and probably lower than the peak.

This means you can leave the general threshold low for lower-latency triggers, evade most dampened peaks from the same hit, but still catch most similar-velocity hits.

Consider also that for some channels, you can reject such things harder. You're not going to do few-ms drumrolls on a kickdrum, on a crash it's more of a sustain so the speed doesn't matter as much, while on a ride drum or tom this is more important.

If you vary designs, e.g. have kickdrum just be a block of wood, then you may want some knobs to tweak thresholds and curves per channel -- though you probably have dedicated channels anyway (because otherwise you need to think about configurable MIDI mapping).

If you do velocities, then you may like the ability to tweak the curve on the fly.

Hihat logic

Two-sensor logic

Muting logic

MIDI practicalities

(see also MIDI_notes#Percussion)

In my code I delayed sending NoteOff for ~10ms (unless the next trigger is sooner), mostly for debug reasons - it makes it easier for to see hits when something (physical/DAW) chooses to visualise it.

MIDI Velocity

You may find that compared to the sound you get at velocity 100ish, velocities under 30 or so are barely heard - even ghost notes would probably be at 40-60.

Much lower and it'd sound like you're playing part of your kit from the next room.

(I spent a day trying to figure out why hits went missing when it was just that velocity ~15 is not audible)

As such, you've got some amount of balancing between enough variation expression while also getting it to be repeatable, sound natural, and and allow ghost notes.

This, may take good isolation, calibration, habit, and it may help to put a transform that makes the mapping from physical to MIDI velocities nonlinear.

A little tweakability to that can't hurt.

PC side

Drum sounds