XM540 모터를 이용해서 OPEN-RB150 에 아두이노를 통해서 일정 각도만큼 계속 돌아가는 프로젝트를 하고 있습니다.
근데 이게 처음에는 각도가 잘 맞는데, 오차가 아주 조금씩 생겨서 나중에는 각도가 계속 벌어지더라구요.
그래서 원래 모터가 이런건지 제가 코드를 잘 못짜고 있는건지.
일정 각도가 일정하게 계속 잘 돌아가는 방법이 있는지 아시는분 도움주시면 감사하겠습니다.
XM540 모터를 이용해서 OPEN-RB150 에 아두이노를 통해서 일정 각도만큼 계속 돌아가는 프로젝트를 하고 있습니다.
근데 이게 처음에는 각도가 잘 맞는데, 오차가 아주 조금씩 생겨서 나중에는 각도가 계속 벌어지더라구요.
그래서 원래 모터가 이런건지 제가 코드를 잘 못짜고 있는건지.
일정 각도가 일정하게 계속 잘 돌아가는 방법이 있는지 아시는분 도움주시면 감사하겠습니다.
안녕하세요.
먼저 openrb에서 12v 출력으로 xm540에 연결하신지 확인하고싶습니다.
rb의 기본 출력은 5v로 12v가 기본 입력인 xm540에 연결을 하기 위해 매뉴얼을 참고하여 출력 전압을 변경시켜야합니다.
또 재현과 확인을 위해 사용하신 코드 공유 가능하신가요??
안녕하세요 답변주셔서 감사합니다.
말씀주신내용 답변드리겠습니다.
→ 12v 출력으로 xm540에 연결하였고, rb 보드 역시 핀값을 바꿔서 출력 전압을 변경시켰습니다.
→ 하단의 코드 공유드리겠습니다. 감사합니다 slight_smile:
#include <Dynamixel2Arduino.h>
// 모터 설정
#define DXL_SERIAL Serial1
#define DEBUG_SERIAL Serial
const uint8_t DXL_DIR_PIN = 2; // OpenRB-150의 방향 제어 핀
const uint8_t DXL_ID = 1; // 모터 ID
const float DXL_PROTOCOL_VERSION = 2.0;
Dynamixel2Arduino dxl(DXL_SERIAL, DXL_DIR_PIN);
// 제어 변수
int currentPosition = 0; // 현재 목표 위치 (60도 단위)
unsigned long lastMoveTime = 0;
bool isMoving = false;
// 상수 정의
const int DEGREES_60 = 683; // 60도에 해당하는 위치값 (4095/360*60)
const int MOVE_TIME = 3000; // 이동 시간 (3초)
const int WAIT_TIME = 3000; // 대기 시간 (3초)
void setup() {
// 시리얼 통신 초기화
DEBUG_SERIAL.begin(57600);
dxl.begin(57600);
dxl.setPortProtocolVersion(DXL_PROTOCOL_VERSION);
// 모터 연결 확인
if(dxl.ping(DXL_ID)) {
DEBUG_SERIAL.println(“모터 연결 성공!”);
} else {
DEBUG_SERIAL.println(“모터 연결 실패!”);
while(1);
}
// 토크 활성화
dxl.torqueOff(DXL_ID);
// Position Control Mode 설정
dxl.setOperatingMode(DXL_ID, OP_POSITION);
// Profile Velocity 설정 (3초 동안 60도 이동)
// XM540의 경우 약 30 정도의 값이 적절함
dxl.writeControlTableItem(PROFILE_VELOCITY, DXL_ID, 30);
// Profile Acceleration 설정
dxl.writeControlTableItem(PROFILE_ACCELERATION, DXL_ID, 10);
// 토크 활성화
dxl.torqueOn(DXL_ID);
// 초기 위치를 0도로 설정
dxl.setGoalPosition(DXL_ID, 0);
delay(1000);
DEBUG_SERIAL.println(“모터 제어 시작!”);
lastMoveTime = millis();
}
void loop() {
unsigned long currentTime = millis();
if (!isMoving) {
// 이동 명령 전송
currentPosition++;
int targetPosition = currentPosition * DEGREES_60;
DEBUG_SERIAL.print("목표 위치로 이동: ");
DEBUG_SERIAL.print(currentPosition * 60);
DEBUG_SERIAL.println("도");
dxl.setGoalPosition(DXL_ID, targetPosition);
isMoving = true;
lastMoveTime = currentTime;
} else {
// 이동 완료 확인 (3초 경과 후)
if (currentTime - lastMoveTime >= MOVE_TIME) {
DEBUG_SERIAL.println(“이동 완료. 3초 대기…”);
// 3초 대기
delay(WAIT_TIME);
isMoving = false;
lastMoveTime = millis();
}
}
// 현재 위치 출력
if (currentTime % 500 == 0) {
int presentPosition = dxl.getPresentPosition(DXL_ID);
float degrees = (presentPosition * 360.0) / 4095.0;
DEBUG_SERIAL.print("현재 위치: ");
DEBUG_SERIAL.print(degrees);
DEBUG_SERIAL.println(“도”);
}
delay(10);
}
// 모터 정지 함수
void stopMotor() {
dxl.torqueOff(DXL_ID);
DEBUG_SERIAL.println(“모터 정지”);
}
Your Directional Pin is currently set to an incorrect value (=2)
It should be set to -1, like shown below:
const uint8_t DXL_DIR_PIN = -1;
Also right now you are using your DXL at 57,600 bps, please verify this setting also.
If you are conversant with English, please check out this free Amazon Kindle sample of my Arduino book, it has lots of information for users of the OpenRB-150.
https://www.amazon.com/Using-ARDUINO-ROBOTIS-Systems-Ngoc-ebook/dp/B0BPXGQ6YX
Also your raw-to-degrees conversion formula is slightly off:
It really should be
float degrees = (presentPosition * 360.0) / 4096.0;