Hi, im having a bit of trouble getting stable readings from an Electroactive Polymer (EAP) sensor Im using. Basically, it behaves as a variable capacitor when stretched. The capacitance range is between c. 1.24nF - 2.2nF, so not lots to go on.
Im using an astable 555 timer circuit to send a frequency to the arduino. As I know accurately the resistors Im using as R1 and R2, I should be able to calculate the capacitance of the EAP sensor.
It works to a degree, but is not consistant. Obviously environmental changes will affect it, but Ive tried to write some calibration code to sort that. Even still, the readings can jum around a litte, and when the EAP goes from stretched to unstretched the values returned are minus?!
ill apologise for my hastily written scruffy code in advance, but hopefully you can get the jist of it.
If anyone has any ideas as to how to make this more accurate and stable that would be amazing!
PS. ive tried altering previous example of arduino cap measuring (http://arduino.cc/en/Tutorial/CapacitanceMeter) but i dont think the setup is accurate enough
#include <FreqCounter.h>
//freq input pin digital 5
#define R1 22000 //precise value measured with an ohm-meter
#define R2 3260
unsigned long frq;
float cap;
float capMax;
float capMin;
float newCap;
int changeConst = 1000;
int outputVal;
int newOutputVal;
int analogOut = 9;
int baseline;
void setup() {
analogWrite(analogOut, 255);
delay(200);
analogWrite(analogOut, 0);
Serial.begin(9600);
baseline = autocalibrate(); //call autocalibrate function to set baseline value
Serial.print("baseline Value is: ");
Serial.println(baseline);
capMax = (baseline + changeConst); //make an estimate of the max cap change for mapping use
}
void loop() {
// wait if any serial is going on
FreqCounter::f_comp=10; // Freq Calibration value
FreqCounter::start(1000); // 1000 ms Gate Time
while (FreqCounter::f_ready == 0)
frq=FreqCounter::f_freq;
Serial.print("freq: ");
Serial.println(frq);
cap = 1440000000000.0/((R1+R2)*frq*1.0); //1.44*1000000000000 is used to get the result in pF
newCap = (cap-baseline);
Serial.print("Change in capacitance: ");
Serial.print(newCap);
Serial.println("pF");
outputVal = map(cap, baseline, capMax, 0, 255); //map the change in capacitance to 0-255 range to work with
newOutputVal = constrain(outputVal, 0, 255); //constrain the output to positive values between 0-255
Serial.print("mapped value: ");
Serial.println(newOutputVal);
analogWrite(analogOut, newOutputVal); //PWM output for LED brightness
//delay(20);
}
int autocalibrate(){
const int numberVals = 5;
int capVals[numberVals];
int i = 0;
int total = 0;
int averageCap;
FreqCounter::f_comp=10; // freq Calibration value
FreqCounter::start(1000); // 1000 ms Gate Time
while (FreqCounter::f_ready == 0)
frq=FreqCounter::f_freq;
cap = 1440000000000.0/((R1+R2)*frq*1.0); //1.44*1000000000000 is used to get the result in pF
for(i=0; i < numberVals; i++){ //itterate through the array
FreqCounter::f_comp=10; // freq Calibration value
FreqCounter::start(1000); // 1000 ms Gate Time
while (FreqCounter::f_ready == 0)
frq=FreqCounter::f_freq;
cap = 1440000000000.0/((R1+R2)*frq*1.0); //1.44*1000000000000 is used to get the result in pF
if(cap > 1000){ //as long as there is a positive capacitance...
capVals[i] = cap; //...store value in array
Serial.println(capVals[i]); //print capacitance values to serial monitor
total = total + capVals[i]; //re-adjust the running total
}
}
averageCap = total/4; //calculate average cap vale(discarding frist value)
//for some reason the first value is always 0?!
return averageCap; //return the average cap val
}