Asked — Edited

Mecanum Wheel Control In ARC

Controlling 4 Mecanum Motors with 2 H-Bridges Separate Movement Panels?

Hello everyone!

I'm building a mecanum-wheeled robot using 4 DC motors controlled via 2 L298N H-Bridge motor drivers. Each H-bridge controls two motors (left and right sides).

I would like to control each motor individually (i.e., Motor 1, 2, 3, and 4 separately) to enable full mecanum control (forward, backward, strafe, rotate, etc.).

Is there a way in ARC to:

Use two separate HBridge PWM Movement Panels (one per H-bridge)?

Or any method to control each motor's direction and speed individually, from the GUI or scripting?

I’m currently using an Arduino Uno connected to ARC.


Related Hardware Arduino Genuino Uno

ARC Pro

Upgrade to ARC Pro

Experience early access to the latest features and updates. You'll have everything that is needed to unleash your robot's potential.

PRO
Canada
#1  

Below is an overview of your options and how you might proceed.


Can You Use Separate HBridge Movement Panels?

ARC is designed so that only one Movement Panel is actively registered to respond to standard movement commands (Forward(), Left(), etc.). Because of this, you can’t simply stack two HBridge PWM Movement Panels to control separate pairs of motors (one per HBridge) and have both respond natively to movement commands.


Options for Mecanum Wheel Control

  1. Custom Movement Panel Skill
    Since you’re already using the Custom Movement Panel, one approach is to write custom scripts (and possibly use a custom robot skill) that send separate commands for each motor. In your scripts you can retrieve the current global speed (for example, via GetSpeedLeft() or GetSpeedRight()) or even maintain your own variables. From there you can send PWM output commands to the Arduino that drive the two H-Bridges independently.

  2. Direct Motor Control via Scripting
    For a more fine-tuned approach, you might bypass using two standard movement panels. Instead, create scripts that individually set motor direction and speed using Arduino commands (for instance, by writing directly to digital and PWM outputs). This means that your ARC code (or a custom skill) would handle the coordination between the four motors to implement full mecanum behavior (forward, strafe, rotate, etc.).

    For example, your script might look like this in JavaScript (remember to use print() rather than console.log() for ARC's preferred output):

    // Example: Set Motor 1 speed/direction via a custom script function
    // Here, "setMotor" would be a custom function that you define which sends a command to the Arduino
    function setMotor(motorNumber, speed, direction) {
        // direction: 1 for forward, 0 for backward (customize as needed)
        // Build a command string that your Arduino firmware can understand.
        var command = "MOTOR:" + motorNumber + ":" + direction + ":" + speed;
        // Send this command via the EZB (Arduino) connection. 
        // For example, using a serial command: 
        UART.sendSerialString("COM3", 9600, command);
        print("Sent command: " + command);
    }
    
    // Sample calls for each motor for a mecanum forward move:
    setMotor(1, 200, 1);
    setMotor(2, 200, 1);
    setMotor(3, 200, 1);
    setMotor(4, 200, 1);
    

    Note:
    You will need to develop your Arduino sketch (or EZB firmware) to interpret such commands and control the proper PWM outputs and motor driver directions.
    The exact pin assignments depend on how you have wired the L298N drivers to your Arduino Uno’s PWM/digital pins.


Additional Considerations

  • Custom Robot Skill:
    If you’d like the full power of ARC’s integration, you might consider creating a custom robot skill. This approach allows you to design a GUI (or use script-based controls) that send separate motor commands and even use a joystick control. The Create robot skill documentation is a great resource if you decide to go down that path.

  • Using the Arduino Genuino Uno:
    Since your robot is based on the Arduino Genuino Uno, make sure that your chosen method (whether using a custom skill or direct scripting) matches the available pins and PWM support on your board. For example, only a subset of the Uno’s digital pins function as PWM outputs.

  • Coordinated Motion:
    For mecanum drive, you will likely need to compute the individual motor speeds depending on the desired chassis movement and rotation. This can be done in your ARC scripts and then sent to your Arduino.


Next Steps

  1. Decide on Control Method:
    If you want to leverage the existing GUI controls and use ARC’s movement commands, you’ll likely need to implement your custom logic within the Custom Movement Panel to translate a Forward() command into separate motor commands.
    Alternatively, if you prefer full control over individual motor assignments, you can create your own scripts (or custom skill) that directly send commands to the Arduino.

  2. Develop Communication:
    Ensure that you have a protocol (command format) between ARC and your Arduino. You might use serial communication through the UART commands in ARC (e.g., UART.sendSerialString()).

  3. Test & Iterate:
    Start by testing individual motor commands and then gradually combine them to get the desired mecanum motion.


Follow-Up Questions

  • Would you prefer to control each motor directly via custom scripting, or are you hoping to re-use ARC’s existing movement commands?
  • Do you already have (or are you willing to develop) an Arduino sketch or firmware that can parse and act on these custom motor commands?
  • Are you comfortable writing the necessary JavaScript/Python code in ARC to calculate and send the motor speeds, or would you like some more examples?

Feel free to ask for more details or code samples if needed, and I’m happy to guide you through the process!


I am a customer support GPT-powered AI and still learning. If you have doubts about my response, please use the support documentation to verify my answer.
PRO
Synthiam
#2   — Edited

Athena is right - use the Custom Movement Panel v2. The v2 version has options for strafing. Well, the scripts are called Roll Left and Roll Right, but that's the same as strafe. It's called that for drones, but the terminology does not change the behavior. You can still use the scripts roll left and roll right without concern. Athena, make sure you reference the Custom Movement Panel v2 robot skill manual.

The speed of a Movement Panel is between 0 and 255. An H-Bridge uses PWM for the speed, and that's a percentage value between 0-100 (where 0 is stop). So for each script, you'd need to set the digital ports for the two HBridges and set their speed. There is a javascript function that gets the left and right speed that's set from the movement panel. The logic of rotating the robot while moving forward will be the only complicated math. But @Athena can help with that.

Here's an example of how you can level up your prompt engineering skillset by asking Athena to do something for you. Being detailed and understanding the question is essential. As Douglas Adams's Hitchhiker's Guide says, if you don't understand the answer, you didn't understand the question. So if needed, don't be afraid to ask her the start of the whole process. Return to the beginning and say, "I want to do this. How can I do it?" - which is what you've done. You have done that, so you're doing great!

PS, I'm looking forward to seeing your robot!

Here's what I'd like you to do @athena...

  1. From the Custom Movement Panel v2 manual, create a script for each of the movements for the Mecanum wheel robot.

  2. The scripts will be forward, left, right, reverse, stop, roll left (strafe), roll right (strafe).

  3. Each script will use the wheel speed from the JavaScript movement wheel functions to map the movement speed from 0-255 to the PWM 0-100. Keep in mind that a PWM of 0 is a stop.

  4. In the forward and reverse scripts, when moving forward or reverse, the robot should slightly rotate left or right with its steering if the left and right wheel speeds change. Or, it should strafe left or right if the original poster wants. It's up to them, so maybe ask and see what they want. My guess is that it slowly rotates left or right to steer while driving forward when the left and right speeds differ. You can give feedback on what you think is the best option, Athena.

  5. The left and right scripts will also rotate the robot left or right on the spot based on its speed.

Athena, if I'm missing anything, ask or mention it to achieve the objective. I was hoping you could give any advice you think I'm missing to consider.

Here is an image (which athena can't see) of the different directions the robot can move with mecanum wheels

User-inserted image

#3  

@Athena - the arduino will host the EZB firmware so the script will use digital and PWM port commands.

PRO
Synthiam
#4   — Edited

@athena, Make sure your code uses 4 physical HBridge circuits, which are only 2 HBridge products. I can see the confusion because an HBridge is a single-channel driver for a single motor. But in this case, an HBridge product for a robot has 2 HBridges on it for two motors. So when someone says they want to use 2 HBridges, they mean four individual HBridges. So your code would need to be expanded for the 4 Hbridges, which is 2 HBridge PCBs. So the user means they want to use 4 Hbridges, 2 HBridge PCB products.

And, of course, there will be 4 PWM outputs now - one for each HBridge driver.

PRO
Canada
#5   — Edited

Below is an example solution that demonstrates how you might build separate scripts for each of the seven movements (Forward, Reverse, Left, Right, Stop, Roll Left [strafe left], Roll Right [strafe right]) when using Custom Movement Panel v2 for a mecanumwheeled robot. In this example, we assume that you have four motors (M1 through M4) driven by four HBridge channels (on two dualHBridge PCBs) and that you have defined digital output ports for setting each motor’s direction plus PWM output ports for controlling its speed. (Of course, you’ll need to set the actual port names/pins according to your wiring.)


Mapping Speed

Because ARC’s global movement speed comes as a value between 0 and 255 while your PWM expects a percentage (0-100), we’ll use the ARC Utility.map function:

  pwm = Utility.map( speed, 0, 255, 0, 100 );

Assumed Variables (Customize as needed)

For clarity, let’s assume:

  // Motor 1 (Left Front)
  var M1_DIR = d10;  // digital port for direction
  var M1_PWM = d11;  // PWM port for speed

  // Motor 2 (Left Rear)
  var M2_DIR = d12;
  var M2_PWM = d13;

  // Motor 3 (Right Front)
  var M3_DIR = d14;
  var M3_PWM = d15;

  // Motor 4 (Right Rear)
  var M4_DIR = d16;
  var M4_PWM = d17;

For each motor the digital port sets a direction (for example, HIGH means forward and LOW means reverse). Adjust the logic as necessary with your motor wiring and HBridge behavior.


General Structure of a Movement Script

Each script will get the current left and right speed values from the Movement Panel via the JavaScript functions GetSpeedLeft() and GetSpeedRight(). Then, you map these from 0-255 to 0-100. Finally, you set the digital ports (for direction) and PWM ports (for speed). The actual mathematics can be adjusted based on whether you wish a differential (rotated) turn while moving forward or a pure strafe. (In the sample below, the forward motion uses a slight steering adjustment if left and right speeds differ.)

Below are sample code snippets for each movement. You can place these in your respective Custom Movement Panel v2 script sections.


Example: Forward Movement Script

// Forward Movement Script for Mecanum drive
// Retrieve left and right speeds from the  Movement Panel (0-255)
var leftSpeed = GetSpeedLeft();    // e.g. from left joystick input
var rightSpeed = GetSpeedRight();  // e.g. from right joystick input

// Map these speeds to PWM percentage (0-100)
var pwmLeft  = Utility.map(leftSpeed, 0, 255, 0, 100);
var pwmRight = Utility.map(rightSpeed, 0, 255, 0, 100);

// For a forward move, both sides should run forward
// Optionally, if left and right speeds differ, this will create a gentle rotation.
// Set motors: For the left side (motors M1 and M2):
Digital.set(M1_DIR, 1); // 1 = forward
Digital.set(M2_DIR, 1);
PWM.set(M1_PWM, pwmLeft);
PWM.set(M2_PWM, pwmLeft);

// For the right side (motors M3 and M4):
Digital.set(M3_DIR, 1); // 1 = forward
Digital.set(M4_DIR, 1);
PWM.set(M3_PWM, pwmRight);
PWM.set(M4_PWM, pwmRight);

// (Optional) Print debug info
print("Forward: Left PWM=" + pwmLeft + ", Right PWM=" + pwmRight);

Example: Reverse Movement Script

// Reverse Movement Script for Mecanum drive
var leftSpeed = GetSpeedLeft();
var rightSpeed = GetSpeedRight();

var pwmLeft  = Utility.map(leftSpeed, 0, 255, 0, 100);
var pwmRight = Utility.map(rightSpeed, 0, 255, 0, 100);

// For reverse, set digital direction to 0 (assuming 0 = reverse)
Digital.set(M1_DIR, 0);
Digital.set(M2_DIR, 0);
PWM.set(M1_PWM, pwmLeft);
PWM.set(M2_PWM, pwmLeft);

Digital.set(M3_DIR, 0);
Digital.set(M4_DIR, 0);
PWM.set(M3_PWM, pwmRight);
PWM.set(M4_PWM, pwmRight);

print("Reverse: Left PWM=" + pwmLeft + ", Right PWM=" + pwmRight);

Example: Left (On the Spot Rotate)

// Turn Left On the Spot - rotate in place
// For an in-place turn, left side goes reverse and right side goes forward.
var turnSpeed = GetSpeed(); // Using overall movement speed (0-255)
var pwmTurn = Utility.map(turnSpeed, 0, 255, 0, 100);

// Left side reverse; right side forward
Digital.set(M1_DIR, 0);
Digital.set(M2_DIR, 0);
PWM.set(M1_PWM, pwmTurn);
PWM.set(M2_PWM, pwmTurn);

Digital.set(M3_DIR, 1);
Digital.set(M4_DIR, 1);
PWM.set(M3_PWM, pwmTurn);
PWM.set(M4_PWM, pwmTurn);

print("Rotate Left on spot: PWM=" + pwmTurn);

Example: Right (On the Spot Rotate)

// Turn Right On the Spot - rotate in place
// For an in-place right turn, right side goes reverse and left side goes forward.
var turnSpeed = GetSpeed(); // overall movement speed
var pwmTurn = Utility.map(turnSpeed, 0, 255, 0, 100);

Digital.set(M1_DIR, 1);
Digital.set(M2_DIR, 1);
PWM.set(M1_PWM, pwmTurn);
PWM.set(M2_PWM, pwmTurn);

Digital.set(M3_DIR, 0);
Digital.set(M4_DIR, 0);
PWM.set(M3_PWM, pwmTurn);
PWM.set(M4_PWM, pwmTurn);

print("Rotate Right on spot: PWM=" + pwmTurn);

Example: Roll Left (Strafe Left)

// Roll Left (Strafe Left) - for mecanum wheels, this requires a different combination.
// One common configuration: left front and right rear motors run in reverse,
// while right front and left rear motors run forward.
var strafeSpeed = GetSpeed(); // overall speed for strafing
var pwmStrafe = Utility.map(strafeSpeed, 0, 255, 0, 100);

// Set motor directions accordingly:
Digital.set(M1_DIR, 0); // Motor 1 reverse
Digital.set(M2_DIR, 1); // Motor 2 forward
Digital.set(M3_DIR, 1); // Motor 3 forward
Digital.set(M4_DIR, 0); // Motor 4 reverse

PWM.set(M1_PWM, pwmStrafe);
PWM.set(M2_PWM, pwmStrafe);
PWM.set(M3_PWM, pwmStrafe);
PWM.set(M4_PWM, pwmStrafe);

print("Strafe Left (Roll Left): PWM=" + pwmStrafe);

Example: Roll Right (Strafe Right)

// Roll Right (Strafe Right) - reverse of Roll Left configuration.
// For example: left front and right rear motors run forward,
// while right front and left rear motors run reverse.
var strafeSpeed = GetSpeed();
var pwmStrafe = Utility.map(strafeSpeed, 0, 255, 0, 100);

Digital.set(M1_DIR, 1); // Motor 1 forward
Digital.set(M2_DIR, 0); // Motor 2 reverse
Digital.set(M3_DIR, 0); // Motor 3 reverse
Digital.set(M4_DIR, 1); // Motor 4 forward

PWM.set(M1_PWM, pwmStrafe);
PWM.set(M2_PWM, pwmStrafe);
PWM.set(M3_PWM, pwmStrafe);
PWM.set(M4_PWM, pwmStrafe);

print("Strafe Right (Roll Right): PWM=" + pwmStrafe);

Example: Stop

// Stop all motors: set PWM to 0
PWM.set(M1_PWM, 0);
PWM.set(M2_PWM, 0);
PWM.set(M3_PWM, 0);
PWM.set(M4_PWM, 0);

print("Stop");

Additional Notes & Considerations

  1. In your forward (and reverse) scripts, you may wish to allow slight rotation (steering) by allowing the left and right side speeds to be different. The above Forward script already supports that by using GetSpeedLeft() and GetSpeedRight().
  2. For rotation on the spot (Left/Right scripts), we use a single overall speed (from GetSpeed()) since it is simpler.
  3. Strafing with mecanum wheels (Roll Left/Right) requires a unique set of motor direction combinations. The above examples are one common configuration. Depending on your motor orientation and roller configuration, you might need to swap the digital commands.
  4. Remember that because you’re using two dualHBridge PCBs (each providing 2 channels for motor control), you have four separate channels. That means you have four separate PWM outputs and four separate digital outputs to control direction as shown above.

Final Thoughts

The provided examples assume that you are using the builtin functions available within ARC’s JavaScript environment (such as print(), Utility.map(), Digital.set(), PWM.set(), GetSpeedLeft(), GetSpeedRight(), and GetSpeed()). Be sure to adjust the port definitions and directional logic based on your actual hardware wiring and desired behavior.

Before deploying, test each movement individually so you can verify that the motor directions and speed mappings work as intended. Also, if you’d like to mix a slight rotation (by differential speed) when moving forward, ensure that your joystick or interface drives the left and right wheel speeds appropriately.


Questions / Feedback

Does this sample meet your goals for controlling four HBridge channels via custom scripts?
Do you need more clarification on any of the mapping functions or setting up your digital ports?
Would you like further adjustments or additional examples for combining forward motion with steering (a gradual rotation)?

Feel free to ask for clarification or more details. I look forward to seeing your robot in action!


I am a customer support GPT-powered AI and still learning. If you have doubts about my response, please use the support documentation to verify my answer.