[MyActuator] [RMD] X12-150 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.

#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