Hi,
I have a piezoelectric ribbon sensor that I am trying to get to turn on an LED when a force is applied and a "knock" is detected. It seems to work every so often but not consistently. When I have the force values printed it is showing that it seems to be reading force values even when I am not touching the sensor. It'll start at the negative value of the baseline from calibration then steadily increase without any force applied. I am using a 1M ohm resistor for it. I'll post my code and setup below. Any help would be appreciated.
// Constants
const int piezoPin = A0; // Analog pin connected to the piezo sensor
const int ledPin = 13; // Digital pin connected to the LED
const int numReadings = 100; // Number of readings for calibration
const int knockThreshold = 100; // Threshold for detecting a knock
// Variables
int readings[numReadings]; // Array to store sensor readings
int readIndex = 0; // Index of the current reading
int total = 0; // Total of all readings
int average = 0; // Average of the readings
int baseline = 0; // Baseline value for calibration
void setup() {
Serial.begin(9600); // Initialize serial communication
pinMode(piezoPin, INPUT); // Set the piezo pin as input
pinMode(ledPin, OUTPUT); // Set the LED pin as output
// Initialize all readings to 0
for (int i = 0; i < numReadings; i++) {
readings[i] = 0;
}
// Calibrate the sensor
Serial.println("Calibrating sensor...");
calibrateSensor();
Serial.println("Calibration complete.");
Serial.print("Baseline value: ");
Serial.println(baseline);
}
void loop() {
// Subtract the last reading
total = total - readings[readIndex];
// Read the sensor
int sensorValue = analogRead(piezoPin);
readings[readIndex] = sensorValue;
// Add the reading to the total
total = total + readings[readIndex];
// Advance to the next position in the array
readIndex = readIndex + 1;
// If we're at the end of the array, wrap around to the beginning
if (readIndex >= numReadings) {
readIndex = 0;
}
// Calculate the average
average = total / numReadings;
// Calculate the force
int force = average - baseline;
Serial.begin(9600); // Initialize serial communication
Serial.print("force value");
Serial.print(force);
// Detect a knock
if (force > knockThreshold) {
Serial.println("Knock detected!");
digitalWrite(ledPin, HIGH); // Turn on the LED
delay(5); // Keep the LED on for 200 milliseconds
digitalWrite(ledPin, LOW); // Turn off the LED
}
// Wait 50 milliseconds before the next loop
delay(200);
}
void calibrateSensor() {
long sum = 0;
// Take multiple readings to determine the baseline
for (int i = 0; i < numReadings; i++) {
int reading = analogRead(piezoPin);
sum += reading;
delay(50); // Short delay between readings
}
// Calculate the baseline
baseline = sum / numReadings;
}
Force outputs:
Circuit Setup:



