/*********************************************************** * * checkBttnStatus * ***********************************************************/ void TTUI::update() { boolean keyDown = false; boolean hold = false; int hitKeyVal = 0; systemCheck(); //check for stop or reset updateLCD(); //updates the lcd if something needs to change in realtime if(touch.hold() == true) //press and hold key pad { keyDown = true; hold = true; hitKeyVal = touch.getKey(); } if(touch.hit() == true) //just press key pad { keyDown = true; hitKeyVal = touch.readActiveKey(); //read which key was hit } //call a specific function based on which key is pressed if(keyDown == true) { previousMillis_UIPower = millis(); //time key was active keyDown = false; switch (hitKeyVal) { case MODE_BTTN: bttnMode(); break; case SELECT_BTTN: bttnOption(); break; case DOWN_BTTN: bttnDown(hold); break; case UP_BTTN: bttnUp(hold); break; default: //no default option, just here for compiler break; } } if(batteryPower() == true) { uiPowerTimeOut(); //if there has been no activity turn off lcd power } }
/*********************************************************** * * updateLCD * ***********************************************************/ void TTUI::updateLCD() { //only update LCD every 300ms int now = millis()/100; //100 ms int elapsed = now - activeRefreshTime; if(elapsed > 3) //300ms { activeRefreshTime = now; if(trapActive_ == true) { if(batteryPower() == false) //USB connected { clear(); printMode(0); char printBuffer[9]; triggers[currentTrigger]->getActiveMessage(printBuffer); setCursor(0,1); print(printBuffer); } } else if(trapActive_ == false) //waiting for UI input { if(activeMenu == UP_MENU || activeMenu == DOWN_MENU) { clear(); printSelect(0); printInc(1,0); } else if(activeMenu == MODE_MENU || activeMenu == OPTION_MENU) { clear(); printMode(0); printSelect(1); } else if(activeMenu == START_MESSAGE) { clear(); print("TrigTrap"); setCursor(0,1); print("v"); print(FIRMWARE_VERSION); } } } }
/*********************************************************** * * uiPowerOff * ***********************************************************/ void TTUI::uiPowerOff() { if(state_UIPower == true) //power currently on { state_UIPower = false; #ifdef TT_SHIELD touch.clear(); #else detachInterrupt(1); // disable the touch key interrupt I2c.end(); // stop i2c if(batteryPower() == false) //USB connected { //do nothing } else //battery power { // Prevent leakage current: Bring all pins connected to devices on Vsw to ground. // Shutdown LCD noDisplay(); // clear output digitalWrite(A3,LOW); // LCD RS digitalWrite(4,LOW); // LCD RW digitalWrite(5,LOW); // LCD EN digitalWrite(6,LOW); // LCD DB4 digitalWrite(7,LOW); // LCD DB5 digitalWrite(8,LOW); // LCD DB6 digitalWrite(9,LOW); // LCD DB7 analogWrite (10, 0); // LCD Contrast PWM // Shutdown main power to LCD and Touch IC PORTB |= (1<<PORTB6); // turn off Vsw_SW // i2c pins SDA and SCL are already input with internal pullups disabled // KEY_CHG interrupt is already input without pullup } #endif //ifdef TTShield #ifdef SERIAL_DEBUG Serial.println("UI Off"); #endif } }
/*********************************************************** * * trigger * * * ***********************************************************/ boolean BulbRamp::trigger() { unsigned long remainTime; //don't allow zero time delta. Will crash the device if(option(BULB_DELTA) == 0) { incOption(BULB_DELTA,1); } //----------------Duration //if you set a duration limit, stop take pictures when it is reached if(elapsedDuration >= option(BULB_DURATION)) { if(focusActive == false && shutterActive == false) //don't abort if shutter is triggered { elapsedDuration = 0; //clear this for next time abortTrigger = true; return false; } } remainTime = countDown(); //get the remaining time to next shot //calulate the shutterPulseTime. int steps = option(BULB_DURATION) / option(BULB_DELTA); int stepSize = ( option(BULB_ENDEXP) - option(BULB_STARTEXP) ) / steps; shutterPulseTime_ = option(BULB_STARTEXP) + (stepSize * shotCounter_); #ifdef SERIAL_DEBUG Serial.print("pulseTime:"); Serial.println(shutterPulseTime_); #endif //-------------Delay if(delayFirstShot() == true) { return true; } shutter(false,false); //trigger shutter if shutterReady = true, set delay to false, false time unit seconds //----------Sleep if(batteryPower() == true) { if(focusActive == false && shutterActive == false) //don't sleep if shutter is triggered { sleep_->pwrDownMode(); //deepest sleep sleep_->sleepDelay(abortTrigger,remainTime,shotCounter_); remainTime = 0; } } //---------- Shutter if ((long) remainTime < 0 ) {remainTime = 0;} //check for unsigned underflow, by converting to signed if (remainTime <= 0) { //times up,take a shot delayCount = millis(); //start counting till delay is up startBttnTime = delayCount; //don't call millis twice, just use delayCount, reset startButtnTime focusReady = true; shutterReady = true; //set shutter ready, will activate shutter next time through loop IRReady = true; return shutterReady; } else { return false; } }
TTUI::TTUI():LiquidCrystal_SR_LCD3(11, 10, 12 ,2) #else TTUI::TTUI():LiquidCrystal(A3,4,5, 6, 7, 8, 9) #endif { pTTUI = this; //the ptr points to this object trapActive_ = false; } /*********************************************************** * * begin * ***********************************************************/ void TTUI::setup(Trigger *sensors[]) { #ifdef SERIAL_DEBUG Serial.begin(9600); #endif #ifndef SERIAL_DEBUG // USB Serial port configure as input, disable pullup pinMode (0, INPUT); pinMode (1, INPUT); digitalWrite(0, LOW); digitalWrite(1, LOW); #endif analogReference(INTERNAL); //assign sensor[] pointers to triggers[] array for(int i=0;i<NUM_OF_SENSORS;++i) { triggers[i] = sensors[i]; } //TODO: move system menu eeprom settings out of Trigger.cpp into TTUI.cpp triggers[0]->restoreSystem(); //restore system menu settings from trigger 0. Could work with any trigger though boolean focusSetting = triggers[0]->getFocus(); boolean shutterSetting = triggers[0]->getShutter(); boolean hdrshutterSetting = triggers[0]->getHDRShutter(); boolean IRSetting = triggers[0]->getIRShutter(); lcdContrast = triggers[0]->getContrast(); for(uint8_t i=0;i<NUM_OF_SENSORS;++i) { triggers[i]->setIndex(i); triggers[i]->restoreState(); triggers[i]->focusOn(focusSetting); triggers[i]->shutterOn(shutterSetting); triggers[i]->hdrshutterOn(hdrshutterSetting); triggers[i]->IRShutterOn(IRSetting); } systemMenu = NUM_OF_SENSORS; //system Menu is always the last menu, even if you add more sensors incSystemOption = 0; //the current system option menu state trapActive_ = false; startBttnHold = false; currentTrigger = 0; //configure start button pinMode(START_BUTTON, INPUT); // Start Button digitalWrite(START_BUTTON, HIGH); // turn on pullup resistor for Start button #ifdef TT_SHIELD PCintPort::attachInterrupt(START_BUTTON,startDownHandler,FALLING); #else attachInterrupt(0,startDownHandler,FALLING); //trigger ISR function on start button press. #endif //Shutter and Focus pins set to output pinMode(FOCUS_TRIGGER_PIN, OUTPUT); pinMode(SHUTTER_TRIGGER_PIN, OUTPUT); digitalWrite(FOCUS_TRIGGER_PIN, HIGH); // is off digitalWrite(SHUTTER_TRIGGER_PIN, HIGH); // is off //set UI Power #ifndef TT_SHIELD //if TT is normal not Shield DDRB |= (1<<PORTB7); //pinMode(KEY_PAD_LEDS, OUTPUT); // LED on UI DDRB |= (1<<PORTB6); //pinMode(POWER_UI,OUTPUT); #endif state_UIPower = false; uiPowerOn(); //turn on power at startup previousMillis_UIPower = 0; #ifdef TT_SHIELD touch.begin(); #else touch.begin(KEY_CHANGE); //init touch UI with key change interrupt #endif //TT_SHIELD endif activeMenu == START_MESSAGE; //this class inherits from LCD, so call lcd functions as part of this class #ifndef TT_SHIELD //if TT is normal not Shield //LCD Stuff TCCR1B = TCCR1B & 0b11111000 | 0x01; //-- sets the pwm base //pinMode (10, OUTPUT); // lcd contrast output not required to set output for analogWrite if(batteryPower() == true) { // under certain conditions ADC doesnot resart from deep sleep ADCSRA |= (1 << ADEN); // Enable ADC if(lcdContrast == 30) //probably means its from a blank eeprom. { lcdContrast = analogRead(A1); lcdContrast = analogRead(A1); // read twice, toss first // case switch to handle non-linear contrast curve switch (lcdContrast) { case 1 ... 613: // 0v0 to 3v1 lcdContrast = map(lcdContrast, 550, 613, 128, 61); break; case 614 ... 791: // 3v1 to 4v0 lcdContrast = map(lcdContrast, 614, 791, 60, 35); break; case 792 ... 1023: // 4v0 to 5v2 lcdContrast = map(lcdContrast, 792, 1023, 36, 1); break; default: break; } }
TTUI::TTUI():LiquidCrystal_SR_LCD3(11, 10, 12 ,2) #else TTUI::TTUI():LiquidCrystal(A3,4,5, 6, 7, 8, 9) #endif { pTTUI = this; //the ptr points to this object trapActive_ = false; } /*********************************************************** * * begin * ***********************************************************/ void TTUI::setup(Trigger& laser, Trigger& sound, Trigger& light,Trigger& timeLapse, Trigger& aux) { #ifdef SERIAL_DEBUG Serial.begin(9600); #endif #ifndef SERIAL_DEBUG // USB Serial port configure as input, disable pullup pinMode (0, INPUT); pinMode (1, INPUT); digitalWrite(0, LOW); digitalWrite(1, LOW); #endif analogReference(INTERNAL); //set triggers into array triggers[0] = &laser; triggers[1] = &sound; triggers[2] = &light; triggers[3] = &timeLapse; triggers[4] = &aux; triggers[0]->restoreSystem(); //restore system menu settings from trigger 0. Could work with any trigger though boolean focusSetting = triggers[0]->getFocus(); boolean shutterSetting = triggers[0]->getShutter(); boolean IRSetting = triggers[0]->getIRShutter(); for(uint8_t i=0;i<NUM_OF_SENSORS;++i) { triggers[i]->setIndex(i); triggers[i]->restoreState(); triggers[i]->focusOn(focusSetting); triggers[i]->shutterOn(shutterSetting); triggers[i]->IRShutterOn(IRSetting); } systemMenu = NUM_OF_SENSORS; //system Menu is always the last menu, even if you add more sensors incSystemOption = 0; //the current system option menu state trapActive_ = false; startBttnHold = false; currentTrigger = 0; //configure start button pinMode(START_BUTTON, INPUT); // Start Button digitalWrite(START_BUTTON, HIGH); // turn on pullup resistor for Start button #ifdef TT_SHIELD PCintPort::attachInterrupt(START_BUTTON,startDownHandler,FALLING); #else attachInterrupt(0,startDownHandler,FALLING); //trigger ISR function on start button press. #endif //Shutter and Focus pins set to output pinMode(FOCUS_TRIGGER_PIN, OUTPUT); pinMode(SHUTTER_TRIGGER_PIN, OUTPUT); digitalWrite(FOCUS_TRIGGER_PIN, HIGH); // is off digitalWrite(SHUTTER_TRIGGER_PIN, HIGH); // is off //set UI Power #ifndef TT_SHIELD //if TT is normal not Shield DDRB |= (1<<PORTB7); //pinMode(KEY_PAD_LEDS, OUTPUT); // LED on UI DDRB |= (1<<PORTB6); //pinMode(POWER_UI,OUTPUT); #endif state_UIPower = false; uiPowerOn(); //turn on power at startup previousMillis_UIPower = 0; #ifdef TT_SHIELD touch.begin(); #else touch.begin(KEY_CHANGE); //init touch UI with key change interrupt #endif //TT_SHIELD endif activeMenu == START_MESSAGE; //this class inherits from LCD, so call lcd functions as part of this class #ifndef TT_SHIELD //if TT is normal not Shield //LCD Stuff TCCR1B = TCCR1B & 0b11111000 | 0x01; //-- sets the pwm base pinMode (10, OUTPUT); // lcd contrast output if(batteryPower() == true) { long lcdContrast = analogRead(A1); lcdContrast = 175 - ((lcdContrast * 5) / 32); analogWrite (10, lcdContrast); } else { byte lcdContrast = 25; analogWrite (10, lcdContrast); } #endif // END TT if begin(8, 2); // Print a message to the LCD. print("TrigTrap"); setCursor(0,1); print("v"); print(FIRMWARE_VERSION); #ifdef SERIAL_DEBUG Serial.print("TT v"); Serial.println(FIRMWARE_VERSION); #endif interrupts(); //make sure interrupts are on }
/*********************************************************** * * trigger * * * ***********************************************************/ boolean TimeLapse::trigger() { unsigned long remainTime; //don't allow zero time delta. Will crash the device if(option(TIME_DELTA) == 0) { incOption(TIME_DELTA,1); } //----------------NumShot //if you set a shot limit, stop take pictures when it is reached if(shotCounter_ >= option(TIME_NUMSHOTS) && option(TIME_NUMSHOTS) != 0) { if(focusActive == false && shutterActive == false) //don't abort if shutter is triggered { abortTrigger = true; return false; } } remainTime = countDown(); //get the remaining time to next shot //-------------Delay if(delayFirstShot() == true) { return true; } shutter(false,false); //trigger shutter if shutterReady = true, set delay to false, false time unit seconds //----------Sleep if(batteryPower() == true) { if(focusActive == false && shutterActive == false) //don't sleep if shutter is triggered { sleep_->pwrDownMode(); //deepest sleep sleep_->sleepDelay(abortTrigger,remainTime,shotCounter_); remainTime = 0; } } //---------- Shutter if ((long) remainTime < 0 ) {remainTime = 0;} //check for unsigned underflow, by converting to signed if (remainTime <= 0) { //times up,take a shot delayCount = millis(); //start counting till delay is up startBttnTime = delayCount; //don't call millis twice, just use delayCount, reset startButtnTime focusReady = true; shutterReady = true; //set shutter ready, will activate shutter next time through loop IRReady = true; return shutterReady; } else { return false; } }