Jump to content
Search In
  • More options...
Find results that contain...
Find results in...
Daftlander

Making a scanner out of my dslr

Recommended Posts

Posted · Original PosterOP

I'm following this instructable with some success. https://www.instructables.com/id/Build-a-DIY-Desktop-3d-Scanner-With-Infinite-Resol/

 

But stepper motors movement is random and jerky, causing my scans to fail. Instead of gently moving forward a few degrees between shots it randomly spin and lands on a new position. 

 

I'm using an A4988 instead of a Big Easy Driver, might that be causing the issue? Here's the arduino code

#include <Stepper.h>

/* 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 <LiquidCrystal.h>
#include "DFR_Key.h"
#include <Stepper.h>
#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 = 2000;  // pre exposure pause in milis.  Allows the specimen to settle before exposure.
const long postWait = 2000;  // 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
         }
      }
      
      
      
      
      
    }
   }
}

Let me know if you see anything I can fix. Ignore the double use of Stepper.h that's a copy error by me.

 

Thanks in advance!

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now


×