//pins on the arduino. const int shutterPin = 3; //output to camera const int startLEDPin = 13; //visual display of timelapse running const int upPin = 5; //input for up button const int downPin = 4; //input for down button const int minutePin = 10; //visual display of minutes yes/no (seconds in active if not HIGH) const int ledPin = 12; //visual display of photo command const int HDRPin = 11; //visual display of HDR yes/no const int startPin = 2; //input for begin button //for displaying digits on the 7-segment LEDs. const int clockPin = 6; const int serialOnesPin = 7; const int serialTensPin = 8; const int serialHundsPin = 9; const int a=1; const int b=2; const int c=4; const int d=8; const int e=16; const int f=32; const int g=64; byte digits[10]; byte inf[3]; byte pic[3]; byte intvl[3]; //interval settings long interval = 10; //seconds long oldInterval; long intervalCounter = 0; //this variable and the next allow for incrementation of the interval long intervalStep = 10; //so that the timelapse can be interrupted at any time. int infoDelay = 1500; //number of pictures to be taken total boolean changeNumPics = true; int oldNumPics = 0; int numPics = 0; //total number of pictures, 0 means infinite. long numPicsChanged = infoDelay; long numPicsTimeout = 2000; //ms int count = 0; //keeps track of number of pictures. //variables for different options (HDR and minute/second) boolean minute = false; int minuteMultiplier = 1; boolean HDR = false; //flag for hdr timelapses //button logic and debouncing boolean start = false; //records whether timelapse should be going or not. int startReading; //reads start button input int prevStartReading = LOW; //stores last start button input for latching. int upReading; //reads up/down button input int prevUpReading = LOW; //stores last up button input for latching. int downReading; //reads down button input int prevDownReading = LOW; //stores last down button input for latching. long pressStartTime = 0; //stores time of last button state change for debouncing long pressUpTime = 0; //ditto long pressDownTime = 0; //ditto long debounceDelay = 100; //debounce wait period in ms //miscellaneous variables boolean sleeping = false; long activityTime = 0; long sleepTime= 300000; //ms, time to wait before sleeping. (300000 ms = 5 min) int waitTime; int safetyDelay = 50; //ms, wait period when camera pin is HIGH to give the camera time to respond int HDRsafetyDelay = 1500; //ms, time the camera pin is HIGH for fast-fire HDR pictures to be taken void setup(){ //declare the pins as inputs or outputs pinMode(shutterPin, OUTPUT); pinMode(ledPin, OUTPUT); pinMode(HDRPin, INPUT); pinMode(startPin, INPUT); pinMode(startLEDPin, OUTPUT); pinMode(clockPin, OUTPUT); pinMode(serialOnesPin, OUTPUT); pinMode(serialTensPin, OUTPUT); pinMode(serialHundsPin, OUTPUT); pinMode(upPin, INPUT); pinMode(downPin, INPUT); pinMode(minutePin, INPUT); //define which segments of the 7-segment LEDs should light for different digits digits[0] = a + b + c + d + e + f; digits[1] = b + c; digits[2] = a + b + g + e + d; digits[3] = a + b + g + c + d; digits[4] = f + g + b + c; digits[5] = a + f + g + c + d; digits[6] = a + f + g + c + d + e; digits[7] = a + b + c; digits[8] = a + b + c + d + e + f + g; digits[9] = a + b + f + g + c + d; //define the segments for displaying "inf" inf[0] = b + c; inf[1] = e + g + c; inf[2] = a + f + g + e; //define the segments for displaying "pic" pic[0] = a + b + g + f + e; pic[1] = inf[0]; pic[2] = a + f + e + d; //define the segments for displaying "int" intvl[0] = b + c; intvl[1] = inf[1]; intvl[2] = f + g + e + d; Serial.begin(9600); //start/stop button is an interrupt so that it's always active attachInterrupt(0, checkStart, RISING); //give some parameter information. displayPIC(); delay(infoDelay); if (numPics == 0){ displayINF(); } else{ displayDEC(numPics/10); } while (changeNumPics){ oldNumPics = numPics; checkUp(); checkDown(); Serial.println(numPics); if (oldNumPics != numPics){ if (numPics == 0){ displayINF(); } else{ displayDEC(numPics/10); } } if (millis() - numPicsChanged > numPicsTimeout){ changeNumPics = false; } } displayINT(); delay(infoDelay); displayDEC(interval); } void loop(){ //if timelapse is not running, display the current interval between pictures and be ready //to accept input that will change the value of interval. if (!start){ minute = digitalRead(minutePin); oldInterval = interval; checkUp(); checkDown(); if (oldInterval != interval){ //helps reduce flicker in the display displayDEC(interval); } } while ((count <= numPics || numPics == 0) && start == true){ sleeping = (millis()-activityTime > sleepTime); Serial.println("sleep status"); Serial.println(sleeping, DEC); //set wait time, depending on status of HDR flag. HDR = digitalRead(HDRPin); if (HDR){ waitTime = HDRsafetyDelay; } else{ waitTime = safetyDelay; } //take a picture digitalWrite(shutterPin, HIGH); digitalWrite(ledPin, HIGH); delay(waitTime); digitalWrite(ledPin, LOW); digitalWrite(shutterPin, LOW); count++; //display picture number if (sleeping){ displayOFF(); } else{ displayDEC(count); } //wait the user-set interval if (minute){ minuteMultiplier = 60; } else{ minuteMultiplier = 1; } intervalCounter = 0; while((intervalStep*intervalCounter) < (((interval*1000)*minuteMultiplier)-(2*waitTime)) && start){ delay(intervalStep); intervalCounter++; } //if the timelapse is to be stopped (or is finished), reset the counter to prepare it for the next timelapse. if (!start || count == numPics){ displayDEC(interval); count = 0; start = false; digitalWrite(startLEDPin, start); } } } //////////////////////////////////////////// //////Other Functions/////////////////////// //////////////////////////////////////////// //function to check the state of the start button and change the variables/LED state correspondingly void checkStart(){ if (!changeNumPics){ activityTime = millis(); if (sleeping){ sleeping = false; displayDEC(count); } else{ //if (millis() - pressStartTime > debounceDelay){ **debounce handled by hardware. start = !start; digitalWrite(startLEDPin, start); //pressStartTime = millis(); //} } } } //function to check the state of the up button and increment interval accordingly. void checkUp(){ upReading = digitalRead(upPin); if (upReading == HIGH && prevUpReading == LOW && millis() - pressUpTime > debounceDelay){ activityTime = millis(); if (changeNumPics){ if (numPics >= 9950){ //allows variable to wrap around. numPics = 0; } else{ numPics += 50; numPicsChanged = millis(); } } else{ if (interval >= 999){ interval = 0; } else{ interval += 1; } } pressUpTime = millis(); } prevUpReading = upReading; } //function to check the state of the down button and increment interval accordingly. void checkDown(){ downReading = digitalRead(downPin); if (downReading == HIGH && prevDownReading == LOW && millis() - pressDownTime > debounceDelay){ activityTime = millis(); if (changeNumPics){ if (numPics <= 0){ //allows variable to wrap around. numPics = 9950; } else{ numPics -= 50; numPicsChanged = millis(); } } else{ if (interval <= 0){ interval = 999; } else{ interval -= 1; } } pressDownTime = millis(); } prevDownReading = downReading; } //function to display a 3 digit number on 7-segment displays. void displayDEC(int i){ for (byte bitMask = 128; bitMask > 0; bitMask >>= 1){ digitalWrite(clockPin, LOW); digitalWrite(serialOnesPin, bitMask & ~digits[i%10] ? HIGH : LOW); digitalWrite(serialTensPin, bitMask & ~digits[(i/10%10)] ? HIGH : LOW); digitalWrite(serialHundsPin, bitMask & ~digits[i/100] ? HIGH : LOW); digitalWrite(clockPin, HIGH); } } //function to display "inf" on 3 7-segment displays. void displayINF(){ for (byte bitMask = 128; bitMask > 0; bitMask >>= 1){ digitalWrite(clockPin, LOW); digitalWrite(serialOnesPin, bitMask & ~inf[2] ? HIGH : LOW); digitalWrite(serialTensPin, bitMask & ~inf[1] ? HIGH : LOW); digitalWrite(serialHundsPin, bitMask & ~inf[0] ? HIGH : LOW); digitalWrite(clockPin, HIGH); } } void displayPIC(){ for (byte bitMask = 128; bitMask > 0; bitMask >>= 1){ digitalWrite(clockPin, LOW); digitalWrite(serialOnesPin, bitMask & ~pic[2] ? HIGH : LOW); digitalWrite(serialTensPin, bitMask & ~pic[1] ? HIGH : LOW); digitalWrite(serialHundsPin, bitMask & ~pic[0] ? HIGH : LOW); digitalWrite(clockPin, HIGH); } } void displayINT(){ for (byte bitMask = 128; bitMask > 0; bitMask >>= 1){ digitalWrite(clockPin, LOW); digitalWrite(serialOnesPin, bitMask & ~intvl[2] ? HIGH : LOW); digitalWrite(serialTensPin, bitMask & ~intvl[1] ? HIGH : LOW); digitalWrite(serialHundsPin, bitMask & ~intvl[0] ? HIGH : LOW); digitalWrite(clockPin, HIGH); } } void displayOFF(){ for (byte bitMask = 128; bitMask > 0; bitMask >>= 1){ digitalWrite(clockPin, LOW); digitalWrite(serialOnesPin, HIGH); digitalWrite(serialTensPin, HIGH); digitalWrite(serialHundsPin, HIGH); digitalWrite(clockPin, HIGH); } } ///////////////////////////////////////////