2014年12月18日 星期四

趕製《縮時拍攝裝置》・四


把最後的 BLE mini 也焊接好後,零件部份已經完工。接著是外殼及軟件部份。而軟件部份又分為 Arduino 端及 iOS 端。iOS 端目前可以用《AMIGO Controller》來頂上。外殼內部空間加大了,底板沒有卡著。加高了筒的尺寸,耳機接口有足夠空間。同時也留了放置電線的地方。接著搞 Arduino 部份。

在紙上考慮好需要的指令,定義出相關的參數,以最簡單的方式編寫 Arduino 程式。雖然 delay 指令會佔領著時間,無法做出分工工作,但時間緊迫,暫時使用。以下是目前為止的代碼:
//========================================================================
//  AMIGO Timelapse for Arduino
//------------------------------------------------------------------------
//  Created by Pacess on 2014-12-17
//  Copyright (c) 2014 Hotaru Productions Company.  All rights reserved.
//========================================================================

//------------------------------------------------------------------------
//  0    1         2         3         4         5         6         7
//  5678901234567890123456789012345678901234567890123456789012345678901234

#include <SoftwareSerial.h>

//------------------------------------------------------------------------
//  Command list
//------------------------------------------------------------------------
//   ! means end of command
//
//   Input:  Capital letters for Bluetooth to Arduino
//     O!     = Shutter open
//     C!     = Shutter close
//     F!     = Focus
//     O0000! = Set shutter open duration
//     C0000! = Set shutter close duration
//     R!     = Reset frame counter
//     I!     = Get current information and settings
//     G!     = Go according to the settings
//
//   Output:  Small letters for Arduino to Bluetooth
//     f0000o0000c0000! = Frames taken, Shutter open duration, Shutter close duration
//------------------------------------------------------------------------

//  Defines
const int PORT_LED = 13;

const int PORT_BLUETOOTH_RX = 10;
const int PORT_BLUETOOTH_TX = 11;

const int PORT_SHUTTER = 4;
const int PORT_FOCUS = 3;

const int ONE_SECOND = 1000;

const unsigned int BAUDRATE_ARDUINO = 57600;
const unsigned int BAUDRATE_BLUETOOTH = 57600;

//------------------------------------------------------------------------
//  Global variables
SoftwareSerial bluetoothSerial(PORT_BLUETOOTH_RX, PORT_BLUETOOTH_TX);

int ledValue = HIGH;

//  1 = One second
unsigned int shutterOpenDuration = 1;
unsigned int shutterCloseDuration = 59;
unsigned int framesTaken = 0;

//========================================================================
void setup()  {
   pinMode(PORT_LED, OUTPUT);
   pinMode(PORT_FOCUS, OUTPUT);
   pinMode(PORT_SHUTTER, OUTPUT);

   //  Make sure pin is low
   digitalWrite(PORT_FOCUS, LOW);
   digitalWrite(PORT_SHUTTER, LOW);
   delay(ONE_SECOND/4);

   //------------------------------------------------------------------------
   //  Open onboard serial communication
   Serial.begin(BAUDRATE_ARDUINO);

   //  Wait for serial port to connect.  Needed for Leonardo only
   while (!Serial);
    Serial.println("AMIGO Timelapse is ready!");

   //  Set my data rate for SoftwareSerial port
   bluetoothSerial.begin(BAUDRATE_BLUETOOTH);
   bluetoothSerial.println("AMIGO Timelapse connected.");
}

//------------------------------------------------------------------------
//  Toggle LED light
void toggleLED()  {
   if (ledValue == HIGH)  {ledValue = LOW;}
   else  {ledValue = HIGH;}
   digitalWrite(PORT_LED, ledValue);
}

//------------------------------------------------------------------------
char readSerialByte()  {
   char data = 0;
   while (1)  {
      if (bluetoothSerial.available())  {data = bluetoothSerial.read();  break;}
      else if (Serial.available())  {data = Serial.read();  break;}
   }

   Serial.write(data);
   return data;
}

//------------------------------------------------------------------------
void openShutter()  {
   toggleLED();
   digitalWrite(PORT_SHUTTER, HIGH);
}

//------------------------------------------------------------------------
void closeShutter()  {
   toggleLED();
   digitalWrite(PORT_SHUTTER, LOW);
}

//------------------------------------------------------------------------
void focusNow()  {
   toggleLED();
   digitalWrite(PORT_SHUTTER, HIGH);  delay(ONE_SECOND);
   digitalWrite(PORT_SHUTTER, LOW);
}

//------------------------------------------------------------------------
void loop()  {

   //  Read byte from serial ports
   char dataByte = readSerialByte();

   //------------------------------------------------------------------------
   //  Process command
   switch (dataByte)  {

      default:  {
         //Serial.print("# ");  Serial.println(dataByte, DEC);
      }  break;

      //------------------------------------------------------------------------
      case 'O':  {
         dataByte = readSerialByte();
         if (dataByte == '!')  {

            //  This is an immediate action (O!)
            openShutter();
            Serial.println("OK");
            break;
         }

         //  This should be setting (O0000!)
         unsigned int value = 0;
         do  {

            value = (value<<8)|dataByte;

            //  Read the rest bytes
            dataByte = readSerialByte()-'0';

         }  while (dataByte != '!');
         shutterOpenDuration = value;

         Serial.print(shutterOpenDuration, DEC);  Serial.println(" OK");
      }  break;

      //------------------------------------------------------------------------
      case 'C':  {
         dataByte = readSerialByte();
         if (dataByte == '!')  {

            //  This is an immediate action (C!)
            closeShutter();
            Serial.println("OK");
            break;
         }

         //  This should be setting (C0000!)
         unsigned int value = 0;
         do  {

            value = (value<<8)|dataByte;

            //  Read the rest bytes
            dataByte = readSerialByte()-'0';

         }  while (dataByte != '!');
         shutterCloseDuration = value;

         Serial.print(shutterCloseDuration, DEC);  Serial.println(" OK");
      }  break;

      //------------------------------------------------------------------------
      case 'F':  {
         dataByte = readSerialByte();
         if (dataByte != '!')  {break;}

         focusNow();
         Serial.println("OK");
      }  break;

      //------------------------------------------------------------------------
      case 'R':  {
         dataByte = readSerialByte();
         if (dataByte != '!')  {break;}

         framesTaken = 0;
         Serial.println("OK");
      }  break;

      //------------------------------------------------------------------------
      case 'I':  {
         dataByte = readSerialByte();
         if (dataByte != '!')  {break;}

         bluetoothSerial.print("f");
         bluetoothSerial.print(framesTaken, DEC);
         bluetoothSerial.print("o");
         bluetoothSerial.print(shutterOpenDuration, DEC);
         bluetoothSerial.print("c");
         bluetoothSerial.print(shutterCloseDuration, DEC);
         bluetoothSerial.println();

         Serial.print("f");
         Serial.print(framesTaken, DEC);
         Serial.print("o");
         Serial.print(shutterOpenDuration, DEC);
         Serial.print("c");
         Serial.println(shutterCloseDuration, DEC);
      }  break;

      //------------------------------------------------------------------------
      case 'G':  {
         dataByte = readSerialByte();
         if (dataByte != '!')  {break;}

         bluetoothSerial.print("Start ");
         bluetoothSerial.print(shutterOpenDuration, DEC);
         bluetoothSerial.print(" vs ");
         bluetoothSerial.print(shutterCloseDuration, DEC);
         bluetoothSerial.println();

         Serial.print("Start O");
         Serial.print(shutterOpenDuration, DEC);
         Serial.print(" vs C");
         Serial.print(shutterCloseDuration, DEC);
         Serial.println();

         framesTaken = 0;
         while (1)  {

            Serial.print("Open #");
            Serial.println(framesTaken, DEC);

            openShutter();
            delay(shutterOpenDuration*1000);

            Serial.print("Close #");
            Serial.println(framesTaken, DEC);

            closeShutter();
            delay(shutterCloseDuration*1000);

            framesTaken++;

            if (bluetoothSerial.available())  {break;}
            else if (Serial.available())  {break;}
         }
         Serial.println("OK");
      }  break;
   }
}

沒有留言: