BBB Logo  BBB Board
After working with the Arduino board I learned of the Beagleboard community and their Beaglebone Black board. With a 1-GHz ARM® Cortex-A8 processor it runs 60 times faster than the Arduino and had more features like HDMI video! This board was more like a true PC in the palm of your hand.

My robotic goals with this board are the same as with the Arduino - run stepper motors. But with the BBB you can't just write C code, upload it and off you go. This board runs a full OS, namely Linux, which makes getting low-level, fast access to the GPIO pins more than trivial. It involved accessing the "/dev/mem" area and compiling/installing Device Tree Overlays and dealing with permissions ... Arrrggg @#$%&*! :|

Also, I wanted my robot to be controllable from the web. So instead of taking serial commands I needed this firmware to connect with web-socket messaging like a real-time chat session. This will allow a website to be the motion control user interface to the robot arm !!!

So rather than the traditional C/C++ code for the firmware I thought I'd try "the web way" using Javascript. I know all you firmware gurus out there are going "JavaScript ??? Gross!". But with Node.JS, Socket.IO and BoneScript, much had been done for me. Node.JS let me setup the BBB as a Web Server and Socket.IO gave me web socket communications.

The commands for this firmware, the DSBotServer, are the same as the Arduino firmware:
(Except velocities are specified with four digits, not five.)

//=============================================================================
//
//  Stepper Motor Controller, Version 2.0 - 10/30/2014
//
//  Notes  : This firmware is a Node.JS module running BoneScript.  It is
//           used to operate up to eight stepper motors.  The DSBotServer
//           module receives motor command messages by web socket from the
//           host web app (the D+S Motion Controller) and forwards them to
//           this module for execution.
//
//           For professional robotic installations a separate Beaglebone Black
//           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 (over-current)
//             - 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-2014, D+S Tech Labs Incorporated
//           All Rights Reserved
//
//=============================================================================
//
//  This SMC module is designed to work with the DSBotServer web server module.
//  It receives and executes stepper motor commands forwarded from the DSBotServer.
//  The DSBotServer receives motor commands from a host web application, the "D+S Motion Controller".
//
//  This firmware is designed for the Beaglebone Black Microcontroller board.
//  It communicates with micro-stepping motor drivers that take Enable, Direction and Pulse signals.
//  A typical stepper motor driver would be the MA860H Microstep Driver.
//
//  This firmware can control up to eight(8) motors simultaneously with the following 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
//     RHm... = ROTATE HOME           - Rotates motor to its HOME position
//     RLm... = ROTATE to LOWER LIMIT - Rotates motor to its LOWER LIMIT position
//     RUm... = ROTATE to UPPER LIMIT - Rotates motor to its UPPER LIMIT position
//     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
//     ES     = E-STOP                - Immediately stops all motors (Emergency Stop)
//     RE     = RESUME                - Resume E-Stopped motors
//     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 speed follows a trapezoidal shape.  A linear ramp-up/ramp-down rate is set by the
//  SET RAMP (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.
//
//------------------------------------------------------------------------------------------------------------------
//
//  Maximum rotation speed for all motors is 9999 steps per second (4-digits).  Speeds are always indicated
//  by four(4) digits padded to the right with spaces.
//
//  All five ROTATE commands return a ROTATE COMPLETE (RCm...) message to indicate completion of rotation.
//  The RC message includes the motor's final absolute position:
//     RCmppp... = Rotate Complete for motor m, its position is ppp...
//
//  For example: Receiving "RC41250" from this firmware = ROTATE COMPLETE for Motor 4,
//                                                         and it final postion is +1250 steps from HOME
//
//------------------------------------------------------------------------------------------------------------------
//
//  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.
//
//------------------------------------------------------------------------------------------------------------------
//
//  The default LOWER and UPPER Range Limits are set to +2 billion and -2 billion at start up.
//  It is assumed the host (web application) 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 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 vvvv ssssssssss
//                             |  |   |       |
//  Command/Query -------------*  |   |       |
//     [2-chars]                  |   |       |
//     EN = ENABLE                |   |       |
//     DI = DISABLE               |   |       |
//     SH = SET HOME              |   |       |
//     SL = SET LOWER LIMIT       |   |       |
//     SU = SET UPPER LIMIT       |   |       |
//     SR = SET RAMP              |   |       |
//     RH = ROTATE HOME           |   |       |
//     RL = ROTATE to LOWER LIMIT |   |       |
//     RU = ROTATE to UPPER LIMIT |   |       |
//     RA = ROTATE ABSOLUTE       |   |       |
//     RR = ROTATE RELATIVE       |   |       |
//     ES = E-STOP                |   |       |
//     RE = RESUME                |   |       |
//     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) ---------*       |      |
//     [4-digits] 1___ - 9999                 |      |
//     Right-padded with spaces               |      |
//                                            |      |
//  Absolute or Relative Step Position -------*      |--- For ROTATE commands only
//     [1 or more digits plus sign]                  |
//     No padding necessary                          |
//     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
//  "RH34000        - Rotate motor 3 back to its HOME position (0) at 4000 steps per second
//  "RL4500"        - Rotate motor 4 to its LOWER LIMIT position at 500 steps per second
//  "SR06"          - Set the velocity ramp-up/ramp-down rate to 6 for motor 0 (first motor)
//  "ES"            - Immediately stop all motors
//  "GR3"           - Get the current relative step position of motor 3 (forth motor)
//
//---------------------------------------------------------------
//  Beaglebone Black Board, P8 and P9 Header Connections:
//---------------------------------------------------------------
//
//  Each motor driver requires three(3) GPIO pin outputs to operate, one for Enable, Direction and Pulse.
//  Many of the Beaglebone Black's pins are used by the system such as the eMMC and HDMI.
//  And with the Linux 3.8.x Kernel, pin muxing had to be done by writing, compiling, installing and activating a
//  Device Tree Overlay, rather than the usual sysfs method.  So the following pins are used to drive the motors:
//
//  On the P8 Header:
//  -----------------
//  Motor 0 | Enable = P8_7 , Direction = P8_9 , Pulse = P8_11
//  Motor 1 | Enable = P8_8 , Direction = P8_10, Pulse = P8_12
//  Motor 2 | Enable = P8_13, Direction = P8_15, Pulse = P8_17
//  Motor 3 | Enable = P8_14, Direction = P8_16, Pulse = P8_18
//
//  On the P9 Header:
//  -----------------
//  Motor 4 | Enable = P9_11, Direction = P9_13, Pulse = P9_15
//  Motor 5 | Enable = P9_12, Direction = P9_14, Pulse = P9_16
//  Motor 6 | Enable = P9_17, Direction = P9_19, Pulse = P9_21
//  Motor 7 | Enable = P9_18, Direction = P9_20, Pulse = P9_22
//
//  - Pins 1 & 2 of the P8 Header should be used for digital grounds.
//
//  - Future connections will include multiple E-Stop switch inputs, motor shaft encoder inputs
//    and LOW/HIGH limit switch inputs for each motor.
//
//  - A separate Beaglebone Black board will run safety firmware.  It will monitor motor temperatures,
//    foreign object cell proximity, etc.
//
//==================================================================================================================