Picture In Picture icon Picture In Picture — Picture-in-picture camera overlay: superimpose one camera onto another; configure source/destination, position, size, border, processed frames, and swap Try it →
 
Ssc32 Servo Controller Robot Skill

Ssc32 Servo Controller

by Lynxmotion

Drives up to 32 servos on Lynxmotion SSC-32/SSC-32U from ARCx virtual ports with flexible mapping, speed, and pulse control

Requires ARCx v1 (Updated 10/12/2026)
Tags: Servo
Compatible with: Compatible with Microsoft Windows 10 or 11 Windows Compatible with ARM Linux (Raspberry pi, etc) ARM Compatible with Linux Linux Compatible with MacOS MacOS

How to add the Ssc32 Servo Controller robot skill

  1. Load the most recent release of ARCx on a compatible operating system (Get ARCx).
  2. Press the + Skills menu from the top menu bar in ARCx.
  3. Choose the Servo category tab.
  4. Press the Ssc32 Servo Controller icon to add the robot skill to your project.

Don't have a robot yet?

Follow the Getting Started Guide to build a robot and use the Ssc32 Servo Controller robot skill.


How to use the Ssc32 Servo Controller robot skill

The SSC-32 servo Controller robot skill drives up to 32 hobby servos on a Lynxmotion SSC-32 or SSC-32U servo controller from ARCx virtual servo ports. Every robot skill that moves servos (Auto Position, joysticks, scripts, servo Animation, kinematics) moves a virtual port such as V7, and this robot skill turns that move into an SSC-32 command and sends it to the board.

Unlike the ARC SSC-32 skill, which fixed V0 to V31 onto channels 0 to 31, any virtual port can be mapped to any SSC-32 channel. V7 can drive channel 16, one port can drive two channels for a mirrored pair, and each channel has its own pulse range, direction and speed limit.

Requirements

  • A Lynxmotion SSC-32 or SSC-32U servo controller with its own servo power supply.
  • One way to talk to it:
    • USB: the SSC-32U's USB port (or an SSC-32 on a USB to serial adapter) plugged into the computer running ARCx. No EZB is needed for the servos.
    • EZB hardware UART: the SSC-32's serial input (RX) wired to the TX pin of UART 0, 1 or 2 of an EZ-B v4, with a common ground. Wire the SSC-32's TX back to the UART's RX as well if you want to read anything from the board.
    • EZB digital port: the SSC-32's RX wired to any digital port. This is transmit only: servos move, but nothing can be read back.
  • The baud rate of the board. The original SSC-32 picks 2400, 9600, 38400 or 115200 with its baud jumpers; the SSC-32U is set with its button (9600 out of the box). 115200 is the best choice when many servos move at once.

Even when the SSC-32 is on USB, the robot skill listens to the virtual ports of one EZB in the project (EZB #0 unless you change it), because that is where ARCx keeps virtual servo positions. That EZB does not have to be connected for a USB board to work.

The window

SSC-32 <a href='/Support/Advanced-Fundamentals/servo-motor' target='_top'>servo</a> Controller window

  • Link chip - the connection (USB port or EZB and UART) and its baud rate. Green when the link is working, amber when the last attempt failed, grey when the port is not there.
  • Status - Ready, or the reason the last send failed. The firmware version is shown beside it once it has been read.
  • TX / RX / T/O - command lines sent, replies received and queries that timed out since the counters were reset with the button beside them.
  • Open - opens (or reopens) the link now. It also opens by itself when the EZB connects, when the project loads for a USB board, and on the first move.
  • Version - asks the SSC-32 for its firmware version. A quick check that the board's TX is wired back and the baud rate is right.
  • Release all - releases every mapped port, so the servos go limp and can be moved by hand.
  • Table - one row per mapped channel: the virtual port, the SSC-32 channel, its pulse range, and the last pulse sent (with its speed limit, when there was one). The buttons on each row move the port to the centre position or release it, through ARCx, the same as any other robot skill would.
  • Log - what the robot skill did. With Debug logging on, every command line sent and every reply.

Configuration: Connection

Connection settings

Setting Meaning
EZB The EZB whose virtual servo ports (V0 to V255) this robot skill answers to. For the UART and digital port connections it is also the EZB the SSC-32 is wired to.
Port Where the SSC-32 is connected: a COM port on this computer (USB), EZB hardware UART 0, 1 or 2, or an EZB digital port (transmit only).
Digital port The digital port wired to the SSC-32's RX, when Port is a digital port.
COM port The SSC-32U's port (COM5, /dev/ttyUSB0), when Port is a COM port. Press refresh after plugging the board in.
Baud rate Pick a preset or type another rate. It must match the board. A digital port only supports 4800 to 115200.
Open automatically Open the link as soon as the EZB connects, or when the project loads for a USB board. Off waits for the first move or the Open button.
Release stops the pulse When ARCx releases a port, send a pulse width of 0 to its channels, which stops the pulses so the servos go limp. Off leaves them holding their last position.
Answer position reads When a script or robot skill asks for a mapped port's real position (for example Servo.getPositionRealtime(v7)), ask the SSC-32 for the pulse it is putting out right now, which shows where a slow move has got to. Needs the board's TX wired back, and every read is a round trip on the link. Off answers with the last position ARCx sent.
Query timeout (ms) How long a question to the board (version, position, movement, inputs) waits for the answer.
Speed at velocity 1 (us/s) How ARCx servo velocities become SSC-32 speed limits. Velocity 1 moves at this many microseconds per second and higher velocities are slower: the speed is this value divided by the velocity. With the default 3000, velocity 2 is 1500 us/s and velocity 10 is 300 us/s. Velocity 0 uses each channel's own Speed.
Debug logging Write every command line sent and every reply to the log. Useful while wiring up the board, noisy once it works.

Configuration: Channels

Channel map

Each row connects one ARCx virtual servo port to one SSC-32 channel. The port number and the channel number do not have to match. A new robot skill starts with V0 to V31 on channels 0 to 31, the layout of the ARC SSC-32 skill, so a project moved from ARC behaves the same until you change it.

Column Meaning
On Untick to park a row without losing its settings. A parked row sends nothing.
Virtual port The ARCx port, V0 to V255, that moves this channel.
SSC-32 channel The channel the servo is plugged into, 0 to 31, as printed beside the header on the board.
Min us The pulse width in microseconds for the lowest ARCx position (1). The SSC-32 accepts 500 to 2500.
Max us The pulse width for the highest ARCx position (the project's servo maximum, normally 180).
Invert Reverse the direction, so the lowest position gives Max us. For a servo mounted mirrored.
Speed us/s The channel's speed limit while no robot skill has set a velocity on the port. 0 is full speed. 1000 us/s sweeps a typical servo about 90 degrees in a second.

The buttons above the table:

  • Add channel - adds a row on the lowest free channel, with the virtual port of the same number when that port is free.
  • V0-V31 to 0-31 - replaces every row with the ARC SSC-32 skill's layout. It asks first.
  • Remove all - removes every row. It asks first, and so does the delete button on each row.
  • Pulse range for every row - sets Min us and Max us of every row at once, handy when all the servos are the same model.

One port, several channels

A port can appear on more than one row. Each move of that port then moves all of its channels together, in the same command line, so they start and finish together. The usual use is a pair of servos working one joint from opposite sides: map both to the same port and tick Invert on one of them. A channel, however, can only belong to one port. If two rows use the same channel, the configuration page warns you and only the first row drives it.

Finding the pulse range

The defaults (650 to 2250) are the ARC skill's and suit most standard servos, but servos differ. To find a servo's real limits, move it slowly towards each end with the servo robot skill and stop when it reaches its mechanical end or starts to buzz, then set Min us and Max us a little inside those points. The ControlCommand SetChannelPulse is useful here as well, because it sends a raw pulse width to a channel without the map.

How moves reach the SSC-32

  • Every move ARCx makes on mapped ports goes to the board as one command line, for example #16P1797#31P1203, which the SSC-32 runs as a group move. A servo Animation frame or an Auto Position frame moving ten servos is one line, not ten.
  • ARCx's servo fine tune is applied before the pulse width is worked out, so fine tuning a port in ARCx fine tunes the SSC-32 channel.
  • A velocity set on the port (from a script, Auto Position or another robot skill) becomes the S speed limit of the moves that follow. Acceleration is ignored; the SSC-32 has none.
  • Ports that are not mapped are ignored, so this robot skill can share an EZB's virtual ports with other servo drivers (Dynamixel, Feetech) as long as they use different ports.

Using it from scripts

Move servos with the normal servo commands on the mapped virtual ports. The robot skill's control commands add what the servo commands cannot do: raw pulses, the SSC-32's digital outputs and inputs, and questions to the board.

// Move V7 (both of its channels) to 120 degrees at a gentle speed
Servo.setVelocity(v7, 5);
Servo.setPosition(v7, 120);

// Wait until the board says every speed limited move has finished
while (controlCommand("Ssc32 servo Controller", "IsMoving"))
  sleep(50);

// A timed group move straight to the board: both servos arrive together after 2 seconds
controlCommand("Ssc32 servo Controller", "SendCommand", "#0P1500#1P1800T2000");

// Switch an LED on channel 30
controlCommand("Ssc32 servo Controller", "SetDigitalOutput", 30, true);
# Read the SSC-32's analog input A (0 to 255 for 0 to 5 volts)
value = controlCommand("Ssc32 servo Controller", "ReadAnalogInput", "A")
print(value * 5.0 / 255)

Anything sent with SendCommand or SetChannelPulse goes straight to the board, so ARCx's own idea of the servo positions does not change. Use the servo commands for anything other robot skills need to know about.

Notes

  • Questions to the board (Version, IsMoving, GetChannelPulse, the inputs, and Answer position reads) need the SSC-32's TX wired back to the EZB UART's RX, or a USB connection. Over a digital port they fail at once.
  • The table's Last sent is what ARCx sent, not what the servo did. If the SSC-32 loses power while ARCx keeps running, the servos are limp while the table still shows the old pulses.
  • When the EZB disconnects, a UART or digital port link stops until it reconnects; it reopens by itself when Open automatically is on. A USB link does not care about the EZB.
  • Add the robot skill once per SSC-32 for a robot with two boards, each with its own connection and its own ports.

Troubleshooting

Symptom Cause
Nothing moves, the status says EZB disconnected The link is on an EZB UART or digital port and that EZB is not connected. Connect it, or use the USB connection.
Nothing moves, the status is Ready The port that moved is not mapped, its row is unticked, the baud rate does not match the board, or the servo power supply is off. Turn on Debug logging and check that the command lines in the log name the channels you expect.
Could not find file 'COM5' The COM port is not there. Plug the board in, press refresh on the Connection tab and pick the port again.
Version (or another query) times out The board's TX is not wired back, the baud rate does not match, or the link is a digital port. Movement still works without it.
A servo moves the wrong way Tick Invert on its row.
A servo buzzes at one end of its travel Its pulse range goes past what it can reach. Bring Min us or Max us in.
Servos move with a jerk at the start of the project The SSC-32 had no pulse before the first move. Move the servos to a known pose (an Auto Position frame, for instance) when the project starts.
Release does not make a servo go limp Release stops the pulse is off, or the port was released while the link was down.

Control Commands for the Ssc32 Servo Controller robot skill

There are Control Commands available for this robot skill which allows the skill to be controlled programmatically from scripts or other robot skills. These commands enable you to automate actions, respond to sensor inputs, and integrate the robot skill with other systems or custom interfaces. If you're new to the concept of Control Commands, we have a comprehensive manual available here that explains how to use them, provides examples to get you started and make the most of this powerful feature.

Control Command Manual

This robot skill has 13 control commands, listed below. Send them from a JavaScript or Python script, from Blockly, or from another robot skill.

The first value is always the window title, which is the name in the title bar of the robot skill on your workspace. It starts out as Ssc32 servo Controller, which is what every example below uses. If you rename the robot skill, or add a second copy of it to the project, use the title as it appears on that window instead.

ControlCommand() can be shortened to CC(), and both spellings work in JavaScript and in Python. The examples are JavaScript; Python is the same call, except that true and false are written True and False.

GetChannelMap

The enabled virtual port to channel mappings, one "V3 -> #12" entry per channel.

Syntax

ControlCommand("Ssc32 servo Controller", "GetChannelMap")

Returns: Array of String

Example

var result = ControlCommand("Ssc32 servo Controller", "GetChannelMap");

GetChannelPulse

Ask the SSC-32 for the pulse width it is outputting on a channel (0 to 31) right now, in microseconds (10 us resolution). 0 means no pulse. Needs the SSC-32's transmit line wired back.

Syntax

ControlCommand("Ssc32 servo Controller", "GetChannelPulse", (Number)channel)

Parameters

# Name Type What to pass
1 channel Number A number, without quotes

Returns: Integer [-2,147,483,648 to 2,147,483,647]

Example

var result = ControlCommand("Ssc32 servo Controller", "GetChannelPulse", 0);

GetStatus

The link description and its status, such as "COM5 @ 115,200 bps: Ready".

Syntax

ControlCommand("Ssc32 servo Controller", "GetStatus")

Returns: String

Example

var result = ControlCommand("Ssc32 servo Controller", "GetStatus");

GetVersion

The SSC-32 firmware version text. Needs the SSC-32's transmit line wired back.

Syntax

ControlCommand("Ssc32 servo Controller", "GetVersion")

Returns: String

Example

var result = ControlCommand("Ssc32 servo Controller", "GetVersion");

Initialize

Open (or reopen) the serial link to the SSC-32 now rather than on the next move. Returns true when it opened.

Syntax

ControlCommand("Ssc32 servo Controller", "Initialize")

Returns: Boolean [true or false]

Example

var result = ControlCommand("Ssc32 servo Controller", "Initialize");

IsMoving

True while a speed limited move is still running on the SSC-32, false once every servo has arrived. Needs the SSC-32's transmit line wired back.

Syntax

ControlCommand("Ssc32 servo Controller", "IsMoving")

Returns: Boolean [true or false]

Example

var result = ControlCommand("Ssc32 servo Controller", "IsMoving");

ReadAnalogInput

Read SSC-32 input A, B, C or D as an analog input. Returns 0 to 255 for 0 to 5 volts. Needs the SSC-32's transmit line wired back.

Syntax

ControlCommand("Ssc32 servo Controller", "ReadAnalogInput", (String)input)

Parameters

# Name Type What to pass
1 input Text Your text, in quotes

Returns: Integer [-2,147,483,648 to 2,147,483,647]

Example

var result = ControlCommand("Ssc32 servo Controller", "ReadAnalogInput", "input");

ReadDigitalInput

Read SSC-32 input A, B, C or D as a digital input. Returns true when high. Needs the SSC-32's transmit line wired back.

Syntax

ControlCommand("Ssc32 servo Controller", "ReadDigitalInput", (String)input)

Parameters

# Name Type What to pass
1 input Text Your text, in quotes

Returns: Boolean [true or false]

Example

var result = ControlCommand("Ssc32 servo Controller", "ReadDigitalInput", "input");

ReleaseAll

Release every mapped virtual port, which stops the pulses on their SSC-32 channels so the servos go limp.

Syntax

ControlCommand("Ssc32 servo Controller", "ReleaseAll")

Returns: Boolean [true or false]

Example

var result = ControlCommand("Ssc32 servo Controller", "ReleaseAll");

ReleaseChannel

Stop the pulses on one SSC-32 channel (0 to 31) so its servo goes limp, bypassing the virtual port map.

Syntax

ControlCommand("Ssc32 servo Controller", "ReleaseChannel", (Number)channel)

Parameters

# Name Type What to pass
1 channel Number A number, without quotes

Returns: Boolean [true or false]

Example

var result = ControlCommand("Ssc32 servo Controller", "ReleaseChannel", 0);

SendCommand

Send any SSC-32 command line as it is, such as "#0P1500#1P1500T2000" for a timed group move. The carriage return is added. Nothing is read back.

Syntax

ControlCommand("Ssc32 servo Controller", "SendCommand", (String)command)

Parameters

# Name Type What to pass
1 command Text Your text, in quotes

Returns: Boolean [true or false]

Example

var result = ControlCommand("Ssc32 servo Controller", "SendCommand", "command");

SetChannelPulse

Send a raw pulse width (500 to 2500 microseconds) to an SSC-32 channel (0 to 31), bypassing the virtual port map and ARCx's servo state. Optional speed in microseconds per second, 0 for full speed. Returns the pulse sent.

Syntax

ControlCommand("Ssc32 servo Controller", "SetChannelPulse", (Number)channel, (Number)microseconds, (Number)speed)

Parameters

# Name Type What to pass
1 channel Number A number, without quotes
2 microseconds Number A number, without quotes
3 speed Number A number, without quotes

Returns: Integer [-2,147,483,648 to 2,147,483,647]

Example

var result = ControlCommand("Ssc32 servo Controller", "SetChannelPulse", 0, 0, 0);

SetDigitalOutput

Use an SSC-32 channel (0 to 31) as a digital output: true drives it high, false low. Do not use a channel that has a servo on it.

Syntax

ControlCommand("Ssc32 servo Controller", "SetDigitalOutput", (Number)channel, (Bool)high)

Parameters

# Name Type What to pass
1 channel Number A number, without quotes
2 high True or false true or false, without quotes

Returns: Boolean [true or false]

Example

var result = ControlCommand("Ssc32 servo Controller", "SetDigitalOutput", 0, true);

This list is read out of the robot skill itself each time its package is uploaded, so it matches the published version (v1).


ARC Pro

Upgrade to ARC Pro

Don't limit your robot's potential – subscribe to ARC Pro and transform it into a dynamic, intelligent machine.