Piezo consistency and repeatibility

Hello everyone, and thanks for your time and feedbacks.
I'm attaching a picture of the piezo I'm using. I don't have any electronic specification for it.

Good question :slight_smile: I'm not setting a sampling rate, so I assume using the default one. Where can I find / modify such setting ?

Unfortunately, averaging is not an option, as user is requested to hit the surface once.

I'm using 1M Ohm resistor in parallel with the piezo, and later, added a 50v 1uF cap, also in parallel, and appearently it smoothes the signal, and it is somehow easier to detect the peak, at the cost of a longer time to reach zero again.
Thanks again for the replies, and apologies for my late reply.

So how, exactly, are you getting your readings?

Again, please post your schematic!

Please also post your code, and some good, clear photos of your setup.

Apologies, didn't get home sooner to get the code and schematics, here they are:

// Define the analog input pin
const int analogPin = A0;

// Variables to store peak values
int peakValue = 0;
int previousValue = 0;
int descendingCount = 0;  // Counter for consecutive descending reads

int maxValue = 50;
int maxValueNormalized = 100;
int sensorValue;

String piezoString;
char incomingCharacter;

bool debugMode = false;
bool descending = false;  // Flag to track if the value is descending
unsigned long peakReturnTime = 0;  // Time of the last peak value return

void setup() {
  // Initialize serial communication
  Serial.setTimeout(25);
  Serial.begin(9600);
}

void loop() {
  // Read the analog value
  HandleSerial();

  maxValue = constrain(maxValue, 0, 1000);

  sensorValue = analogRead(analogPin);
  sensorValue = constrain(sensorValue, 0, maxValue);
  sensorValue = map(sensorValue, 0, maxValue, 0, maxValueNormalized);

  ReturnPiezoValue();
}

void ReturnPiezoValue() {
  if (debugMode) {
    Serial.print(maxValueNormalized);
    Serial.print(",");
    Serial.println(sensorValue);
  } else {
    // Check if the value is a new peak
    if (sensorValue > peakValue) {
      peakValue = sensorValue;
      descending = false;  // Reset the descending flag
    }

    // Check if the value is descending
    if (sensorValue < previousValue) {
      descendingCount++;
      if (descendingCount >= 5) {
        descending = true;
      }
    } else {
      descendingCount = 0;
    }

    // Check if the value is descending and print the peak value
    if (descending) {
      // Print the peak value if it's not zero and reset it
      if (peakValue > 0) {
        if (millis() - peakReturnTime >= 1000) {
          piezoString = "p" + String(peakValue);
          Serial.println(piezoString);
          peakReturnTime = millis();
        }
      }
      peakValue = 0;
      descending = false;  // Reset the descending flag
      descendingCount = 0; // Reset the descending counter
    }

    // Store the current value for comparison in the next loop iteration
    previousValue = sensorValue;
  }
}

void HandleSerial() {
  while (Serial.available() > 0) {
    incomingCharacter = Serial.read();
    switch (incomingCharacter) {
      case 'd':
        debugMode = !debugMode;
        break;

      case 'a':
        maxValue += 10;
        Serial.print("maxVal = ");
        Serial.println(maxValue);
        break;

      case 'z':
        maxValue -= 10;
        Serial.print("maxVal = ");
        Serial.println(maxValue);
        break;
    }
  }
}

please let me know if there is anything unclear about them.
thanks !

Hi.
Do you have the sensor flat on a surface when you test, or do you have its edges suspended with a ring so the piezo can flex in the middle.

When you think about it, that is how its transmitting of sound occurs, by vibration of the centre section of the element.
image

You may be helped by Googling;

arduino using a piezo as a force sensor

Tom... :smiley: :+1: :coffee: :australia:

1 Like

@vittoriofaella

Those piezo elements can generate voltages much higher than 5V and even worse generate Negative voltages, neither of which is good for an Arduino

You are probably damaging your Arduino analog input.

1 Like

This is also an usefull topic
https://forum.arduino.cc/t/how-to-wire-a-piezo-as-an-impact-sensor/901726

I have made my own version based on that topic but I must say that I have had an defect in my analog input reading after one night/day with unpowered Seeeduino board and connected piezo wiring. I had done a long test of running board and connected piezo continuesly for some days without problems. I had to think about a comment from @Wawa that the input is max Vcc + 0.5V... maybe I add a diode from analog input to Vcc to catch this?

I keep the lowest and the highest reading and use the substraction as 'sensorresponse'.
My code:

<code>
// these constants won't change:
const int piezoSensor = A5; // the piezo is connected to analog pin 5

// these variables will change:
long int sensorReading = 0;      // variable to store the value read from the sensor pin
long int sensorReadingLow = 1024;  //max value
long int sensorReadingHigh = 0; 
int counter = 0;


void setup()
{
  Serial.begin(115200);       // use the serial port
}

void loop() {
  counter++;
  // read the sensor and store it in the variable sensorReading:
  sensorReading = analogRead(piezoSensor);
  if (sensorReading > sensorReadingHigh) {
    sensorReadingHigh = sensorReading;
  }
  if (sensorReading < sensorReadingLow) {
    sensorReadingLow = sensorReading;
  }
      
  if (counter > 10000 ) {
    Serial.print("Sensor Reading = ");
    Serial.print(sensorReading);
    Serial.print("  Sensor Reading range = ");
    Serial.println(sensorReadingHigh - sensorReadingLow);

    counter = 0; //reset
    sensorReadingHigh = 0;
    sensorReadingLow = 1024; //max value   
  }
}
</code>

Grtz
Jan

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.