Hello everyone,
I'm facing some difficulties reading AC voltage from multiple piezoelectric elements connected in parallel. I'm using an Arduino MKR 1010 WiFi board and an LTC3588 energy-harvesting IC to extract energy from footsteps. My goal is to measure the AC voltage generated by the collective output of the negative and positive terminals of 100 piezo discs.
The problem I'm encountering is that I cannot obtain a stable reading of the piezo voltage. Despite connecting the piezo elements in parallel, the measurements fluctuate and lack consistency. I have attempted various methods to mitigate this issue but have not yet achieved the desired stability.
Currently, I'm measuring the DC voltage using a 100 Farad capacitor with a voltage rating of 16 volts. However, I plan to switch to a 3.7-volt, 850mAh battery for improved performance.
In my code, I have implemented the calculation of joules, milliamps, and coulombs. Here is the code I'm currently using:
#include <Arduino.h>
#include <WiFiNINA.h>
#include <WiFiClient.h>
#include <WiFiUdp.h>
#include <ArduinoHttpClient.h>
#include "secrets.h"
const char* host = "api.thingspeak.com";
const char* apiKey = "API KEY"; // your ThingSpeak Write API Key
WiFiClient wifi;
HttpClient client = HttpClient(wifi, host, 80);
unsigned long counter = 0; // counter for the number of times data is sent
const int ledPin = 5; // LED connected to digital pin 5
void setup() {
Serial.begin(115200);
delay(2000); // Allow time for MKR WiFi to boot
pinMode(ledPin, OUTPUT); // set the LED pin as output
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi...");
digitalWrite(ledPin, HIGH); // turn on the LED
delay(500); // wait for half a second
digitalWrite(ledPin, LOW); // turn off the LED
delay(500); // wait for half a second
}
digitalWrite(ledPin, HIGH); // turn on the LED when connected
Serial.println("Connected to WiFi");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
}
void loop() {
if (WiFi.status() == WL_CONNECTED) {
digitalWrite(ledPin, HIGH); // turn on the LED when connected
int capacitorPin = A0; // Analog pin connected to measure voltage across the capacitor
int piezoPin = A1; // Analog pin connected to measure AC voltage from the piezo
const int numReadings = 20;
float totalCap = 0; // the running total for capacitor readings
float totalPiezo = 0; // the running total for piezo readings
// take numReadings readings and add them to the total
for (int i = 0; i < numReadings; i++) {
totalCap += analogRead(capacitorPin);
totalPiezo += analogRead(piezoPin);
delay(200); // short delay between readings
}
// calculate the average
float capacitorVoltage = totalCap / numReadings * (5.0 / 1023.0);
float piezoVoltage = totalPiezo / numReadings * (5.0 / 1023.0);
float cap_value = 100; // Capacitance value in Farads
float resistor_value = 1000000; // Resistance value of the resistor in the voltage divider
float energy = capacitorVoltage * capacitorVoltage * cap_value;
float joules = energy * 3.6;
float coulombs = energy / (3.6 * 1000.0);
Serial.print("DC Voltage across capacitor: ");
Serial.print(capacitorVoltage, 5);
Serial.println(" V");
Serial.print("Energy stored in the capacitor (Joules): ");
Serial.print(joules, 5);
Serial.println(" J");
float current = capacitorVoltage / resistor_value;
float milliamps = current * 1000;
Serial.print("Current flowing through the resistor (milliamps): ");
Serial.print(milliamps, 5);
Serial.println(" mA");
Serial.print("Charge stored in the capacitor (Coulombs): ");
Serial.print(coulombs, 5);
Serial.println(" C");
// Add a buffer line for easier reading in the serial monitor
Serial.println("---------------------------------------");
Serial.print("AC Voltage from piezo: ");
Serial.print(piezoVoltage, 5);
Serial.println(" V");
// Add a buffer line for easier reading in the serial monitor
Serial.println("---------------------------------------");
String url = String("/update?api_key=") + apiKey +
"&field1=" + String(capacitorVoltage, 5) +
"&field2=" + String(joules, 5) +
"&field3=" + String(milliamps, 5) +
"&field4=" + String(coulombs, 5) +
"&field5=" + String(piezoVoltage, 5);
client.get(url);
// read the status code and body of the response
int statusCode = client.responseStatusCode();
String response = client.responseBody();
Serial.print("Status code: ");
Serial.println(statusCode);
Serial.print("Response: ");
Serial.println(response);
counter++; // increment the counter
Serial.print("Data sent to ThingSpeak ");
Serial.print(counter);
Serial.println(" times.");
} else {
digitalWrite(ledPin, LOW); // turn off the LED when not connected
}
delay(1000);
}
I would greatly appreciate any insights, suggestions, or advice regarding this problem. Has anyone encountered a similar issue when reading AC voltage from parallel piezoelectric elements? If so, how did you overcome it? I'm open to any recommendations, circuit modifications, or alternative approaches to help me achieve a stable and accurate AC voltage measurement.
Additionally, I'm considering purchasing a 30A Current Sensor Module and a Max 25V Voltage Sensor Module. These modules are designed for current and voltage measurements and may provide more accurate readings. Do you think it will help if I invest in these modules for my project? Has anyone used similar sensor modules with Arduino for measuring AC voltage in parallel piezo configurations?
You can find my project on GitHub, where I have shared more details: GitHub Link
Thank you in advance for your assistance.
piezo tiel connected in parallel with the LTC: image
Link to the Ltc 3588-1 - https://www.analog.com/media/en/technical-documentation/data-sheets/35881fc.pdf
link to the piezo that I bought - https://www.amazon.co.uk/gp/product/B0C68Q6N8B/ref=ppx_yo_dt_b_asin_title_o04_s00?ie=UTF8&psc=1
link to generic piezo datasheet - https://www.cuidevices.com/product/resource/ceb-27d44.pdf
Link to the Voltage Sensor Module - https://www.amazon.co.uk/gp/product/B09F6CT827/ref=ewc_pr_img_1?smid=A1SIE5VFG4T3WE&psc=1
Image of the tile that I made :