Capturing timer value based on external interrupt , leveraging the 62.5nsec (16MHz) resolution) of the ATMEGA328 on the Arduino Uno

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!