/* Digital camera controller board test sketch */ //#include #include #include #include #include #include #include #include #include "camcontroller.h" #include "controls.h" #include "eoseventparser.h" #include "dataitem.h" #include "screenitem.h" #include "screen.h" #include "menu.h" #include "hdrcapture.h" #define DEV_ADDR 1 // Canon EOS 400D #define DATA_IN_EP 1 #define DATA_OUT_EP 2 #define INTERRUPT_EP 3 #define CONFIG_NUM 1 #define EEP_APERTURE_LIST_OFFSET 0 #define EEP_APERTURE_LIST_SIZE 32 #define EEP_SHTSPEED_LIST_OFFSET (EEP_APERTURE_LIST_OFFSET + EEP_APERTURE_LIST_SIZE) #define EEP_SHTSPEED_LIST_SIZE 64 #define EEP_WBALANCE_LIST_OFFSET (EEP_SHTSPEED_LIST_OFFSET + EEP_SHTSPEED_LIST_SIZE) #define EEP_WBALANCE_LIST_SIZE 12 #define EEP_PICSTYLE_LIST_OFFSET (EEP_WBALANCE_LIST_OFFSET + EEP_WBALANCE_LIST_SIZE) #define EEP_PICSTYLE_LIST_SIZE 12 #define EEP_EXPOCOR_LIST_OFFSET (EEP_PICSTYLE_LIST_OFFSET + EEP_PICSTYLE_LIST_SIZE) #define EEP_EXPOCOR_LIST_SIZE 48 #define EEP_ISO_LIST_OFFSET (EEP_EXPOCOR_LIST_OFFSET + EEP_EXPOCOR_LIST_SIZE) #define EEP_ISO_LIST_SIZE 8 EEPROMByteList vlAperture(EEP_APERTURE_LIST_OFFSET, EEP_APERTURE_LIST_SIZE); EEPROMByteList vlShutterSpeed(EEP_SHTSPEED_LIST_OFFSET, EEP_SHTSPEED_LIST_SIZE); EEPROMByteList vlWhiteBalance(EEP_WBALANCE_LIST_OFFSET, EEP_WBALANCE_LIST_SIZE); EEPROMByteList vlPictureStyle(EEP_PICSTYLE_LIST_OFFSET, EEP_PICSTYLE_LIST_SIZE); EEPROMByteList vlIso(EEP_ISO_LIST_OFFSET, EEP_ISO_LIST_SIZE); EEPROMByteList vlExpCompensation(EEP_EXPOCOR_LIST_OFFSET, EEP_EXPOCOR_LIST_SIZE); class CamStateHandlers : public EOSStateHandlers { bool stateConnected; public: CamStateHandlers() : stateConnected(false) {}; virtual void OnDeviceDisconnectedState(PTP *ptp); virtual void OnDeviceInitializedState(PTP *ptp); }; class CamHDRCapture : public HDRCapture { public: CamHDRCapture(CanonEOS &eos) : HDRCapture(eos) {}; protected: virtual void OnFrameCaptured(uint16_t left); virtual void OnSelfTimerProgress(uint32_t left); virtual void OnIntrTimerProgress(uint32_t left); }; CamStateHandlers CamStates; Max_LCD LCD; SimpleTimer ControlTimer, PTPPollTimer; CanonEOS Eos(DEV_ADDR, DATA_IN_EP, DATA_OUT_EP, INTERRUPT_EP, CONFIG_NUM, &CamStates); CamHDRCapture hdrCapture(Eos); GPInRegister ExtControls(Eos.GetMax()); QEvent evtTick, evtAbort; //--- (0) Message Screen ---------------------------------------------------------------------- PgmStringDataItem diFirst(msgCamera); PgmStringDataItem diSecond(msgDisconnected); ScreenItem siFirst (5, 0, 16, false, &diFirst); ScreenItem siSecond (2, 1, 16, false, &diSecond); ScreenItem *messageScreenItems[] PROGMEM = { &siFirst, &siSecond }; Screen messageScreen(2, (ScreenItem*)messageScreenItems); //--- (1) Main Menu Screen -------------------------------------------------------------------- ScreenItem siIntervalometer (1, 0, 8, true, (const char*)&msgIntervalometer); ScreenItem siSettings (1, 1, 8, false, (const char*)&msgSettings); ScreenItem *mainMenuScreenItems[] PROGMEM = { &siIntervalometer, &siSettings }; Screen scrMainMenu(2, (ScreenItem*)mainMenuScreenItems); //--- (2) Timer Menu Screen ------------------------------------------------------------------- ScreenItem siSelf (1, 0, 4, true, (const char*)&msgSetSelf); ScreenItem siFrames (1, 1, 4, false, (const char*)&msgSetFrames); ScreenItem siBkt (6, 0, 3, false, (const char*)&msgSetBkt); ScreenItem siInterval (6, 1, 3, false, (const char*)&msgSetInterval); ScreenItem siRun (10, 0, 4, false, (const char*)&msgSetRun); ScreenItem siExit (10, 1, 4, false, (const char*)&msgExit); ScreenItem *timerSettingsScreenItems[] PROGMEM = { &siSelf, &siFrames, &siBkt, &siInterval, &siRun, &siExit }; Screen timerSettingsScreen(6, (ScreenItem*)timerSettingsScreenItems); //--- (3) Self Timer Screen ------------------------------------------------------------------- DIT_TIMER_DIGIT_PAIR diHourSelf(0), diHourInt(0), diMinSelf(0), diMinInt(0), diSecSelf(0), diSecInt(0); ScreenItem siSelfTimer(0, 0, 16, false, (const char*)&msgSelfTimer); ScreenItem siHourSelf(3, 1, 2, false, &diHourSelf); ScreenItem siMinSelf (6, 1, 2, false, &diMinSelf); ScreenItem siSecSelf (9, 1, 2, false, &diSecSelf); ScreenItem *scitmSelfTimerSet[] PROGMEM = { &siSelfTimer, &siHourSelf, &siMinSelf, &siSecSelf }; Screen scrSelfTimerSet(4, (ScreenItem*)scitmSelfTimerSet); //--- (4) Number of Frames Screen ------------------------------------------------------------- IntDataItem diFramesCount(0); IntDataItem diFramesLeft(0); ScreenItem siFramesText (5, 0, 6, false, (const char*)&msgCntFrames); ScreenItem siFramesCount (6, 1, 4, false, &diFramesCount); ScreenItem *scitmFramesSet[] PROGMEM = { &siFramesText, &siFramesCount }; Screen scrFramesSet(2, (ScreenItem*)scitmFramesSet); //--- (5) Bracketing Screen ------------------------------------------------------------------- KeyValuePairDataItem diBktEV(0, ExpCompTitles); KeyValuePairDataItem diBktStep(0, ExpCompTitles); uint8_t nBktStep; uint8_t nBktNegativeIndex; uint8_t nBktPositiveIndex; ScreenItem siBracketing(0, 0, 15, false, (const char*)&msgBracketing); ScreenItem siBktEV (1, 1, 6, false, &diBktEV); ScreenItem siBktStep (9, 1, 6, false, &diBktStep); ScreenItem *scitmBkt[] PROGMEM = { &siBracketing, &siBktEV, &siBktStep }; Screen scrBktSet(3, (ScreenItem*)scitmBkt); //--- (6) Interval Timer Screen --------------------------------------------------------------- ScreenItem siIntTimer(0, 0, 16, false, (const char*)&msgIntTimer); ScreenItem siHourInt(3, 1, 2, false, &diHourInt); ScreenItem siMinInt (6, 1, 2, false, &diMinInt); ScreenItem siSecInt (9, 1, 2, false, &diSecInt); ScreenItem *scitmIntTimerSet[] PROGMEM = { &siIntTimer, &siHourInt, &siMinInt, &siSecInt }; Screen scrIntTimerSet(4, (ScreenItem*)scitmIntTimerSet); //--- (7) Run Screen --------------------------------------------------------------------------- TimeSpanDataItem diLeftTimer(0); TimeSpanDataItem diIntTimer(0); ScreenItem siRunLeftTime( 0, 0, 8, false, &diLeftTimer); ScreenItem siRunIntTime( 0, 1, 8, false, &diIntTimer); ScreenItem siRunFramesLeft ( 10, 0, 4, false, &diFramesLeft); ScreenItem siAbort(10, 1, 5, false, (const char*)&msgAbort); ScreenItem *scitmRun[] PROGMEM = { &siRunLeftTime, &siRunIntTime, &siRunFramesLeft, &siAbort }; Screen scrRun(4, (ScreenItem*)scitmRun); //--- (8) Camera Settings Screen --------------------------------------------------------------- DIT_MODE diMode(0, ModeTitles); DIT_APERTURE diAperture(0, ApertureTitles); DIT_WB diWb(0, WbTitles); DIT_SHUTTER_SPEED diShutterSpeed(0, ShutterSpeedTitles); DIT_PSTYLE diPStyle(0, PStyleTitles); DIT_ISO diIso(0, IsoTitles); DIT_EXPCOMP diExpComp(0, ExpCompTitles); ScreenItem siMode ( 0, 0, 3, false, &diMode); ScreenItem siAperture ( 0, 1, 3, false, &diAperture); ScreenItem siWb ( 4, 0, 3, false, &diWb); ScreenItem siShutterSpeed( 4, 1, 4, false, &diShutterSpeed); ScreenItem siPStyle ( 8, 0, 3, false, &diPStyle); ScreenItem siIso (12, 0, 4, false, &diIso); ScreenItem siExpComp ( 9, 1, 6, false, &diExpComp); ScreenItem *scitmSettings[] PROGMEM = { &siMode, &siAperture, &siWb, &siShutterSpeed, &siPStyle, &siIso, &siExpComp }; Screen scrSettings(7, (ScreenItem*)scitmSettings); IntSpin hourSpinSelf(0, 99, 1, &diHourSelf, NULL); IntSpin minSpinSelf(0, 99, 1, &diMinSelf, NULL); IntSpin secSpinSelf(0, 99, 1, &diSecSelf, NULL); IntSpin hourSpinInt(0, 99, 1, &diHourInt, NULL); IntSpin minSpinInt(0, 99, 1, &diMinInt, NULL); IntSpin secSpinInt(0, 99, 1, &diSecInt, NULL); void SpinSetAperture(DataItemBase *data_item) { Eos.SetProperty(EOS_DPC_Aperture, ((DIT_APERTURE*)data_item)->Get()); }; void SpinSetShutterSpeed(DataItemBase *data_item) { Eos.SetProperty(EOS_DPC_ShutterSpeed, ((DIT_SHUTTER_SPEED*)data_item)->Get()); }; void SpinSetWb(DataItemBase *data_item) { Eos.SetProperty(EOS_DPC_WhiteBalance, ((DIT_WB*)data_item)->Get()); }; void SpinSetPStyle(DataItemBase *data_item) { Eos.SetProperty(EOS_DPC_PictureStyle, ((DIT_PSTYLE*)data_item)->Get()); }; void SpinSetIso(DataItemBase *data_item) { Eos.SetProperty(EOS_DPC_Iso, ((DIT_ISO*)data_item)->Get()); }; void SpinSetExpComp(DataItemBase *data_item) { Eos.SetProperty(EOS_DPC_ExposureCompensation, ((DIT_EXPCOMP*)data_item)->Get()); }; void SpinUpdateBktStepValues(DataItemBase *data_item); void SpinUpdateBktStep(DataItemBase *data_item); EEPROMListIntSpin spinAperture(&vlAperture, &diAperture, &SpinSetAperture); EEPROMListIntSpin spinShutterSpeed(&vlShutterSpeed, &diShutterSpeed, &SpinSetShutterSpeed); EEPROMListIntSpin spinWb(&vlWhiteBalance, &diWb, &SpinSetWb); EEPROMListIntSpin spinPStyle(&vlPictureStyle, &diPStyle, &SpinSetPStyle); EEPROMListIntSpin spinIso(&vlIso, &diIso, &SpinSetIso); EEPROMListIntSpin spinExpComp(&vlExpCompensation, &diExpComp, &SpinSetExpComp); EEPROMListIntSpin spinBktEV (&vlExpCompensation, &diBktEV, &SpinUpdateBktStepValues); BKT_STEP_VALUE_LIST vlExpCompStep; SRAMListIntSpin spinBktStep(&vlExpCompStep, &diBktStep, &SpinUpdateBktStep); void SpinUpdateBktStepValues(DataItemBase *data_item) { uint8_t cur_value = ((EXP_COMP_DATA_ITEM*)data_item)->Get(); vlExpCompStep.SetSize(0); // Check value for zerro. Exit on zerro. if (cur_value == 0) return; // Calculate negative and positive values of expo compensation uint8_t negative_value = (cur_value & 0x80) ? cur_value : ~(cur_value - 1); uint8_t positive_value = (cur_value & 0x80) ? ~(cur_value - 1) : cur_value; // Get indices of negative and positive expo compensation values uint16_t negative_index = vlExpCompensation.GetValueIndex(negative_value); uint16_t positive_index = vlExpCompensation.GetValueIndex(positive_value); nBktNegativeIndex = negative_index; nBktPositiveIndex = positive_index; // Calculate interval length uint16_t len = positive_index - negative_index; // Calculate zerro value index uint16_t zerro_index = vlExpCompensation.GetValueIndex(0); // Calculate positive index offset uint16_t zerro_based_offset = positive_index - zerro_index; // Calculate all possible interval indices for (uint16_t i = zerro_based_offset, j = positive_index; i>0; i--, j--) { // Insert values into the list if (len % i == 0) vlExpCompStep.Append(vlExpCompensation.Get(j)); } diBktStep.Set(cur_value); diBktStep.SetUpdated(true); }; void SpinUpdateBktStep(DataItemBase *data_item) { uint8_t cur_value = ((EXP_COMP_DATA_ITEM*)data_item)->Get(); nBktStep = vlExpCompensation.GetValueIndex(cur_value) - vlExpCompensation.GetValueIndex(0); }; void MenuExit(); void MenuSetAperture(); void MenuSetShutterSpeed(); void MenuSetWb(); void MenuSetPStyle(); void MenuSetIso(); void MenuSetExpComp(); extern Menu mainMenu; //--- Camera Settings Menu ----------------------------------------------------------------- MenuItem settingsMenuItems[] = { {&siMode, &MenuExit}, {&siAperture, &MenuSetAperture}, {&siWb, &MenuSetWb}, {&siShutterSpeed, &MenuSetShutterSpeed}, {&siPStyle, &MenuSetPStyle}, {&siIso, &MenuSetIso}, {&siExpComp, &MenuSetExpComp} }; Menu settingsMenu(8, 7, settingsMenuItems, 0, &mainMenu); void MenuSetAperture() { spinAperture.SetReturnState(&settingsMenu); StateMachine::SetState(&spinAperture); }; void MenuSetShutterSpeed() { spinShutterSpeed.SetReturnState(&settingsMenu); StateMachine::SetState(&spinShutterSpeed); }; void MenuSetWb(){ spinWb.SetReturnState(&settingsMenu); StateMachine::SetState(&spinWb); }; void MenuSetPStyle(){ spinPStyle.SetReturnState(&settingsMenu); StateMachine::SetState(&spinPStyle); }; void MenuSetIso(){ spinIso.SetReturnState(&settingsMenu); StateMachine::SetState(&spinIso); }; void MenuSetExpComp(){ spinExpComp.SetReturnState(&mainMenu); StateMachine::SetState(&spinExpComp); }; //--- Self Timer Menu ---------------------------------------------------------------------- void MenuSelfSetH(); void MenuSelfSetM(); void MenuSelfSetS(); extern Menu timerSettingsMenu; MenuItem selfSetMenuItems[] = { {&siHourSelf, &MenuSelfSetH}, {&siMinSelf, &MenuSelfSetM}, {&siSecSelf, &MenuSelfSetS} }; Menu selfSetMenu(3, 3, selfSetMenuItems, 0, &timerSettingsMenu); void MenuSelfSetH() { hourSpinSelf.SetReturnState(&selfSetMenu); StateMachine::SetState(&hourSpinSelf); }; void MenuSelfSetM() { minSpinSelf.SetReturnState(&selfSetMenu); StateMachine::SetState(&minSpinSelf); }; //--- Timer Settings Menu ------------------------------------------------------------------ void MenuSelf(); void MenuBkt(); void MenuFrames(); void MenuInterval(); void MenuExit(); void MenuRun(); MenuItem timerSettingsMenuItems[] = { {&siSelf, &MenuSelf}, {&siFrames, &MenuFrames}, {&siBkt, &MenuBkt}, {&siInterval, &MenuInterval}, {&siRun, &MenuRun}, {&siExit, &MenuExit} }; Menu timerSettingsMenu(2, 6, timerSettingsMenuItems, 0, &mainMenu); void MenuSelfSetS() { secSpinSelf.SetReturnState(&timerSettingsMenu); StateMachine::SetState(&secSpinSelf); }; void MenuSelf() { StateMachine::SetState(&selfSetMenu); }; void MenuBktSetStep(); void MenuBktStepExit(); MenuItem bktSetMenuItems[] = { {&siBktEV, &MenuBktSetStep}, {&siBktStep, &MenuBktStepExit} }; Menu bktSetMenu(5, 2, bktSetMenuItems, 0, &timerSettingsMenu); void MenuBktSetStep() { spinBktEV.SetReturnState(&bktSetMenu); if (vlExpCompensation.GetSize()) StateMachine::SetState(&spinBktEV); }; void MenuBktStepExit() { spinBktStep.SetReturnState(&timerSettingsMenu); if (vlExpCompensation.GetSize()) StateMachine::SetState(&spinBktStep); }; void MenuBkt() { if (vlExpCompensation.GetSize()) StateMachine::SetState(&bktSetMenu); }; IntSpin, int16_t> framesSpin(0, 9999, 1, &diFramesCount, NULL); void MenuFrames() { framesSpin.SetReturnState(&timerSettingsMenu); Screen::Set(4); StateMachine::SetState(&framesSpin); }; void MenuIntSetH(); void MenuIntSetM(); void MenuIntSetS(); MenuItem intSetMenuItems[] = { {&siHourInt, &MenuIntSetH}, {&siMinInt, &MenuIntSetM}, {&siSecInt, &MenuIntSetS} }; Menu intSetMenu(6, 3, intSetMenuItems, 0, &timerSettingsMenu); void MenuIntSetH() { hourSpinInt.SetReturnState(&intSetMenu); StateMachine::SetState(&hourSpinInt); }; void MenuIntSetM() { minSpinInt.SetReturnState(&intSetMenu); StateMachine::SetState(&minSpinInt); }; void MenuIntSetS() { secSpinInt.SetReturnState(&timerSettingsMenu); StateMachine::SetState(&secSpinInt); }; void MenuInterval() { StateMachine::SetState(&intSetMenu); }; void MenuRunAbort() { hdrCapture.PostEvent(&evtAbort); diFramesLeft.Set(0); StateMachine::SetState(&timerSettingsMenu); }; MenuItem runMenuItems[] = { {&siAbort, &MenuRunAbort} }; Menu runMenu(7, 1, runMenuItems, 0); void MenuRun() { if (!diFramesCount.Get()) return; uint32_t intr_timeout = ((uint32_t)diHourInt.Get() * 3600 + (uint32_t)diMinInt.Get() * 60 + (uint32_t)diSecInt.Get()); uint32_t self_timeout = ((uint32_t)diHourSelf.Get() * 3600 + (uint32_t)diMinSelf.Get() * 60 + (uint32_t)diSecSelf.Get()); diFramesLeft.Set(diFramesCount.Get()); diLeftTimer.Set(self_timeout); diIntTimer.Set(intr_timeout); SetEvt setEvt; setEvt.sig = SET_FRAMES_SIG; setEvt.value = diFramesCount.Get(); hdrCapture.dispatch(&setEvt); setEvt.sig = SET_FRAME_TIMEOUT_SIG; setEvt.value = intr_timeout; hdrCapture.dispatch(&setEvt); setEvt.sig = SET_SELF_TIMEOUT_SIG; setEvt.value = self_timeout; hdrCapture.dispatch(&setEvt); SetBktEvt setBktEvt; setBktEvt.sig = SET_BRACKETING_SIG; setBktEvt.step = nBktStep; setBktEvt.negative = nBktNegativeIndex; setBktEvt.positive = nBktPositiveIndex; hdrCapture.dispatch(&setBktEvt); StateMachine::SetState(&runMenu); setEvt.sig = RUN_SIG; hdrCapture.dispatch(&setEvt); }; //--- Main Menu ---------------------------------------------------------------------------- void MenuIntervalometer() { StateMachine::SetState(&timerSettingsMenu); }; void MenuSettings() { StateMachine::SetState(&settingsMenu); }; MenuItem mainMenuItems[] = { {&siIntervalometer, &MenuIntervalometer}, {&siSettings, &MenuSettings} }; Menu mainMenu(1, 2, mainMenuItems, 0); void MenuExit() { StateMachine::SetState(&mainMenu); }; class DummyMenu : public StateMachine { public: virtual bool OnInitialState() { Screen::Set(0); return true; }; } DisconnectedState; void CamStateHandlers::OnDeviceDisconnectedState(PTP *ptp) { if (stateConnected) { stateConnected = false; PTPPollTimer.Disable(); StateMachine::SetState(&DisconnectedState); } } void CamStateHandlers::OnDeviceInitializedState(PTP *ptp) { if (!stateConnected) { stateConnected = true; PTPPollTimer.Enable(); StateMachine::SetState(&mainMenu); } hdrCapture.Run(); } void CamHDRCapture::OnFrameCaptured(uint16_t left) { diFramesLeft.Set(left); if (!left) StateMachine::SetState(&timerSettingsMenu); } void CamHDRCapture::OnSelfTimerProgress(uint32_t left) { diLeftTimer.Set(left); } void CamHDRCapture::OnIntrTimerProgress(uint32_t left) { diIntTimer.Set(left); } void OnControlTimer() { ExtControls.CheckControls(); hdrCapture.PostEvent(&evtTick); Screen::Run(&LCD); } void OnPTPPollTimer() { EOSEventParser prs; Eos.EventCheck(&prs); diLeftTimer.SetUpdated(true); diIntTimer.SetUpdated(true); } void setup() { StateMachine::SetState(&DisconnectedState); #ifdef PTPDEBUG Serial.begin(115200); #endif Eos.Setup(); delay( 200 ); // set up the LCD's number of rows and columns: LCD.begin(16, 2); LCD.clear(); LCD.home(); LCD.setCursor(0,0); PTPPollTimer.Set(OnPTPPollTimer, 300); // 1ms is the perfect interval for encoder polling ControlTimer.Set(OnControlTimer, 1); ControlTimer.Enable(); evtTick.sig = TICK_MILLIS_SIG; evtAbort.sig = ABORT_SIG; hdrCapture.init(); #ifdef PTPDEBUG Serial.println("Start"); #endif } void loop() { Eos.Task(); PTPPollTimer.Run(); ControlTimer.Run(); }