Arduino - based camera trigger: source code

Arduino icon

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.)

  1. // WIND TUNNEL LASER TRIGGER MODULE
  2. // Armin J Hinterwirth, 2009
  3. // ++++++++++++++++++++++++++++++++++++
  4. //
  5. // PIN ASSIGNEMT AND DEFAULT VALUES
  6. // INPUT PINS:
  7. int level_Pin1 = 0; // input from light sensor 1
  8. int level_Pin2 = 1; // input from light sensor 2
  9. int lightlevel1 = 650; // value of light level input 1
  10. int lightlevel2 = 650; // value of light level input 2
  11. int thresh1 = 900; // threshold for beam interruption
  12. int thresh2 = 900; // threshold for beam interruption
  13. int tm_delay = 84; // time it takes for receiver to produce signal after button is pressed
  14. int status_button_Pin = 2; // pin for toggling between 'armed' and 'idle'
  15. boolean status_button = HIGH; // value read at reset button
  16.  
  17. int trigger_button_Pin = 3; // pin for manually triggering an event
  18. boolean trigger_button = HIGH; // value read at reset button
  19. boolean trigger_button_Last = HIGH;
  20.  
  21. // OUTPUT PINS:
  22. int sound_out = 5; // pin for buzzer
  23. int status_trigger = 6; // output for trigger status light
  24. int status_idle = 7; // idle indicator light
  25. int status_armed = 8; // armed indicator light
  26. int laser_Pin1 = 10; // power source for laser #1 (on only when armed is laser turned on)
  27. int trigger_Pin1 = 12; // pin for Phantom camera trigger
  28. int trigger_Pin2 = 13; // camera event marker
  29. int trigger_Pin3 = 11; // another trigger output signal (TTL pulse)
  30. int trigger_Pin4 = 4; // output for RadioFlyer Tx trigger (goes to L or R switch)
  31.  
  32. long time = 0; // the last time the output pin was toggled
  33. int debounce = 300; // the debounce time for pressing buttons
  34. int holdTime = 1000; // how long to wait for press+hold event to get into aligment mode
  35. long downTime = -1; // time button B was pressed down
  36. long upTime = -1; // time button B was released
  37.  
  38. byte flag = 0; // flag for loop control
  39.  
  40. // timing for buzz in trigger function:
  41. int pulseLength = 100; // length of each buzz pulse
  42. int interPulseT = 150; // delay in between buzzes
  43. int pulseNumber = 400;
  44.  
  45. void setup() {
  46. // PIN SETUP +++++++++++++++++++++++++++++++++++++++++++++++++
  47. pinMode(level_Pin1, INPUT); // light level sensor input
  48. pinMode(level_Pin2, INPUT); // light level sensor input
  49.  
  50. pinMode(status_button_Pin, INPUT); // toggle between idle and armed
  51. pinMode(trigger_button_Pin, INPUT); // manual trigger
  52.  
  53. pinMode(sound_out, OUTPUT); // buzzer pin
  54. pinMode(status_trigger, OUTPUT); // trigger indicator light
  55. pinMode(status_idle, OUTPUT); // indicator LED when idle
  56. pinMode(status_armed, OUTPUT); // indicator LED when armed
  57. pinMode(trigger_Pin1, OUTPUT); // trigger signal out
  58. pinMode(trigger_Pin2, OUTPUT); // trigger signal out
  59. pinMode(trigger_Pin3, OUTPUT); // trigger signal out
  60. pinMode(trigger_Pin4, OUTPUT); // trigger signal out
  61. pinMode(laser_Pin1, OUTPUT); // pin that turns laser power on and off
  62.  
  63. // DEFAULT VALUES +++++++++++++++++++++++++++++++++++++++++++
  64. digitalWrite(laser_Pin1, LOW); // start with laser off
  65. digitalWrite(status_idle, HIGH); // turn 'idle' indicator ON
  66. digitalWrite(status_armed, LOW); // turn 'armed' indicator OFF
  67. Serial.begin(9600); // serial comm. for debugging
  68. }
  69.  
  70. // MAIN LOOP +++++++++++++++++++++++++++++++++++++++++++++++++
  71. void loop() {
  72. status_button = digitalRead(status_button_Pin); // read value at button 1
  73. trigger_button = digitalRead(trigger_button_Pin); // read value at button 2
  74.  
  75. if (status_button == LOW && (millis() - time) > debounce) { // button A was pressed!
  76. armed(); // call 'armed' routine
  77. time = millis(); // get the time for debouncing routing
  78. }
  79. // go into a laser setup mode if trigger button was pressed while in idle mode:
  80. // Test for button B pressed and store the last down time
  81. if (trigger_button == LOW && trigger_button_Last == HIGH && (millis() - upTime) > debounce) { // trigger button was pressed!
  82. downTime = millis(); //
  83. }
  84. // Test for button B release and store the last down time
  85. if (trigger_button == HIGH && trigger_button_Last == LOW && (millis() - downTime) > debounce) { // trigger button was released!
  86. upTime = millis();
  87. }
  88. // Test whether button B held down for longer than the hold time
  89. if (trigger_button == LOW && (millis() - downTime) > holdTime) {
  90. align(); // call 'align' routine
  91. downTime = millis();
  92. }
  93.  
  94. trigger_button_Last = trigger_button;
  95. }
  96.  
  97. // ALIGN FUNCTION ++++++++++++++++++++++++++++++++++++++++++++
  98. // turns on lasers regardless of input levels at sensors
  99. // helpful for aligning lasers with targets
  100. void align() {
  101. Serial.println();
  102. Serial.println("Status: Lasers ON for alignment");
  103. buzz();
  104. delay(100);
  105. buzz();
  106.  
  107. digitalWrite(status_armed, HIGH); // turn 'armed' indicator ON
  108. digitalWrite(status_idle, HIGH); // turn 'armed' indicator ON
  109. digitalWrite(laser_Pin1, HIGH); // turn laser ON
  110.  
  111. delay(500); // wait so button B can be released
  112.  
  113. do {
  114. lightlevel1 = analogRead(level_Pin1);
  115. lightlevel2 = analogRead(level_Pin2);
  116. status_button = digitalRead(status_button_Pin); // read button
  117. trigger_button = digitalRead(trigger_button_Pin); // read trigger button
  118.  
  119. Serial.print(lightlevel1);
  120. Serial.print('\t');
  121. Serial.println(lightlevel2);
  122.  
  123. if (trigger_button == LOW || status_button == LOW) {
  124. Serial.println();
  125. Serial.println("Status: Idle");
  126. flag = 1;
  127. }
  128. }
  129. while (flag == 0);
  130. flag = 0; // reset flag
  131. digitalWrite(status_armed, LOW); // turn 'armed' indicator OFF
  132. digitalWrite(status_idle, HIGH); // turn 'armed' indicator ON
  133. digitalWrite(laser_Pin1, LOW); // turn laser OFF
  134.  
  135. delay(500); // delay to get the finger off the button...
  136. }
  137.  
  138. // BUZZ FUNCTION +++++++++++++++++++++++++++++++++++++++++++++++++
  139. // creates audible alarm when switching modes
  140. void buzz() {
  141. //Serial.println("Buzz function evoked");
  142. int pulseLength = 200; // length of each buzz pulse
  143. int interPulseT = 300; // delay in between buzzes
  144. int pulseNumber = 100; // number of pulses
  145.  
  146. for (int i = 0; i < pulseNumber; i++) {
  147. digitalWrite(sound_out, HIGH);
  148. delayMicroseconds(pulseLength);
  149. digitalWrite(sound_out, LOW);
  150. delayMicroseconds(interPulseT);
  151. }
  152. }
  153.  
  154.  
  155. // ARMED FUNCTION: +++++++++++++++++++++++++++++++++++++++++++++++++
  156. // lasers ON, levels are measured, waiting for threshold crossings
  157. void armed(){
  158. Serial.println();
  159. Serial.println("Status: Armed");
  160. buzz();
  161. delay(100); // delay a bit to allow button to settle to low
  162. buzz();
  163. delay(100);
  164. buzz();
  165. delay(300); // delay a bit to allow button to settle to low
  166. digitalWrite(status_armed, HIGH); // turn 'armed' indicator ON
  167. digitalWrite(status_idle, LOW); // turn 'armed' indicator ON
  168. digitalWrite(laser_Pin1, HIGH); // turn laser ON
  169. trigger_button = HIGH;
  170.  
  171. do {
  172. lightlevel1 = analogRead(level_Pin1);
  173. lightlevel2 = analogRead(level_Pin2);
  174. status_button = digitalRead(status_button_Pin); // read button
  175. trigger_button = digitalRead(trigger_button_Pin); // read trigger button
  176. delayMicroseconds(200); // give the ADC time to read value
  177.  
  178. if ( (lightlevel1 < thresh1 && lightlevel2 < thresh2) || trigger_button == LOW ) {
  179. trigger();
  180. flag = 1; // loop exit condition true
  181. }
  182. if (status_button == LOW) {
  183. Serial.println();
  184. Serial.println("Aborted --> Status: Idle");
  185. flag = 1;
  186. }
  187. }
  188. while (flag == 0);
  189.  
  190. flag = 0; // reset flag for the next round
  191. digitalWrite(laser_Pin1, LOW); // turn laser OFF
  192. digitalWrite(status_armed, LOW); // turn 'armed' indicator OFF
  193. digitalWrite(status_idle, HIGH); // turn 'armed' indicator OFF
  194. }
  195.  
  196. // TRIGGER FUNCTION +++++++++++++++++++++++++++++++++++++++++++
  197. void trigger() {
  198. digitalWrite(trigger_Pin1, HIGH); // trigger signal 1 (Phantom camera trigger) high
  199. digitalWrite(trigger_Pin3, HIGH); // trigger signal 2 (TTL signal) high
  200. digitalWrite(trigger_Pin4, HIGH); // trigger signal 4 (TTL signal) high
  201. digitalWrite(status_trigger, HIGH); // turn trigger status LED on
  202. delay(tm_delay); //wait xx ms to account for radioFlyer transmission delay
  203. digitalWrite(trigger_Pin2, HIGH); // trigger signal 2 (event marker) high
  204.  
  205. // audible buzz:
  206. for (int i = 0; i < pulseNumber; i++) {
  207. digitalWrite(sound_out, HIGH);
  208. delayMicroseconds(pulseLength);
  209. digitalWrite(sound_out, LOW);
  210. delayMicroseconds(interPulseT);
  211. }
  212.  
  213. delay(60); // to make total trigger signal last for 250 ms
  214.  
  215. digitalWrite(status_trigger, LOW); // turn LED off after buzz is over
  216. digitalWrite(trigger_Pin1, LOW); // trigger signal 1 LOW
  217. digitalWrite(trigger_Pin2, LOW); // trigger signal 2 LOW
  218. digitalWrite(trigger_Pin3, LOW); // trigger signal 2 high
  219. digitalWrite(trigger_Pin4, LOW); // trigger signal 2 high
  220. Serial.println();
  221. Serial.println("TRIGGER function has been executed.");
  222. Serial.println("--> Back to IDLE mode");
  223. }
Category: 
Code