// Ethan's Arduino Nikon Programmable Remote w/ Intervalometer (July 2009) #include // Flow control variables boolean mainloopbool = true; boolean checkbool = false; boolean beganserial = false; // Pin assignments // IR LED pin assignment NikonRemote remote(12); // Status LED int statusPin = 13; // Pin assignment for each program LED int progOne = 2; int progTwo = 3; int progThree = 4; int progFour = 5; int progFive = 6; int progSix = 7; int progSeven = 8; // Pin assignements for each button int butLeft = 9; int butGo = 10; int butRight = 11; //The amount of time that the LEDs are all off to eliminate ambient light. int allOffMS = 300; // Starting default program = manual trigger mode int progNum = 6; // Time delays for each interval program (1-5) unsigned long milliOne = 5000; // five seconds unsigned long milliTwo = 30000; // thirty seconds unsigned long milliThree = 60000; // one minute unsigned long milliFour = 300000; // five minutes unsigned long milliFive = 840000; // fourteen minutes // Runs when the microcontroller boots void setup(){ // Power all pins to default values pinMode(statusPin, OUTPUT); pinMode(progOne, OUTPUT); pinMode(progTwo, OUTPUT); pinMode(progThree, OUTPUT); pinMode(progFour, OUTPUT); pinMode(progFive, OUTPUT); pinMode(progSix, OUTPUT); pinMode(progSeven, OUTPUT); pinMode(butLeft, INPUT); pinMode(butGo, INPUT); pinMode(butRight, INPUT); } // Main Loop - Runs immediately after setup() void loop(){ // Reset status LED to OFF digitalWrite(statusPin, LOW); interface(); // button selection logic LEDstate(); // power all LEDs to selected values delay(100); // One tenth second button debounce } // Terminate a program, resume the main loop void resumeLoop(){ digitalWrite(statusPin, HIGH); mainloopbool = false; checkbool = false; LEDstate(); } // button selection logic void interface(){ if (digitalRead(butGo)==LOW){ // Middle "GO" button to ground means it's pressed digitalWrite(statusPin, HIGH); mainloopbool = true; program(); // execute the selected program digitalWrite(statusPin, LOW); }else if (digitalRead(butLeft)==LOW){ // "Left" button pressed, decrement selected program digitalWrite(statusPin, HIGH); progNum-=1; digitalWrite(statusPin, LOW); }else if (digitalRead(butRight)==LOW){ // "Right" button pressed, increment selected program digitalWrite(statusPin, HIGH); progNum+=1; digitalWrite(statusPin, LOW); } // Keep program selection in range if (progNum > 7) { progNum = 1; } else if (progNum < 1) { progNum = 7; } /* uncomment for diagnostic code if (beganserial == false){ digitalWrite(statusPin, HIGH); Serial.begin(9600); beganserial = true; delay (50); digitalWrite(statusPin, LOW); } Serial.println(progNum); */ } // Run the selected program void program(){ delay(200); //Debounce delay to make sure the button isn't still pressed. while (mainloopbool == true){ switch (progNum){ case 1: intervalsnap(milliOne); break; case 2: intervalsnap(milliTwo); break; case 3: intervalsnap(milliThree); break; case 4: intervalsnap(milliFour); break; case 5: intervalsnap(milliFive); break; case 6: manualTrigger(); break; case 7: serialTrigger(); break; } } } // Manually trigger the camera void manualTrigger(){ if (digitalRead(butGo)==LOW){ // Trigger camera if GO is pressed snap(); digitalWrite(statusPin, HIGH); } else if ((digitalRead(butLeft)==LOW) || (digitalRead(butRight)==LOW)){ // If Left or Right are pressed, exit program back to main loop resumeLoop(); } } // Trigger the camera via Laptop serial port, etc. void serialTrigger(){ // Initialize serial one time only if (beganserial == false){ digitalWrite(statusPin, HIGH); Serial.begin(9600); beganserial = true; delay (50); digitalWrite(statusPin, LOW); } // Snap a photo upon upper-case "S" if (Serial.available() > 0) { int serialByte = Serial.read(); if (serialByte == 'S') { digitalWrite(statusPin, HIGH); snap(); Serial.println("Picture Taken."); digitalWrite(statusPin, LOW); } } if ((digitalRead(butLeft)==LOW) || (digitalRead(butRight)==LOW) || (digitalRead(butGo)==LOW)){ resumeLoop(); } } // Intervalometer - time delay determined by which program is selected void intervalsnap(unsigned long timeMS){ // If time to wait is longer than 8 seconds, the status blink will last 5 seconds // otherwise, the status blink lasts 2 seconds. unsigned long preStatusBlinkTime; int nBlinks; if (timeMS < 1000){ nBlinks = 1; preStatusBlinkTime = 500; }else if (timeMS < 8000){ nBlinks = 4; preStatusBlinkTime = timeMS - 2000; }else{ //anything longer nBlinks = 10; preStatusBlinkTime = timeMS - 5000; } //Take account of the time it takes to turn back on the LEDs during snap(); preStatusBlinkTime = preStatusBlinkTime - (allOffMS + 63); //Delay for specified number of milliseconds, quitting if any button is pressed delaycheck(preStatusBlinkTime); // Blink the status lights at half-second intervals for the remainder of the time if (checkbool == true){ int i; for(i=0; i < nBlinks; i++){ digitalWrite(statusPin, HIGH); delaycheck(400); digitalWrite(statusPin, LOW); delaycheck(100); } // Trigger the shutter snap(); } } // Delay for specified number of tenths of a second, quitting if any button is pressed void delaycheck(unsigned long delayMs){ int i = 0; checkbool = true; int hundredms = delayMs / 100; while(i < hundredms && checkbool == true){ delay(100); if ((digitalRead(butLeft)==LOW) || (digitalRead(butRight)==LOW) || (digitalRead(butGo)==LOW)){ resumeLoop(); } i=i+1; } } // Trigger the shutter void snap(){ remote.Snap(); delay(63); remote.Snap(); allOff(); delay(allOffMS); LEDstate(); } // Called by main loop to power all LEDs to selected values void LEDstate(){ digitalWrite(statusPin, LOW); if (progNum == 1) { digitalWrite(progOne, HIGH); digitalWrite(progTwo, LOW); digitalWrite(progThree, LOW); digitalWrite(progFour, LOW); digitalWrite(progFive, LOW); digitalWrite(progSix, LOW); digitalWrite(progSeven, LOW); } if (progNum == 2) { digitalWrite(progOne, LOW); digitalWrite(progTwo, HIGH); digitalWrite(progThree, LOW); digitalWrite(progFour, LOW); digitalWrite(progFive, LOW); digitalWrite(progSix, LOW); digitalWrite(progSeven, LOW); } if (progNum == 3) { digitalWrite(progOne, LOW); digitalWrite(progTwo, LOW); digitalWrite(progThree, HIGH); digitalWrite(progFour, LOW); digitalWrite(progFive, LOW); digitalWrite(progSix, LOW); digitalWrite(progSeven, LOW); } if (progNum == 4) { digitalWrite(progOne, LOW); digitalWrite(progTwo, LOW); digitalWrite(progThree, LOW); digitalWrite(progFour, HIGH); digitalWrite(progFive, LOW); digitalWrite(progSix, LOW); digitalWrite(progSeven, LOW); } if (progNum == 5) { digitalWrite(progOne, LOW); digitalWrite(progTwo, LOW); digitalWrite(progThree, LOW); digitalWrite(progFour, LOW); digitalWrite(progFive, HIGH); digitalWrite(progSix, LOW); digitalWrite(progSeven, LOW); } if (progNum == 6) { digitalWrite(progOne, LOW); digitalWrite(progTwo, LOW); digitalWrite(progThree, LOW); digitalWrite(progFour, LOW); digitalWrite(progFive, LOW); digitalWrite(progSix, HIGH); digitalWrite(progSeven, LOW); } if (progNum == 7) { digitalWrite(progOne, LOW); digitalWrite(progTwo, LOW); digitalWrite(progThree, LOW); digitalWrite(progFour, LOW); digitalWrite(progFive, LOW); digitalWrite(progSix, LOW); digitalWrite(progSeven, HIGH); } /* //simple, overrated approach to the same thing as above. int pin; for (pin = 2; pin <= 8; pin++) { if (pin == progNum+1) { digitalWrite(pin, HIGH); } else { digitalWrite(pin, LOW); } } digitalWrite(statusPin, LOW); */ } //Turn off all LEDs void allOff(){ digitalWrite(progTwo, LOW); digitalWrite(progThree, LOW); digitalWrite(progFour, LOW); digitalWrite(progFive, LOW); digitalWrite(progSix, LOW); digitalWrite(progSeven, LOW); digitalWrite(statusPin, LOW); }