Well, my first attempt at implementing a solution is giving me problems, and I can't figure out what may be going on. I've added various Serial.println() to track where the code is going wrong, and for some reason, the monitor shows that I go through function "setup_comparator" , but gets messed up (prints messed up characters to the serial monitor) as it starts on function "reset_capacitor" and somehow, I enter function "setup_comparator" again. I don't know how this can happen without going through a reset -- so this is where I'm focusing to find my bug(s).
Anyway, I'm attaching the code to see if I can get some help. I decided to use the analog comparator with the bandgap reference. My intent is to
-
set Timer 1 to input capture mode.
-
then I set up the analog comparator- using the bandgap ref on AIN0 ) and generating an interrupt to the timer1 on the falling edge.
-
then drive an I/0 pin low holding the node between a resistor and a capacitor low to reset the external capacitor. I initially wanted to use the same AIN1 pin as a digital output first to hold the capacitor in reset, and then switch it to the comparator input after I started the timer, but I thought this might be part of the behavior I was seeing, so I decided to have a separate I/O reset the capacitor. This is not what I prefer, since now I'm adding a second I/O's capacitance to the external capacitor (the input capacitances of AIN1 and PD5) which I'm measuring, but at least I can get it working this way first.
-
I then start the timer, enable interrupts, and switch the Digital I/O (PD5) to "release" the external cap and allow it to begin charging.
I set up the comparator and reset the cap first in setup(), and then in loop, I start the timer and wait for the interrupt to occur.
When the interrupt occurs, I calculate the time, and call the reset_cap() after some delay to prepare the capacitor to be measured again.
From what I can tell, I don't seem to come out of setup() correctly.
Here's the code:
// Arduino Input: Digital Pin 8 (ICP1), AVR pin PB0
// If using analog comparator input, use AIN1 (PD7, inverting input), AIN0(PD6,non-inverting)
volatile unsigned long dlyTime;
volatile boolean triggered;
// These constants won't change:
const int COMPIN = 7; // PD7 used as input to comparator
const int RST_B = 5; // PD7 used for reseting capacitor
ISR (TIMER1_OVF_vect) // timer overflows (every 65536 counts)
{
Serial.println ("TimerCounter OVRFLW ");
} // end of TIMER1_OVF_vect
ISR (TIMER1_CAPT_vect)
{
// grab counter value before it changes any more
dlyTime = ICR1; // see datasheet, page 117 (accessing 16-bit registers)
TCCR1B = 0;// Timer 1 control register 8-bit -- Normal Mode/Clock source stopped
triggered = true;
TIMSK1 = 0; // no more interrupts for now
} // end of TIMER1_CAPT_vect
void setup_comp ()
{
Serial.println("in setup_comp");
//Set up Comparator
//reference voltage AIN1, sense on AIN0 (using bandgap ref on AIN0, interrupt on falling edge of COMPOUT)
ADCSRB = 0; // disable mux--AIN1 connected to neg input of comparator
ACSR =(0<<ACD)|(1<<ACBG)|(1<<ACIC)|(1<<ACIS1);//enable comparator, bandgap selected,
DIDR1 = (0<<AIN1D)|(1<<AIN0D);
Serial.println("leaving setup_comp");
return;
} // end of setup_comp
void reset_cap ()
{
noInterrupts (); //protected code
Serial.println("in reset_cap");
pinMode(RST_B,OUTPUT);
digitalWrite(RST_B,0); //drive output low to reset sense capacitor
TCNT1 = 0; //reset counter
TIFR1 = (1<<ICF1)|(1<<TOV1); // clear flags so we don't get a bogus interrupt
ACSR |= (1<<ACI); //clear any comparator interrupt
triggered = false;
return;
} // end reset_capacitor
void start_timer ()
{
TIMSK1=(1<<ICIE1)|(1<<TOIE1); //interrupt on Timer 1 input capture and overflow
TCCR1B = (1<<CS10); //timer started
ACSR |=(1<<ACIE);//enable comparator interrupt\
interrupts ();
pinMode(RST_B,INPUT); // switch port to comparator input
return;
}
void setup (){
Serial.begin(9600);
Serial.println("Tau");
delay(1000);
TCCR1A = 0; // Timer 1 control register 8-bit -- Normal Mode
TCCR1B = (0<<ICES1);// Timer 1 control register 8-bit -- Normal Mode/Clock source stopped; falling edge
setup_comp();
delay(1000);
reset_cap ();
delay(1000);
} // end of setup
void loop ()
{
Serial.println("Timer Started...");
Serial.println("*");
start_timer ();
Serial.println(triggered);
//wait until interrupt
while (!triggered)
{
Serial.println("Waiting");
}
// Calculate time from counts
float elapsedTime = F_CPU * float (dlyTime); // each tick is 62.5 ns at 16 MHz
Serial.print ("Time =: ");
Serial.println (elapsedTime);
delay(10000);
reset_cap ();
} // end of loop
I'm am a HW guy trying to write code my first Arduino program, so please bear that in mind. I appreciate any help I can get.
Thanks!