Wednesday, March 11, 2026

ST-Robotics R12 robot arm with K11R controller

 We've had the good fortune of coming into possession of a 5-axis robotic arm.  It's a K12, made by ST-Robotics in 2018.

The machine is mostly as depicted in other web pages.  The arm looks as you'd expect a red and white robotic arm to look like.  It does not have working LED lights.  

The controller is a K11R.  It is a rather industrial-looking thing, boxy with the appearance of being rack-mountable.  There is a control pad for "teaching" the robot.

Power

The first challenge with the robot controller is that it did not come with an obvious power plug.  In most other pages that show an R12, you see a typical 110V female port on the back.  (I supposed a European model might have a 220V plug.)  Instead, for this one, there was a circular plug, and a locking connector with two pins connecting to external red and black wires.  There was no documentation about intended voltage or current draw.

These days, for any device these days that has some kind of power plug, you will normally see a label, declaring the power type -- voltage, AC vs DC, polarity, and amperage.

I disassembled the controller to determine the voltage.  The inner workings of the controller are pretty spaciously housed, but not clearly labeled.  There was no transformer.

After getting pretty deep into the controller, I found that the red line went through a fuse, and then branched outward from terminal blocks.  Some of the branches connected to the stepper motor power port of Gecko motor drivers.

I then took a peek under the labels that covered the original labels of the arm motors.  After some searching, I found that the typical voltage to drive them would be 24 VDC.  So, I was pretty confident that it would work if I used 24 VDC on red, and 0 VDC on black. 

The documentation (page 9, see below under Documentation and software) states that the power connector has a "6.5A anti-surge" fuse for 110v power and says there's an equivalent 3.5A anti-surge for 220-240v power.   

After adding a bench power supply, pre-set to and tested at 24 V, I hooked up the controller and arm, and got a good "motor powered" single knock sound from the arm.

Subsequently, I've changed things to use a spare 24v, 10A dedicated power supply.  I'm pretty sure I pulled that from a Cube Pro Duo hefty 3d printer.  

Documentation and software

The arm came with a Mini CD.  On it, there is one directory, called manuals.  In that folder you can find many things, including PDF manuals, software, and drivers.

Manuals

There are lots of files provided in the manuals/manualsPDF folder on the CD.   Several documents on the CD are relevant for my set-up, but most are not.  Some describe other arms (e.g., R17) or expansion cards or other hardware that I do not have (e.g., teaching pads, end-effectors). 

Many of the manuals on the CD are not posted online.

Some manuals exist online.  The R12 manual is most commonly found, e.g., https://docs.rs-online.com/d934/0900766b8152ed18.pdf 

Some information I found online was not on the CD.  An important one is the useful tutorial7.pdf.

The ST-Robotics github page refers to documentation, but the links point to a now-defunct section of the ST-Robotics web site, and thus yield a 404 error.

Software 

Robwin provides the main UI for interfacing with the arm.  There are other command-line ways to do so, too, but unfortunately not all Robwin functions are described in command-line equivalents. 

The github repo provides Python code and ROS (v1)-related code for interfacing to MoveIt and Rviz.  The "python shell" provided at the git repo originally came from the Adam Heins implementation at https://github.com/adamheins/r12

Videos 

There are also several videos available on Youtube from ST-Robotics.  It appears that they are hosted by David N. Sands himself.  

Some of the same content is found in .mp4 form on the CD.

ST-Robotics had one more video posted to Youtube, showing usage of an R12 with ROS (v1). 

Recommendations

I have found these resources to be the most helpful:

1. The R12 manual

2. The tutorial7.pdf pages linked from superdroidrobots (https://www.superdroidrobots.com/blog-a/manuals/tutorial7.pdf)

3. The MultiIOcard.pdf manual.  This is only on the CD and not posted anywhere.  It describes the expansion ports and card and connections.  This is only relevant if your K11R is configured to include this card.

4. The source code and utilities at the Github repo (https://github.com/st-robotics)

5. The D.N.Sands Youtube videos.

Physical connections

The controller connects to the arm at two connection points, each of which is clearly labeled on the back of the controller.  One of these is referred to in the doc (section 12, Connections, page 25) as "25-way D-type, female", or what I'd call a D Sub 25 female port.  The other is a circular connector with lots of holes and a locking connector.

A front-side RS-232 serial port, labeled COMPUTER, connects to my laptop using a USB-to-Serial connector.  An FTDI driver disk was provided with the machine, but my Windows 7 laptop already had the drivers installed.  

A 9-pin female port labeled TEACH on the front connects the Teach pad.  The protocol for communication between the Teach pad and the controller is not described.  

Most ports are labeled clearly, and really don't give me any opportunity to mess up the connections.

OUTPUT (PA) and INPUT (PB) ports 

The OUTPUT port on the back is a 15-pin D Sub female.  Below it is an INPUT port, which is a 9-pin male port.  It turns out that these are ports PA (OUTPUT) and PB (INPUT).  Connections to these are optional.

On my controller, these were only labeled OUTPUT and INPUT.  The relationship to PA and PB could only be determined by shape, inspection, and testing. 

Expansion ports 

There are three more 25-pin ports on the back, and with a modified panel plate, there would be room for one more.  After much analysis, I've found that the ones I have connect to the J4 and J5 points on a MultiIOcard inside, and the other one appears to be for analog input/output.  As with PA and PB, connections to these are optional.

STOP jack 

Finally, while there is a STOP button on the front control panel, there is also a 1/4" jack on the back of the box for a second STOP switch.  Mine has a 1/4" plug that has two normally closed, temporary switches wire in series between the barrel and tip. 

The simple presence of an empty 1/4" plug in the jack does not allow for normal operation.

Without this STOP switch/plug in place and in a closed circuit state, the controller will power on, but will not respond to arm movements (e.g., will not honor a CALIBRATE command). 

Robwin software set-up (Windows)

The initial foray into working with the robot is to use the provided Robwin.exe program.  That runs on Windows, and provides a graphical user interface.  Among its features, the UI allows you to type and send FORTH commands, kind of like you have a terminal emulator for FORTH.

There is a .msi installer provided on the disk for installing Robwin.

For modern computers, connection to the RS232 serial port is done by a USB-to-Serial connector.  If necessary, an FTDI driver must be installed.  (It's available on a disk provided with the machine, and also can be found online.)   

Even with the driver installed, Robwin will not recognize the controller if it is connected to a COM port numbered higher than 9.  It's not clear why Robwin faces this limitation.  It turns out that upon connection, my laptop-to-controller connection was on COM16.

As it turns out, there are ways to remap the COM ports on Windows to bring a given COM port down to the desired range, as long as all those aren't already taken.  For me, they were already taken.  I disabled other software that was hogging the lower COM ports.  Between that and the remapping, I was able to get Robwin to see the controller.

Initial operation 

Much of the robot operation is as described in the demonstration videos and documentation.

The initial discussion of the machine centers around its use of FORTH as a base language.  I think I read somewhere that it's running a Z80 processor.

The main drivers are Geckos, one for each joint.  

The system is described as having an outer interpreter, and an inner interpreter.  I don't really care which is which.  The thing is, when you connect to the machine, you're using a plain FORTH interpreter.  Then, within that you issue the command ROBOFORTH, and that starts up another FORTH interpreter that has knowledge of all the special commands that let you control the robot.

You connect to the controller, run ROBOFORTH, and then say START.  At that point, if everything has gone well and all the connection checks are ok, the joint positions are assumed to be at 0, 0, 0, 0, 0, wherever the arm is currently positioned.  But, normally (and especially when first learning), you'll want that home position to be a known location, so that's why you run a calibration sequence.

To calibrate, you do this:

  • De-energize the motors (run DE-ENERGISE or DE-ENERGIZE)
  • Manually rotate the waist and arm joints roughly to a position where it's pointing straight up
  • Restore power (ENERGISE or ENERGIZE)
  • Run the CALIBRATE command.  

The CALIBRATE command moves the joints slowly to known points.  As each joint's calibration sensor point is found, it moves on to the next joint.  When all joints are calibrated, it rapidly moves all joints, leaving the arm in a fully up position.

If the CALIBRATE operation moves a joint a certain number of stepper motor steps (or perhaps a pre-defined amount of time), and does not hit its expected calibration sensor, the CALIBRATION operation stops and gives you an error message.  This may happen if a joint wasn't close enough to the sensor position to start with.  In that case, you might just want to run CALIBRATE again right away, and let it continue to the desired point.  However, if a joint is moving significantly away from the upright position, you might be better off de-energizing, manually moving the arm more upright, and trying anew.

The bottom of the arm doesn't really indicate where the "front" is.  You kind of have to guess and experiment, and be ready to hit the STOP button during movements until you're comfortable with its position.

Upon successful calibration, the arm joint positions will be at 0, 0, 0, 0, 0, which is its knowledge of "home".  You can see the step position by running the WHERE command.  If you were in Cartesian mode, you may need to run JOINT and then WHERE.  If you operate in Cartesian coordinates, you will see that the home position is X=0, Y=0, Z=5000 (i.e., 500.0 mm). 

The documentation provides other ways to modify the zero calibration points so that the arm isn't sticking straight up initially.  This can be important for environments that have limited vertical clearance, for example. 

Joint movement

For initial operation of the robot arm, you can enter either Joint teaching mode or Cartesian teaching movement in Robwin.

Clicking the T icon starts movement in joint mode.  Clicking the L-shaped axes icon starts Cartesian teaching mode.  The teaching pad becomes active, and you can move the robot arm joints by clicking on a joint button first, and then + or - to move.  

When in Joint mode, a joint moves continuously as long as the + or - button remains pressed.  The speed button, followed by + or -, changes the rate of joint movement.

In Cartesian modem, movement is stepwise, and the meaning of "speed" changes to mean an axis movement distance.  Lower step sizes might be 1 mm, whereas higher step sizes might be 10mm, or more.

What is joint movement?

The joint movement done by the teaching pad is a reflection of the relative MOVE operations underlying the system.  The controller moves the joint stepper motors by a number of steps, managing acceleration and jerk to reach the destination smoothly and with precision.  (And when I say "smooth movement", that's different from the smoothing function that the controller provides for route travel, explained later on.)

The waist joint rotates the arm around its vertical axis.

When the shoulder moves, everything further down -- the elbow, hand, and wrist -- comes along for the ride.  Similar applies to elbow movement.

Focusing on the elbow, it's important to realize that when it moves, the hand orientation relative to the elbow remains the same.  For example, suppose you calibrate, and the arm is pointing straight up and the hand is also pointing straight up.  If you rotate the elbow 45 degrees, the elbow-to-hand orientation is still straight.  But relative to ground, the hand is now 45 degrees.

The hand and wrist are a bit odd.  When the hand joint moves, the wrist does, too.  That's a result of how the gearing is done to control the wrist.  

What is Cartesian movement?

The controller provides a mechanism for doing "Cartesian" movement.  You can think of this as moving the hand-wrist in an X, Y, Z coordinate space.  At the calibrated home, you're at (x,y,z) = (0,0,5000), where 5000 means "500.0 mm".

When the Teach box is used to move in the Cartesian system, the top, left 3 buttons are for controlling X, Y, and Z motion.

Suppose you want to move the hand/wrist outward along the positive X axis.  You click the X button on the pad, and then hit +.   (The box's "speed" setting controls how far it moves along the axis.)  By moving out along X, the robot cannot possibly extend itself to maintain the original Z height.  So, the software computes new Y and Z locations that will accommodate the intended X position.  It moves all joints as needed to achieve the new X position goal.

Cartesian movements only cover X, Y, and Z positional changes.  As such, to reach a new location in one axis, the controller only has to figure out a "bend" in the other two.  The teach pad still lets you move the hand and wrist joints.  When in Cartesian mode, those are reported back as angular positions instead of motor step counts. 

More operations and details

There are mechanisms for setting up and running smoothed routes.  This is really the main function of the R12 robot.  It was built with the intent that users would move the arm to particular locations, save them as points in a route, and then run the route repeatedly.  
 
The smoothing of a route makes it such that as you move the joints from one point to another, it doesn't do a straight vector movements.  For example, suppose you have a route with four points 1, 2, 3, and 4.  You could have the arm move from 1 to 2, pause, 2 to 3, pause, and then 3 to 4.  That's what a route run looks like without smoothing.  With a smoothed route, it moves from 1 to 4, curving the motions around points 2 and 3.  It's not clear if the kinematics computations attempt to hit points 2 and 3, and maintain momentum, or if it moves near 2 and 3 as it eventually gets to the ultimate goal, point 4.
 

Addenda 

tutorial7 highlights

Some of the important things about the tutorial7 document

  • It seems to have come from ST Robotics originally.
  • Page 12 explains flag bytes that store motor enable and direction for each joint, e.g., 1 MEP C! 0 MDP C! 1000 MOVE for moving the waist 1000 steps.  MEP is preceded by a bitwise value (1 = waist, 2 = shoulder, 4 = elbow, etc.).  MDP is preceded by 0 for positive movement, or 2 for reverse movement.  (Does the existence of a per-joint MEP operation mean that you can selectively de-energize?)
  •  Page 15 shows how the command "TELL joint" is a separate operation from the MOVE or position MOVETO commands.  So, you can say TELL WAIST as one command, and then 1000 MOVE and -1000 MOVE as subsequent commands for relative movement.
  •  Page 19 shows how you can use the POINT name command to store a current location in a variable called name.  Later, you can use name GOTO to move the arm back to that point.  This is different from learned route points, but can be helpful in setting up a route.
  • Page 23 mentions the decimeters PLUNGE command.
  • Page 27 starts talking about "objects" and their presence markers at route locations.
  • Page 28 shows delay operations, e.g., MSECS or n USECS
  • Page 32 discusses some of the route location learning operations that can be performed.  However, it only goes into what the Teach pad is revealing.  What isn't shown are the route location reservation commands:
    • ROUTE name
    • n RESERVE
    • (use MOVE or MOVETO or GOTO commands to move arm)
    • LEARN
    • L.
  • Page 36 shows some commands that are not explained: LINE, EXAD, AXES, TRANSFORM.  It also discusses the CRUN and DSPASSUME commands.  I have not been able to try those yet, and don't really understand their purpose.
  • Page 36 also mentions the COMPUTE command.  This one is important, because it's pretty easy to move the arm using JOINT operations (number of motor steps a given joint moves), but in order to save those, you have to COMPUTE (get the controller to convert joint location information to Cartesian) before you can save the information as a point (using POINT name).
  • Page 39 shows how the L. command can show relative lines.  But, it doesn't really explain how a line is marked as being a relative movement.  This also appears on page 41 when discussing the "set approach" or "Set Apprch" button.
  • Page 50 discusses ENCASSUME which allows the system to pull the encoder locations as the true location.  (It's not clear what the "assume" word means here.  It could be a FORTHism, or it could mean "assume that the encoder locations are representative of a real location and are relatively accurate".  ENCASSUME is referenced later in a description of how you can do "lead by the nose" teaching, wherein you de-energize the motors, move the arm around, and then record a new position using ENCASSUME.  If you don't run ENCASSUME upon re-energizing, it will find a significant difference between the encoder positions and the last known instructed position, and will think that the arm crashed. It won't work well from then on.
  • Page 52 discusses the I/O ports PA and PB, but doesn't go into enough detail.  I'll have a separate page that discusses ports, pins, and bit offsets.  But, it does provide commands such as
    • PB IN .
    • PB 5 BIT? .
    • PB 5 1 WAIT
  • Page 52 also touches on usage of the ADC and DAC pins.  But, it does not really describe which pins of the 25-pin connector are used for what purpose.