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)
Diff: Flipper.h
- Revision:
- 0:4b5874bff9bb
- Child:
- 1:4284f27d638d
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Flipper.h Mon Jul 14 09:35:12 2014 +0000 @@ -0,0 +1,178 @@ +#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 \ No newline at end of file