I am a new arduino user and i need some help with interrupts. i was able to get the TIMER INPUT CAPTURE INTERRUPT running by looking at some libraries. whenever there is a change on PB0(pin 8 on the FREEDUINO SB) it triggers the ISR without any issues. i then tried to read the TCNT1 register and the ICR1 registers to know the difference between 2 edges but it doesn't work. anyone with any suggestions??? below is the code i used.
Please help... and Thank you in Advance...
/*
This code explores the external interrupts on the Freeduino SB
as of 7/03/09 i was able to get the led on and off when there is a
rising edge on INPUT CAPTURE1 PORTB0 pin 8 on the Freeduino SB Board.
I am still trying to figure out how to read the Timer regs..
I succesfully completed the setting up of the ISR and writin an ISR
*/
boolean state = HIGH;
int ledPin = 13; // LED connected to digital pin 13
unsigned int iCountnew = 0;// iCountold = 0;
void setup() // run once, when the sketch starts
{
pinMode(ledPin, OUTPUT); // sets the digital pin as output
TCCR1B = 1<<ICES1;
// iCountnew = ICR1;
TIMSK1 = (1 << ICIE1);
Serial.begin(115200);
}
void loop() // run over and over again
{
// Serial.print("OLD: ");
// Serial.println(int(iCountold));
Serial.print("NEW: ");
Serial.println(iCountnew, DEC);
digitalWrite(13, state);
You can do something like this to capture the rising and falling edge pulse counts. You may need to disable interrupts when you read these values - you want to avoid the interrupt handler being in the middle of updating the value at the same time your sketch is in the middle of using the value.
unsigned volatile int iFallingCount, iRisingCount;
/* ICR interrupt vector */
ISR(TIMER1_CAPT_vect){
TCNT1 = 0; // reset the counter
if( bit_is_set(TCCR1B ,ICES1)){ // was rising edge detected ?
iFallingCount = ICR1;
}
else {
iRisingCount = ICR1; // falling edge was detected
}
TCCR1B ^= _BV(ICES1); // toggle bit value to trigger on the other edge
}
Thanx mem...!!
i figured out why i couldn't read the regs. it was because the CS21:0 bits in TCCR1B were configured to stop the timers..!! so then i learnt how to use bitwise OR '|' and i can now read the registers.. however i do have another question.. is 255dec the maximum i can get for a count.. because if i read it correctly in the datasheets, TCNT1 and ICR1 are both 16 bit regs.
this is what i did to be able to read the timers...
boolean state = HIGH;
int ledPin = 13; // LED connected to digital pin 13
unsigned volatile int viCountnew, viCountold;
void setup() // run once, when the sketch starts
{
pinMode(ledPin, OUTPUT); // sets the digital pin as output
TCCR1B = 1<<ICNC1 | 1<<ICES1 | 1<<CS12 | 0<<CS11 | 1<<CS10;
void loop() // run over and over again
{
Serial.print("OLD: ");
Serial.print(viCountold);
Serial.print(" NEW: ");
Serial.println(viCountnew);
digitalWrite(13, state);
// delay(10);
}
TCNT1 is the 16 bit value of timer1, it will increment until it overflows at 65535 and start counting again from 0
ICR1 is the value of TCNT1 at the time of the input pulse transition (rising or falling depending on the value of bit ICES1). It is a snapshot of TCNT1 at the moment the pulse transition occurs.
If you want the count between two similar edges, you can do the following
ISR(TIMER1_CAPT_vect)
{
// we want to measure the time between interrupts (i.e. the count between similar edges)
TCNT1 = 0; // reset the counter
viCount =ICR1; // the count since the same edge on the previous pulse
}
BTW, it's a good idea to set TCCR1A to 0 in your setup. This disconnects the output compare pin and disables PWM
i still have a problem reading the regs.. i tried wat u suggested. could it be that i am not sending it out right.. could it be that "serial.print is eating up the High byte of my variable..
this is what i have for siplaying the count.. that is after using the code that u suggested previously..
Just before you print the value you should really disable interrupts and copy viCount in another variable and then re-enable interrupts. This avoids the case that the interrupt occurs when the Serial print routine is processing the print argument, but most of the time the values would print ok.
What is the prescaler value you re using and what is the data rate of the actual pulses? Does your output only ever print 255?
Lets have a look at the latest code you are running and perhaps also paste in a few lines of serial output, with an indication of what you would expect the output values to show.
Good Day..!! this is my latest code.. the results that i get in the serial monitor do vary from 0 - 255 following the code is a sample result pattern.
my input for now is just a push button.
thank you
boolean state = HIGH;
int ledPin = 13; // LED connected to digital pin 13
unsigned volatile int viCountnew, viCountold, viCount;
int iCount1, count2;
void setup() // run once, when the sketch starts
{
pinMode(ledPin, OUTPUT); // sets the digital pin as output
TCCR1B = 1<<ICNC1 | 1<<ICES1 | 1<<CS12 | 0<<CS11 | 1<<CS10;
void loop() // run over and over again
{
cli();
iCount1 = viCount;
sei();
Serial.print("OLD: ");
Serial.println(iCount1, DEC);
digitalWrite(13, state);
}
ISR(TIMER1_CAPT_vect)
{
TCNT1 = 0; // reset the counter
viCount =ICR1; // the count since the same edge on the previous pulse
state = !state;
}
well.. actually i might really not need input capture someone else is making a PWM temp sensor project. i might use my board instead of the HC11 for a motor speed control project. the instructor gave us a choice to use the HC11 or the freeduino. coz he is just amazed by the freeduino. have you looked into combining the arduino and Processing ?? i tried and i gota say its pretty gud..
wow.. that is quite a project with processing.. i did not use any arduino libraries when i created my GUI in processing.. i just set up processing to receive a serial byte and i had my control bits in that byte. therefore my freeduino was constantly sending out the control byte and processing was just receiving it and determining what it was and doing stuff accordingly so i had 2 push buttons on connected to the board. and i had a byte that varied from 1-4 depending on the combination of buttons pressed.. since i was just exploring and did not have any real project with it, i just had it change the color of a box on the screen.
if at all i decide to do my school project on the arduino instead of the Motorola 68HC11 then i also intend to have some sort of GUI for the speed ..etc but i might really need to dig into the arduino library for processing.. you might have noticed that i sometimes use arduino and sometimes freeduino...lol.. freeduino is the board i am using..