Dear DAVID Community,

As you are probably aware, the entire DAVID company, team and product range has been integrated into HP Inc.
This forum is now read-only. Relevant content has been migrated to HP and merged into HP's Support Forums on November 1, 2016.

To start new discussions for 3D Scanning, please register and post your new topic at the HP Support Forums

2-Axis Positioner

Which camera works? Where can you buy an adequate laser? And more...

2-Axis Positioner

Postby WalterMo » Thu Mar 01, 2012 10:38 am

This 2-axis positioning system could be very helpful for DAVID scanning. It can precisely and comfortably (by means of the remote control) position light weight objects. I think up to a few hundred grams.
Two stepping motors, mounted perpendicular to one another, turn the object by 3 adjustable angle increments: 1.8° for fine positioning, 36° and 45° during scanning. Each position will be displayed on the 2x16 characters LCD display (in degrees).
The horizontal stepping motor (1.8°) has a planetary gear (64:1) attached. The other motor has a resolution of 0.9°. Both motors are driven by Pololu A 4988 boards. The bigger one in full step mode and the small one in 1/8 microstep mode.
If you take a closer look into the controller you can see that I have hooked up both Pololus onto a common carrier board. Advantage: Better handling of the Pololu mini boards, easy to exchange if damaged and the boards are also a carrier for the necessary external electrolytic capacitors.
The Pololus and the LCD display are controlled by the well known Arduino Uno. The device is powered by an external 9V wall power supply.

Walter

PS. Resetting the display for the motor positions will be done by first pressing the 'RESET' button and then simultaneously the requested 'AXIS' button.
Attachments
Positioner Mats1.jpg
Positioner Controller.jpg
User avatar
WalterMo
Moderator
 
Posts: 2363
Joined: Mon Apr 02, 2007 6:52 pm
Location: Braunschweig, Germany

Re: 2-Axis Positioner

Postby benoy » Thu Mar 01, 2012 12:43 pm

Excellent work. :D :D :D :D This can take the entire community to much greater heights. Thanks Walter mo for this great work

regards

Benoy
benoy
 
Posts: 143
Joined: Wed Feb 11, 2009 8:03 pm
Location: India

Re: 2-Axis Positioner

Postby benoy » Thu Mar 01, 2012 4:05 pm

Sorry about the double posting. The first one was my response to the design.

I do not know if I understood the concept behind the turn table completely. So if I am wrong some where please do not hesitate to correct me.

1) The motors A & B can rotate independently at the 3 pre decided angles.
2) The remote that WalterMo suggests is the communication through the com port of David
3) The Arduino acts like an on off switch to the 2 motors
4) The display is also controlled by Arduino.
5) The pololu mini boards drive the 2 motors independently
6) Now where does the software( code) come into picture

thanks in advance

Benoy
benoy
 
Posts: 143
Joined: Wed Feb 11, 2009 8:03 pm
Location: India

Re: 2-Axis Positioner

Postby WalterMo » Thu Mar 01, 2012 4:24 pm

Hello Benoy,
Thanks for the compliments for the design.

I am just drawing the schematic diagram and if it's finished I will post it together with the code for the Arduino. Up to now I haven't implemented that DAVID can control all. Means you must do it manually.
The DAVID feature will come as a next step.

Walter
User avatar
WalterMo
Moderator
 
Posts: 2363
Joined: Mon Apr 02, 2007 6:52 pm
Location: Braunschweig, Germany

Re: 2-Axis Positioner

Postby WalterMo » Thu Mar 01, 2012 8:46 pm

Here are the schematic diagram of the positioner-controller and the code for the Arduino.

A few remarks about the circuit diagram:
The resistor R3 and its value depends on the used LCD display. Some displays have this resistor already integrated and others not. Therefore, not to damage the display, have a look to the display's datasheet or precautionally use a 180 Ohms resistor. Mine came from here and had the resistor integrated:
http://www.pollin.de/shop/dt/Nzc1OTc4OT ... 2A_09.html

On the photo of the inside of the controller are some components to see which aren't on the diagram. E.g. 2 x 4 diodes and 2 x 2 resistors on the Pololu carrier board. These components aren't indispensable for a normal usage.
The MS3 inputs of the Pololus are left open and not connected to DIP mini switches like MS1 and MS2. In so doing it's only possible to set the step modes of the Pololus from full step up to 1/8 micro step.
Both resistors at the 'Angle Increment' toggle switch must have the same value! 2 x 1K or 2 x 2.2K or similar. This switch has 3 positions, the middle position has no "connection" to a pin. It's called ON-OFF-ON switch.

If you like to recreate the positioner and intend to use other stepping motors please don't hesitate to ask how to modify the Arduino code.

Walter

Code: Select all
//  Positioner Mats1, Version 1.0               
//  2-Axis positioning system. Motor driver with 2 Pololu boards A4988. LCD display with 16x2 characters.
//  Position display of both motors in degrees.
//  Horizontal stepping motor: 1.8° motor (Motor A) with a gear (ratio 64:1). Driven by Pololu in full step mode.
//  Vertical stepping motor: 0.9° Motor (Motor B), driven by Pololu in 1/8 micro step mode.
//  By WalterMo, Febr. 2012

// include the library code:
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal g_lcd (8, 9, 10, 11, 12, 13);

int i;                    // i as integer for the for - next loop.
int outDirA = 2;          // Digital output for direction of motor A at pin 2
int outClockA = 3;        // Digital output for clock (steps) of motor A at pin 3
int outDirB = 4;          // Digital output for direction of motor B at pin 4
int outClockB = 5;        // Digital output for clock (steps) of motor B at pin 5
int Button_reset = 7;     // Digital input for Reset
int ButtonB_up = A0;         // Motor B Button up
int ButtonB_down = A1;       // Motor B Button down
int ButtonA_up = A2;         // Motor A Button up
int ButtonA_down = A3;       // Motor A Button down
int incrementSwitch = A4;    // Increment switch at Analog pin A4
int incrementValue = 0;      // Variable to store the analog value of the increment switch
int turnDirectionA;          // Direction of rotation motor A
int turnDirectionB;          // Direction of rotation motor B
int currentMotorstepA;       // Current number of steps of motor A
int currentMotorstepB;       // Current number of steps of motor B
int resetA1;                 // Variable of the result of ButtonA_up
int resetA2;                 // Variable of the result of ButtonA_down
int resetB1;                 // Variable of the result of ButtonB_up
int resetB2;                 // Variable of the result of ButtonA_down
int reset;                   // Variable of the result of the RESET button
int incrStepsA;              // Variable of the result of the motor A steps for the next inctrement
int incrStepsB;              // Variable of the result of the motor B steps for the next inctrement
float currentPosA;           // Current position of motor A in degrees
float currentPosB;           // Current position of motor B in degrees
//************************************************************************************************************

// The setup() method runs once, when the sketch starts

void setup()   {               
  // initialize the analog and digital pins as an input or output:
 
  pinMode(outClockA, OUTPUT);          //Define outClock A as an output
  pinMode(outDirA, OUTPUT);            //Define outDir A as an output
  pinMode(outClockB, OUTPUT);          //Define outClock B as an output
  pinMode(outDirB, OUTPUT);            //Define outDir B as an output
  pinMode(A0, INPUT);                  //Define A0 as an input
  pinMode(A1, INPUT);                  //Define A1 as an input         
  pinMode(A2, INPUT);                  //Define A2 as an input
  pinMode(A3, INPUT);                  //Define A3 as an input
  pinMode(A4, INPUT);                  //Define A4 as an (analog) input
  pinMode(Button_reset, INPUT);        //Define Button_reset as an input
  digitalWrite(Button_reset,HIGH);     //Pull this input up
   
  g_lcd.begin(16, 2);                 // Define your LCD Display! Characters and rows.
   
   // Show welcome message:
  g_lcd.clear();
  g_lcd.setCursor(0,0);
  g_lcd.print("POSITIONER MATS1");
  g_lcd.setCursor(0,1);
  g_lcd.print("Version 1.0");
  delay(3000);
  g_lcd.clear();
 
  currentPosA = 0;
       g_lcd.setCursor(0,0);                // Cursor to top left
       g_lcd.print("PosMotorA:      ");     // Display the word 'PositionMotorA'
       g_lcd.setCursor(11,0);               // Cursor to 11th position, first row
       g_lcd.print((currentPosA));          // Display the value of 'Motor position A'
  currentPosB = 0;
       g_lcd.setCursor(0,1);                // Cursor to left, second row
       g_lcd.print("PosMotorB:      ");     // Display the word 'PositionMotorB'
       g_lcd.setCursor(11,1);               // Cursor to 11th position, second row
       g_lcd.print((currentPosB));          // Display the value of 'Motor position B'
  }

// the loop() method runs over and over again, as long as the Arduino has power

void loop() {
   //*****  Read the increment switch and define the number of steps for both motors for this switch position*************
        incrementValue = analogRead (incrementSwitch);
        if (incrementValue < 200){
           incrStepsB = 16;     // 16 steps for a 1.8° rotation of motor B
           incrStepsA = 64;     // 64 steps for a 1.8° rotation of motor A
        }
        if (incrementValue > 800){
           incrStepsB = 400;     // 400 steps for a 45° rotation of motor B
           incrStepsA = 1600;    // 1600 steps for a 45° rotation of motor A
        }
         if (incrementValue > 200 & incrementValue < 800){
           incrStepsB = 320;     // 320 steps for a 36° rotation of motor B
           incrStepsA = 1280;    // 1280 steps for a 36° rotation of motor A
        }
  //****************************** MOTOR B upwards  ************************************************************
     turnDirectionB = digitalRead(ButtonB_up); // Read the direction button 'Up' for MOTOR B
     reset = digitalRead (Button_reset);            // Read reset button
     if (turnDirectionB == LOW & reset == HIGH) {
     digitalWrite(outDirB,LOW);                // Set direction output motor B = Low
     delay (100);
      for (i = 0; i<incrStepsB; i++){          //
       g_lcd.setCursor(0,1);
       g_lcd.print("Wait, MotB is on");        // Print: Wait!!
       digitalWrite(outClockB,HIGH);           // High and Low impulses
       delay (4);
       digitalWrite(outClockB,LOW);
       delay (4);
       currentPosB = (currentPosB + 0.1125);   // 0.1125° = one 1/8 microstep
   }
       g_lcd.setCursor(0,1);                // Cursor to left, second row
       g_lcd.print("PosMotB:        ");     // Display the word 'PositionMotorB'
       g_lcd.setCursor(9,1);               // Cursor to 11th position, second row
       g_lcd.print((currentPosB));          // Display the value of 'Motor steps'
    }
  //******************************* MOTOR B downwards ************************************************+       
      turnDirectionB = digitalRead(ButtonB_down);    // Read the direction button 'Down' for MOTOR B
      reset = digitalRead (Button_reset);            // Read reset button
  if (turnDirectionB == LOW & reset == HIGH) {
     digitalWrite(outDirB,HIGH);             // Set direction output motor B = High
     delay (100);
     for (i = 0; i<incrStepsB; i++){         //
       g_lcd.setCursor(0,1);
       g_lcd.print("Wait, MotB is on");      // Print: Wait!!
       digitalWrite(outClockB,HIGH);         // High and low impulses
       delay (4);
       digitalWrite(outClockB,LOW);
       delay (4);
       currentPosB = (currentPosB - 0.1125);  // 0.1125° = one 1/8 microstep
    }
       g_lcd.setCursor(0,1);                // Cursor to left, second row
       g_lcd.print("PosMotB:        ");     // Display the word 'PositionMotorB'
       g_lcd.setCursor(9,1);               // Cursor to 11th position, second row
       g_lcd.print((currentPosB));          // Display the value of 'Motor steps'
     }
     
  //****************************** MOTOR A upwards ************************************************************
     turnDirectionA = digitalRead(ButtonA_up);    // Read the direction button 'Up' for MOTOR A
     reset = digitalRead (Button_reset);          // Read reset button
  if (turnDirectionA == LOW & reset == HIGH) {
     digitalWrite(outDirA,LOW);     // Set direction output motor A = Low
     delay (10);
   for (i = 0; i<incrStepsA; i++){                  //
       digitalWrite(outClockA,HIGH);        // High and low impulses
       g_lcd.setCursor(0,0);
       delay (1);
       digitalWrite(outClockA,LOW);
       g_lcd.print("Wait, MotA is on");     // Print: Wait!!
       currentPosA = (currentPosA + 0.028125);   // 0.028125° = 0ne full step
   }
       g_lcd.setCursor(0,0);                // Cursor to top left
       g_lcd.print("PosMotA:        ");           // Display the word 'PositionMotorA'
       g_lcd.setCursor(9,0);              // Cursor to 11th position, first row
       g_lcd.print((currentPosA));         // Display the value of 'Motor steps'
  }
//**************************************** MOTOR A downwards ******************************************+         
      turnDirectionA = digitalRead(ButtonA_down);    // Read the direction button 'Down' for MOTOR A
      reset = digitalRead (Button_reset);            // Read reset button
  if (turnDirectionA == LOW & reset == HIGH) {
     digitalWrite(outDirA,HIGH);             // Set direction output motor A = High
     delay (10);
     for (i = 0; i<incrStepsA; i++){         //
       digitalWrite(outClockA,HIGH);         // High and low impulses
       delay (1);
       g_lcd.setCursor(0,0);
       digitalWrite(outClockA,LOW);
       g_lcd.print("Wait, MotA is on");     // Print: Wait!!
       currentPosA = (currentPosA - 0.028125);     // 0.028125° = one full step
     }
       g_lcd.setCursor(0,0);                // Cursor to top left
       g_lcd.print("PosMotA:        ");     // Display the word 'PositionMotorA'
       g_lcd.setCursor(9,0);                // Cursor to 11th position, first row
       g_lcd.print((currentPosA));          // Display the value of 'Motor steps'
  }
       
  //***************   RESET of the display counter of motor B   ********************************************
        resetB1 = digitalRead (ButtonB_up);
        resetB2 = digitalRead (ButtonB_down);
        reset = digitalRead (Button_reset);
     if ((resetB1 == LOW | resetB2 == LOW) & reset == LOW) {
        currentPosB = 0;
        g_lcd.setCursor(0,1);                // Cursor to left, second row
        g_lcd.print("PosMotB:        ");     // Display the word 'PosMotB'
        g_lcd.setCursor(9,1);                // Cursor to 10th position, second row
        g_lcd.print((currentPosB));          // Display the value of 'Motor Position B'
        delay (1000);
   }
    //***************   RESET of the display counter of motor A   ********************************************
      resetA1 = digitalRead (ButtonA_up);
      resetA2 = digitalRead (ButtonA_down);
      reset = digitalRead (Button_reset);
   if ((resetA1 == LOW | resetA2 == LOW) & reset == LOW) {
        currentPosA = 0;
        g_lcd.setCursor(0,0);                // Cursor to left, first row
        g_lcd.print("PosMotA:        ");     // Display the word 'PositionMotorA'
        g_lcd.setCursor(9,0);                // Cursor to 10th position, first row
        g_lcd.print((currentPosA));          // Display the value of 'Motor Position A'
        delay (1000);
   }
 
}
Attachments
Positioner Diagram.jpg
Positioner_Mats1.zip
(2.39 KiB) Downloaded 299 times
User avatar
WalterMo
Moderator
 
Posts: 2363
Joined: Mon Apr 02, 2007 6:52 pm
Location: Braunschweig, Germany

Re: 2-Axis Positioner

Postby andreasa » Fri Mar 02, 2012 4:43 pm

Wow, this is an awesome accessory to David scanner. You'r works are a true inspiration.
User avatar
andreasa
 
Posts: 34
Joined: Wed May 04, 2011 11:49 am
Location: Tartu, Estonia

Re: 2-Axis Positioner

Postby pottersfriend » Sat Mar 03, 2012 1:10 am

I knew it was just a matter of time.

Great work as usual. Would be nice if you could post a video of it moving.
pottersfriend
 
Posts: 153
Joined: Wed Jun 03, 2009 1:49 am
Location: Washington State, USA

Re: 2-Axis Positioner

Postby WalterMo » Sat Mar 03, 2012 4:19 pm

As you can see on the photo above of the opened controller, I have provided the output stages of the Pololus with 4 diodes each. These diodes should protect the Pololus if the plug contacts of the motor cables are inadvertently opened. This is strongly forbidden to do if the motor is with current.
In the past I had often used the motor driver board from Marcus Mechatronics, equipped with 4 protecting diodes and this board never failed, even if it was used in the just mentioned forbidden way. But in the meantime the company Marcus Mechatronics doesn't exists no longer.

Now I have equipped the Pololu carrier also with (nearly the same) ultra fast avalanche diodes, Type BYV 26 D or BYV 26 C:
http://www.datasheetcatalog.net/de/data ... YV26.shtml

I don't know if it will be a 100% security, but I feel a bit better. Of course if you don't have an openable connection you can forget the diodes.

Walter

PS. Both 10k resistors aren't necessary
Attachments
Pololu1XSchaltplan.JPG
Pololu Layout.jpg
Layout made with Micrografx Designer
Double PololuBoard.jpg
Double Pololu carrier board
User avatar
WalterMo
Moderator
 
Posts: 2363
Joined: Mon Apr 02, 2007 6:52 pm
Location: Braunschweig, Germany

Re: 2-Axis Positioner

Postby WalterMo » Sat Mar 03, 2012 6:50 pm

Now it is possible to trigger the vertical axis (motor B) by DAVID. :D

That means if DAVID has successfully saved a scan and this was receipted by you, DAVID will send the character 'Z'. 'Z' stands for 'Scan saved'. See DAVID's Advanced Settings below 'Communication', 'COM' and then 'Messages'.

This trigger pulse will cause the vertical motor to turn for one angle increment which was set before by you on the controller's console.

Test it with Sven's software 'Test COM 6'. It is attached as a *.zip file. Of course before you can send the 'Z' you have to set the right COM port address and 'Open' it. There are 3 ways to find it:
1. You will find it at Arduino when you upload the Mats1_1 code from your PC to the controller. Find it below 'Tools', 'Serial port'.
2. DAVID 3.2 (or higher) will find it: Connect the controller, Start DAVID, goto 'Hardware Setup', Setup Type: 'Motorized DAVID Setup'.
3. By your PC itself, e.g. for Win7: Start, Control panel, Hardware and Sound, Devices and printers, click with the right mouse button on the USB device, 'Properties', 'Hardware', USB Serial port =

Walter

Edit. If the controller should do e.g. 18° angle increments, set the toggle switch to 1.8° and send 10 x Z (in one go).
Attachments
TestCOM6.zip
(546.82 KiB) Downloaded 322 times
Positioner_Mats1_1.zip
(2.54 KiB) Downloaded 301 times
COM 6 Test.jpg
COM5 as an example with 10 x Z for an 18° angle increment
User avatar
WalterMo
Moderator
 
Posts: 2363
Joined: Mon Apr 02, 2007 6:52 pm
Location: Braunschweig, Germany

Re: 2-Axis Positioner

Postby ddstech » Sat Mar 03, 2012 9:28 pm

WalterMo,

Thank you very much for posting your progress on this project! Please keep the build photos coming. I hope to build a similar setup, based on your work, soon.

A couple of questions.....
1. Will you be able to feed the table positions (motor rotations) to DAVID for use in ShapeFusion scan alignments?
2. Would servo motors be accurate and stable enough for this setup? I found this great source of parts that might work well for this type of project. http://servocity.com/html/pan_tilt_roll ... ories.html

Thanks
Camera: Point Grey Chameleon 1.3 MP Mono USB 2.0 camera
Lens: Fujinon DF6HA-1B Lens
Closeup lens on Camera: Carl Zeiss Ikon Proxar A28.5 .2m Close Up Lens
Projector: 3M 225a set to 1024x768
Projector closeup lens: +3 diopter closeup lens
ddstech
 
Posts: 21
Joined: Sat Nov 19, 2011 2:08 pm

Re: 2-Axis Positioner

Postby WalterMo » Sun Mar 04, 2012 8:01 pm

@ddstech,

To your questions:
1. If you have adjusted the axis precisely in that way as DAVID is working, you can set the used angle increments in DAVID's Shape Fusion and DAVID will align the scans automatically. This feature was also working in former DAVID versions. The attached sketch shows how DAVID is using the 3 axis.

2. Stepping motors have some advantages over servo motors: They can do a certain number of defined steps without any feedback to the controller.
A servo motor is a DC motor with an attached gear and needs a feedback to the controller. This can be done in a servo loop which consists of a simple potentiometer at the gears output shaft or better, a high resolution optical incremental rotary encoder. And the incoming informations of the potentiometer or the encoder must be interpreted by an electronic circuit and forwarded to the DC motor.
My experience is, coming from that time when I tinkered with model boats, that servos like to jitter. Even if they should stand still. Of course there are good servos out there which are working well but its price is rather high.
It will be more difficult to let DAVID cause an axis to rotate for e.g. 45°. OK, the Arduino is also able to send pulses of differend widths to control a model-servo. But its resolution and precision is worse, compared with a stepper motor.

The stepping motors which I have used were lying around at home. A low-cost alternative could be:
For the horizontal motor (a gear isn't necessary):
http://www.phidgets.com/products.php?ca ... _id=3308_0

And for the vertical motor:
http://www.phidgets.com/products.php?ca ... _id=3301_0


Walter

Edit: Just found, for Germany and Austria, two nearly identical motors to those of above:
http://www.pollin.de/shop/p/OTk0OTg4/Mo ... toren.html
Attachments
DAVID coordinats.jpg
User avatar
WalterMo
Moderator
 
Posts: 2363
Joined: Mon Apr 02, 2007 6:52 pm
Location: Braunschweig, Germany

Re: 2-Axis Positioner

Postby ddstech » Tue Mar 06, 2012 2:39 am

WalterMo,

Thank you for the great response and the links to the stepper motors! That looks like a great resource. Please keep us posted on your progress.

ddstech
Camera: Point Grey Chameleon 1.3 MP Mono USB 2.0 camera
Lens: Fujinon DF6HA-1B Lens
Closeup lens on Camera: Carl Zeiss Ikon Proxar A28.5 .2m Close Up Lens
Projector: 3M 225a set to 1024x768
Projector closeup lens: +3 diopter closeup lens
ddstech
 
Posts: 21
Joined: Sat Nov 19, 2011 2:08 pm

Re: 2-Axis Positioner

Postby WalterMo » Mon Mar 12, 2012 3:16 pm

benoy wrote:1) The motors A & B can rotate independently at the 3 pre decided angles.
2) The remote that WalterMo suggests is the communication through the com port of David
3) The Arduino acts like an on off switch to the 2 motors
4) The display is also controlled by Arduino.
5) The pololu mini boards drive the 2 motors independently
6) Now where does the software( code) come into picture

Sorry Benoy, I had forgotten to answer and I do hope that's not too late. To your questions:

1) Yes, but not at the same time.
2) There are now two remote controls: The main control can be done by the switchboard manually and the second, only for the vertical motor, by DAVID when a scan was saved.
3) The Arduino controls all. It "knows" e.g. how many steps must be done for each motor to fulfil the preset angle increment.
4) Yes.
5) Yes.
6) In the meantime I have posted the Arduino code.

Walter
User avatar
WalterMo
Moderator
 
Posts: 2363
Joined: Mon Apr 02, 2007 6:52 pm
Location: Braunschweig, Germany

Re: 2-Axis Positioner

Postby benoy » Wed Mar 14, 2012 7:14 pm

Thankyou WalterMo,

I was a little busy here. Though I am following the thread I didn't get time to write mails. I was busy working on my 7mm cal;calibration panel. It shows signs of success. I had to try out different lens and modify existing lens. I am also making the 2 axis position-er. Thank you I'll get back to you with happy news

Benoy
benoy
 
Posts: 143
Joined: Wed Feb 11, 2009 8:03 pm
Location: India

Re: 2-Axis Positioner

Postby DeeboFitts » Tue Mar 20, 2012 8:42 pm

Ive been studying this page the past few days. I am really intrigued by your setup. You'll be happy to know, I went ahead and bought a projector after talking to you the other day Walter.

Now I just noticed the Positioner_Mats1.zip, how it evaded me these past few days dumbfounds me. Anyways, after unzipping it, it shows a .pde file format. What program do you use to open this?
DeeboFitts
 
Posts: 1
Joined: Tue Feb 07, 2012 3:00 pm

Next

Return to Laser and Camera Hardware

Who is online

Users browsing this forum: No registered users and 1 guest

cron