Measuring two different interrupt activities in one interrupt

Hi,

i'm fairly new to this, and in search of some help

if I use an ISR, i can detect a rising and a falling edge...
so is it possible to connect two different routines to one ISR?

meaning:

do something with the rising edge (detect a photosensor being activated)
and later on
detect that same sensor being de-activated?

grtz
Yves

Yes.

In the ISR you can determine the status of the interrupt pin after the interrupt was triggered using digitalRead, bitRead, or direct port manipulation and see if the change went High or Low. Then perform conditional action.

if (interruptPinStatus==1)
{
  // action A
}
else
{
  // action B
}

Hi Cattledog,

i've just read the Nick Gammon article about interupts and ISR's,
Interupts by Nick Gammon

but my knowledge is too small to really, really understand it all.

I had the idea that it would have been simple to attacht 2 routines to the same interrupt pin.

I'm using photosensors to get timings in dogsports...

i my case to rows of 6 sensors

it would be great if i could, at least measure on one of, these rows.
and thus how long a sensorsbeam is broken by a dog...

my thought was that :

if the dog comes in, i would get a "rising edge" signal and the moment the dog leaves the same beam, that i would get a "falling edge" signal.

that way, i had hoped to measure the time between the rising edge and the falling edge...

but as i mentioned before, my knowledge is too small at this moment to try things out :disappointed_relieved:

Hope to get some ideas here to point me in the right direction

Grtz,
Yves

I'm using photosensors to get timings in dogsports...

Can you please describe a bit more what you are trying to do and the timings you are trying to measure.

Are you interested in how long the dog stays in one position (i.e. the length of time the dog stays in front of the sensor and breaks the beam)?

Are you trying to measure the speed of the dog through a course, and you are interested in the time between when two sensors change?

If the dog can reliably break the photosensor path, then you should be able to use interrupts to start and stop time measurements.

Controlling the position of the dog between the pair of sensors to get a reliable blocking of the sensor may be a bigger problem :wink:

Hi Cattledog,

cattledog:
Controlling the position of the dog between the pair of sensors to get a reliable blocking of the sensor may be a bigger problem :wink:

no, that's the one thing i'm confident in :stuck_out_tongue:

the dogsport is called flyball
flyball passings to perfection

if you take a look at the video of our team, you'll see that a certain dog blocks a certain amount of time the sensor. the other team didn't pass that close, that time i can measure...

my goal is to capture that time that the sensorgate is blocked (should indeed be used to calculate a speedtrap) :wink:

but also, if we do perfect passings like in this video, I also want to calculate the time that the sensors are blocked by two dogs, that way i can calculate the smallest passings

grtz
Yves

Hi cattledog,

I've made a little drawing of what I mean to achieve by those two ISR routines

I think for experienced Aduinists this is a piece of cake, but i can't get to start this...

I would'nt know where to start programming this type of sensoring

because the routines may not interupt other things that are important that moment (like displaying data on the LCD's, etc...)

Grtz,
Yves

My first attempt at using an interrupt. Could be a starting point for your project. Results displayed in serial monitor:

boolean inputStatePrevious = LOW;
volatile boolean inputState = LOW;
volatile unsigned long startMillis = 0;
volatile unsigned long stopMillis = 0;
unsigned long durationMillis = 0;

void setup()
{
  attachInterrupt(0, blink, CHANGE);
  Serial.begin(115200);
}

void loop()
{
  if ((inputState == LOW) && (inputStatePrevious == HIGH)) {
    durationMillis = stopMillis - startMillis;
    Serial.print("startMillis = "); Serial.println(startMillis);
    Serial.print("stopMillis = "); Serial.println(stopMillis);
    Serial.print("durationMillis = "); Serial.println(durationMillis);
    Serial.println();
  }
  inputStatePrevious = inputState;
}

void blink()
{
  inputState = digitalRead(2);
  if (inputState == HIGH)
  {
    startMillis = millis();
  }
  else
  {
    stopMillis = millis();
  }
}

Yves,

I've had a most enjoyable time with Google and YouTube learning about Flyball. Surely if you have the patience, persistance and precision required to train a flyball dog you can program an Arduino.

I've added a pulse generating routine to dlloyd's pulse duration sketch, which should give you a tool for developing your program. Connect a wire from pin 8 to pin 2. I've set it up for a 100ms pulse length every 5 seconds. You can set things up for micros() instead of millis() if you need that precision.

//Pulses generated on pin8 and read with interrupts on pin2
//Pulse measument variables

boolean inputStatePrevious = LOW;
volatile boolean inputState = LOW;
volatile unsigned long startMillis = 0;
volatile unsigned long stopMillis = 0;
unsigned long durationMillis = 0;

//Pulse generation constants and variables

const int pulsePin = 8;//pin sending pulses 
const int pulseHigh = 100;//High time, millis() or micros()
const int pulseLow = 5000;//Low time
unsigned long ms;//time from millis() or micros()
unsigned long msLast;//last time the pulse pin changed state
boolean pinState = LOW;//current pulsePin state
unsigned long millisStart;
//unsigned long microsStart;
int pulseNumber = 0;

void setup()
{
  attachInterrupt(0, blink, CHANGE);
  Serial.begin(115200);

  pinMode(pulsePin, OUTPUT);
  millisStart = millis();
  //microsStart = micros():

  pinMode(2,INPUT);//Interrupt 0 on pin2
}

void loop()
{
  /* pulse generation routine using ternary operator: "?"
   The basic syntax of using the ternary operator is:
   (condition) ? (if_true) : (if_false)
   The pulse routine takes (ms-ms_last value) and if pinState High compares it
   to pulseHigh time, and if Low, to pulseLow time. */

  ms = millis();
  //ms = micros(); 

  if (pulseNumber < 4) //send train of four pulses
  {
    if (ms - msLast > (pinState ? pulseHigh : pulseLow)) 
    {
      digitalWrite(pulsePin, pinState = !pinState);
      msLast = ms;
    }
  }

  if ((inputState == LOW) && (inputStatePrevious == HIGH)) 
  {
    ++pulseNumber;//numbers pulses from 1 to 4
    Serial.print("pulseNumber = ");
    Serial.println(pulseNumber);
    durationMillis = stopMillis - startMillis;
    Serial.print("startMillis = "); 
    Serial.println(startMillis);
    Serial.print("stopMillis = "); 
    Serial.println(stopMillis);
    Serial.print("durationMillis = "); 
    Serial.println(durationMillis);
    Serial.println();
  }
  inputStatePrevious = inputState;
}

void blink()
{
  //inputState = digitalRead(2);
  inputState = bitRead(PIND,2);//bitRead is faster than digitalRead
  if (inputState == HIGH)
  {
    startMillis = millis();
  }
  else
  {
    stopMillis = millis();
  }
}

Can you provide a little more information about the start/finish gates. Are there two lines of sensors so you know which dog crossed first when measuring pass timing?

It sounds like you are planning to use an Arduino to automate some timing in your practice sessions. Will you be using a commercial optical gate, or will you be making something? I'm curious about how you will use pulse duration, and what length you expect. It doesn't seem to give you either pass timing, or the start/finish time of a dog.