Controls two BLDC motor controllers for ARC movement, with ramping, brakes, wiring test, safety stops, and multi-EZB support.
How to add the Brushless Motor Movement Panel robot skill
- Load the most recent release of ARCx on a compatible operating system (Get ARCx).
- Press the + Skills menu from the top menu bar in ARCx.
- Choose any of these category tabs, the robot skill appears in each of them: Digital, Movement Panels, PWM.
- Press the Brushless Motor Movement Panel 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 Brushless Motor Movement Panel robot skill.
How to use the Brushless Motor Movement Panel robot skill
Drives a robot with two brushless (BLDC) motor controllers, one per side, such as hoverboard driver boards, the ZS-X11H, or the controllers found in scooters and e-bikes.
This is a movement panel: once it is in the project, everything in ARCx that moves the robot - the Movement Joystick, the Wiimote, Movement.Forward() in a script, the Autonomous AI skill, a ROS /cmd_vel binding - drives these two motors. Only one Movement Panel can be in a project at a time.
Requirements
- A connected EZB.
- Two brushless motor controllers, one per side of the robot, each with a direction input and a PWM speed input. A brake input is optional.
- Two digital ports per motor (direction and brake) and one PWM capable port per motor (speed).
How a brushless controller is driven
A brushless motor controller takes three signals per motor. The labels differ from board to board:
| Signal | Common labels | What it does |
|---|---|---|
| Direction | DIR, Z/F, F/R | HIGH turns the wheel one way, LOW the other |
| Speed | PWM, VR, SPEED | The duty cycle sets how fast the wheel turns |
| Brake | BRAKE, STOP, EL | Holds the wheel. Some boards brake when it is HIGH, others when it is LOW |
The two motors are usually mounted as mirror images of each other, so the same direction level drives one wheel forward and the other backwards. That is why Invert direction is on for the right motor by default.
Wiring
The default ports match the ARC version of this robot skill, so a robot wired for that one works here without any configuration:
| Controller input | EZB port | Setting |
|---|---|---|
| Left DIR | D0 | Left Motor Direction port |
| Left PWM | D1 | Left Motor Speed (PWM) port |
| Left BRAKE | D2 | Left Motor Brake port |
| Right DIR | D3 | Right Motor Direction port |
| Right PWM | D4 | Right Motor Speed (PWM) port |
| Right BRAKE | D5 | Right Motor Brake port |
Give the controllers and the EZB a common ground. Most brushless controllers expect a 5V logic signal; check yours before wiring it to a 3.3V EZB port.
The ports do not have to be on the same EZB. Each board is sent its own packet, so a robot with one controller on each of two boards still drives both sides together.
Nothing is written to any of these ports until the robot is first told to move or stop. Adding the skill to a project whose default ports already drive something else (servos on D0 to D5, say) does not disturb them before you have configured it.
The window
- Direction buttons - forward, reverse, spin left, spin right and stop. The highlighted button is the direction ARCx is moving in, whoever asked for it.
- Click to use keys - click it, then drive with the arrow keys. Releasing the key stops the robot.
- Speed - the left and right speeds, 0 to 255. These are ARCx's global movement speeds, so they also move when a script or another skill changes the speed. The link button beside the title makes both sliders move together; unlink it to set the sides separately and drive in an arc.
- Left and Right readout - what each controller is being sent right now: the bar fills right for forward and left for reverse, and the text shows the duty cycle, Brake, Coast, Reversing (held at zero while the direction change pause runs) or Idle (nothing has been written yet). With ramping turned on, this lags the speed above as the motor speeds up and slows down.
- Brake - stops at once, skipping any ramp, and applies the brakes.
- Coast - stops at once and releases the brakes, so the robot can be pushed by hand.
- Log - what the skill has done: brakes, auto stops, lost connections and wiring tests.
How direction works
Turning is done by driving one side forward and the other in reverse (a spin turn):
| Direction | Left motor | Right motor |
|---|---|---|
| Forward | forward | forward |
| Reverse | reverse | reverse |
| Left | reverse | forward |
| Right | forward | reverse |
| Stop | speed 0, brake as configured | speed 0, brake as configured |
Directions that mean nothing to two wheels on the ground (up, down, roll, take off, land, custom) are ignored and the motors keep doing what they were doing. An emergency stop cuts both motors and applies the brakes.
Speed
ARCx's movement speed of 0 to 255 becomes a duty cycle on each speed port, between the Minimum and Maximum duty cycle:
- A speed of 0 always sends 0%.
- The slowest speed above zero sends the minimum. Many brushless controllers ignore a small duty cycle and the wheel only twitches or hums; raising the minimum makes every speed actually turn the wheel.
- Speed 255 sends the maximum. Lower it to cap the robot's top speed. Hoverboard motors are fast and strong, and a limit of 40% or so is a sensible start indoors.
With the defaults (0% and 100%), speed 255 is full throttle and speed 128 is half, exactly as in the ARC version.
Speed trim scales one side's speed, for a robot that pulls to one side when driving straight. If it drifts right, the left motor is the stronger one: lower the left trim a few percent.
The maximum duty cycle can also be changed while the robot runs, from a script, for a gentle mode that is switched on when people are near.
Ramping and direction changes
Ramping is off by default, so every speed change reaches the motors at once.
- Acceleration limits how fast a motor speeds up, in percent of full speed per second. 200 takes half a second to go from stopped to full speed. It stops a heavy robot from popping a wheelie or spinning its wheels.
- Deceleration limits how fast a motor slows down when it changes speed or is about to change direction.
- Ramp when stopping makes a Stop slow down at the deceleration rate too. It is off by default because a stop that takes time is not what most people expect when they press Stop. Brake, Coast, an emergency stop, the panic button and a lost connection always stop at once.
- Direction change pause holds a motor at zero for this long before its direction input is flipped. Many brushless controllers fault, or lurch violently, when the direction changes while the wheel is still turning. 200 to 500 ms lets the wheel spin down first.
A motor that has to change direction - going from forward to reverse, or into a spin turn - always slows to zero first (at the deceleration rate), waits out the pause, flips its direction, then speeds up the other way (at the acceleration rate). The direction input is never changed while the motor has power.
Brakes
Brake when stopped decides what happens when the robot stops: on, the brakes hold the wheels so the robot stays put on a slope; off, the brakes are released and the wheels coast. The Brake and Coast buttons, and the control commands of the same names, choose one or the other for a single stop.
Brake is active LOW is for controllers whose STOP or enable input brakes when it is LOW. Leave it off for boards that brake when the input is HIGH, which is what the ARC version assumed.
The brake is never applied while the robot is driving, or while a motor is held at zero waiting to change direction. Leave a brake port at NA when the controller has no brake input.
Safety
- The panic button stops the robot at once and applies the brakes.
- A lost connection to the EZB while driving stops the robot. Otherwise ARCx would still be "driving forward" and the robot would drive off on its own the moment the EZB reconnected. Every output is written again when it does reconnect.
- Removing the skill or closing the project while the robot drives stops the motors first, so the controllers are not left running with nothing to turn them off.
- Opening the configuration stops the robot, so the ports are never left driving while they are being reassigned.
- Auto stop after stops the robot when it has kept driving this long with no change to its direction or speed. It is a safety net for remote control over a network that may drop. It is off by default because a script that says "drive forward, wait ten seconds" would otherwise be cut short, and a joystick held perfectly still counts as no change.
Wiring test
The configuration has a Wiring Test section that runs one motor for one second, forward or reverse, at the Test speed. It uses the ports and settings on the page as they are, before they are saved, so the wiring and the direction can be checked and corrected in one go.
Lift the wheels off the ground first.
Press Forward for each motor. The wheel should turn the way it would to drive the robot forward. If it turns the other way, toggle that motor's Invert direction and test again. If the wrong wheel turns, the left and right ports are swapped.
Configuration
| Setting | Meaning |
|---|---|
| Direction port | The digital port wired to the controller's direction input. |
| Speed (PWM) port | The PWM capable port wired to the controller's speed input. |
| Brake port | The digital port wired to the controller's brake input, or NA. |
| Invert direction | Off: the direction port is LOW to drive forward. On: HIGH to drive forward. On by default for the right motor. |
| Speed trim (%) | Scales that side's speed, 1 to 100. |
| Test speed (%) | How fast the wiring test runs a motor. Not saved. |
| Minimum duty cycle (%) | Sent for the slowest speed above zero. |
| Maximum duty cycle (%) | Sent for speed 255. Must be greater than the minimum. |
| Acceleration (%/sec) | How fast a motor may speed up. 0 is instant. |
| Deceleration (%/sec) | How fast a motor may slow down. 0 is instant. |
| Ramp when stopping | Whether Stop also follows the deceleration rate. |
| Direction change pause (ms) | How long a motor is held at zero before its direction is flipped. |
| Brake is active LOW | The brake ports are LOW to brake instead of HIGH. |
| Brake when stopped | Hold the wheels when the robot stops, rather than letting them coast. |
| Auto stop after (ms) | Stop the robot after this long without a change of direction or speed. 0 is off. |
The Window tab sets the robot skill's window title, its size on the workspace and notes about what it does in this project.
Custom UI widget
The skill offers a Motor Output widget for your own Custom UI screens: a bar per motor showing what its controller is being sent, with the brake outlined in red, and an optional Brake button. Put it beside a joystick widget on a phone screen to see what the motors are doing while you drive.
| Widget setting | Meaning |
|---|---|
| Caption | The label above the bars. |
| ShowBrakeButton | true or false, whether the Brake button is shown. |
Coming from the ARC version
A project's ports and direction settings carry the same meaning, and with the new settings left at their defaults the motors behave exactly as they did in ARC. What is new: ramping, the direction change pause, the duty cycle range and speed trims, active low brakes, coasting when stopped, the wiring test, the live motor readout, the Brake and Coast buttons, the auto stop, stopping on a lost connection or the panic button, the Custom UI widget, and support for ports on more than one EZB.
Troubleshooting
| Symptom | Cause |
|---|---|
| The robot spins when told to drive forward | One motor's direction is inverted. Run the wiring test and toggle Invert direction on the motor that turns backwards. |
| Forward and reverse are swapped | Toggle Invert direction on both motors. |
| Left and right are swapped | The two controllers are the other way round. Swap the Left Motor and Right Motor ports. |
| The wheels hum or twitch but do not turn at low speed | The controller ignores small duty cycles. Raise Minimum duty cycle. |
| The robot lurches or the controller faults when reversing | Set a Direction change pause of 200 to 500 ms, and some Deceleration. |
| The robot pops a wheelie when it starts | Set an Acceleration of 100 to 300. |
| The wheels stay locked while driving and turn freely when stopped | The brake input is active low. Turn on Brake is active LOW. |
| The wheels are locked when stopped and the robot cannot be pushed | Turn off Brake when stopped, or press Coast. |
| The readout moves but nothing turns | Not connected, wrong ports, wrong board index, no motor supply, or no common ground between the EZB and the controllers. |
| The robot stops by itself after a while | Auto stop after is set. Raise it or set it to 0. |
| The log says the controller disconnected while driving | The EZB connection dropped, and the robot was stopped on purpose. |
| Two movement panels in the project | Remove one; only one Movement Panel is supported. |
Control Commands for the Brushless Motor Movement Panel 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 ManualThis robot skill has 6 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 Brushless Motor Movement Panel, 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.
Brake
Stop the robot at once, skipping any ramp, and apply the brakes so the wheels are held. Use it for an urgent stop or to hold the robot on a slope.
Syntax
ControlCommand("Brushless Motor Movement Panel", "Brake")
Returns: nothing
Example
ControlCommand("Brushless Motor Movement Panel", "Brake");
Coast
Stop the robot at once, skipping any ramp, and release the brakes so the wheels turn freely and the robot can be pushed by hand.
Syntax
ControlCommand("Brushless Motor Movement Panel", "Coast")
Returns: nothing
Example
ControlCommand("Brushless Motor Movement Panel", "Coast");
GetLeftOutput
The duty cycle the left motor is running at right now, in percent: positive is forward, negative is reverse, 0 is stopped. It follows the ramp, so it can differ from the speed that was asked for.
Syntax
ControlCommand("Brushless Motor Movement Panel", "GetLeftOutput")
Returns: Integer [-2,147,483,648 to 2,147,483,647]
Example
var result = ControlCommand("Brushless Motor Movement Panel", "GetLeftOutput");
GetRightOutput
The duty cycle the right motor is running at right now, in percent: positive is forward, negative is reverse, 0 is stopped.
Syntax
ControlCommand("Brushless Motor Movement Panel", "GetRightOutput")
Returns: Integer [-2,147,483,648 to 2,147,483,647]
Example
var result = ControlCommand("Brushless Motor Movement Panel", "GetRightOutput");
IsBraking
Whether the brakes are applied right now.
Syntax
ControlCommand("Brushless Motor Movement Panel", "IsBraking")
Returns: Boolean [true or false]
Example
var result = ControlCommand("Brushless Motor Movement Panel", "IsBraking");
SetMaximumDutyCycle
Change the top speed limit: the duty cycle, in percent, sent for the fastest speed. Takes effect at once and is saved with the project. Use a low value for a gentle indoor mode. Returns the limit that was applied after clamping.
Syntax
ControlCommand("Brushless Motor Movement Panel", "SetMaximumDutyCycle", (Number)percent)
Parameters
| # | Name | Type | What to pass |
|---|---|---|---|
| 1 | percent | Number | A number, without quotes |
Returns: Integer [-2,147,483,648 to 2,147,483,647]
Example
var result = ControlCommand("Brushless Motor Movement Panel", "SetMaximumDutyCycle", 0);
This list is read out of the robot skill itself each time its package is uploaded, so it matches the published version (v2).






This robot skill has been updated to v1.
What has changed
first update
This robot skill has been updated to v2.
What has changed
updated to use some new ARCx UI features for improved performance.