Timing/Velocity/Acceleration Logger

I posted this in the general forum but then discovered this and thought it might be a more appropriate place so apologies for cross posting:

Hi,
I have built a prototype light gate velocity logger. I have a single light gate connected up to pin 2 of an UNO which goes from 0V to 5V when the beam is broken. It all seems to work but I am wondering if my approach is the most efficient. At present I am constantly polling to look for a state change and start the timing. Is this good practice or should I be putting this in an interrupt?
Here’s my code, any feedback would be highly appreciated as this is my first arduino project.

#include <DFR_Key.h>
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

// setup global variables
int photodiodePin = 2, ledPin = 13;
volatile int mode = 0, count = 0;
int lastState = LOW;
unsigned long startTime, deltaTime, deltaTimes[2];
float output, cardLength = 5.0;

void setup() {    
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.print("Select Mode");
  pinMode(ledPin, OUTPUT);                           // sets an output to display when gate is high
  pinMode(photodiodePin, INPUT);                     // sets the digital pin as input to read photodiode
  attachInterrupt(1, changeMode, FALLING);
}

void loop() {
  if(mode > 0){
    byte currentState = digitalRead(photodiodePin);  // read current state of input
    if(currentState == HIGH && lastState == LOW){    // rising edge detected
      if(count == 1){                                // 2nd pulse
        deltaTime = micros() - startTime;            // calc time delay
      }
      startTime = micros();
      digitalWrite(ledPin, HIGH);                    // set output LED ON
    }
    if(currentState == LOW && lastState == HIGH){    // falling edge detected
      deltaTimes[count] = micros() - startTime;
      switch(count){                                 // determine if 1st or 2nd pulse
      case 0:                                      // 1st pulse
        switch(mode){
        case 1:
          output = (float)deltaTimes[0] / 1000000;
          lcd.setCursor(0,1);
          lcd.print("                ");
          lcd.setCursor(0,1);
          lcd.print(output, 4);
          lcd.print(" s");
          break;
        case 2:
          output = 10000 * (cardLength / (float)deltaTimes[0]);
          lcd.setCursor(0,1);
          lcd.print("                ");
          lcd.setCursor(0,1);
          lcd.print(output, 4);
          lcd.print(" m/s");
          break;
        case 3:
          count = 1;                             // increment counter at the end of the pulse
          break;
        }
        break;
      case 1:                                      // 2nd pulse
        count = 0;
        // Calculate acceleration
        output = 10000000000 * ((cardLength / (float)deltaTimes[1]) - (cardLength / (float)deltaTimes[0])) / (float)deltaTime;
          lcd.setCursor(0,1);
          lcd.print("                ");
          lcd.setCursor(0,1);
          lcd.print(output, 4);
          lcd.print(" m/s2");
        break;
      }
      digitalWrite(ledPin, LOW);                     // set output LED OFF
    }
    lastState = currentState;  
  }
}

void changeMode() {
  static unsigned long last_interrupt_time = 0;
  unsigned long interrupt_time = millis();
  // If interrupts come faster than 200ms, assume it's a bounce and ignore
  if (interrupt_time - last_interrupt_time > 200) {
    count = 0;
    if(mode < 3){
      mode++;
    }
    else{
      mode = 1;
    }
    lcd.clear();
    switch(mode){
     case 1:
     lcd.print("Timing");
     break;
     case 2:
     lcd.print("Velocity");
     break;
     case 3:
     lcd.print("Acceleration");
     break;
    }
  }
  last_interrupt_time = interrupt_time;  
}

At present I am constantly polling to look for a state change and start the timing.

That's probably the lowest latency approach. You could lower it still further by using direct port manipulation, at the expense of limiting the portability.

You certainly should NOT be fiddling around with an LCD in interrupt context.

Thanks, why should I not write to the lcd in the interrupt? Martyn

Because you want to spend as little to e as possible in interrupt context.