External interrupt (INT0) and digital Pin2 (INPUT) simultaneous usage

Hi,

While I read most of the standard Arduino reference documents, but I've not found a clear answer on if it is possible to use external interrupt (in 'CHANGE' mode, i.e. ISR invoked everything pin-state changes from 0 to 1, or 1 to 0), i.e. INT0 on same pin as DigitalPin#2, while also doing digitalRead(2). Is this a safe combination on a single pin ?

Here is what I was thinking of doing:

volatile char direction;
volatile unsigned long lastTime;
volatile unsigned long howLong;

void setup()
{
  pinMode(2, INPUT);
  lastTime = micros();
  lastState = digitalRead(2);
  attachInterrupt(0, myISR, CHANGE);  
}

void myISR()
{
  noInterrupts();
  direction = (lastState == HIGH) ? 'U' : 'D';
  lastState != lastState;
  howLong = lastTime - micros();
  interrupts();
}

void loop()
{
  switch (lastState)
  {
    case 'U': 
      Serial.print("Going up... ");
      Serial.println(howLong);
      break;
    case 'D':
      Serial.print("Going down... ");
      Serial.println(howLong);
      break;
  }

  lastState = 0;
}

Objective of the above code being tracking the direction (going up/going down) of the leading edge of signal on pin# 2, along with the duration of how long it stays in the previous state.

Reason for asking is that I am getting somewhat erratic behaviour regarding the duration of pin being in certain states, even when what I am feeding it is a squarewave. With a squarewave, I was expecting to see absolutely repeating cycle of Going-up/Going-down, at roughly same duration, but duration seems to over a not-so-narrow range.

Thanks,
f74

Why are you disabling and re-enabling interrupts in the ISR? Setting a couple of variables and calling micros() takes next to no time at all.

@PaulS, thanks for taking time to answer.
I've tried removing the interrupt disable/enable pair, but there's hardly any noticeable change in behavior.

Reason for putting the interrupt disable/enable pair was to avoid any kind of race-condition around the 'lastState' and 'howLong' values. Since the ISR itself can be interrupted (if I understood what I read so far, correctly), interruption of ISR, before 'lastState' is updated, vs if it were interrupted after 'lastState' is updated, would give very different results. I'd miss pin value toggles etc., and missing pin value toggles breaks my logic completely.

I'd miss pin value toggles etc., and missing pin value toggles breaks my logic completely.

And ignoring interrupts while the ISR is running doesn't result in data loss? What, exactly, is triggering the interrupt, and what are you trying to accomplish?

void myISR()

{
  noInterrupts();
  ...
  interrupts();
}

Those instructions achieve nothing except wasting time. Interrupts are disabled inside an ISR, and enabling them upon leaving is done automatically.

As for your results, what frequency is the square wave? Those Serial.prints take quite a bit of time to execute.

falcon74:
Since the ISR itself can be interrupted (if I understood what I read so far, correctly) ...

No it can't. Where did you read that? If ISRs could be interrupted the code would be very hard to write. For example, what happens if the ISR is interrupted before it does noInterrupts()?

PaulS:

I'd miss pin value toggles etc., and missing pin value toggles breaks my logic completely.

And ignoring interrupts while the ISR is running doesn't result in data loss? What, exactly, is triggering the interrupt, and what are you trying to accomplish?

Thanks @PaulS. You've got a point, and I've to admit that I am not embedded programming expert by any stretch of imagination. Trying to learn while reading and trying out stuff.

The interrupt is current triggered by an Arduino clone (on breadboard actually, using 16MHz xtal), which is currently my square wave generator. The squarewave is generated @ 25 kHz. Eventually, I intend to turn this square wave to a more arbitrary digital data pattern.

The square wave is generated at 25kHz. In fact I tried at 33.334kHz initially, then thought of reducing it to make it easier for the receiving Arduino to catch-up. Goal is not to work with square waves though. I would like to decode some arbitrary digital signal patterns. In there, the high frequency is 33.334kHz.

So in typical beginner fashion you start off with asking how to implement what you think is the solution to your problem without actually telling what the problem is.
This is fine if you know what you are doing but clearly you don't. It looks like all this effort put in by others has been wasted because you have not actually defined your problem.

You still haven't and for us to be any use to you this will have to be done.

I would like to decode some arbitrary digital signal patterns.

Decode covers a multitude of sins, what do you mean by this? Is it frequency, period, pulse width modulation, phase modulation, frequency shift keying or something else?

The larger problem which I would like to solve is to decode the signal generated by a 315MHz remote keyfob (http://www.ebay.com/itm/12V-10A-315MHZ-4-Channel-200M-Wireless-Remote-Control-Switch-/170738374763) using Arduino. Instead of using the 4-channel relay-board, I would like to eventually make a device that can attach with a PC via USB, and the received RF signal start some application on my PC. The parts are all ready, I mean my Processing based PC application, and Arduino/Processing communication. The part which is left is being able to decode the RF signal on Arduino. Opening the remote, I can see only 1 IC, which says SC2262. Searching around a lot, I only found a Chinese company, and instead of it being a uC, turned out to be some kind of an encoder IC. In fact, I managed to find the datasheet for this IC herehttp://electronics-diy.com/pdf/SC2272_eng.pdf.

Tomorrow I plan to take the remote to my friend who has a DSO, to see what the signal looks like. So while waiting for this, I'd thought of learning about how to decode any digital encoded data.