Midi Drums with Piezoelectric Sensor

I’m working on a DIY drum kit using piezoelectric sensors. I have a basic setup finished with a singular drum, having successfully gotten an output using Logic Pro.

However, an issue that I’m having is that whenever I hit my drum the piezoelectric sensor gives off multiple readings decaying over time (as in the image). How would I code so that my arduino knows to only send 1 reading for every hit?

Thanks in advance!

You have to apply a filter. Just compare the value from the sensor to the threshold value -- say 75? -- and reject if below.

How do you make the drum sound when your sketch detects the input from the piezo sensor, please? I know someone who is struggling with that part.


Basically the technique you want is called "debouncing". The easiest way is when you have seen a hit don't take any notice of that piezo again for a certain amount of time. Usually somewhere between 10-50ms is long enough to let the ringing die away below your threshold.

If you post the code you're using now we can show you how to incorporate debouncing. Or just search for "Arduino drum kit debounce". It's been done many times before.


I think I have the “debouncing” idea incorporated. However, if the hits are too quick wouldn’t they not register?

Here’s the code I’m currently using
#include <pitchToFrequency.h>
#include <pitchToNote.h>
#include <frequencyToNote.h>
#include <MIDIUSB_Defs.h>
#include <MIDIUSB.h>

//Snare Center - Analog 0 - Note 38
//Snare Rim - Analog 1
//Low Tom - Analog 2 - Note 41
//Mid Tom - Analog 3
//High Tom - Analog 4
//Bass Drum - Analog 5
//Ride Cymbal - Analog 6
//Crash Cymbal - Analog 7
//Hi Hat - Analog 8
//Hi Hat Pedal - Analog 9

unsigned long currentMillis;
unsigned long lowTomMillis;

float LowTomLowerThreshold = 2;
float LowTomUpperThreshold = 759;

void noteOn(byte channel, byte pitch, byte velocity) {
midiEventPacket_t noteOn = {0x09, 0x90 | channel, pitch, velocity};

void noteOff(byte channel, byte pitch, byte velocity) {
midiEventPacket_t noteOff = {0x08, 0x80 | channel, pitch, velocity};

void controlChange(byte channel, byte control, byte value) {
midiEventPacket_t event = {0x0B, 0xB0 | channel, control, value};

void setup() {
// put your setup code here, to run once:

void loop() {
// put your main code here, to run repeatedly:
currentMillis = millis();

if (currentMillis - lowTomMillis > 30) {
lowTomMillis = currentMillis;

float lowTomSensor = analogRead(2);

int lowTomVelocity = (lowTomSensor * (127/(LowTomUpperThreshold - LowTomLowerThreshold)));

if (lowTomSensor > 10)
if (lowTomVelocity >= 127)
lowTomVelocity = 127;
if (lowTomVelocity <2)
lowTomVelocity = 2;

noteOn(0, 38, lowTomVelocity);
noteOff(0, 38, lowTomVelocity);



I'm using the MIDIUSB library for my Arduino and Logic Pro on my laptop to process the midi signal.


I see LogicPro is for Apple. I'm interested in Windows.

I'm trying to make it work with FL Studio, LoopMIDI and Hairless Serial Bridge.

No success yet.