MyActuator RMD X12-150. Can't control via CAN-BUS Arduino

Hello,

I am trying to control RMD X12-150 motor via CAN-BUS using Arduino Nano. I use MCP2515 CAN module for arduino. I wrote the code based on the User manual. I attached my code below. I am trying to do speed control of the motor. When I press ‘x’ it should increase the speed, and inverse when I press ‘s’. However, the motor is just spinning with constant speed, even when I set the speed as 0. Also, when I try to do position control and give 0 degree angle, it is still rotating to a random angle. Also, I receive some response from the motor. Based on this response, I see that I don’t receive any position feedback. Is it possible to reset the motor to factory settings? Or receive any help from someone who worked with this motor? It is not V2 nor V3. Its can message types are of different structure.

Code:

#include <SPI.h>          // Library for using SPI Communication 
#include <mcp2515.h>      // Library for using CAN Communication

/*SAMD core*/
#ifdef ARDUINO_SAMD_VARIANT_COMPLIANCE
#define SERIAL SerialUSB
#else
#define SERIAL Serial
#endif

struct can_frame canMsg;
MCP2515 mcp2515(10);
char incomingChar; // Store incoming character from Serial

int speedControl = 0; // Speed control value

void setup() 
{
    Serial.begin(115200);
    while (!Serial);

    mcp2515.reset();
    mcp2515.setBitrate(CAN_1000KBPS, MCP_8MHZ); // Set CAN bus speed to 1000 kbps
    mcp2515.setNormalMode();

    Serial.println("Setup done");

    enable();
    // setZero();
    sendPositionControlCommand(0, 10000, 10);

    delay(5000);
}

void enable(){
    canMsg.can_id  = 0x7FF; // Use an appropriate ID for speed control
    canMsg.can_dlc = 4;     // Data length is 4 bytes

    // Populate CAN message data according to the datasheet
    canMsg.data[0] = (0x01 >> 8) & 0xFF;
    canMsg.data[1] = 0x01 & 0xFF;
    canMsg.data[2] = 0x00;
    canMsg.data[3] = 0x01;
    mcp2515.sendMessage(MCP2515::TXB1, &canMsg); // Send CAN message for speed control
    Serial.print("Enable: ");
    printserial(canMsg.can_id, canMsg.data);
    Serial.println();
}

void setZero(){
    canMsg.can_id  = 0x7FF; // Use an appropriate ID for speed control
    canMsg.can_dlc = 4;     // Data length is 4 bytes

    canMsg.data[0] = (0x01 >> 8) & 0xFF; // Motor id high
    canMsg.data[1] = 0x01 & 0xFF; // motor id low
    canMsg.data[2] = 0x00; 
    canMsg.data[3] = 0x03; 
    mcp2515.sendMessage(MCP2515::TXB1, &canMsg); // Send CAN message for speed control
    Serial.print("Zero Setting: ");
    printserial(canMsg.can_id, canMsg.data);
    Serial.println();
}





void sendSpeedControlCommand(int32_t speedControl) {
    canMsg.can_id  = 0x1FF; // Use an appropriate ID for speed control
    canMsg.can_dlc = 7;     // Data length is 7 bytes

    // Populate CAN message data according to the datasheet
    canMsg.data[0] = 0x03; // Motor mode
    canMsg.data[1] = 0x00; // Reserved control status (must be 0)
    canMsg.data[2] = 0x00; // Message return status (set to 0)

    float expectedSpeed = static_cast<float>(speedControl);
    uint32_t speedBytes = *reinterpret_cast<uint32_t*>(&expectedSpeed);

    canMsg.data[3] = (speedBytes >> 8) & 0xFF; // High byte of speed
    canMsg.data[4] = speedBytes & 0xFF; // Next byte
    canMsg.data[5] = 0x00; 
    canMsg.data[6] = 0x00; 

    mcp2515.sendMessage(MCP2515::TXB1, &canMsg); // Send CAN message for speed control
    Serial.print("Sent: ");
    printserial(canMsg.can_id, canMsg.data);
    Serial.println();
}

void sendPositionControlCommand(float expectedPosition, uint16_t expectedSpeed, uint16_t currentThreshold) {
    canMsg.can_id  = 0x1FF; // Use an appropriate ID for position control
    canMsg.can_dlc = 8;     // Data length is 8 bytes

    canMsg.data[0] = 0x01; // Motor mode (Position Control)
    
    // Convert expected position to bytes
    uint32_t positionBytes = *reinterpret_cast<uint32_t*>(&expectedPosition);
    canMsg.data[1] = (positionBytes >> 24) & 0xFF; // High byte
    canMsg.data[2] = (positionBytes >> 16) & 0xFF; // Next byte
    canMsg.data[3] = (positionBytes >> 8) & 0xFF;  // Next byte
    canMsg.data[4] = positionBytes & 0xFF;         // Low byte

    // Populate expected speed (15 bits)
    canMsg.data[5] = (expectedSpeed >> 8) & 0xFF; // High byte of speed
    canMsg.data[6] = expectedSpeed & 0xFF;        // Low byte of speed

    // Populate current threshold (12 bits)
    canMsg.data[7] = (currentThreshold & 0x0FFF); // Low byte of current threshold (12 bits)

    mcp2515.sendMessage(MCP2515::TXB1, &canMsg); // Send CAN message for position control
    Serial.print("Sent Position Control: ");
    printserial(canMsg.can_id, canMsg.data);
    Serial.println();
}

void printserial(unsigned long ID, unsigned char buf[8]) {
    Serial.print(ID, HEX);
    Serial.print(": ");
    for (int i = 0; i < 8; i++) {
        Serial.print(buf[i], HEX);
        Serial.print("  ");
    }
    Serial.println();
}

void loop() 
{
    if (Serial.available() > 0) {
        incomingChar = Serial.read(); // Read a single character
        if (incomingChar == 'x') { // Increase speed
            speedControl += 100; // Adjust increment as needed
            if (speedControl > 10000) speedControl = 10000; // Limit maximum speed
        } 
        else if (incomingChar == 's') { // Decrease speed
            speedControl -= 100; // Adjust decrement as needed
            if (speedControl < -10000) speedControl = -10000; // Limit minimum speed
        }
    }

    // sendSpeedControlCommand(speedControl); // Send updated speed command

    // Read incoming CAN message if available
    if (mcp2515.readMessage(&canMsg) == MCP2515::ERROR_OK) {
        // Response received
        Serial.print("Recv: ");
        printserial(canMsg.can_id, canMsg.data);
        Serial.println();
    } else {
        // No response
        Serial.println("Recv: NO ANSWER");
    }

    delay(100); // Adjust delay as needed
}

Motor Response:
Recv: 205: FE 48 0 1 1 B0 66 0

Sent: 1FF: 3 0 0 0 0 0 0 0

Recv: 205: FE 48 0 1A 2 20 66 0

Sent: 1FF: 3 0 0 0 0 0 0 0

Recv: 205: FE 48 1 29 2 13 66 0

Sent: 1FF: 3 0 0 0 0 0 0 0

Recv: 205: FE 48 C 12 0 31 66 0

Sent: 1FF: 3 0 0 0 0 0 0 0

Recv: 205: FE 48 F 1 0 37 66 0

1 Like

Hello @nurda100rich and welcome to our forum.

I would usually recommend that for this specific technical issue, you get in contact with MyActuator support. They know how to solve these problems and they usually reply fast.

You can reach out to them on [email protected].

Or maybe you already contacted them?

Yeah, I contacted them. But they are on holidays till 6th of october, and this is kinda urgent for me. I thought, maybe someone worked with exactly that motors:)

1 Like

Hi @nurda100rich ,

Did you get any support from MyActuator? They should be back from the holidays.

Thank you.

Hi @igor_X,

Yes they replied. I was able to do speed control. However, there are problems with position and torque control. When i set some angle of rotation in position control, it just rotates for some random angle. And when i do toque control, even if i don’t have any load on the shaft of the motor it just starts rotating. I am having trouble understanding the core of the problem. I also read some discussions in this forum, where people were having problems with myactuator motors, some were because of the driver problems. I suspect I have driver problems too.

1 Like

Hi @nurda100rich . Maybe you need to update firmware but I am sure MyActuator support would help you with that.