/* Lightning auto-trigger for my Nikon D40 DSLR Created August 2, 2012 The purpose of this sketch is to remotely trigger my camera using an infrared signal in order to capture a lightning bolt. I borrowed a couple of different sketches from other folks, which I truly appreciate: http://www.glacialwanderer.com/hobbyrobotics/?p=16 : this site explains the code for actuating a cable-type trigger upon sensing a change in light. Since my Nikon does not use a cable input, I combined it with http://luckylarry.co.uk/arduino-projects/arduino-ir-remote-intervalometer-for-nikon-d80-that-means-timelapse-photography-yarrr/ in order to get the results I desired. This guy did the research into the required pulses for Nikon IR receivers, but instead of using it for lightning, he used it for a time lapse scene. IR Pulse description for this particular model: - Wait for a start pulse (2000 usec) - There must be no pulse for 27830 usec (pause) - Receive a pulse (400 usec) - Pause (1580 usec) - Receive a second pulse (400 usec) - Longer pause (3580 usec) - Receive the last pulse (400 usec) (derived from http://www.bigmike.it/ircontrol/) micros() is an Arduino function that calls the time in Microseconds since your program first ran. Arduino doesn't reliably work with microseconds so we work our timings by taking the current reading and then adding our delay on to the end of it rather than rely on the in built timer. */ int shutterPin = 13; // assign the Infrared emitter/ diode to pin 13 int triggerPin = 0; // assign the lightning receiver to analog pin 0 int threshold = 5; // set the threshold to not fire shutter on erraneous signals int lightningVal; // define an integer to be used later void setup() { pinMode(shutterPin, OUTPUT); // set the pin (digital 13) as an output digitalWrite(shutterPin, LOW); // set the initial IR state to off Serial.begin(9600); // open serial to display on the computer what the arduino is doing lightningVal = analogRead(triggerPin); // set a baseline value for the receiver. later, anything greater than this + threshold will trigger shutter } // sets the pulse of the IR signal. void pulseON(int pulseTime) { unsigned long endPulse = micros() + pulseTime; // create the microseconds to pulse for while( micros() < endPulse) { digitalWrite(shutterPin, HIGH); // turn IR on delayMicroseconds(13); // half the clock cycle for 38Khz (26.32×10-6s) - e.g. the 'on' part of our wave digitalWrite(shutterPin, LOW); // turn IR off delayMicroseconds(13); // delay for the other half of the cycle to generate wave/ oscillation } } void pulseOFF(unsigned long startDelay) { unsigned long endDelay = micros() + startDelay; // create the microseconds to delay for while(micros() < endDelay); } void takePicture() { for (int i=0; i < 2; i++) { // loop the signal twice. pulseON(2000); // pulse for 2000 uS (Microseconds) pulseOFF(27850); // turn pulse off for 27850 us pulseON(390); // and so on pulseOFF(1580); pulseON(410); pulseOFF(3580); pulseON(400); pulseOFF(63200); } } void loop() { int newLightningVal = analogRead(triggerPin); Serial.println(lightningVal, DEC); if (abs(newLightningVal - lightningVal) > threshold) { takePicture(); delay(1200); // delay 1 sec before continuining to sense for lightning bolts Serial.println("Shutter triggered"); } lightningVal = newLightningVal; }