Hi Guys, i would like to thank you in advance for helping with this problem that i m having getting input capture working in arduino uno. I have read all the post there is in most of the forums and haven't come to a solution yet.
GOAL: The main purpose of the project that i m working on is to capture the time between two events. I m using timer1 and pin 8 on the arduino uno. This is what i have...
#include <avr/io.h>
#include <avr/interrupt.h>
volatile uint16_t T1Ovs1, T1Ovs2;//OVERFLOW COUNTERS
volatile uint16_t Capt1, Capt2, Capt3;//VARIABLES TO HOLD TIMESTAMPS
volatile uint8_t Flag;//CAPTURE FLAG
#define icpPin 8
/*--------------------------------------------------------------------------------------------------
INTIALIZING TIMER
---------------------------------------------------------------------------------------------------*/
void InitTimer1(void)
{
TCNT1=0;//SETTING INTIAL TIMER VALUE
TCCR1B|=(1<<ICES1);//SETTING FIRST CAPTURE ON RISING EDGE
TIMSK1|=(1<<ICIE1)|(1<<TOIE1);//ENABLING INPUT CAPTURE AND OVERFLOW INTERRUPTS
}
/*--------------------------------------------------------------------------------------------------
STARTING TIMER
---------------------------------------------------------------------------------------------------*/
void StartTimer1(void)
{
TCCR1B|=(1<<CS11);//STARTING TIMER WITHOUT PRESCALER
sei();//ENABLING GLOBAL INTERRUPTS
}
/*--------------------------------------------------------------------------------------------------
CAPTURE ISR
---------------------------------------------------------------------------------------------------*/
ISR(TIMER1_CAPT_vect)
{
TCNT1 = 0;
if (Flag==0)
{
Capt1=ICR1;//SAVING CAPTURED TIMESTAMP
TCCR1B&=~(1<<ICES1);//CHANGE CAPTURE ON FALLING EDGE
T1Ovs2=0;//RESETING OVERFLOWS
//digitalWrite(13, HIGH); // set the LED on
//delay(100); // wait for a second
}
if (Flag==1)
{
Capt2=ICR1;//SAVING CAPTURED TIMESTAMP
TCCR1B|=(1<<ICES1);//CHANGING CAPTURE ON RISING EDGE
T1Ovs1=T1Ovs2;//SAVING FIRST OVERFLOW COUNTER
//digitalWrite(13, LOW); // set the LED off
//delay(100); // wait for a second
}
if (Flag==2)
{
Capt3=ICR1;//SAVING CAPTURED TIMESTAMP
TIMSK1&=~((1<<ICIE1)|(1<<TOIE1));//STOP INPUT CAPTURE AND OVERFLOW INTERRUPTS
//digitalWrite(13, HIGH); // set the LED on
//delay(100); // wait for a second
}
Flag++;//INCREMENTING FLAG
}
/*--------------------------------------------------------------------------------------------------
OVERFLOW ISR
---------------------------------------------------------------------------------------------------*/
ISR(TIMER1_OVF_vect)
{
T1Ovs2++;//INCREMENTING OVERFLOW COUNTER
}
/*--------------------------------------------------------------------------------------------------
MAIN FUNCTION
---------------------------------------------------------------------------------------------------*/
int main(void)
{
volatile uint8_t FINALTIME;//VARIABLE TO HOLD THE FINAL TIME
pinMode(icpPin,INPUT);
digitalWrite(icpPin,HIGH);//pull up
// pinMode(13, OUTPUT);
InitTimer1();//CALLING FUNCTION INITTIMER1 TO INITIALIZE TIMER 1
StartTimer1();//CALLING FUNCTION STARTTIMER1 TO START TIMER 1
while(1)
{
//calculate duty cycle if all timestamps captured
if (Flag==3)
{
Serial.begin(9600);
Serial.print("\r");
Serial.print("<Capture1>:");
Serial.print(Capt1);
Serial.print("<Capture2>:");
Serial.print(Capt2);
Serial.print("<Capture3>:");
Serial.print(Capt3);
Serial.print("\n");
Serial.print("<FINAL TIME>:");
Serial.print((Capt2-Capt1)*0.000125);
Serial.print(" Millisecond");
Serial.print("\n");
Flag=0;//CLEARING FLAG
T1Ovs1=0;//CLEARING OVERFLOW COUNTERS
T1Ovs2=0;
TIFR1=(1<<ICF1)|(1<<TOV1);//CLEARING INTERRUPT FLAGS TO AVOID ANY PENDING INTERRUPTS
TIMSK1|=(1<<ICIE1)|(1<<TOIE1);//ENABLING INPUT CAPTURE AND OVERFLOW INTERRUPTS
}
}
}
Moderator edit: </mark> <mark>[code]</mark> <mark>
Sorry about not clarifying the specs: Yes, the program complies and the time i m looking is about a second and i m using the 5 volts source in the arduino board to triggered the input capture. I tried to verify if i am even getting to the ISR by having the program to turn on and off led when it reached ISR, but it doesnt seem to do that, which made me thinkg that i m not even getting to ISR.I was getting the counter to count yesterday, but it was randomly triggering the event without any input to the capture pin. I m getting multiples results when tried triggering just one event, which i really dont understand. do i need to use the pull up resistor? I have verified my setup many times and read the user manual plenty. Your help is appreciated. Thank you
AJG059:
Hello together,
I tested the proposal from ballistics and made some changes. Now it seems to work. Nice code
Andreas
That code is hideously complicated for such a simple task, and you don't see to be making any use of the Arduino development environment or runtime library.
Why don't you just poll the input until you see the first event, record the start time, poll the input until you see the second time, record the end time. Subtract start from end to get the elapsed time and then calculate and print whatever it is you're deriving from this. If the events were happening at very high frequency you might have needed to use interrupts to respond to them quickly enough, but when you're looking for very long intervals like this it hardly seems necessary.
As a general note - when posting code, please enclose it in [ CODE ] [ /CODE ] tags to prevent the forum software from munging it.
...poll the input until you see the first event, record the start time, poll the input until you see the second time, record the end time. Subtract start from end to get the elapsed time...
This works just fine. Each millis() returns a long int with the current number of milliseconds since the board was powered. When you subtract two event times, the answer is the time difference in milliseconds.
i have confuse during rising edge and falling edges on input capture nethod,
please any one expalin during rising edge what values are stored in ICR1.
it can store upto 0 to 65535 for rising edge only if its than what values are stored during falling edges. how timer values are detecting the edges