Ok! Next question,
Just what are these counts from Timer1? Nick, I see in your example that you multiply the counts time 1000 then divide by 16. (the micro also has a 16 mhz clock)
From my diagnostic output on the serial monitor my count is approximately 59850
X 1000 / 16 = 3738875
Using this formula: t = -RC*ln(1-(V/Vc(t)))
with V=5v, Vc(t)=3.3v, R=330ohms and C=47uF
I get a time of 0.016732337848
If I did my math right, it doesn't resemble 3738875 at all.
DIAGNOSTIC OUTPUT:
analog pin = 1023
analog pin = 1023
analog pin = 1023
analog pin = 1023
analog pin = 1023
start discharge
end discharge
analog pin = 1
start discharge
end discharge
analog pin = 1
Number of counts 59860.00
start discharge
end discharge
analog pin = 1
analog pin = 1
start discharge
end discharge
analog pin = 1
Number of counts 59833.00
start discharge
end discharge
analog pin = 0
analog pin = 1
start discharge
end discharge
analog pin = 0
Number of counts 59822.00
CURRENT SCHEMATIC:
CURRENT SCRIPT:
/*
Untested rough draft
Keshka Kotera 7 Feb 2016
*/
#include <Math.h>
#define Charge_pin4 12 // pin to charge 100pF and smaller caps
#define CapPositive_pin 7 // pin used by comparator for reference
#define Analog_pin A0 // analog pin for measuring capacitor voltage
char message[80];
volatile unsigned long Timer_counts; //volatile- for vars used in AND out of ISR's (interupt service routines)
volatile unsigned long overflowCount;
unsigned int timer1CounterValue;
unsigned long overflowCopy = overflowCount;
volatile boolean Triggered;
volatile boolean Active;
float Resistance_value = 330;
unsigned long Previous_millis = 0;
int times;
void setup()
{
pinMode(Analog_pin, INPUT); // set Analog_pin to input, will be pulled high by the current charge pin if no cap
pinMode(4, INPUT); // set D4 (our AIN- later) to input
digitalWrite(4, LOW); // make sure pull-up resistor is off so as not to load the 3.3v ref
pinMode(CapPositive_pin, INPUT); // AIN0 (PE6) the + input on D7 on the Micro cap to test here.
digitalWrite(CapPositive_pin, LOW); // make sure pull-up resistor is off
Active = false; // we have no capacitor to test
Serial.begin(19200);
Previous_millis = millis();
pinMode(Charge_pin4, OUTPUT); // set Charge_pin to output for range 4
digitalWrite(Charge_pin4, HIGH); // set ready for testing
ADCSRB = 0; // (Disable) ACME: Analog Comparator Multiplexer Enable
ACSR = bit (ACI) // (Clear) Analog Comparator Interrupt Flag
| bit (ACIC) // Analog Comparator Input Capture Enable bit (ACIC) of the Analog Comparator Control and Status Register (ACSR)
| bit (ACIE) // Analog Comparator Interrupt Enable
| bit (ACIS0) | bit (ACIS1); // ACIS1, ACIS0: Analog Comparator Interrupt Mode Select (trigger on rising edge)
ADMUX = B00100000; // set the AIN- to ADC8 (D4 on the Micro) for our reference voltage
}
void loop()
{
if(millis() - Previous_millis > 5000) // only update every 5 seconds
{
Serial.print("analog pin = ");
Serial.println(analogRead(Analog_pin));
Previous_millis = millis();
if(times++ > 3) // my auto start for testing when cap is already charged
{
discharge_cap();
times = 0;
}
}
if((analogRead(Analog_pin) < 1020) && !Active) // we have a cap to test!
{
Active = true;
discharge_cap(); // start over
// prepare timer
noInterrupts ();
overflowCount = 0; // no overflows yet
TCCR1A = 0; // reset Timer 1
TCCR1B = 0; // reset Timer 1
TIFR1 = bit (ICF1); // *clear* ICF1
TCNT1 = 0; // Counter to zero
TIMSK1 = bit (TOIE1) | bit (ICIE1); // set bits in timer/counter1 (TIMSK1) register for interrupt on Timer 1 overflow (TOIE1) and input capture (ICIE1)
TCCR1B = bit (CS10) | bit (ICES1); // start Timer 1, no prescaler plus Input Capture Edge Select
digitalWrite (Charge_pin4, HIGH); // start charging capacitor
interrupts (); // enable interupts
}
if (Triggered)
{
char Flt_str[15];
float Capacitance = 0;
Triggered = false;
Active = false;
dtostrf(Timer_counts, 8, 2, Flt_str);
sprintf(message,"Number of counts %s",Flt_str); // debug
Serial.println(message); // debug
// calc capicitance C=-t/R ln(1-(Vc(t)/Vin)) ......Vc(t) is current charge level t is time, R resistance
// Capacitance = (Timer_counts/(Resistance_value*log(1-(3.3/5)))); // rough draft! not sure what we counted
// dtostrf(Capacitance, 8, 2, Flt_str);
// sprintf(message,"Capacitance is %s",Flt_str);
// Serial.println(message);
delay(10000); // display value for ten seconds
discharge_cap(); // drain the cap. get ready for next read
pinMode(Analog_pin, INPUT); // reset Analog_pin to input
}
}
ISR (TIMER1_OVF_vect)
{
++overflowCount; // count number of Counter 1 overflows
}
ISR (TIMER1_CAPT_vect)
{
timer1CounterValue = ICR1; // grab timer count, see datasheet, page 117 (accessing 16-bit registers)
if (Active) // did we finish?
{
if ((TIFR1 & bit (TOV1)) && timer1CounterValue < 0x7FFF) // if just missed an overflow
{
overflowCopy++;
}
Timer_counts = (overflowCopy << 16) + timer1CounterValue; //calculate total count, each overflow is 65536 more
Triggered = true;
TCCR1B = 0; // stop the timer
}
}
ISR (ANALOG_COMP_vect) // hangs if this ISR does not exist
{
int do_something;
do_something = 1;
do_something = 10;
do_something = 100;
}
void discharge_cap()
{
Serial.println("start discharge");
digitalWrite(Charge_pin4, LOW); // set it to LOW
while(analogRead(Analog_pin) > 0); // wait until capacitor is completely discharged
Serial.println("end discharge");
Serial.print("analog pin = ");
Serial.println(analogRead(Analog_pin));
}