How to detect rising or falling edge of a Pin Change Interrupt?

Hi.. I have this interrupt code that sets Pin Change interrupts on two PortB pins - PCINT9 (PB1) and PCINT10 (PB2) on an Attiny167.

It works, but what could I add to detect if the interrupt was flagged by a rising or falling edge?

volatile uint8_t portbhistory = 0xFF;  // default is high because of the  pull-ups

void initInterrupt() {
  PCICR |= 1 << PCIE1;                       // enable PCINT[8:15] pin change interrupt
  PCMSK1 |= (1 << PCINT9) | (1 << PCINT10);  // configure interrupt at PCINT9 PIN9 e PCINT10 PIN 10
  sei();                                     // globaly enable interrupts
}

ISR(PCINT1_vect) {
  uint8_t changedbits;
  changedbits = PINB ^ portbhistory;
  portbhistory = PINB;

  if (changedbits & (1 << PB1)) {  // PB1 is PCINT 9 - PCINT 9 changed 
    trx2.tickISR();
  }
  if (changedbits & (1 << PB2)) {  // PB2 is PCINT 10 - PCINT 10 changed 
    disconnected_cable = 1;        // Cable is connected or disconnected ??
  }
}

Could I just add this to check if PB2 was rising of falling?

// read PCINT10 (PB2 - pin 10):
  if(PINB & (1 << PB2)) {
}
    // rising edge detected
  }
  else{
    // falling edge detected
  }

So it would look like this? Is that correct?

ISR(PCINT1_vect) {
  uint8_t changedbits;
  changedbits = PINB ^ portbhistory;
  portbhistory = PINB;

  if (changedbits & (1 << PB1)) {  // PB1 is PCINT 9 - PCINT 9 changed
    trx2.tickISR();
  }
  if (changedbits & (1 << PB2)) {  // PB2 is PCINT 10 - PCINT 10 changed
    if (PINB & (1 << PB2)) {       // rising edge on PCINT10 detected
      disconnected_cable = 0;      // cable is connected
    } else {                       // falling edge on PCINT10 detected
      disconnected_cable = 1;      // Cable is disconnected
    }
  }
}

If the last edge was a falling edge, this one is rising. If the last one was rising, this one is falling.

... for when you realize you can't do it your way.

There's a library, if you're interested.

ISR(PCINT1_vect) {
  uint8_t changedbits, risingbits, fallingbits, portbnow;
  portbnow = PINB;
  changedbits = portbnow ^ portbhistory;
  risingbits = portbnow & ~portbhistory;
  fallingbits = ~portbnow & portbhistory;
  portbhistory = portbnow;
1 Like

Read the pin in the interrupt routine.

1 Like

If you have more than one pin doing inerrupts in a port you do need to determine which changed. then you can use the new value (HIGH or LOW) to determine if it was a RISING or FALLING interrupt this time.

1 Like

I was going to suggest the same as last two posts. But actually, there is a caveat on that. It assumes that the signal remains stable long enough to read it, after the ISR is called.

1 Like

Thanks! This interrupt is to detect if a cable is/has been plugged/unplugged...so it´s not a fast changing signal (on PB2) but ... if I´d like to detect two different interrupts on PortB, one on CHANGE, and the other on RISING and FALLING, it would be something like this, right? Is this correct?


volatile uint8_t portbhistory = 0xFF;
volatile bool cable_connected = 0;

void setup(){
portbhistory = PINB;  // read PINB bits at power_up
initInterrupt();

}
void initInterrupt() {
  PCICR |= 1 << PCIE1;     // enable PCINT[8:15] pin change interrupt
  PCMSK1 |= 1 << PCINT9;   // configure interrupt at PCINT9 PIN9 - PB1
  PCMSK1 |= 1 << PCINT10;  // configure interrupt at PCINT10 PIN10 - PB2
  sei();                   // globaly enable interrupts
}


ISR(PCINT1_vect) {

  uint8_t changedbits, risingbits, fallingbits, portbnow;
  portbnow = PINB;
  changedbits = portbnow ^ portbhistory;
  risingbits = portbnow & ~portbhistory;
  fallingbits = ~portbnow & portbhistory;
  portbhistory = portbnow;

  if (changedbits & (1 << PB1)) {  // PCINT 9 changed  - PB1
    // do something here
  } 

  if (fallingbits & (1 << PB2)) {  // Falling Edge on PCINT10 - PB2
    cable_connected = 1;           // Pin is Low, so cable is connected
  }
  if (risingbits & (1 << PB2)) {   // Rising Edge on PCINT10 - PB2
    cable_connected = 0;           // Pin is High, so cable is disconnected
  }
}
1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.