synch the camera trigger with the signal in phase and quadrature (every frame or every N frames). We can also simulate the product by the in-phase signal (with a small arbitrary phase difference)
Flipper.h
- Committer:
- mbedalvaro
- Date:
- 2014-07-14
- Revision:
- 0:4b5874bff9bb
- Child:
- 1:4284f27d638d
File content as of revision 0:4b5874bff9bb:
#ifndef Flipper_h #define Flipper_h #include "mbed.h" #define shutterPin p21 // for tests #define ledPin p22 // the actual modulation of the LED source (equal to PHASE or QUAD signal every N frames) #define cameraTriggerPin p23 // A class for flip()-ing a DigitalOut using a timer //1) Class for toggling the LED (in phase or quadrature, with a multiplier) class Flipper { public: static DigitalOut _pin; static bool state; static bool multiplier;//=true; // this is for simulating the deconvolution // NOTE initialization needs to be in the cpp file, unless it's a const static void delay90() {state = !state; _pin=state;} static void multImmediate() { _pin=state&&multiplier;} Flipper(PinName pin, unsigned int interval): us_interval(interval) { Flipper::_pin=pin; state=true; _pin=state; } void start() { myTicker.attach_us(this, &Flipper::flip, us_interval); // the address of the object, member function, and interval } void stop() { myTicker.detach(); } void flip() { state = !state; _pin=state&&multiplier; } private: unsigned int us_interval; Ticker myTicker; }; // 2) Camera trigger class (NOTE: we are using MODE 2 of Point gray, meaning we control the exposure) class Trigger { friend class Flipper; // because we will call delay90() method public: enum triggerState { WAITING=0, EXPOSE, NUM_STATES }; Trigger(PinName pin, float fps, unsigned int exposure) : _pin(pin) { _pin=1; us_exposureTime=exposure; us_waitingTime=(unsigned int)(1000000.0/fps-us_exposureTime); framesQPToggle=2; // default number of frames before toggling between Q and P signals (delaying the Flipper signal by 90 deg). QP_Mode=true; } void setQPToggleFrames(unsigned int numToggleQPFrames) { framesQPToggle=numToggleQPFrames; } void setFrameRate(float fps) { us_waitingTime=(unsigned int)(1000000.0/fps-us_exposureTime); } void setExposure(unsigned int exposure) { us_exposureTime=exposure; } void start() { // We start in WAITING and go to EXPOSE myTimer.attach_us(this, &Trigger::trigger, us_waitingTime); // the address of the object, member function, and interval myTriggerState=WAITING; frameCounter=0; } void toggleQP(bool mode) { QP_Mode=mode; } void stop() { myTimer.detach(); } void trigger() { switch(myTriggerState) { case WAITING: // if the state was "wait" and we got here, we need to start exposing: _pin=0; // a high-low change triggers the camera // now we need to reset the timeout and give it another value: myTimer.attach_us(this, &Trigger::trigger, us_exposureTime); myTriggerState=EXPOSE; break; case EXPOSE: // if the state was EXPOSE, we need to stop exposing and go to wait: _pin=1; // a low-high stop exposing // now we need to reset the timeout and give it another value: myTimer.attach_us(this, &Trigger::trigger, us_waitingTime); myTriggerState=WAITING; // Also, this means we acquired ONE frame... // Switch the from phase to quadrature int the friend class Flipper, every N frames (if we want): frameCounter=(frameCounter+1)%framesQPToggle; if (QP_Mode&&frameCounter==0) { //Flipper::state = ! Flipper::state ; // this correspond to calling the flip function (but without multiplier) Flipper::delay90(); } break; default: break; } } private: DigitalOut _pin; bool QP_Mode; // this is to select toggling or not triggerState myTriggerState; unsigned int frameCounter; unsigned int framesQPToggle; unsigned int us_exposureTime, us_waitingTime; Timeout myTimer; // I need to use a timeout, and not a ticker because the intervals are different for the trigger period and exposure time }; // 3) The simulation of the LCD shutter: class Shutter{ friend class Flipper; // because we will modify the Flipper variable "multiplier" public: // Note: we don't really need a toggling pin for this, but it can be good to see it on the oscilloscope Shutter(PinName pin, unsigned int interval) : _pin(pin), us_interval(interval) { state=true; _pin=state; mix=true; } void start() { myTicker.attach_us(this, &Shutter::flip, us_interval); // the address of the object, member function, and interval } void mixSignal(bool mode) { mix=mode; } void stop() { myTicker.detach(); } // the shutter "flip" function also affect the friend variable "multiplier": void flip() { state = !state; _pin=state; if (mix) { Flipper::multiplier=state; } else { Flipper::multiplier=true; } Flipper::multImmediate(); } private: bool mix; // this is for mixing this signal with the led (ie, product) bool state; DigitalOut _pin; unsigned int us_interval; Ticker myTicker; }; #endif