Hi!
I'm writing code for a chonograph. My sensors and signal conditioning for my chronograph work well as verified by an o-scope. I'm getting clean square signals on the order of a couple hundred microseconds. I have 2 light channels, CHANNEL_1 and CHANNEL_2. The signal conditioning is setup such that as the light channel is blocked my output goes from low to high and when the channel is unblocked the signal goes from high to low.
My issues is my code on my Arduino at the moment.
I'm juggling some interrupts to accomplish the task and wondering if my approach is good or not. The code utilizes the TimerOne library, the timer1 interrupt, and the 2 interrupts "0" and "1" corresponding to pins 2 and 3 on my Arduino Nano (ATmega328). Right now, I'm just trying to test the code out. I've enabled pull up resistors on my pins 2 and 3. For testing purposes I have a wire connecting pin 2 to ground. My goal was to quickly detach the wire and attach the wire to ground to simulate a signal rise and fall coming into that pin. But when I pull the wire the arduino fires my timeout_ISR() code and not the correct ISR.
My guess is that I'm probably missing something major about interrupts. This is my first time using interrupts on the Arduino.
Thanks for your input. Here is my code (note that the reset_variables() subroutines sets my initial interrupt setting).
#include <TimerOne.h>
/*
Constants
*/
#define CHANNEL_1 2 //set light channel 1 to pin 2 NOTE: most Arduino boards only have two external interrupts, numbers 0 and 1 (digital pins 2 and 3).
//the signal for the channels needs to be sent to a pin that is interrupt enabled in this current version of the software.
#define CHANNEL_2 3 //set light channel 2 to pin 3
#define CHANNEL_1_INT 0 //interrupt number associated with channel 1
#define CHANNEL_2_INT 1 //interrupt number associated with channel 2
#define TIMEOUT 8000000 //sets the time duration in microseconds
#define WAIT_STATE 0
#define MONITOR_STATE 1
#define OUTPUT_STATE 2
/*
Global Variables
*/
unsigned long channel_1_initial = 0;
unsigned long channel_1_final = 0;
unsigned long channel_2_initial = 0;
unsigned long channel_2_final = 0;
boolean is_timeout = false;
unsigned int current_state = WAIT_STATE;
void setup() {
pinMode(CHANNEL_1, INPUT);
pinMode(CHANNEL_2, INPUT);
digitalWrite(CHANNEL_1, HIGH); //turn on pullup resistor
digitalWrite(CHANNEL_2, HIGH);
reset_variables();
Serial.begin(9600);
}
void loop() {
switch (current_state) {
case WAIT_STATE:
break;
case MONITOR_STATE:
break;
case OUTPUT_STATE:
output_serial_info();
reset_variables();
current_state = WAIT_STATE;
break;
}
}
void channel_1_rise_ISR() {
channel_1_initial = 0;
Timer1.initialize(TIMEOUT);
Timer1.start();
Timer1.attachInterrupt(timeout_ISR);
attachInterrupt(CHANNEL_1_INT, channel_1_fall_ISR, FALLING);
attachInterrupt(CHANNEL_2_INT, channel_2_rise_ISR, RISING);
current_state = MONITOR_STATE;
}
void channel_1_fall_ISR() {
channel_1_final = Timer1.read();
detachInterrupt(CHANNEL_1_INT);
}
void channel_2_rise_ISR() {
channel_2_initial = Timer1.read();
attachInterrupt(CHANNEL_2_INT, channel_2_rise_ISR, FALLING);
}
void channel_2_fall_ISR() {
channel_2_final = Timer1.read();
detachInterrupt(CHANNEL_2_INT);
Timer1.stop();
Timer1.detachInterrupt();
current_state = OUTPUT_STATE;
}
void timeout_ISR() {
is_timeout = true;
detachInterrupt(CHANNEL_1_INT);
detachInterrupt(CHANNEL_2_INT);
Timer1.stop();
Timer1.detachInterrupt();
current_state = OUTPUT_STATE;
}
void output_serial_info() {
if(is_timeout)
Serial.println("TIMEOUT");
Serial.print("Channel 1 Init: ");
Serial.println(channel_1_initial);
Serial.print("Channel 1 Final: ");
Serial.println(channel_1_final);
Serial.print("Channel 2 Init: ");
Serial.println(channel_2_initial);
Serial.print("Channel 2 Final: ");
Serial.println(channel_2_final);
Serial.print("Channel 1 Duration: ");
Serial.println((channel_1_final - channel_1_initial));
Serial.print("Channel 2 Duration: ");
Serial.println((channel_2_final - channel_2_initial));
Serial.print("Total Duration: ");
Serial.println((channel_2_initial - channel_1_initial));
}
void reset_variables() {
channel_1_initial = 0;
channel_1_final = 0;
channel_2_initial = 0;
channel_2_final = 0;
is_timeout = false;
attachInterrupt(CHANNEL_1_INT, channel_1_rise_ISR, RISING);
detachInterrupt(CHANNEL_2_INT);
}