Two Axis Stepper Controller

= What =

For some time I have wanted to aim a laser with good precision across a room. Long time ago I did this with servo motors, Worked fine excpt for the good precision. I thought that steppers might do better. The problem is that steppers move ( typically ) over a degree per step. Gearing the motor down decreases the speed, but improves the precision. And these motors, with built in gears are available, and they can be cheap ( Amazon.com : Longruner 5x Geared Stepper Motor 28byj 48 Uln2003 5v Stepper Motor Uln2003 Driver Board for arduino LK67 : Camera & Photo ) For the mount I found a 3D printer file (  *Bare Bones 28BYJ-48 Gimbal. by mmontee - Thingiverse ).

You can aim the laser in both altitude and azimuth. Once you get it to a place you want the program can memorize the location as a target and then go back there on demand.

Get the Code

 * russ-hensel/TwoAxis: A TwoAxis stepper motor controller for the arduino

= How =

Laser/Motor Mount

 * Get the motors: ( Amazon.com : Longruner 5x Geared Stepper Motor 28byj 48 Uln2003 5v Stepper Motor Uln2003 Driver Board for arduino LK67 : Camera & Photo ).


 * Print the mount: ( *Bare Bones 28BYJ-48 Gimbal. by mmontee - Thingiverse ).

Arduino and Driver
Pretty much any arduino should work, I used a really bare bones board I had on hand. The driver chip comes with the motor ( although I used a chip I had on hand ). Any terminal program should work, I used my own Python Smart Terminal.

Arduino Software
In the old days I would have writen the code from the ground up. With the arduino you can often get a well tested library for this. I found the following and decided to use it.


 * AccelStepper: AccelStepper library for Arduino

For a long time I have had a belief that almost all arduino programs should have some sort of serial interface. And this is what I did for this project. The arduino is sent commands, typically a single character optionally followed by a number. From the help command built into the program here is a summary of the commands:

Arduino: TwoAxis Ver1 2017 11 14.00 mnn   chooseMotor tn    move to Target n  t-n    save Target n  b      baklash adj nn    cmotor nudge n  !! snn   cmotor setSpeed ann   cmotor setAcceleration dnn   doDance z     both motors zeroPosition w     statusReport WhatWhere v     Version of software ok

Here is a bit more detail on the commands.

Commands and responses always end with a newline.

After a command is sent the software usually replies with some confirming message. The whole command may take awhile if the position is changed by a lot. In any case the arduino should finally respond with "ok". Each motor has its own position, speed and acceleration settings. You can choose which motor to manipulate with the m1 and m2 commands. Other commands like t ( target ) act on both motors.


 * m -->    select the active Motor, either motor one or 2.  Motor 1 is the asumith, x motor.  Motor 2 is the altitude, y motor.  The commands are m1 or m2
 * n -->    Nudge the active motor forward or backward by some number of steps.  So commands look like n22,  n-99 n 10 and so on.

you can also change the steps for a target to the "current" location of the target by using a negative target numbers. So t-7 saves the current steps to target 7
 * t -->    Target the laser at one of several ( 12 or more ) different targets that are coded into the program.  The commands look like t5, t7.....
 * b -->    Backlash adj wiggles both motors so hopefully the backlash is consistent no matter what the prior motion of the motors
 * s -->    this sets the top Speed of the current or active motor as set by the m command
 * a -->    this sets the Acceleration of the current or active motor as set by the m command
 * z -->    both motors Zeros the position.
 * w -->    this gives a status report of What and Where the motors are doing, see example below.
 * v -->    Version of software is reported.  Looks something like this: TwoAxis Ver1 2017 11 14.00

Status Report Example
This report gives a lot of information on the internal state of the program. Note that the position of each target is given, it is also give in the form of a c++ array that can be plugged back into the code to make the target setting "permanent".


 * 1) <<< Status
 * 2) <<< TwoAxis Ver1 2017 11 14.00
 * 3) <<< Current Motor: 1 = x
 * 4) <<< Target Position: 0
 * 5) <<< Current Position 1, x : 0
 * 6) <<< Current Position 2, y : 0
 * 7) <<< Motor 1, x Speed = 1000.00  Acc = 50.00
 * 8) <<< Motor 2, Y Speed = 1000.00  Acc = 50.00
 * 9) <<< print out targets:...
 * 10) <<< Target: 1 x: 24 y: 24
 * 11) <<< Target: 2 x: 36 y: 36
 * 12) <<< Target: 3 x: 50 y: 50
 * 13) <<< Target: 4 x: 150 y: 150
 * 14) <<< Target: 5 x: 200 y: 200
 * 15) <<< Target: 6 x: 250 y: 250
 * 16) <<< Target: 7 x: 12 y: 12
 * 17) <<< Target: 8 x: 24 y: 24
 * 18) <<< Target: 9 x: 36 y: 36
 * 19) <<< Target: 10 x: 50 y: 50
 * 20) <<< Target: 11 x: 150 y: 150
 * 21) <<< Target: 12 x: 200 y: 200
 * 22) <<< c format for targets:...
 * 23) <<< int  target_coords[]  = { 12, 24, 24, 36, 36, 50, 50, 150, 150, 200, 200, 250, 250, 12, 12, 24, 24, 36, 36, 50, 50, 150, 150, 200,  };
 * 24) <<< ok

Code Explanation
The code is quite straight forward, reading it should tell you most of what you might want to know. I used my own serial object it is in SerialCmd.cpp and .h. The actual application is in TwoAxis.ino and .h. Most of the easily changed values are in TwoAxis.h Finally some comments are in readme.h ( which despite the .h file is not part of the software but just an extra text file, with comment and notes.

Email me if you have questions, or post to the github location.