다이나믹셀 모터 속도 제어 문제

안녕하세요!

현재 다이나믹셀 mx-28 모델 사용하고 있습니다. 모터를 아두이노 우노에 다이나믹셀 쉴드를 달아서 제어를 시도하고 있습니다. 다이나믹셀 위자드로 확인을 해보니 프로토콜 버전이 1.0이라서 펌웨어 복구를 통해 2.0으로 변경을 시도했습니다. 그 후 아래 코드를 이용해보니 모터가 돌아가지 않더라구요! 그리고 또 다이나믹셀 라이브러리를 이용해서 velocity_mode 예제를 돌려보는데 그 것도 잘 안 되더라구요. 다른 예저인 operating mode나 ping모드는 잘 돌아가고요. dxl.setGoalVelocity로 하는게 안 되는 건지 펌 복구가 이상하게 돼서 이런 오작동이 일어나는 건지 궁금해서 문의해봅니다!

전체 코드는 아래에 첨부해보겠습니다! 감사합니다!

#include <Dynamixel2Arduino.h>
#include <DynamixelShield.h>

#if defined(ARDUINO_AVR_UNO) || defined(ARDUINO_AVR_MEGA2560)
  #include <SoftwareSerial.h>
  SoftwareSerial soft_serial(7, 8); // DYNAMIXELShield UART RX/TX
  #define DEBUG_SERIAL soft_serial
#elif defined(ARDUINO_SAM_DUE) || defined(ARDUINO_SAM_ZERO)
  #define DEBUG_SERIAL SerialUSB
#else
  #define DEBUG_SERIAL Serial
#endif

const uint8_t DXL_ID = 3;
const float DXL_PROTOCOL_VERSION = 2.0;

DynamixelShield dxl;
//Dynamixel2Arduino dxl(DXL_SERIAL, DXL_DIR_PIN);

//This namespace is required to use Control table item names
using namespace ControlTableItem;

float distance_to_time = 60.0 / (22.9 * 2 * PI * 10); // Update: Add decimal point to ensure correct float division

void setup() {
  DEBUG_SERIAL.begin(9600);
  
  dxl.begin(9600);
  while (!DEBUG_SERIAL);

  // Set Port Protocol Version.
  dxl.setPortProtocolVersion(DXL_PROTOCOL_VERSION);
  
  // Get DYNAMIXEL information
  dxl.ping(DXL_ID);

  // Turn off torque when configuring items in EEPROM area
  dxl.torqueOff(DXL_ID);
  dxl.setOperatingMode(DXL_ID, OP_VELOCITY);
  dxl.torqueOn(DXL_ID);
}

void loop() {
  if (DEBUG_SERIAL.available()) { // Read the desired duration from the serial monitor
    String mess = DEBUG_SERIAL.readStringUntil('.');
    DEBUG_SERIAL.print("Input values: ");
    DEBUG_SERIAL.println(mess);
    delay(10);

    int moving_distance1 = mess.toInt();

    DEBUG_SERIAL.print("Moving distance 1 (mm) = ");
    DEBUG_SERIAL.println(moving_distance1);

    if (moving_distance1 > 0) {
      float time1 = moving_distance1 * 1000.0 * distance_to_time; 
      DEBUG_SERIAL.print("Motor 1 expected rotation time: ");
      DEBUG_SERIAL.print(time1);
      DEBUG_SERIAL.println(" milliseconds");

      unsigned long startTime1 = millis();
      while (millis() - startTime1 < time1) {
        dxl.setGoalVelocity(DXL_ID, 300);
        delay(1); // Update: Add small delay for motor control
      }

      DEBUG_SERIAL.print("Motor 1 rotation time: ");
      DEBUG_SERIAL.print(millis() - startTime1);
      DEBUG_SERIAL.println(" milliseconds");

      dxl.setGoalVelocity(DXL_ID, 0);
      delay(1);
    }
    else if (moving_distance1 < 0) {
      float time2 = (-1) * moving_distance1 * 1000.0 * distance_to_time;
      DEBUG_SERIAL.print("Motor 1 expected rotation time: ");
      DEBUG_SERIAL.print(time2);
      DEBUG_SERIAL.println(" milliseconds");

      unsigned long startTime2 = millis();
      while (millis() - startTime2 < time2) {
        dxl.setGoalVelocity(DXL_ID, -100);
        delay(1);
      }

      DEBUG_SERIAL.print("Motor 1 rotation time: ");
      DEBUG_SERIAL.print(millis() - startTime2);
      DEBUG_SERIAL.println(" milliseconds.");

      dxl.setGoalVelocity(DXL_ID, 0);
      delay(1);
    }
    else {
      dxl.setGoalVelocity(DXL_ID, 0);
      DEBUG_SERIAL.println("Motor 1 did not rotate.");
    }
  }
}

안녕하세요.

다른 예제에서는 잘 동작하셨다면, 다이나믹셀의 문제는 없어 보입니다.
(펌웨어 복구는 잘 된 것 같습니다.)

첨부하신 코드를 보면

const uint8_t DXL_ID = 3;

dxl.begin(9600);

사용하시는 다이나믹셀의 id가 3번이고 통신속도가 9,600bps이신가요?

펌웨어 복구를 하셨다면, id는 1번으로 통신속도는 57,600bps로 변경됩니다.

사용하시는 다이나믹셀의 설정을 확인 후 맞게 수정하여 사용해 주세요.

또한, while (!DEBUG_SERIAL); // 터미널 창을 열어야 예제가 실행이 됩니다.

감사합니다.

넵! 다이나믹셀 위저드를 통해서 다이나믹셀의 id가 3번이고 통신속도가 9,600bps 인 것을 확인하고 코드를 업로드 후 시리얼 통신을 했는데 모터가 돌아가지않네요.

그리고 다이나믹셀 쉴드에 있는 라이브러리에 velocity_mode 예제 또한 아이디랑 통신 속도를 바꾸어서 돌려봤는데 실행이 안 되네요. 시리얼 모니터 상에서 통신은 잘 되는데 모터만 돌아가지 않습니다!

위가 다이나믹셀 설정입니다!

보니까 속도가 300이면 range에서 벗어나서 작동이 안 되는 거였군요! 속도를 다른 숫자로 바꾸니 잘 돌아갑니다!