Posted by Armin on Thursday, January 06, 2011

This page contains the source code for the Arduino-based laser trigger unit described in a separate post.
I tried to insert comments in the code, so it should be pretty self-explanatory. To play and modify the code, you can copy and paste it into your Arduino IDE. (The line numbers in the code listing won't be copied.)
// WIND TUNNEL LASER TRIGGER MODULE
// Armin J Hinterwirth, 2009
// ++++++++++++++++++++++++++++++++++++
//
// PIN ASSIGNEMT AND DEFAULT VALUES
// INPUT PINS:
int level_Pin1 = 0; // input from light sensor 1
int level_Pin2 = 1; // input from light sensor 2
int lightlevel1 = 650; // value of light level input 1
int lightlevel2 = 650; // value of light level input 2
int thresh1 = 900; // threshold for beam interruption
int thresh2 = 900; // threshold for beam interruption
int tm_delay = 84; // time it takes for receiver to produce signal after button is pressed
int status_button_Pin = 2; // pin for toggling between 'armed' and 'idle'
boolean status_button = HIGH; // value read at reset button
int trigger_button_Pin = 3; // pin for manually triggering an event
boolean trigger_button = HIGH; // value read at reset button
boolean trigger_button_Last = HIGH;
// OUTPUT PINS:
int sound_out = 5; // pin for buzzer
int status_trigger = 6; // output for trigger status light
int status_idle = 7; // idle indicator light
int status_armed = 8; // armed indicator light
int laser_Pin1 = 10; // power source for laser #1 (on only when armed is laser turned on)
int trigger_Pin1 = 12; // pin for Phantom camera trigger
int trigger_Pin2 = 13; // camera event marker
int trigger_Pin3 = 11; // another trigger output signal (TTL pulse)
int trigger_Pin4 = 4; // output for RadioFlyer Tx trigger (goes to L or R switch)
int debounce = 300; // the debounce time for pressing buttons
int holdTime = 1000; // how long to wait for press+hold event to get into aligment mode
long downTime = -1; // time button B was pressed down
long upTime = -1; // time button B was released
byte flag = 0; // flag for loop control
// timing for buzz in trigger function:
int pulseLength = 100; // length of each buzz pulse
int interPulseT = 150; // delay in between buzzes
int pulseNumber = 400;
void setup() {
// PIN SETUP +++++++++++++++++++++++++++++++++++++++++++++++++
pinMode(level_Pin1, INPUT); // light level sensor input
pinMode(level_Pin2, INPUT); // light level sensor input
pinMode(status_button_Pin, INPUT); // toggle between idle and armed
pinMode(trigger_button_Pin, INPUT); // manual trigger
pinMode(sound_out, OUTPUT); // buzzer pin
pinMode(status_trigger, OUTPUT); // trigger indicator light
pinMode(status_idle, OUTPUT); // indicator LED when idle
pinMode(status_armed, OUTPUT); // indicator LED when armed
pinMode(trigger_Pin1, OUTPUT); // trigger signal out
pinMode(trigger_Pin2, OUTPUT); // trigger signal out
pinMode(trigger_Pin3, OUTPUT); // trigger signal out
pinMode(trigger_Pin4, OUTPUT); // trigger signal out
pinMode(laser_Pin1, OUTPUT); // pin that turns laser power on and off
// DEFAULT VALUES +++++++++++++++++++++++++++++++++++++++++++
digitalWrite(laser_Pin1, LOW); // start with laser off
digitalWrite(status_idle, HIGH); // turn 'idle' indicator ON
digitalWrite(status_armed, LOW); // turn 'armed' indicator OFF
Serial.begin(9600); // serial comm. for debugging
}
// MAIN LOOP +++++++++++++++++++++++++++++++++++++++++++++++++
void loop() {
status_button = digitalRead(status_button_Pin); // read value at button 1
trigger_button = digitalRead(trigger_button_Pin); // read value at button 2
armed(); // call 'armed' routine
}
// go into a laser setup mode if trigger button was pressed while in idle mode:
// Test for button B pressed and store the last down time
if (trigger_button == LOW && trigger_button_Last == HIGH && (millis() - upTime) > debounce) { // trigger button was pressed!
downTime = millis(); //
}
// Test for button B release and store the last down time
if (trigger_button == HIGH && trigger_button_Last == LOW && (millis() - downTime) > debounce) { // trigger button was released!
upTime = millis();
}
// Test whether button B held down for longer than the hold time
if (trigger_button == LOW && (millis() - downTime) > holdTime) {
align(); // call 'align' routine
downTime = millis();
}
trigger_button_Last = trigger_button;
}
// ALIGN FUNCTION ++++++++++++++++++++++++++++++++++++++++++++
// turns on lasers regardless of input levels at sensors
// helpful for aligning lasers with targets
void align() {
Serial.println();
Serial.println("Status: Lasers ON for alignment");
buzz();
delay(100);
buzz();
digitalWrite(status_armed, HIGH); // turn 'armed' indicator ON
digitalWrite(status_idle, HIGH); // turn 'armed' indicator ON
digitalWrite(laser_Pin1, HIGH); // turn laser ON
delay(500); // wait so button B can be released
do {
lightlevel1 = analogRead(level_Pin1);
lightlevel2 = analogRead(level_Pin2);
status_button = digitalRead(status_button_Pin); // read button
trigger_button = digitalRead(trigger_button_Pin); // read trigger button
Serial.print(lightlevel1);
Serial.print('\t');
Serial.println(lightlevel2);
if (trigger_button == LOW || status_button == LOW) {
Serial.println();
Serial.println("Status: Idle");
flag = 1;
}
}
while (flag == 0);
flag = 0; // reset flag
digitalWrite(status_armed, LOW); // turn 'armed' indicator OFF
digitalWrite(status_idle, HIGH); // turn 'armed' indicator ON
digitalWrite(laser_Pin1, LOW); // turn laser OFF
delay(500); // delay to get the finger off the button...
}
// BUZZ FUNCTION +++++++++++++++++++++++++++++++++++++++++++++++++
// creates audible alarm when switching modes
void buzz() {
//Serial.println("Buzz function evoked");
int pulseLength = 200; // length of each buzz pulse
int interPulseT = 300; // delay in between buzzes
int pulseNumber = 100; // number of pulses
for (int i = 0; i < pulseNumber; i++) {
digitalWrite(sound_out, HIGH);
delayMicroseconds(pulseLength);
digitalWrite(sound_out, LOW);
delayMicroseconds(interPulseT);
}
}
// ARMED FUNCTION: +++++++++++++++++++++++++++++++++++++++++++++++++
// lasers ON, levels are measured, waiting for threshold crossings
void armed(){
Serial.println();
Serial.println("Status: Armed");
buzz();
delay(100); // delay a bit to allow button to settle to low
buzz();
delay(100);
buzz();
delay(300); // delay a bit to allow button to settle to low
digitalWrite(status_armed, HIGH); // turn 'armed' indicator ON
digitalWrite(status_idle, LOW); // turn 'armed' indicator ON
digitalWrite(laser_Pin1, HIGH); // turn laser ON
trigger_button = HIGH;
do {
lightlevel1 = analogRead(level_Pin1);
lightlevel2 = analogRead(level_Pin2);
status_button = digitalRead(status_button_Pin); // read button
trigger_button = digitalRead(trigger_button_Pin); // read trigger button
delayMicroseconds(200); // give the ADC time to read value
if ( (lightlevel1 < thresh1 && lightlevel2 < thresh2) || trigger_button == LOW ) {
trigger();
flag = 1; // loop exit condition true
}
if (status_button == LOW) {
Serial.println();
Serial.println("Aborted --> Status: Idle");
flag = 1;
}
}
while (flag == 0);
flag = 0; // reset flag for the next round
digitalWrite(laser_Pin1, LOW); // turn laser OFF
digitalWrite(status_armed, LOW); // turn 'armed' indicator OFF
digitalWrite(status_idle, HIGH); // turn 'armed' indicator OFF
}
// TRIGGER FUNCTION +++++++++++++++++++++++++++++++++++++++++++
void trigger() {
digitalWrite(trigger_Pin1, HIGH); // trigger signal 1 (Phantom camera trigger) high
digitalWrite(trigger_Pin3, HIGH); // trigger signal 2 (TTL signal) high
digitalWrite(trigger_Pin4, HIGH); // trigger signal 4 (TTL signal) high
digitalWrite(status_trigger, HIGH); // turn trigger status LED on
delay(tm_delay); //wait xx ms to account for radioFlyer transmission delay
digitalWrite(trigger_Pin2, HIGH); // trigger signal 2 (event marker) high
// audible buzz:
for (int i = 0; i < pulseNumber; i++) {
digitalWrite(sound_out, HIGH);
delayMicroseconds(pulseLength);
digitalWrite(sound_out, LOW);
delayMicroseconds(interPulseT);
}
delay(60); // to make total trigger signal last for 250 ms
digitalWrite(status_trigger, LOW); // turn LED off after buzz is over
digitalWrite(trigger_Pin1, LOW); // trigger signal 1 LOW
digitalWrite(trigger_Pin2, LOW); // trigger signal 2 LOW
digitalWrite(trigger_Pin3, LOW); // trigger signal 2 high
digitalWrite(trigger_Pin4, LOW); // trigger signal 2 high
Serial.println();
Serial.println("TRIGGER function has been executed.");
Serial.println("--> Back to IDLE mode");
}
Category: 
Code