Interrupts...

Hello...!!

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... :slight_smile:

/*

  • 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);

delay(10);
}

ISR(TIMER1_CAPT_vect)
{
// iCountold = iCountnew;
iCountnew=ICR1;
state = !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...

TCCR1B = 1<<ICES1 | 1<<CS10;//

previously i had TCCR1B = 1<<ICES1 ;

Cheers,
swalehm

Hi mem..!!

This is what have at the moment

Thanx..

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;

TIMSK1 = (1 << ICIE1);
Serial.begin(115200);
delay(10);
}

void loop() // run over and over again
{
Serial.print("OLD: ");
Serial.print(viCountold);
Serial.print(" NEW: ");
Serial.println(viCountnew);
digitalWrite(13, state);
// delay(10);
}

ISR(TIMER1_CAPT_vect)
{
// cli();
// TCNT1 =0;
viCountold = viCountnew;
viCountnew=ICR1;
state = !state;
ICR1 = 0;
// sei();

}

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

hey.. thanx for that..

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..

Serial.println(viCount, DEC);

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;

TIMSK1 = (1 << ICIE1);
Serial.begin(115200);
delay(10);
}

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;
}

OLD: 0 OLD: 0 OLD: 0 OLD: 0 OLD: 0 OLD: 0 OLD: 0 OLD: 0 OLD: 0 OLD: 0 OLD: 0 OLD: 0 OLD: 0 OLD: 0 OLD: 0 OLD: 0 OLD: 0 OLD: 0 OLD: 0 OLD: 0 OLD: 0 OLD: 0 OLD: 92 OLD: 92 OLD: 92 OLD: 92 OLD: 92 OLD: 92 OLD: 94 OLD: 94 OLD: 94 OLD: 94 OLD: 94 OLD: 234 OLD: 234 OLD: 234 OLD: 67 OLD: 67 OLD: 67 OLD: 83 OLD: 83 OLD: 83 OLD: 16 OLD: 16 OLD: 7 OLD: 7 OLD: 127 OLD: 127 OLD: 127 OLD: 204 OLD: 204 OLD: 204 OLD: 204 OLD: 204 OLD: 204 OLD: 204 OLD: 204 OLD: 111 OLD: 111 OLD: 130 OLD: 130 OLD: 3 OLD: 3 OLD: 144 OLD: 144 OLD: 151 OLD: 151 OLD: 20 OLD: 20 OLD: 109 OLD: 109 OLD: 141 OLD: 141 OLD: 165 OLD: 165 OLD: 191 OLD: 191 OLD: 110 OLD: 110 OLD: 211 OLD: 211 OLD: 20 OLD: 20 OLD: 20 OLD: 41 OLD: 41 OLD: 119 OLD: 119 OLD: 21 OLD: 21 OLD: 49 OLD: 49 OLD: 195 OLD: 195 OLD: 195 OLD: 195 OLD: 195 OLD: 195 OLD: 195 OLD: 195 OLD: 195 OLD: 195 OLD: 195 OLD: 195 OLD: 195 OLD: 195 OLD: 195 OLD: 195 OLD: 195 OLD: 195 OLD: 195 OLD: 195 OLD: 195 OLD: 195 OLD: 195 OLD: 195 OLD: 195 OLD: 195 OLD: 195 OLD: 195 OLD: 195 OLD: 195 OLD: 195 OLD: 195

in setup, try adding :
TCCR1A = 0;

Thanx alot man..!!

u r awesome.. it worked after i cleared TCCR1A which is kind of strange.. bt it works...

if there's anything you think i can assist you with please do let me know..

Thanks again..

Good to hear you have Input Capture working. What are you making?

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..

I have used Processing with Arduino for many projects. Here is something I posted last year for someone that needed a GUI interface for an Arduino project http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1201840336/219#219

It was a lot of fun seeing Arduino pins come to life on a PC screen.

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..