G+_Daniel Stagner Posted October 6, 2017 Share Posted October 6, 2017 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 More sharing options...
G+_Daniel Stagner Posted October 6, 2017 Author Share Posted October 6, 2017 /* 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 More sharing options...
G+_Telford Dorr Posted October 6, 2017 Share Posted October 6, 2017 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 More sharing options...
G+_Daniel Stagner Posted October 7, 2017 Author Share Posted October 7, 2017 Telford, That cut my overall wait time in half but did not have the disired affect. Quistion How dose the program know what waitFlag 1 and waitFlag 2 are. There is no reference to the two other flags (1 and 2) in the top of the code. Link to comment Share on other sites More sharing options...
G+_Daniel Stagner Posted October 7, 2017 Author Share Posted October 7, 2017 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 More sharing options...
G+_Telford Dorr Posted October 7, 2017 Share Posted October 7, 2017 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 More sharing options...
Recommended Posts