Hi guys. I’m trying to build some camera control gear to move a focus puller in intervals between exposures with a small gear motor. Starting with the code from OpenMoco.org, here is what I’ve got, modified in that the variables are input via Serial and can thus change (and this code has been removed to simplify my question here). I want to use MSTimer to engage the motor during the interval time and generally organize the order of what happens in my program and thus with my gear. I need the sequence of events to be:
- Focus
- Exposure
- Delay
- Interval
- Focus
- Exposure
- Delay
- Interval
…etc.
So a complete cycle is <focus, exposure, delay, interval>. Typical values would be focus=500ms, exposure=5000ms, delay = 800ms, and interval=2000ms. And again, I want the motor to be on during the Interval time, but the motor cannot be on during Exposure. Once started it should loop cycle after cycle. I’dd eventually like to add physical start and stop buttons but for now I’ll just disengage the power supply to stop it.
#include <MsTimer2.h>
int CAMERA_PIN = 13;
int MotorPin = 9;
int FocusPin = 8;
//last time our camera fired
unsigned long last_tm = 0;
// whether or not we're currently exposing
bool exposing = false;
//variable for Exposure (length of time camera is on)
unsigned int EXP;
//variable for Focus (signal sent to camera to focus)
unsigned int FT;
//variable for Interval (time between shots)
unsigned int INT;
//variable for Exposure Delay (time placed before exposure)
unsigned int EXPDLY;
//variable for Motor Speed given in % from 0 to 100%
unsigned int MTR;
void setup() {
pinMode(CAMERA_PIN, OUTPUT);
pinMode(MotorPin, OUTPUT);
pinMode(FocusPin, OUTPUT);
Serial.begin(115200);
}
void loop() {
if( exposing == false && millis() - last_tm > INT ) {
// if the camera is not currently exposing, and our timer has elapsed, fire camera...
// set timer interrupt to call our function to disengage the camera
MsTimer2::set( EXP, camera_off );
// enable timer
MsTimer2::start();
// set flag to indicate that we're currently exposing
exposing = true;
// enable optocoupler and fire camera
digitalWrite(CAMERA_PIN, HIGH);
} // end if not exposing and timer has elapsed
}
void camera_off() {
// disable optocoupler, stop exposing
digitalWrite(CAMERA_PIN, LOW);
// disable timer
MsTimer2::stop();
// we set this now to ensure that our interval time is measured from the
// time an image is completed until the time the next one is triggered
// if you want the interval time to be measured between the time the image
// is triggered and the next image is triggered, move this to before
// bringing the camera pin high
last_tm = millis();
// reset exposing flag
exposing = false;
}
How would I go about adding functionality to the program so that I can also engage the motor (on pin #9 for PWM) during the interval time? Would it be via another void() function placed at the bottom, something like "motor_on()? Or do I need to change the MsTimer2(set) function in the loop with some if or if/else or while statements? If you hadn’t guessed it I’m relatively new to Arduino and still learning a lot of the basic concepts and I know I have dove into the deep end of the pool with this as a project. Thanks.
void motor_on() {
if (exposing == false && millis() - last_tm > INT){
MsTimer2::set(EXP,camera_off);
MsTimer2::start();
exposing == true;
analogWrite(MotorPin, MTR / 2.55); // this # should convert the range of 1-100 (motor %) to 0 to 255 for PWM
To put it another way, basically what I want to do is the same things as this loop, but with MSTimer to make things a bit more reliable:
void loop() {
/* There needs to be a way to order the loop. The cycle should be:
1. Focus Tap (FT)
2. Exposure (EXP)
3. Exposure Delay (EXPDLY)
4. Interval (INT)
The motor should be on at the % given by the value of MTR during INT.
*/
//1. Focus Tap
digitalWrite (FocusPin, HIGH);
delay(FT);
digitalWrite (FocusPin, LOW);
//2. Exposure
digitalWrite (CameraPin, HIGH);
delay (EXP);
digitalWrite (CameraPin, LOW);
//3. Exposure Delay
delay (EXPDLY);
//4. Interval
analogWrite (MotorPin, MTR / 2.55);
delay (INT);
// for INT milliseconds, BUT only while the camera is not exposing
}