Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //////////////////////////////////
- // PANO-XY 4 BUTTON V-1.0.4 //
- /////////////////////////////////
- /*
- Pano-XY is the program for controlling a servo-motor driven
- panorama camera-mount that allows panoramas with multiple rows of
- images. The photographer is prompted to enter the focal length of the
- camera's lens, the width of the panorama (in degrees), the number
- of rows of images, and whether the camera is in landscape or
- portrait orientation.
- The program will then calculate the field of view and the total
- number of images required for the panorama using a 50% overlap for
- horizontal moves and a 65% overlap for vertical moves. The 65%
- vertical overlap is a change from 50% in previous versions.
- The program will then automatically move the camera to the correct position
- and fire the shutter for each image. At the completion of the panorama, the
- camera will return to its home position.
- */
- /* Pano-XY-4-Button_V-1.0.4
- Changed default lens focal length to 50mm and the default pano width to 50 degrees.
- */
- /* Pano-XY-4-Button_V-1.0.3
- Shortened the delay times for settling after camera moves and the shutter time by 25%.
- */
- /* Pano-XY-4-Button_V-1.0.2
- Corrected rows algorithm when there is more than 1 row. For 2 row panos, neither row will be at horizontal.
- For 3 or more rows, only one row will below horizontal. All other rows will be horizontal or above.
- */
- /* Pano-XY-4-Button_V-1.0.1a
- Changed the method for calculating the start position for the vertical camera
- movement
- Removed the serial.print commands used for debugging
- */
- /* Pano-XY-4-Button_V-1.0.1
- Changed the amount of movement in the Home Camera exercise during the set-up routine from 30º swing each way to
- 15º swing each way (30º total) for both servos
- */
- /* Previous versions (PANO-XY V-1.1.a, V-1.1.b, & V-1.1.c) utilized a
- 4x4 keypad and a 20 x 4 display. This version uses 4 momentary
- contact buttons and a 16 x 2 display. The change allows for a
- considerably smaller case for the electronics and the controls. The
- original case was 6-1/2" x 6-1/2" x 4-1/2".
- */
- /* PANO-XY V-1.1.a
- Corrected starting position of horizontal arm.
- */
- /* PANO-XY V-1.1.b
- Changed image overlap to 50% from previous 35%.
- */
- /* PANO-XY V-1.1.c
- Corrected starting position of vertical arm, and corrected display
- to read PANO-XY rather than Pano-Riffic.
- */
- //LIBRARIES USED
- #include <LiquidCrystal_I2C.h>
- #include <Servo.h> // servo motor library
- #include <wire.h> //
- /*** Set Servos ***/
- Servo imageServo; // create servo object to control the horizontal servo
- Servo rowServo; // create servo object to control the vertical servo
- /*** Servo Variables ***/
- int imageServoMin = 833; // microseconds = to 0 degrees for a specific servomotor – NOTE: You will have to test your particular servos and set accordingly
- int imageServoMax = 2167; // microseconds = to 180 degrees for a specific servomotor
- int imageServoHome = 1500; // ((servoRange) / 2) + imageServoMin; the midpoint or 90º
- int rowServoMin = 985; // microseconds = to 0 degrees for a specific servomotor – NOTE: You will have to test your particular servos and set accordingly
- int rowServoMax = 1995; // microseconds = to 180 degrees for a specific servomotor
- int rowServoHome = 1500; // ((servoRange) / 2) + imageServoMin; the midpoint or 90º
- /*** LCD Display ***/
- // display i2c address & size
- LiquidCrystal_I2C myLcd(0x27, 16, 2); // 0x27 & 0x3F are typical addresses for the I2C. If either of these do not work, read this: https://lastminuteengineers.com/i2c-lcd-arduino-tutorial/
- /*** LCD Arrows ***/
- byte RtArrow[8] =
- {0b00000, 0b00100, 0b00010, 0b11111, 0b00010, 0b00100, 0b00000, 0b00000}; // create right arrow character for display
- byte LtArrow[8] =
- {0b00000, 0b00100, 0b01000, 0b11111, 0b01000, 0b00100, 0b00000, 0b00000}; // create left arrow character for display
- byte DnArrow[8] =
- {0b00000, 0b00100, 0b00100, 0b00100, 0b10101, 0b01110, 0b00100, 0b00000}; // create down arrow character for display
- byte UpArrow[8] =
- {0b00000, 0b00100, 0b01110, 0b10101, 0b00100, 0b00100, 0b00100, 0b00000}; // create up arrow character for display
- /*** assign button pins ***/
- const int buttonPinLeft = 4; // left button (back arrow)
- const int buttonPinRight = 5; // right button (forward arrow)
- const int buttonPinUp = 6; // up button (up or increase arrow)
- const int buttonPinDown = 7; // down button (down or decrease arrow)
- /***state of buttons un-pressed ***/
- int buttonStateLeft = 0;
- int buttonStateRight = 0;
- int buttonStateUp = 0;
- int buttonStateDown = 0;
- /*** menu arrays ***/
- const int FrameNum = 12;
- int CurrentFrame = 0;
- int Inputs[FrameNum] = {85, 75, 1, 1, 0};
- /*** variables ***/
- // utilities
- int x; // used as a counting tool
- int y; // used as a counting tool
- int buttonBounce = 200; // bounce time for buttons
- int shutterPin = 12; // Pin for camera shutter release relay
- // photo variables
- int focLength = 50; // default focal length (mm) – NOTE: Set your default according to the lens lengths you typically use
- bool camVal = 1; // Camera orientation
- char camOrient = 'P'; // identify camera orientation - NOTE: Set your default according to the camera orientation you typically use
- bool startVal = 0; // start the panorama
- // calculation varibles
- float sensorWidth = 23.6; // width of Pentax APS-C camera sensor – NOTE: Change according to your camera
- float sensorHeight = 15.7 // height of Pentax APS-C camera sensor – NOTE: Change according to your camera
- float fovSens; // calculated horizontal field of view
- float camFov; // actual field of view - landscape or portrait
- float fovHeight; // vertical field of view in degrees
- float imageWidth; // width of image after lap factor
- float imageHeight; // height of image after lap factor
- float hLapFactor = 0.50; // percentage of actual horizontal FOV used for image // NOTE - change to suit (0.35 is common)
- float vLapFactor = 0.35; // percentage of actual vertical FOV used for image // NOTE - change to suit
- // row variables
- int rowCount = 1; // default number of rows - NOTE: Set your default according to the number of rows you typically shoot
- int rowMoves; // # of moves
- float rowTravel; // amount of travel for each row move (degrees)
- float rowPos; // position of the camera center for a row (degrees)
- int rowPosMicros; // position of the camera center for a row (micros)
- int rowHome = 90; // sets the camera to a "zeroed" vertical posiiton
- float rowStart; // a panorama's starting vertical position
- // image variables
- int imageCount; // number of images in panorama (not including initial centered image)
- int cameraMoves; // number of moves between images
- int cameraTravel; // degrees camera travels from one position to the next
- // pano size variables
- int panoWidth = 50; // default desired panorama width in degrees - NOTE: Set your default according to the panorama width you typically want
- int panoHeightActual; // overall height of a panorama
- int panoWidthActual; // actual width of panorama after calculations
- float aspectRatio; // width:height of panorama
- // camera position variables
- float panoPosDegrees; // position of the camera center for an image (degrees)
- int panoPosMicros; // position of the camera center for an image (microseconds)
- int panoHome = 90; // center of the panorama in degrees
- int panoStart; // position of camera center for first image of panorama (not including initial centered image)
- // time variables to use to estimate required time for pano
- // set time to zero
- long panoTime = 0;
- long panoMinutes = 0;
- long panoSeconds = 0;
- /******************************************************************************************************/
- /*********************************************** SETUP ***********************************************/
- void setup() {
- // begin serial
- Serial.begin(9600);
- // initiate LCD
- myLcd.init(); // initializing the LCD
- myLcd.backlight(); // Enable or Turn On the backlight
- // creating the LCD arrows for display
- myLcd.createChar(0, RtArrow);
- myLcd.createChar(1, LtArrow);
- myLcd.createChar(2, DnArrow);
- myLcd.createChar(3, UpArrow);
- // set buttons
- pinMode(buttonPinLeft, INPUT_PULLUP);
- pinMode(buttonPinDown, INPUT_PULLUP);
- pinMode(buttonPinUp, INPUT_PULLUP);
- pinMode(buttonPinRight, INPUT_PULLUP);
- // Initialize Shutter Relay
- pinMode(shutterPin, OUTPUT); // specifies output pin for activating camera shutter
- // Set up the servos and set positions to 90º
- imageServo.attach(9, imageServoMin, imageServoMax); // attaches the horizontal servo on pin 9 & sets the limits
- rowServo.attach(10, rowServoMin, rowServoMax); // attaches the vertical servo on pin 10 & sets the limits
- imageServo.writeMicroseconds(imageServoHome); // centers the horizontal servo
- rowServo.writeMicroseconds(rowServoHome); // centers the vertical servo
- OpeningScreen(); // opening screen & exercise servos
- } // end setup
- /******************************************************************************************************/
- /*********************************************** LOOP ************************************************/
- void loop() {
- InputMenu(); // container for all screens and activities
- } // end loop
- /******************************************************************************************************/
- /**********************************************************************************************************************
- FUNCTIONS
- **********************************************************************************************************************/
- /************************************************ BUTTON DISPLAY FUNCTIONS *******************************************/
- // GO ON ARROW DISPLAY
- void GoOnArrowDisplay()
- {
- myLcd.setCursor(0, 1);
- myLcd.setCursor(9, 1);
- myLcd.print("Go On ");
- myLcd.write(0); // right arrow
- } // end function
- // FOUR ARROWS DISPLAY
- void FourArrowsDisplay()
- { myLcd.setCursor(0, 1);
- myLcd.write(1); // left arrow
- myLcd.setCursor(5, 1);
- myLcd.write(3); // up arrow
- myLcd.setCursor(10, 1);
- myLcd.write(2); // down arrow
- myLcd.setCursor(15, 1);
- myLcd.write(0); // right arrow
- } // end function
- // YES/NO ARROW DISPLAY
- void YesNoArrowDisplay()
- {
- myLcd.setCursor(0, 1);
- myLcd.write(1); // left arrow
- myLcd.setCursor(2, 1);
- myLcd.print("NO");
- myLcd.setCursor(11, 1);
- myLcd.print("YES");
- myLcd.setCursor(15, 1);
- myLcd.write(0); // right arrow
- } // end function
- /************************************************ BUTTON ACTION FUNCTIONS ********************************************/
- // These actions create the different button actions to be used with the arrow displays
- // INPUT FORWARD/BACK ACTION
- void MenuForwardBackAction()
- {
- buttonStateLeft = digitalRead(buttonPinLeft);
- buttonStateRight = digitalRead(buttonPinRight);
- // left button pressed
- if (buttonStateLeft == LOW) {
- delay(buttonBounce);
- myLcd.clear();
- if (CurrentFrame == 0) {
- CurrentFrame = FrameNum - 1;
- }
- else {
- CurrentFrame--;
- }
- }
- // right button pressed
- else if (buttonStateRight == LOW) {
- delay(buttonBounce);
- myLcd.clear();
- if (CurrentFrame == FrameNum - 1) {
- CurrentFrame = 0;
- }
- else {
- CurrentFrame++;
- }
- }
- } // end function
- // RIGHT TO CONTINUE BUTTON
- void RightToContinueAction()
- {
- buttonStateRight = digitalRead(buttonPinRight);
- while (digitalRead(buttonPinRight) == HIGH) {} // wait for right button push
- delay(buttonBounce);
- } // end function
- // RIGHT TO CONTINUE BUTTON
- void GoRightAction()
- {
- buttonStateRight = digitalRead(buttonPinRight);
- // right button pressed
- if (buttonStateRight == LOW) {
- delay(buttonBounce);
- myLcd.clear();
- if (CurrentFrame == FrameNum - 1) {
- CurrentFrame = 0;
- }
- else {
- CurrentFrame++;
- }
- }
- } // end function
- // RUN/RESET BUTTON
- void RunResetAction()
- {
- buttonStateRight = digitalRead(buttonPinRight);
- buttonStateLeft = digitalRead(buttonPinLeft);
- // right button pressed
- if (buttonStateRight == LOW) {
- delay(buttonBounce);
- CurrentFrame = 10;
- } // end if
- // left button pressed
- else if (buttonStateLeft == LOW) {
- delay(buttonBounce);
- ResetMenu();
- } // end if
- } // end function
- // RUN/QUIT BUTTON
- void PanoQuitAction()
- {
- buttonStateRight = digitalRead(buttonPinRight);
- buttonStateLeft = digitalRead(buttonPinLeft);
- // right button pressed
- if (buttonStateRight == LOW) {
- delay(buttonBounce);
- ResetMenu();
- } // end if
- // left button pressed
- else if (buttonStateLeft == LOW) {
- delay(buttonBounce);
- QuitPano();
- } // end if
- } // end function
- // DO PANO BUTTON
- void DoPanoAction()
- {
- buttonStateLeft = digitalRead(buttonPinLeft);
- buttonStateRight = digitalRead(buttonPinRight);
- // left button pressed
- if (buttonStateLeft == LOW) {
- delay(buttonBounce);
- myLcd.clear();
- if (CurrentFrame == 0) {
- CurrentFrame = FrameNum + 1;
- } // end if
- else {
- CurrentFrame++;
- } // end else
- } // end if
- // right button pressed
- else if (buttonStateRight == LOW) {
- delay(buttonBounce);
- myLcd.clear();
- // DoPano();
- } // end if
- } // end function
- // PORTRAIT/LANDSCAPE BUTTON
- void PortLandButtonAction()
- {
- buttonStateUp = digitalRead(buttonPinUp);
- buttonStateDown = digitalRead(buttonPinDown);
- // up button pressed
- if (buttonStateUp == LOW) {
- delay(buttonBounce);
- camOrient = 'P';
- }
- // down button pressed
- if (buttonStateDown == LOW) {
- delay(buttonBounce);
- camOrient = 'L';
- }
- } // end function
- // 1 INCREMENT UP/DOWN BUTTON - adjusts values by an increment of 1
- void UpDownAction1()
- {
- buttonStateUp = digitalRead(buttonPinUp);
- buttonStateDown = digitalRead(buttonPinDown);
- // up button pressed
- if (buttonStateUp == LOW) {
- delay(buttonBounce);
- Inputs[CurrentFrame] = Inputs[CurrentFrame] + 1;
- if (Inputs[CurrentFrame] > 9) { // keeps value from being above 9
- Inputs[CurrentFrame] = 9;
- } // end if
- myLcd.clear();
- } // end if
- // down button pressed
- else if (buttonStateDown == LOW) {
- delay(buttonBounce);
- Inputs[CurrentFrame] = Inputs[CurrentFrame] - 1;
- if (Inputs[CurrentFrame] < 0) { // keeps value from being below zero
- Inputs[CurrentFrame] = 0;
- } // end if
- myLcd.clear();
- } // end else if
- } // end function
- // 5 INCREMENT UP/DOWN BUTTON - adjusts values by an increment of 5
- void UpDownAction5()
- {
- buttonStateUp = digitalRead(buttonPinUp);
- buttonStateDown = digitalRead(buttonPinDown);
- // up button pressed
- if (buttonStateUp == LOW) {
- delay(buttonBounce);
- Inputs[CurrentFrame] = Inputs[CurrentFrame] + 5;
- if (Inputs[CurrentFrame] > 360) { // keeps value from being above 360
- Inputs[CurrentFrame] = 360;
- } // end if
- myLcd.clear();
- } // end if
- // down button pressed
- else if (buttonStateDown == LOW) {
- delay(buttonBounce);
- Inputs[CurrentFrame] = Inputs[CurrentFrame] - 5;
- if (Inputs[CurrentFrame] < 0) { // keeps value from being below zero
- Inputs[CurrentFrame] = 0;
- } // end if
- myLcd.clear();
- } // end else if
- } // end function
- /************************************************ DATA ENTRY FUNCTIONS ********************************************/
- // MENU FRAME HANDLER
- void InputMenu()
- {
- switch (CurrentFrame) {
- case 0:
- FocalFrame();
- break;
- case 1:
- PanoFrame();
- break;
- case 2:
- RowFrame();
- break;
- case 3:
- CamFrame();
- break;
- case 4:
- AllPanoCalcs();
- break;
- case 5:
- ReviewOne();
- break;
- case 6:
- ReviewTwo();
- break;
- case 7:
- ReviewThree();
- break;
- case 8:
- ReviewFour();
- break;
- case 9:
- RunOrReset();
- break;
- case 10:
- PanoRun();
- break;
- case 11:
- RunQuit();
- break;
- }
- } // end function
- // FOCAL LENGTH MENU – FRAME 0
- void FocalFrame()
- {
- focLength = Inputs[CurrentFrame];
- UpDownAction5(); // adjusts focal length by increments of 5
- FourArrowsDisplay();
- myLcd.setCursor(0, 0);
- myLcd.print("Focal Len (mm) ");
- myLcd.setCursor(7, 1);
- myLcd.print(focLength); // displays the default focal length
- MenuForwardBackAction();
- } // end function
- // PANORAMA WIDTH MENU – FRAME 1
- void PanoFrame()
- {
- panoWidth = Inputs[CurrentFrame];
- UpDownAction5(); // adjusts focal length by increments of 5
- FourArrowsDisplay();
- myLcd.setCursor(0, 0);
- myLcd.print("Pano Width ( ) ");
- myLcd.setCursor(12, 0);
- myLcd.print((char)223); //degree symbol
- myLcd.setCursor(7, 1);
- myLcd.print(panoWidth); // displays the default pano width
- MenuForwardBackAction();
- } // end function
- // NUMBER OF ROWS MENU – FRAME 2
- void RowFrame()
- {
- rowCount = Inputs[CurrentFrame];
- UpDownAction1(); // adjusts focal length by an increment of 1
- FourArrowsDisplay();
- myLcd.setCursor(0, 0);
- myLcd.print("Number of Rows "); // displays the default number of rows
- myLcd.setCursor(7, 1);
- myLcd.print(rowCount); // displays the default number of rows
- MenuForwardBackAction();
- } // end function
- // CAMERA POSITION MENU – FRAME 3
- void CamFrame()
- {
- camVal = Inputs[CurrentFrame];
- UpDownAction1(); // adjusts focal length by an increment of 1
- FourArrowsDisplay();
- myLcd.setCursor(0, 0);
- myLcd.print("Camera Position ");
- myLcd.setCursor(7, 1);
- myLcd.print(camOrient); // displays camera orientation (landscape/portrait)
- PortLandButtonAction();
- MenuForwardBackAction();
- } // end function
- // CALCULATE PANO - FRAME 4
- void AllPanoCalcs()
- {
- //UpDownAction1();
- GoOnArrowDisplay();
- myLcd.setCursor(0, 0);
- myLcd.print("Pano Calcs ");
- // FOV Calcs
- // calculate horizontal FOV (degrees) based on lens focal length
- fovSens = round(2 * atan(sensorWidth / (2 * focLength)) * (180 / PI));
- if (camOrient == 'L') // sets FOV values for landscape-mounted camera
- {
- camFov = fovSens; // sets the calculated width image FOV
- fovHeight = round(fovSens * (0.67 )); // sets the calculated height image FOV
- }
- // calculate portrait FOV (degrees) based on lens focal length
- if (camOrient == 'P') // sets FOV values for portrait-mounted camera
- {
- camFov = round(fovSens * (0.67 )); // adjusts the camera FOV to the calculated portrait FOV
- fovHeight = fovSens;
- }
- // serial print statements for debugging only
- // all serial print statements are cureently commented out with "//"
- // remove "//" to print info to monitor
- // feel free to competely remove serial print statements when all testing complete
- //Serial.print("Cam Orient: "); Serial.println(camOrient);
- //Serial.print("Focal Len: "); Serial.println(focLength);
- //Serial.print("FOV Width: "); Serial.println(camFov);
- //Serial.print("FOV Height: "); Serial.println(fovHeight);
- //Serial.print("Pano Width: "); Serial.println(panoWidth);
- //Serial.print("Row Count: "); Serial.println(rowCount);
- //Serial.print("Horizontal Lap Factor: "); Serial.println(hLapFactor);
- //Serial.print("Vertical Lap Factor: "); Serial.println(vLapFactor);
- //calculate actual FOV after image overlap (rounded up)
- imageWidth = (round(camFov * hLapFactor));
- // Serial.print("Image Width: "); Serial.println(imageWidth);
- imageHeight = (round(fovHeight * vLapFactor));
- //Serial.print("Image Height: "); Serial.println(imageHeight);
- rowTravel = imageHeight;
- // calculate the number of images for the panorama (rounded)
- imageCount = (round(panoWidth / imageWidth));
- // Serial.print("# images "); Serial.println(imageCount); Serial.println();
- if ((imageCount % 2) != 1)
- {
- imageCount = imageCount + 1; // test for odd; if even, add 1
- }
- // Pano Calcs
- // calculate camera moves
- cameraMoves = imageCount - 1;
- // Serial.print("camera moves "); Serial.println(cameraMoves);
- // calculate the degrees between images (rounded up)
- cameraTravel = (round((panoWidth / imageCount) + 0.5));
- // Serial.print("camera travel "); Serial.println(cameraTravel);
- // calculate the actual width of the panorama
- panoWidthActual = cameraTravel * cameraMoves;
- // Serial.print("actual pano width "); Serial.println(panoWidthActual); Serial.println();
- // calculate the horizontal starting position of the panorama
- panoStart = panoHome - (panoWidthActual / 2);
- // Serial.print("start position "); Serial.println(panoStart);
- // calculate actual height of the panorama
- panoHeightActual = rowCount * rowTravel;
- // Serial.println(rowCount);
- // Serial.println(rowTravel);
- // Serial.print("pano height "); Serial.println(panoHeightActual); Serial.println();
- // calculate pano aspect ratio
- aspectRatio = ((panoWidthActual * 100.0) / (panoHeightActual)) / 100.0;
- // Serial.print("pano aspect ratio "); Serial.println(aspectRatio);
- // calculate row moves
- rowMoves = rowCount - 1;
- // Serial.print("row moves "); Serial.println(rowMoves); Serial.println();
- // calculate the vertical starting position of the panorama
- if (rowCount == 1) {
- rowStart = rowHome;
- }
- else if (rowCount == 2) {
- rowStart = rowHome + (imageHeight / 2);
- }
- else if (rowCount > 2) {
- rowStart = rowHome + imageHeight;
- }
- // Serial.print("row start position "); Serial.println(rowStart);
- // calculate approximate time required
- panoTime = (15000L + (8000L * cameraMoves * rowCount) ) + (4500L * rowCount);
- panoMinutes = (panoTime / 60000);
- panoSeconds = ((panoTime - (60000 * panoMinutes)) / 1000);
- MenuForwardBackAction();
- } // end function
- // INFORMATION REVIEW SCREENS
- // Screens preview all info about the pano
- // PANO SIZE REVIEW – FRAME 5
- void ReviewOne()
- {
- myLcd.setCursor(0, 0);
- myLcd.print("Pano Size ");
- myLcd.setCursor(10, 0);
- myLcd.print(panoWidthActual);
- myLcd.write(223);
- myLcd.print("x");
- myLcd.print(panoHeightActual);
- myLcd.write(223);
- GoOnArrowDisplay();
- GoRightAction();
- }
- // PANO RATIO REVIEW – FRAME 6
- void ReviewTwo()
- {
- // myLcd.clear();
- myLcd.setCursor(0, 0);
- int aspect = aspectRatio;
- myLcd.print("Pano Ratio "); myLcd.print(aspect, 1); myLcd.print(":1");
- GoOnArrowDisplay();
- GoRightAction();
- }
- // IMAGE COUNT REVIEW – FRAME 7
- void ReviewThree()
- {
- myLcd.setCursor(0, 0);
- myLcd.print(imageCount); myLcd.print(" Images "); myLcd.print(rowCount); myLcd.print(" Rows");
- GoOnArrowDisplay();
- GoRightAction();
- }
- // EST TIME REVIEW – FRAME 8
- void ReviewFour()
- {
- // myLcd.clear();
- myLcd.setCursor(0, 0);
- myLcd.print("Est Time ");
- myLcd.setCursor(9, 0);
- myLcd.print(panoMinutes);
- myLcd.print("m ");
- myLcd.print(panoSeconds);
- myLcd.print("s");
- GoOnArrowDisplay();
- GoRightAction();
- } // end function
- // RUN OR RESET MENU - FRAME 9
- void RunOrReset()
- {
- //resetAll = Inputs[CurrentFrame];
- myLcd.setCursor(0, 0);
- myLcd.print("RUN PANO? ");
- YesNoArrowDisplay();
- RunResetAction();
- } // end function
- // RUN PANORAMA - FRAME 10
- void PanoRun()
- {
- rowPos = rowStart;
- myLcd.clear();
- myLcd.setCursor(0, 0);
- myLcd.print("Begin pano images");
- delay(1125); // was 1500
- myLcd.setCursor(0, 1);
- myLcd.print("Move to Start");
- // move to row start position
- for (int y = 0; y <= rowMoves; y = y + 1)
- {
- rowPosMicros = map(rowPos, 0, 180, rowServoMin, rowServoMax);
- rowServo.writeMicroseconds(rowPosMicros);
- delay(1500); // was 2000
- rowPos = rowPos - rowTravel;
- // move to pano start position & begin images
- panoPosDegrees = (panoStart); // sets the camera position in degrees
- panoPosMicros = map(panoPosDegrees, 0, 180, imageServoMin, imageServoMax); //change degrees to microseconds (truncated)
- imageServo.writeMicroseconds(panoPosMicros); // moves camera to start position
- delay(4500); // was 6000
- // begin the pano imaging sequence (settle-photo-settle-move)
- x = 0;
- for ( x = 0; x <= cameraMoves; x++) { //
- myLcd.clear();
- myLcd.setCursor(0, 0);
- myLcd.print("Row "); myLcd.print(y + 1); myLcd.print(" of "); myLcd.print(rowCount);
- myLcd.setCursor(0, 1);
- myLcd.print("Image "); myLcd.print(x + 1); myLcd.print(" of "); myLcd.print(imageCount);
- panoPosMicros = map(panoPosDegrees, 0, 180, imageServoMin, imageServoMax); //change degrees to microseconds (truncated)
- imageServo.writeMicroseconds(panoPosMicros); // move camera to next image stop
- delay(3300); // settle camera // was 4500
- digitalWrite(12, HIGH); // shutter on
- delay(75); // was 100
- digitalWrite(12, LOW); // shutter off
- delay(2250); // was 3000
- panoPosDegrees = (panoPosDegrees + cameraTravel); // increment to next camera position
- }
- }
- delay(1125); // was 1500
- imageServo.writeMicroseconds(imageServoHome);
- rowServo.write(rowServoHome);
- delay(3000); // was 4000
- myLcd.clear();
- myLcd.setCursor(1, 0);
- myLcd.print("PANO COMPLETED!");
- delay(1125); // was 1500
- GoOnArrowDisplay();
- if (buttonStateRight = digitalRead(buttonPinRight))
- {
- while (digitalRead(buttonPinRight) == HIGH) {} // wait for right button push
- delay(buttonBounce);
- CurrentFrame = 11;
- myLcd.clear();
- }
- } // end function
- // ANOTHER PANO OR QUIT - FRAME 11
- void RunQuit()
- {
- myLcd.setCursor(0, 0);
- delay(buttonBounce);
- myLcd.print("Another Pano? ");
- YesNoArrowDisplay();
- PanoQuitAction();
- } // end function
- // RESET MENU & VARIABLES
- void ResetMenu()
- {
- Inputs[0] = 50;
- Inputs[1] = 50;
- Inputs[2] = 1;
- camOrient = 'P';
- CurrentFrame = 0; // resets frame count
- myLcd.clear();
- myLcd.print("Resetting ");
- delay(1125); // was 1500
- InputMenu();
- } // end function
- // QUIT PANORAMA AND SHUT DOWN
- void QuitPano()
- {
- myLcd.clear();
- myLcd.setCursor(0, 0);
- myLcd.print("Remove camera "); // prompt to remove camera before storing camera arm
- delay(3000); // was 4000
- GoOnArrowDisplay();
- RightToContinueAction();
- myLcd.setCursor(0, 0);
- myLcd.print("Stow camera arm "); // store camera arm in vertical position
- myLcd.setCursor(0, 1);
- myLcd.print(" ");
- rowServo.writeMicroseconds(rowServoMin);
- delay(3000); // was 4000
- GoOnArrowDisplay();
- RightToContinueAction();
- myLcd.clear();
- myLcd.setCursor(0, 0);
- myLcd.print("Remove Power "); // prompt to remove power
- myLcd.setCursor(0, 1);
- myLcd.print("Good Bye");
- delay(15000); // no change
- OpeningScreen();
- myLcd.clear();
- } // end function
- /************************************************ OPENING FUNCTIONS ********************************************/
- void OpeningScreen()
- {
- // reset key variables
- Inputs[0] = 50; // resets default lens focal length
- Inputs[1] = 50; // resets default pano width
- Inputs[2] = 1; // resets default number of rows
- camOrient = 'P'; // resets default camera orientation
- CurrentFrame = 0; // resets frame count
- // opening screen
- myLcd.clear();
- myLcd.setCursor(0, 0);
- myLcd.print("PANO-XY 4-BUTTON");
- GoOnArrowDisplay();
- RightToContinueAction();
- myLcd.clear();
- // exercise servos
- CameraHome();
- }
- //HOME CAMERA
- void CameraHome()
- {
- delay(500); // no change
- myLcd.clear();
- delay(500); // no change
- myLcd.setCursor(0, 0);
- myLcd.print("Exercise Servo"); // exercise servos and return to home position
- myLcd.setCursor(0, 1);
- myLcd.print("& Set Camera");
- delay(1000); // no change
- // both servos
- rowPosMicros = map(75, 0, 180, rowServoMin, rowServoMax);
- rowServo.writeMicroseconds(rowPosMicros);
- panoPosMicros = map(75, 0, 180, imageServoMin, imageServoMax); //change degrees to microseconds (truncated)
- imageServo.writeMicroseconds(panoPosMicros); // moves camera to 1st exercise position
- delay(2250); // was 3000
- rowPosMicros = map(105, 0, 180, rowServoMin, rowServoMax);
- rowServo.writeMicroseconds(rowPosMicros);
- panoPosMicros = map(105, 0, 180, imageServoMin, imageServoMax); //change degrees to microseconds (truncated)
- imageServo.writeMicroseconds(panoPosMicros); // moves camera to 2nd exercise position
- delay(3300); // was 4500
- rowPosMicros = map(90, 0, 180, rowServoMin, rowServoMax);
- rowServo.writeMicroseconds(rowPosMicros);
- panoPosMicros = map(90, 0, 180, imageServoMin, imageServoMax); //change degrees to microseconds (truncated)
- imageServo.writeMicroseconds(panoPosMicros); // moves camera to HOME position
- delay(2700); //was 3500
- myLcd.clear();
- } // end function
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement