Multiple Interrupts on One Input

I have found this code; http://www.gammon.com.au/forum/?id=11091

volatile byte pins [4];  //pins 3, 4, 5, 6
volatile boolean fired;
#define FIRST_PIN 3
#define DEBOUNCE_TIME 100  // ms
unsigned long last_time;
int LEDGreen = 8;
int LEDRed = 11;

void isr ()
{
  // they haven't processed the last one yet
  if (fired)
  return;   
  for (byte i = 0; i < sizeof pins; i++)
  {
    byte val = pins [i] = digitalRead (i + FIRST_PIN);
    if (val == LOW)
    fired = true;  
  }  // end of for
}  // end of isr

void setup ()
{
  // enable pullup on interrupt-detect line
  digitalWrite (2, HIGH);  
  for (byte i = 0; i < sizeof pins; i++)
  digitalWrite (i + FIRST_PIN, HIGH);  // enable pullups on data pins
  attachInterrupt (0, isr, FALLING);
  Serial.begin (9600);
}  // end of setup

void loop ()
{
  if (fired)
  {
    unsigned long now = millis ();
    if (now - last_time > DEBOUNCE_TIME)
    {
      last_time = now;
      Serial.print ("Fired! Switch ");
      for (byte i = 0; i < sizeof pins; i++)
      if (pins [i] == LOW)
      Serial.print (i + 1, DEC);
      Serial.println (" was pressed.");
    }  // end of debounce time elapsed
    fired = false;
  }  // end if fired
}  // end of loop

The code is great and works a treat.
I would like to implement some routines based on which switch was activated.
I think I need to be monitoring the line ‘Serial.print(i+1, DEC);’, as I need to know the value of ‘i’ to initiate certain outputs depending on which input was triggered.

void loop ()
{
  if (fired)
  {
    unsigned long now = millis ();
    if (now - last_time > DEBOUNCE_TIME)
    {
      last_time = now;
      Serial.print ("Fired! Switch ");
      for (byte i = 0; i < sizeof pins; i++)
      if (pins [i] == LOW)
      Serial.print (i + 1, DEC);
      Serial.println (" was pressed.");
    }  // end of debounce time elapsed
    fired = false;
  }  // end if fired
}  // end of loop

How can I monitor the value ‘i’ and also how do I implement different outputs for different inputs?

Many thanks,
Chris

You could make i from the ISR global and volatile, or you could just scan through pins[] to find the one that is low.

Mark

Many thanks for the ideas. I have tried to implement the global variable i, with little success. For some reason ‘i’ always equals ‘0’.

Would you be able to give an example how either of your ideas are done? I am punching bellow my weight on this code!

so, the ISR is very busy, so printing from there may be an issue

look at creating a global variable

byte lastPin;

and doing this:

void loop ()
{
  if (fired)
  {
    unsigned long now = millis ();
    if (now - last_time > DEBOUNCE_TIME)
    {
      last_time = now;
      //Serial.print ("Fired! Switch ");
      for (byte i = 0; i < sizeof pins; i++)
      if (pins [i] == LOW)
      {
        lastPin = i;
        //Serial.print (i + 1, DEC);
      }
      Serial.print("*");
      Serial.println (lastPin);
    }  // end of debounce time elapsed
    fired = false;
  }  // end if fired
}  // end of loop

if it still doesn’t work, comment out those remaining Serial.print()s and print lastPin in the loop() function.

ISR’s need to be very short…

BulldogLowell: so, the ISR is very busy, so printing from there may be an issue

I think you may be confusing the code in loop() with the code in isr() because they both start with if (fired).

The Serial.print() statements are only in loop().

...R

Hi BulldogLowell, your code worked a treat. The output now changes with different input switches, all on one interrupt.

Now more coding to implement case statements for each switch…

Many thanks.

ChrisBTW: Hi BulldogLowell, your code worked a treat. The output now changes with different input switches, all on one interrupt.

Now more coding to implement case statements for each switch......

Many thanks.

Yup. robin noted I slipped in the wrong place.

Sorry bout that.