Converting analogRead to hardware interrupt, electrical or software issue?

I’m working on a timer sketch for a racing gate finish line. My first approach used photosensors with partial success. With one lane I was able to time each car fairly consistently using the analogRead function. When I attempted to add the code to detect a second lane, things fell apart. After some troubleshooting I realized using hardware interrupts would be a better more efficient approach.

Another challenge with interrupts was trying to convert the analog signal to digital. With a photosensor, there is not a consistent clean ON/Off signal, it varies with the amount of light. My second approach was adding a hall sensor to detect the magnets on the bottom of the cars. Without modifying any code using analogRead, it immediately provided more consistent lap readings. Unfortunately I was still stuck trying to read both sensors simultaneously.

I then did some experimentation on the breadboard, I attached the working hall sensor to an LED to see if I could see how strong of a signal it was. The signal was pretty faint, which made things somewhat more complicated. Then I attached a pushbutton to the interrupt pins to test the Interrupt sketch with very promising results. As far as I know, I can’t use hardware interrupts on any analog pins. All the success with detecting the passing car has been with using the A0 pin, the hall sensor and the photosensor both work. On digital pins 2 and 3, the interrupt sketch detects the pushbutton correctly but not the hall sensor of photosensor. I’m not sure if the signal is just too faint, or if the problem is in my sketch.

sketch_mar16b.ino (684 Bytes)

sketch_mar16a.ino (567 Bytes)

I thought it would upload my sketch within my post, so here they both are.

–Using analogRead—

const byte lightPin = 0;

int lightSensor = 0;

unsigned long lapMillis = 0;
unsigned long startMillis = millis();
unsigned long bestMillis = 9999999;
unsigned long scaleSpeed = 0;

float lapTime = 0.00;
float bestLap = 0.00;

void setup()
{
Serial.begin(9600);
}

void loop()
{

lightSensor = analogRead(lightPin);
//If car detected
if(lightSensor < analogRead(1)){
//determine lap time in milliseconds
lapMillis = millis() - startMillis;
startMillis = millis();
lapTime = lapMillis / 1000.00;

Serial.print("lapTime: ");
Serial.println(lapTime);
Serial.print("lapMillis: ");
Serial.println(lapMillis);
}
}

–Using hardware Interrupts–

#define HP1 2
#define HP2 3

void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
pinMode(HP1, INPUT);
pinMode(HP2, INPUT);
attachInterrupt(0, SLOT1, FALLING);
attachInterrupt(1, SLOT2, FALLING);

}

void loop() {
// put your main code here, to run repeatedly:

}

void SLOT1() {
Serial.println(“player 1 laptime”);
}

void SLOT2(){
Serial.println(“player 2 laptime”);
}

You can use pin-change interrupts on analog pins. For example, analog 5 is pin-change 13. However I'm not sure if you can do both at once and you can't set analog thresholds on the interrupts - it's acting as a digital pin when it's looking for interrupts.

The best way to do this, if you have enough spare pins available, is to use an analog comparator chip to detect the threshold you are looking for and attach that to one of the regular interrupt pins. The comparator can be wired to detect rapid changes in intensity and ignore slow changes. If you do it right, you won't need to read the analog values.

The Arduino does have one on-board analog comparator which generates its own special interrupts but I can't think of a simple way to use it for two inputs.

Seems to me the quickest fix is to clean up the signal from your photo sensors so there is clean on-off pulse. Then you original design should work.

Paul