Jump to content

Hello All, I need some help with a project concerning the below code It is used to turn a st...


G+_Daniel Stagner
 Share

Recommended Posts

Hello All,

 

I need some help with a project concerning the below code. It is used to turn a stepper motor a fraction of a full rotation and then snap a photo with an IR blast to a remote controlled camera. I got it from an instructable published by Whitney Potter from the 3d printing today podcast.

 

http://www.instructables.com/id/Build-a-DIY-Desktop-3d-Scanner-With-Infinite-Resol/

 

Problem is that it is not doing a post-wait before turning the platform. It dose seem to perform the pre-wait ok. This results in blurry photos due to the platform moving durning just prior to snapping the photo. I just need a bit of help with the code. My code will be the next post.

http://www.instructables.com/id/Build-a-DIY-Desktop-3d-Scanner-With-Infinite-Resol/

Link to comment
Share on other sites

/* Shapespeare Scanner by Whitney Potter

 

This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.

 

 

Controls

SELECT: Start/Stop automatic scan.

LEFT: Trigger exposure and advance one unit clockwise.

RIGHT: Step one unit clockwise without triggering camera.

DOWN: Step one unit counter clockwise without triggering camera.

UP: Cycle through options for number of exposures per revolution.

 

*/

 

 

 

 

#include

#include "DFR_Key.h"

#include

#include "multiCameraIrControl.h"

 

const int stepsPerRevolution = 200*64; // change this to fit the number of steps per revolution for your motor

 

Stepper myStepper(stepsPerRevolution, 20,21); // initialize stepper

// Enable pin is 19. Step pin is 20. Direction pin is 21

 

 

LiquidCrystal lcd(8, 9, 4, 5, 6, 7); //pin assignments for SainSmart LCD Keypad Shield

 

DFR_Key keypad; // initialize keypad

 

int localKey = 0;

int lastKey = 0;

int keyChange = 1; //set true when key is released. Prevents double triggers.

int stepChoices [] = {25,50,75,100,200}; //different numbers of exposures per revolution which may be selected. Higher number = smaller angle change

int stepIndex = 0; // count exposures starting at 1

int numChoices = 5; //number of step choices

int runFlag = 0; //is scanner running

int stepCount =1; // count exposures starting at 1

unsigned long startWait; //time we start the wait timer

unsigned long currentTime; // current time

const long preWait = 5000; // pre exposure pause in milis. Allows the specimen to settle before exposure.

const long postWait = 10000; // post exposure pause in milis. Allows time for the exposure to finish before moving.

int waitFlag = 0; // 0=ready to move 1=pre-exposure wait 2=post-exposure wait

 

Canon Camera(53); //change Nikon to any other supported brand

 

void setup()

{

lcd.begin(16, 2);

lcd.clear();

lcd.setCursor(0, 0);

lcd.print("Shapespeare Scanner");

delay(2500);

lcd.clear();

 

// set the speed at 60 rpm:

myStepper.setSpeed(2);

 

pinMode(19, OUTPUT); //enable pin

digitalWrite(19, HIGH);

 

}

 

void loop(){

 

//

lcd.setCursor(0,0);

lcd.print("Steps:");

lcd.setCursor(6,0);

lcd.print(" ");

lcd.setCursor(6,0);

lcd.print(stepChoices[stepIndex]);

lcd.setCursor(0,1);

if (runFlag == 1)

{

lcd.print("run ");

 

}

else

{

lcd.print("stop ");

}

 

 

localKey = keypad.getKey(); // read keypad

 

if (localKey != SAMPLE_WAIT)

{

 

 

 

if (localKey == 0) // key has been released

{

keyChange =1; // the next key data represents a new key press

}

 

if (localKey == 1 && keyChange == 1) //select=start sequence

{

if (runFlag == 0 && keyChange ==1)

{

runFlag = 1;

waitFlag = 0;

keyChange = 0;

 

}

if (runFlag == 1 && keyChange ==1)

{

runFlag = 0;

stepCount = 1; //uncomment to reset stepCount every time the auto scan is stopped.

keyChange = 0;

 

}

}

 

if (localKey == 2 && keyChange == 1) //left=manual mode

{

keyChange =0;

lcd.setCursor(0,1);

lcd.print("manual");

Camera.shutterNow(); //trigger exposure

delay (postWait); //wait for exposure to complete

digitalWrite(19, LOW); // activate stepper driver

myStepper.step(stepsPerRevolution/stepChoices[stepIndex]); // advance stepper

digitalWrite(19, HIGH); // deactivate stepper driver to save power, heat and noise

stepCount ++;

 

 

}

 

if (localKey == 3 && keyChange == 1 && runFlag ==0) //up cycle through angle choices

{

keyChange =0;

if (stepIndex < numChoices -1)

{

stepIndex ++;

}

else

{

stepIndex = 0;

}

}

 

 

 

if (localKey == 4 && keyChange == 1) //down

{

keyChange =0;

lcd.setCursor(0,1);

lcd.print("CCW step");

digitalWrite(19, LOW);

myStepper.step(-stepsPerRevolution/stepChoices[stepIndex]);

digitalWrite(19, HIGH);

 

 

}

 

if (localKey == 5 && keyChange == 1) //right

{

keyChange =0;

lcd.setCursor(0,1);

lcd.print("CW step");

digitalWrite(19, LOW);

myStepper.step(stepsPerRevolution/stepChoices[stepIndex]);

digitalWrite(19, HIGH);

 

 

}

 

}

 

 

if (runFlag == 1) //sequence is running

{

 

 

if (stepCount > stepChoices[stepIndex]) //the revolution is complete.

{

runFlag = 0; // stop sequence

lcd.setCursor(9,1);

lcd.print("Done ");

}

 

 

 

 

 

//This interrupt based time delay allows us to still receive keypad input during the delay

 

currentTime = millis();

 

if (waitFlag == 0) // advance stepper and start wait timer

{

startWait = millis();

waitFlag = 1; // start preshutter wait

lcd.setCursor(9,1);

lcd.print("Exp#: ");

lcd.setCursor(13,1);

lcd.print(stepCount);

 

digitalWrite(19, LOW); //activate stepper driver

myStepper.step(stepsPerRevolution/stepChoices[stepIndex]); //advance stepper

digitalWrite(19, HIGH); //deactivate stepper driver

 

 

}

 

if (waitFlag == 1) // when preshutter wait expires trigger shutter

{

 

if (currentTime - startWait >= preWait) //wait time has expired

{

 

Camera.shutterNow(); // trigger shutter

startWait = millis(); // restart wait timer

waitFlag = 2; // initiate post shutter wait

stepCount ++;

}

 

if (waitFlag == 2) // wait after triggering shutter before moving motor

{

 

if (currentTime - startWait >= postWait) //wait time has expired

{

waitFlag = 0; //done waiting

}

}

 

 

 

 

 

}

}

}

Link to comment
Share on other sites

OK, couple of things to check:

 

- the if (waitFlag == 2) seems to be within the if (waitFlag == 1) braces (although one would think that this would just hang the process).

 

- try moving the increment of stepCount to within the if (waitFlag == 2) braces. Incrementing it before that may be short-circuiting the stepCount test above.

 

Not clear that either of these is the cause of the problem...

Link to comment
Share on other sites

Telford, I have read a few more posts on how to program and found a ~fix. I added delay(2000) to the code section that you pointed out just after start wait. It now looks like this...

 

Camera.shutterNow(); // trigger shutter

startWait = millis(); // restart wait timer

delay(2000);

waitFlag = 2; // initiate post shutter wait

stepCount ++;

 

This fix is thanks to ReaganPufall on the AutoDesk form.

Link to comment
Share on other sites

waitFlag is what I would call a state variable. It's value (0, 1, 2) determines what the code will do on the current pass through the loop() function. This type of program is what's called a 'state machine', and is a backbone of industrial process control. It is usually implemented using a switch() statement, although if / else if ... works as well.

 

Speaking of that, I would add an 'else' in front of the 'if (waitFlag == 1)' and 'if (waitFlag == 2)' statements, turning them into 'else if (waitFlag == 1)' and 'else if (waitFlag == 2)'. This will keep the state machine execution a little cleaner by preventing multiple state processing on a single loop pass.

 

The delay( 2000 ) statement may alleviate the symptom, but it isn't compatible with what the code is trying to do, timing-wise. It just sticks in a hard 2 second delay. Use it for now. I'll study it some more and see if I can find a better fix.

 

Question the preWait = 5000 and postWait = 10000 values are in milliseconds, and are thus 5 and 10 seconds, respectively. Do you really want delays this long?

Link to comment
Share on other sites

 Share

×
×
  • Create New...