-->
Page 1 of 1

Interrupt: how to detect polarity?

PostPosted: Sun Dec 22, 2019 10:01 pm
by teddyz
How can I detect both that an interrupt has happened and if it was rising or falling? Having two interrupts on the same pin, like in the code below, did not work.
Code: Select allvoid setup() {

  WiFi.forceSleepWake();
  delay(100);
  Serial.begin(1000000);  pinMode( LED, OUTPUT );
  pinMode( interruptPin, INPUT );
  //attachInterrupt(digitalPinToInterrupt(interruptPin), handleInterrupt, CHANGE);
  attachInterrupt(digitalPinToInterrupt(interruptPin), handleInterruptR, RISING);
  attachInterrupt(digitalPinToInterrupt(interruptPin), handleInterruptF, FALLING);
  Serial.println("\nStart");
}

ICACHE_RAM_ATTR void handleInterruptR() {
  digitalWrite( LED, HIGH );
}

ICACHE_RAM_ATTR void handleInterruptF() {
  digitalWrite( LED, LOW );
}

Re: Interrupt: how to detect polarity?

PostPosted: Mon Dec 23, 2019 12:08 am
by rudy
Maybe on interrupt on change, at the start of the interrupt, check to see the state of the port. This should be pretty reliable.

I have had problems with the ESP32. Getting multiple interrupts on the rising pulse that wasn't quick enough. It seems there was not hysteresis. I had to look at the input and a timer to see if it was a retriggered occurrence. I don't know if the ESP8266 is the same.

Re: Interrupt: how to detect polarity?

PostPosted: Mon Dec 23, 2019 5:32 pm
by teddyz
Thanks! ESP8266 has the same problem. It was not too slow, but instead it sometimes trigs twice on a flank.
Using your idea I got it working reliably (at least when no other code is running).

Code: Select all#include <ESP8266WiFi.h>
const byte interruptPin = D3;
const byte errPin = D2;

void setup() {
  WiFi.mode(WIFI_OFF);
  delay(100);
  Serial.begin(1000000);
  pinMode( interruptPin, INPUT );
  pinMode( errPin, OUTPUT );
  attachInterrupt(digitalPinToInterrupt(interruptPin), handleInterruptY, CHANGE);
  //attachInterrupt(digitalPinToInterrupt(interruptPin), handleInterruptX, CHANGE);
  Serial.println("\nStart");
}

ICACHE_RAM_ATTR void handleInterruptX() { // Not reliable
  static bool lastPol = false;
  lastPol =  !lastPol;
  digitalWrite( errPin, lastPol );
}


ICACHE_RAM_ATTR void handleInterruptY() { // Works fine
  static bool lastPol = false;
  if (lastPol == digitalRead(interruptPin) ) {
    return;
  }
  lastPol =  !lastPol;
  digitalWrite( errPin, lastPol );
}


void loop() {
  ;
}


The latency is close to 4uS, which I hope gives me plenty of time to store the timing.
My idea was to port the arduino pocsag receiver to ESP8266 (because I ran out of Mega2560). :)