Arduino Logo  Arduino MEGA 2560
Having written industrial automation software for years, getting into robotics was a natural progression. I wanted to build a small robot arm and to start I needed to learn how to run a motor. First I played with the little RC Servo motors. Then I got into stepper motors which required a stepper motor driver board and a control board to send the driver the step signals. For the control board I chose the Arduino MEGA 2560 board. The Genuino MEGA 2560 has since replaced this board.
(There's more about my arm building in the Robo Lab).

The Arduino board had an IDE of its own and was simple to program with just C code. It also had RS232 serial communications that I could use to send motor commands. So I was able to write firmware that could run up to eight motors simultaneously with speed ramping.
This firmware is for sale for $49.95 

Here's a video of it running three small motors.
I taped pencils to their shafts so you can see them running:



Here's some comments from the code itself:
//==================================================================================================================
//  Stepper Motor Controller, Version 1.7 - 12/17/2013
//
//  Notes  : This firmware is used to operate up to eight stepper motors.
//           It is assumed that a host application will provide the serial
//           communications to this firmware.
//
//           A separate Arduino board with "Safety Firmware" is recommended
//           to work in conjunction with this firmware.  The "Safety Board"
//           should provide:
//             - Limit switch input monitoring for all motors
//             - Multiple E-Stop button inputs and monitoring
//             - Motor current monitoring (high-current burn out)
//             - Motor temperature monitoring (over heating)
//             - Human or foreign object proximity monitoring (work cell)
//           Safety board firmware is on my "to do" list :)
//
//  Author : Bill Daniels
//           Copyright (c) 2013, D+S Tech Labs Incorporated
//           All Rights Reserved
//==================================================================================================================
//
//  This firmware is designed for the Arduino Mega 2560 MCU but may be modified for other boards.
//  It communicates (by 5-volt pins) with micro-stepping motor drivers that take Enable, Direction
//  and Pulse (step) signals.  A typical stepper motor driver would be the MA860H Microstep Driver.
//
//  This firmware receives and executes stepper motor commands by serial communication.
//  Serial communication parameters are set at 57600-baud, 8 data bits, no parity, 1 stop bit.
//  Serial commands are assumed completed when the "newline" '\n' character is received.
//  Carriage Return characters '\r' are ignored and discarded.
//
//  This firmware can control up to eight(8) motors simultaneously with the following serial commands:
//     ENm    = ENABLE                - Enables the motor driver (energizes the motor)
//     DIm    = DISABLE               - Disables the motor driver (releases the motor)
//     SHm    = SET HOME POSITION     - Sets the current position of the motor as its HOME position (Sets Absolute position to zero)
//     SLm... = SET LOWER LIMIT       - Sets the LOWER LIMIT (minimum Absolute Position) of the motor's range
//     SUm... = SET UPPER LIMIT       - Sets the UPPER LIMIT (maximum Absolute Position) of the motor's range
//     SRmr   = SET RAMP              - Sets the trapezoidal velocity RAMP (up/down) for smooth motor start and stop
//     RAm... = ROTATE ABSOLUTE       - Rotates motor to an Absolute target position from its HOME position
//     RRm... = ROTATE RELATIVE       - Rotates motor clockwise or counter-clockwise any number of steps from its current position
//     RHm    = ROTATE HOME           - Rotates motor to its HOME position
//     RLm    = ROTATE LOWER LIMIT    - Rotates motor to its LOWER LIMIT position
//     RUm    = ROTATE UPPER LIMIT    - Rotates motor to its UPPER LIMIT position
//     PAm    = PAUSE                 - Pause rotation of motor
//     REm    = RESUME                - Resume rotation of paused motor
//     ESm    = E-STOP                - Stops the motor immediately (emergency stop)
//     GAm    = GET ABSOLUTE position - Returns the motor's current step position relative to its HOME position
//     GRm    = GET RELATIVE position - Returns the motor's current step position relative to its last targeted position
//     GLm    = GET LOWER LIMIT       - Returns the motor's Absolute LOWER LIMIT position
//     GUm    = GET UPPER LIMIT       - Returns the motor's Absolute UPPER LIMIT position
//     GV     = GET VERSION           - Returns this firmware's current version
//  where m is the Motor ID (0-7) and r is the velocity ramp rate (0-9).
//
//------------------------------------------------------------------------------------------------------------------
//
//  Motor rotation velocity follows a trapezoidal shape.  A linear ramp-up/ramp-down rate is set by the SR command
//  for each motor.  Along with the motor ID, a single digit ramp value (0-9) is specified:
//
//                                   .--------------------------------.    <-- full velocity
//  A ramp value of 0                |                                |
//  specifies no ramping:            |                                |
//  (not recommended)                |                                |
//                                 --------------------------------------
//
//                                       .------------------------.        <-- full velocity
//  A ramp value of 5                   /                          \
//  specifies moderate ramping:        /                            \
//  This is the default at startup    /                              \
//                                 --------------------------------------
//
//                                           .----------------.            <-- full velocity
//  A ramp value of 9                      /                    \
//  specifies gradual ramping:           /                        \
//                                     /                            \
//                                 --------------------------------------
//
//  Use low values (1, 2, ..) for fast accelerations with light loads and high values (.., 8, 9) for slow accelerations
//  with heavy loads.  It is highly recommended to use slow acceleration when moving high inertial loads.
//
//                                            ----------    <-- full velocity
//  If there is not enough time to achieve
//  full velocity, then rotation velocity         /\
//  follows a "stunted" triangle path:           /  \
//                                            ----------
//
//  Once a ramp value is set for a motor, all rotate commands for that motor will use its specified ramp value.
//  The default ramp value at start-up is 5 for all motors.
//
//------------------------------------------------------------------------------------------------------------------
//
//  All five ROTATE commands return a 3-character string to indicate completion of rotation:
//     RCm = Rotate Complete for motor m
//  where m is the Motor ID (0-7).
//  For example: Receiving "RC4" from this firmware = Rotate Complete for Motor 4 (fifth motor)
//
//  If a Rotate command is received for a motor that is already active (running a previous Rotate command),
//  then the current rotation is interrupted and the new Rotate command is executed from the motor's
//  current position.
//
//  Motor rotations may be suspended and resumed at a later time using the PA(Pause) and RE(Resume) commands.
//
//------------------------------------------------------------------------------------------------------------------
//
//  The default LOWER and UPPER Range Limits are set to +2 billion and -2 billion at start up.
//  It is assumed the host (PC) software will set these limits from a configuration file or other means.
//  If a range limit has been reached (the motor's Absolute Position has reached the set LOWER LIMIT or UPPER LIMIT),
//  then the motor's motion is stopped and a Range Error message is returned:
//     REm = Range Error for motor m
//
//------------------------------------------------------------------------------------------------------------------
//
//  This firmware may also be queried for position, range limits and firmware version,
//  with the following serial commands:
//     GAm = GET ABSOLUTE position - Returns the motor's current step position relative to its HOME position
//     GRm = GET RELATIVE position - Returns the motor's current step position relative to its last targeted position
//     GLm = GET LOWER LIMIT       - Returns the motor's Absolute LOWER LIMIT position
//     GUm = GET UPPER LIMIT       - Returns the motor's Absolute UPPER LIMIT position
//     GV  = GET VERSION           - Returns this firmware's current version
//  where m is the Motor ID (0-7).
//  The returned result is a string with the following format:
//     APms... = Absolute Position of motor m is s steps from its HOME position
//     RPms... = Relative Position of motor m is s steps from its last targeted position
//     LLms... = LOWER LIMIT of motor m relative to its HOME position
//     ULms... = UPPER LIMIT of motor m relative to its HOME position
//  where s is a positive or negative long integer (depending on clockwise or counter-clockwise position)
//  and represents a number of steps which may be 1 to 10 digits plus a possible sign.
//
//  The motor's HOME position is always zero (0).
//
//---------------------------------------------------------------
//  Command String Format: (no spaces between fields)
//---------------------------------------------------------------
//                          cc m vvvvv sssssssssss 
//                          |  |   |       |
//  Command/Query ----------*  |   |       |
//     [2-chars]               |   |       |
//     EN = ENABLE             |   |       |
//     DI = DISABLE            |   |       |
//     SH = SET HOME           |   |       |
//     SL = SET LOWER LIMIT    |   |       |
//     SU = SET UPPER LIMIT    |   |       |
//     SR = SET RAMP           |   |       |
//     RA = ROTATE ABSOLUTE    |   |       |
//     RR = ROTATE RELATIVE    |   |       |
//     RH = ROTATE HOME        |   |       |
//     RL = ROTATE LOWER LIMIT |   |       |
//     RU = ROTATE UPPER LIMIT |   |       |
//     PA = PAUSE              |   |       |
//     RE = RESUME             |   |       |
//     ES = E-STOP             |   |       |
//     GA = GET ABS POSITION   |   |       |
//     GR = GET REL POSITION   |   |       |
//     GL = GET LOWER LIMIT    |   |       |
//     GU = GET UPPER LIMIT    |   |       |
//     GV = GET VERSION        |   |       |
//                             |   |       |
//  Motor ID ------------------*   |       |
//     [1-digit] 0 - 7             |       |
//                                 |       |
//  Velocity Ramp Rate ------------*       |
//     [1-digit] 0 - 9             |       |
//     (For SR command only)       |       |
//                                 |       |  ----.
//  Velocity (steps per sec) ------*       |      |
//     [5-digits] 1____ - 99999            |      |
//     Right-padded with spaces            |      |
//                                         |      |
//  Absolute or Relative Step Position -- -*      |--- For ROTATE commands only
//     [1 to 10-digits plus sign]                 |
//     No padding necessary                       |
//     -2147483648 to 2147483647 (long)           |
//     Positive values = Clockwise                |
//     Negative values = Counter-Clockwise        |
//                                            ----*
//---------------------------------------------------------------
//  Examples: (quotes are not included in string)
//---------------------------------------------------------------
//  "EN4"            - Enable the driver for motor 4 (fifth motor)
//  "DI2"            - Disable the driver for motor 2 (third motor)
//  "SH0"            - Set the current position of motor 0 as its HOME position (zero, not oh)
//  "RA1500  2000"   - Rotate Absolute motor 1, at 500 steps per second, to Absolute position of +2000 steps clockwise from HOME
//  "RR63210 -12000" - Rotate Relative motor 6, at 3210 steps per second, -12000 steps counter-clockwise from its current position
//  "RH3"            - Rotate motor 3 back to its HOME position (0)
//  "RL4"            - Rotate motor 4 to its LOWER LIMIT position
//  "SR06"           - Set the velocity ramp-up/ramp-down rate to 6 for motor 0 (first motor)
//  "ES7"            - Immediately stop motor 7 (eighth motor)
//  "GR3"            - Get the current relative step position of motor 3 (forth motor)
//
//---------------------------------------------------------------
//  Arduino Mega 2560 Board Connections:
//---------------------------------------------------------------
//
//  Each motor requires three(3) Arduino pins to operate, starting with pin 22 and skipping every fourth pin.
//  The order of the pins are Enable, Direction, Pulse and (empty), for each motor.
//
//  Motor 0 ==> Enable = pin 22, Direction = pin 23, Pulse = pin 24, pin 25 is empty (unused)
//  Motor 1 ==> Enable = pin 26, Direction = pin 27, Pulse = pin 28, pin 29 is empty (unused)
//           :
//  Motor 7 ==> Enable = pin 50, Direction = pin 51, Pulse = pin 52, pin 53-54 is empty (unused)
//
//  See the Data comment below for full list.
//  Pin 55 should be used for common ground.
//  Future connections will include LOW and HIGH Limit Switch inputs for each motor, pins A0-A15.
//  A separate Arduino board will run safety firmware.  It will monitor motor temperatures and human proximity, etc.
//
//==================================================================================================================