Piezo Knock Sensor Not Working When Is Touched by anything but my fingers

Hi, I am trying to use a couple of piezo sensors for an art installation but I have a problem.

The piezos are working everytime I touch them between my fingers but when they are on the floor or any other surface they're not reacting at all.

Can somebody help me please? Any help would be much appreciated :smile:


I tried to connect it to an Analog input and tried a different code and it works. However, everytime I connect it to the digital input it only works between when touched between my fingers.

A different code to the one you didn't post the first time?

Here is the first code:


byte note = 48;
byte midiCh = 1;
byte cc = 1;

const int nVBs = 5;
const int vibrationPin[nVBs] = {2, 3, 4, 5, 6};
int vibCState[nVBs] = {0};
int vibPState[nVBs] = {0};

unsigned long lastDebounceTime[nVBs] = {0};
unsigned long debounceDelay = 5;

void setup()

  for (int i = 0; i < nVBs; i++) {
    pinMode(vibrationPin[i], INPUT_PULLUP);

void loop()

//Vibration Sensors
void vbs() {

  for (int i = 0; i < nVBs; i++) {
    vibCState[i] = digitalRead(vibrationPin[i]);

    if ((millis() - lastDebounceTime[i]) > debounceDelay) {

      if (vibPState[i] != vibCState[i]) {
        lastDebounceTime[i] = millis();

        int vbsValue = digitalRead(vibrationPin[i]);

        if (vbsValue == HIGH)
          //digitalWrite(ledPin, HIGH);
          MIDI.sendNoteOn(note + i, 127, midiCh);
          //Serial.println("not touched");
          MIDI.sendNoteOff(note + i, 127, midiCh);
          while (digitalRead(vbsValue) == LOW)
        vibPState[i] = vibCState[i];




Here is the second code when it's used with an Analog Pin an the piezo works when it's touched by anything.

const int ledPin = 13;      // LED connected to digital pin 13
const int knockSensor = A0; // the piezo is connected to analog pin 0
const int threshold = 500;  // threshold value to decide when the detected sound is a knock or not

// these variables will change:
int sensorReading = 0;      // variable to store the value read from the sensor pin
int ledState = LOW;         // variable used to store the last LED status, to toggle the light

void setup() {
  pinMode(ledPin, OUTPUT); // declare the ledPin as as OUTPUT
  Serial.begin(9600);       // use the serial port

void loop() {
  // read the sensor and store it in the variable sensorReading:
  sensorReading = digitalRead(knockSensor);

  // if the sensor reading is greater than the threshold:
  if (sensorReading >= threshold) {
    // toggle the status of the ledPin:
    ledState = !ledState;
    // update the LED pin itself:
    digitalWrite(ledPin, ledState);
    // send the string "Knock!" back to the computer, followed by newline
  delay(100);  // delay to avoid overloading the serial port buffer

You've used it as a digital pin,which makes the thresholding ridiculous.

Yes, sorry. The code automatically saved and it was meant to be analogRead instead of digitalRead.

But what about my second one, where the piezo works but only when it’s touched by hand.

One guess it a missing ground.

the other guess is the connections at the piezo are not correct. Could we see the other side of the piezo?

Next question is, what do you expect to sense when the piezo is on the floor?


When on the floor it is installed under a rubber square that when people step on it activate the piezo so I get a “knock” signal in Arduino and after it will be translated to a MIDI signal launching notes and abstract sounds.

In order to get a signal the piezoelectric crystals have to be deformed. It is during deformation that the voltage is generated.
Putting them under rubber is going to make it hard to deform.
It is not a very suitable solution to your problems.

I did a similar project many years ago and used conducting foam to make the sensors.



1 Like

My guess when you are touching the piezo the 60Hz pickup from your body is being sensed by your processor.

I can't tell what signal you may get if the sensor is under a rubber mat. It likely depends on how fast the folks are walking.
In any case the signal will be a short spike if there even is one. You will NOT get a signal the entire time someone is standing on it. The Piezo element only output voltage during the time the piezo is being distorted or put under and removing pressure.

1 Like

Totally agree - it's just picking up 50/60Hz.

Piezoelectric transducers of the type shown respond to vibration rather than pressure. You need quite a rapid change of force to get a measurable output, and as the transducer is electrically a very small capacitor, the output voltage spike is very short-lived.

I think you'll need a different type of sensor.

1 Like

@Grumpy_Mike wow! I checked out your works and they're impressive!