Remote Mouse icon Remote Mouse Scriptable Remote Mouse for ARC: control PC cursor and ARC window via ControlCommand, using voice, camera or I/O inputs; shows cursor coordinates. Try it →
Holland
Asked
Movement Joystick analog speed to custom panel

Movement Joystick Analog Speed To Custom Panel

Running ARC on a Rock Pi X mounted in a small 2WD rover. The Rock Pi X connects over USB to an Arduino Nano that drives a Cytron dual motor driver (PWM+DIR for each motor). In ARC I’m using a Custom Movement Panel with JavaScript to send serial commands like "Lxxx Rxxx\n" to the Nano, and I added the Movement Joystick skill to get analog steering on a touchscreen. Expected: pushing the stick halfway should map to lower PWM; Actual: regardless of how far I move the joystick, the robot goes at the fixed speed defined in my Custom Movement Panel’s scripts, so it looks like only Forward/Reverse/Left/Right are being triggered without any speed magnitude.

I tried lowering the Movement Joystick Max Speed and tweaking the Dead Zone, but it still runs at my hardcoded values. I opened the Variable Watcher while moving the joystick and don’t see anything updating that looks like X/Y. I also tried grabbing possible vars in JS (e.g., getVar("$MovementJoystickX")/getVar("$MovementJoystickY")) and testing ControlCommand calls to the Movement Joystick, but didn’t find anything documented. I even added a SetSpeed-style function in the Custom Movement Panel in case it’s called automatically, but it never fired.

Here’s the simplified bit of what my Custom Movement Panel is doing now:

function forward() { sendSerial("L200 R200\n"); }
function left()    { sendSerial("L100 R200\n"); }
function stop()    { sendSerial("L0 R0\n"); }

What is the correct way to get analog X/Y values from the Movement Joystick into a Custom Movement Panel (or otherwise achieve variable speed with my USB-serial Arduino motor driver)?



Related Hardware (view all EZB hardware)
Rock Pi X by Radxa
Control robots with Synthiam ARC on ROCK Pi X: affordable x86 SBC running Windows, Z8350 quad-core, 4K HDMI, Wi‑Fi, drivers and setup tips.
Wi-Fi / USB
Servos
Camera
Audio
UART
I2C
ADC
Digital

Related Robot Skills (view all robot skills)
Custom Movement Panel maps directional commands to scripts, adjusts per-wheel speed (0-255), and integrates with joysticks for unsupported motors
Analog joystick UI to control any ARC movement panel via mouse/touch-configurable dead zone, max speed, center-reset for smooth robot motion

ARC Pro

Upgrade to ARC Pro

With ARC Pro, your robot is not just a machine; it's your creative partner in the journey of technological exploration.

Author Avatar
PRO
Canada
Twitter YouTube GitHub
#1  

What you’re seeing is expected behavior in ARC:

  • Movement Joystick sends movement directions to the active Movement Panel
  • It does not pass raw X/Y analog values into a Custom Movement Panel
  • A Custom Movement Panel receives direction events like forward(), reverse(), left(), right(), stop() - but not joystick position values

So the key point is:

There isn’t a built-in analog X/Y handoff from Movement Joystick to Custom Movement Panel.

Why your speed stays fixed

Your scripts are hardcoded:

function forward() { sendSerial("L200 R200\n"); }
function left() { sendSerial("L100 R200\n"); }
function stop() { sendSerial("L0 R0\n"); }

That means ARC is correctly calling the direction event, but the script itself always sends the same PWM values regardless of joystick position.

Correct ways to achieve variable speed

Option 1: Use the movement speed values inside your custom movement panel

ARC exposes movement speed values for movement panels, and those are what you should read inside your custom movement scripts.

In JavaScript, use:

Movement.getSpeed()
Movement.getSpeedLeft()
Movement.getSpeedRight()

Those values come from the current movement system, including the joystick if the joystick is configured to control the movement panel.

Example custom Movement Panel script

function forward() {
  var left = Movement.getSpeedLeft();
  var right = Movement.getSpeedRight();

  print("Forward left=" + left + " right=" + right);
  sendSerial("L" + left + " R" + right + "\n");
}

function reverse() {
  var left = Movement.getSpeedLeft();
  var right = Movement.getSpeedRight();

  sendSerial("L-" + left + " R-" + right + "\n");
}

function left() {
  var left = Movement.getSpeedLeft();
  var right = Movement.getSpeedRight();

  sendSerial("L" + Math.floor(left * 0.5) + " R" + right + "\n");
}

function right() {
  var left = Movement.getSpeedLeft();
  var right = Movement.getSpeedRight();

  sendSerial("L" + left + " R" + Math.floor(right * 0.5) + "\n");
}

function stop() {
  sendSerial("L0 R0\n");
}

Important setup check

Make sure your Movement Joystick is actually controlling the project’s Movement Panel:

  1. Open the Movement Joystick skill
  2. Click the three-line menu in the top-right
  3. Verify it is assigned to control the project’s movement panel
  4. Confirm your Custom Movement Panel is the active movement panel

If it isn’t bound properly, the joystick may move its own internal control without affecting the movement speed values you’re reading.

About X/Y values

ARC does not expose joystick X/Y as simple global variables like:

  • $MovementJoystickX
  • $MovementJoystickY

So your test with getVar() wouldn’t find anything because that’s not how this skill publishes its values.

Best approach for your rover

For a 2WD rover, the cleanest pattern is usually:

  • Movement Joystick controls movement
  • Custom Movement Panel reads Movement.getSpeedLeft() and Movement.getSpeedRight()
  • Your script converts those into serial commands for the Nano

That gives you proper analog speed without needing raw joystick X/Y.

One thing to keep in mind

If your Cytron driver expects signed direction + PWM, you may want to translate the movement speed into left/right motor power and direction yourself rather than sending fixed text commands.

For example:

function forward() {
  var speed = Movement.getSpeed();
  sendSerial("F" + speed + "\n");
}

function left() {
  var leftSpeed = Movement.getSpeedLeft();
  var rightSpeed = Movement.getSpeedRight();
  sendSerial("L" + leftSpeed + " R" + rightSpeed + "\n");
}

That depends on the command format your Arduino Nano is parsing.

Helpful references

If you want, I can help you rewrite your custom Movement Panel script

If you paste:

  1. your exact Nano serial command format, and
  2. whether your rover uses forward/reverse per motor or signed speed values,

I can write the full JavaScript custom Movement Panel scripts for:

  • forward
  • reverse
  • left
  • right
  • stop
  • speed-changed handling

That’s the cleanest way to make the joystick truly analog in ARC.

I am a customer support AI and still learning. Please verify important answers in our support documentation. For advanced AI features, use the AI Script Agent built into ARC.