참고로, 블루투스 장치는 소형이고 값이 싸며, 다른 무선통신보다 손쉽게 구현할 수 있다. 블루투스 통신 수신 거리는 10~20m 정도 되며, 통신 감도를 떨어트리는 장애물이나 전파 방해가 없으면, 10미터이상도 송수신된다. 보통 10미터 내에서 근거리 통신하기 위해 사용한다.
사용한 부품은 다음과 같다.
- 로보티즈 OpenCM 9.04
- BT-410
- 로보티즈 다이나믹셀
- 다이나믹셀 Serial USB
이 내용은 다음 레퍼런스를 참고하였다.
1. 개요
OpenCM 9.04는 BT-210, BT-410을 이용한 블루투스 시리얼 통신을 지원한다. 이 글에서는 상대적으로 저렴한 BT-410을 사용하여, 다이나믹셀을 무선 제어해 보는 내용을 정리하였다.
두 블루투스 통신 방식의 차이점은 다음 표와 같으며, BT-410의 데이터 통신 속도가 128 kbps로 좀 낮은 것 제외하고는 큰 차이점은 없다.
참고로, BT-210보다 가격이 훨씬 저렴한 HC-05, HC-06을 이용한 통신을 처리하기 위해, 4핀 포트 케이블을 만들어 OpenCM과 연결해 보았다. 그리고, Serial2로 통신을 시도해 보았다. 하지만, 이 방식은 로보티스에서 제공하는 Serial2과 호환이 되지 않는다. 해당 무선 포트를 HC 칩과 연결해 보았으나, Serial2에서 데이터를 송수신하지 못한다. 다른 방식으로 이 문제를 해결해 보기 위해, SoftwareSerial을 이용한 방식을 시도해 보았으나, SoftwareSerial 라이브러리는 OpenCM과 호환되지 않아, 실행 이미지가 빌드되지 않았다.
두 블루투스 통신 방식의 차이점은 다음 표와 같으며, BT-410의 데이터 통신 속도가 128 kbps로 좀 낮은 것 제외하고는 큰 차이점은 없다.
ZIG-110/100A | BT-100/110A/210 | BT-410 | ||
Connectivity | Andriod |
X
|
O
|
O
|
Connectivity | iOS |
X
|
X
|
O
|
Connectivity | PC |
X
|
O
|
X
|
Connectivity | 1 Master : 1 Slave |
O
|
O
|
O
|
Connectivity | 1 Master : N Slave |
O
|
X
|
X
|
Connectivity | 1 Phone : 1 Slave |
X
|
O
|
O
|
Connectivity | 1 Phone : N Slave |
X
|
X
|
support later
|
Data | Data Transfer reliability |
Low
|
high
|
high
|
Data | Max throughput |
250kbps
|
250kbps
|
128kbps
|
Update | Module FW update |
X
|
X
|
O
|
MAC address | Default MAC address |
xxxx
|
BT-110/100 : 001901 xxxxxx
BT-210 : B863BC xxxxxx
|
DBE7DF xxxxxx
|
MAC address | MAC address range |
0~65535
|
6 byte
|
6 byte
|
2. 블루투스 코드 다운로드 및 연결 테스트
OpenCM9.04와 BT-410을 다음과 같이 연결한다.
ROBOTIS의 OpenCM IDE 소프트웨어를 실행한다 (아두이노 IDE와 유사한 개발 도구이다).
테스트를 위해, OpenCM IDE 메뉴에서 블루투스 소스 코드 예제를 다음 그림과 같이 선택한다. 그리고, 해당 코드를 OpenCM 보드로 다운로드 한다.
이제, OpenCM에 시리얼 통신으로 블루투스 장치와 통신할 수 있는 코드를 업로드하였으므로, 몇가지 테스트를 해 보자. 우선, OpenCM IDE 프로그램을 종료하여, 점유하고 있는 COM포트를 해제한다.
블루투스 설정 및 테스트를 위해, 다음 링크의 Tera Term 프로그램을 다운로드 후 설치한다. 그리고, 실행한다.
실행한 후, 다음과 같이 'serial'모드와 OpenCM에 연결된 포트를 설정하고 확인을 누른다.
다음과 같이, setup->terminal 메뉴를 선택해, 'local echo'모드를 체크한다.
확인을 누른후, 터미널 창에서 '!'를 누르면, ok메시지를 받을 것이다. 'at'명령도 입력해 본다.
3. 안드로이드 앱 기반 블루투스 연결 및 제어 테스트
4. 바로 앞에서 설명한 OpenCM 블루투스 예제 코드가 업로드되어 있다면, OpenCM IDE에서 시리얼 모니터링을 실행하고, nRF UART 앱에서 문자열을 입력한다. 그럼, 다음과 같이 정상적으로 무선 통신이 되는 것을 확인할 수 있다.
아울러, 'go', 'back', 'left', 'right' 키워드를 입력할 때마다, OpenCM의 13번 LED가 점멸하는 것을 확인 할 수 있다.
4. 로봇 암 무선 제어 테스트
OpenCM에 위 코드를 업로드하고, 무선으로 안드로이드 앱을 통해 테스트를 해 본다. 다음과 같이 작동되면 성공이다.
5. 마무리
OpenCM9.04와 BT-410을 다음과 같이 연결한다.
테스트를 위해, OpenCM IDE 메뉴에서 블루투스 소스 코드 예제를 다음 그림과 같이 선택한다. 그리고, 해당 코드를 OpenCM 보드로 다운로드 한다.
이제, OpenCM에 시리얼 통신으로 블루투스 장치와 통신할 수 있는 코드를 업로드하였으므로, 몇가지 테스트를 해 보자. 우선, OpenCM IDE 프로그램을 종료하여, 점유하고 있는 COM포트를 해제한다.
블루투스 설정 및 테스트를 위해, 다음 링크의 Tera Term 프로그램을 다운로드 후 설치한다. 그리고, 실행한다.
실행한 후, 다음과 같이 'serial'모드와 OpenCM에 연결된 포트를 설정하고 확인을 누른다.
다음과 같이, setup->terminal 메뉴를 선택해, 'local echo'모드를 체크한다.
확인을 누른후, 터미널 창에서 '!'를 누르면, ok메시지를 받을 것이다. 'at'명령도 입력해 본다.
3. 안드로이드 앱 기반 블루투스 연결 및 제어 테스트
이제 안드로이드 용 블루투스 통신 터미널 앱인 nRF UART v2.0을 다운로드하여 설치한다.
다음과 같이 블루투스 통신을 테스트해보자.
1. OpenCM IDE를 띄우고, 다음과 같이 코딩한 후, OpenCM으로 전송한다.
// BT410 bluetooth string test code
// for testing BT410 bluetooth
// by Kang Tae Wook (laputa99999@gmail.com)
// at 2016.6.22
#include <string.h>
#include <stdio.h>
void setup()
{
Serial2.begin(57600);
Serial2.print("BT410 connect!");
pinMode(BOARD_LED_PIN, OUTPUT);
toggleLED();
}
void loop()
{
char string[256];
int i = 0;
while(SerialUSB.available())
{
char ch = SerialUSB.read(); //send data coming from USB to Serial2
string[i] = ch;
i++;
if(ch == -1)
break;
delay(5);
}
string[i] = 0;
if(strlen(string))
Serial2.print(string); //send data coming from USB to Serial2
i = 0;
while(Serial2.available())
{
char ch = Serial2.read();
string[i] = ch;
i++;
if(ch == -1)
break;
delay(5);
}
string[i] = 0;
if(strlen(string))
SerialUSB.print(string); //send data coming from Serial2 to USB(PC)
if(strstr(string, "go"))
{
toggleLED(); delay(1000);
toggleLED(); delay(1000); toggleLED();
}
else if(strstr(string, "back"))
{
toggleLED(); delay(500);
toggleLED(); delay(500); toggleLED();
}
else if(strstr(string, "left"))
{
toggleLED(); delay(500);
toggleLED(); delay(1000); toggleLED();
}
else if(strstr(string, "right"))
{
toggleLED(); delay(1000);
toggleLED(); delay(500); toggleLED();
}
}
2. 안드로이드 기기와 BT-410 블루투스를 연결한다.
3. 앱에서 해당 블루투스를 선택해 연결해 페어링한다. 페어링하면, 블루투스 장치의 깜빡거리던 청색 LED가 점멸을 멈추고 켜진 상태가 된다.
4. 바로 앞에서 설명한 OpenCM 블루투스 예제 코드가 업로드되어 있다면, OpenCM IDE에서 시리얼 모니터링을 실행하고, nRF UART 앱에서 문자열을 입력한다. 그럼, 다음과 같이 정상적으로 무선 통신이 되는 것을 확인할 수 있다.
아울러, 'go', 'back', 'left', 'right' 키워드를 입력할 때마다, OpenCM의 13번 LED가 점멸하는 것을 확인 할 수 있다.
4. 로봇 암 무선 제어 테스트
로봇 암(robot arm)을 무선 제어하기 위해, 로봇 암을 준비한 후, 다음과 같이 OpenCM IDE에서 코딩을 한다. 로봇 암 제작 방법은 이 글 맨 앞의 레퍼런스를 참고한다.
// BT410 bluetooth string test code
// for testing BT410 bluetooth
// by Kang Tae Wook (laputa99999@gmail.com)
// at 2016.6.22
#include <string.h>
#include <stdio.h>
/* Serial device defines for dxl bus */
#define DXL_BUS_SERIAL1 1 //Dynamixel on Serial1(USART1) <-OpenCM9.04
#define DXL_BUS_SERIAL2 2 //Dynamixel on Serial2(USART2) <-LN101,BT210
#define DXL_BUS_SERIAL3 3 //Dynamixel on Serial3(USART3) <-OpenCM 485EXP
/* Dynamixel ID defines */
#define ID_NUM 1
#define ID_NUM2 2
Dynamixel Dxl(DXL_BUS_SERIAL1);
void setup()
{
Serial2.begin(57600);
Serial2.print("BT410 connect!");
pinMode(BOARD_LED_PIN, OUTPUT);
toggleLED();
Dxl.begin(3);
Dxl.jointMode(ID_NUM); //jointMode() is to use position mode
}
void loop()
{
char string[256];
int i = 0;
while(SerialUSB.available())
{
char ch = SerialUSB.read(); //send data coming from USB to Serial2
string[i] = ch;
i++;
if(ch == -1)
break;
delay(5);
}
string[i] = 0;
if(strlen(string))
Serial2.print(string); //send data coming from USB to Serial2
i = 0;
while(Serial2.available())
{
char ch = Serial2.read();
string[i] = ch;
i++;
if(ch == -1)
break;
delay(5);
}
string[i] = 0;
if(strlen(string))
SerialUSB.print(string); //send data coming from Serial2 to USB(PC)
char* value = strstr(string, "=");
int angle = 50;
if(value)
{
value = value + 1;
angle = atoi(value);
if(angle < 0)
angle = 0;
if(angle >= 512)
angle = 512;
SerialUSB.print("angle=");
SerialUSB.print(angle);
}
if(strstr(string, "yaw="))
Dxl.setPosition(ID_NUM, angle, 70); // ID, position between 0 to 1023, speed between 0 to 100
else if(strstr(string, "roll="))
Dxl.setPosition(ID_NUM2, angle, 70);
else if(strstr(string, "left"))
Dxl.setPosition(ID_NUM, 0, 70); // ID, position between 0 to 1023, speed between 0 to 100
else if(strstr(string, "right"))
Dxl.setPosition(ID_NUM, 512, 70); // ID, position between 0 to 1023, speed between 0 to 100
delay(1000);// it has more delay time for slow movement
}
// for testing BT410 bluetooth
// by Kang Tae Wook (laputa99999@gmail.com)
// at 2016.6.22
#include <string.h>
#include <stdio.h>
/* Serial device defines for dxl bus */
#define DXL_BUS_SERIAL1 1 //Dynamixel on Serial1(USART1) <-OpenCM9.04
#define DXL_BUS_SERIAL2 2 //Dynamixel on Serial2(USART2) <-LN101,BT210
#define DXL_BUS_SERIAL3 3 //Dynamixel on Serial3(USART3) <-OpenCM 485EXP
/* Dynamixel ID defines */
#define ID_NUM 1
#define ID_NUM2 2
Dynamixel Dxl(DXL_BUS_SERIAL1);
void setup()
{
Serial2.begin(57600);
Serial2.print("BT410 connect!");
pinMode(BOARD_LED_PIN, OUTPUT);
toggleLED();
Dxl.begin(3);
Dxl.jointMode(ID_NUM); //jointMode() is to use position mode
}
void loop()
{
char string[256];
int i = 0;
while(SerialUSB.available())
{
char ch = SerialUSB.read(); //send data coming from USB to Serial2
string[i] = ch;
i++;
if(ch == -1)
break;
delay(5);
}
string[i] = 0;
if(strlen(string))
Serial2.print(string); //send data coming from USB to Serial2
i = 0;
while(Serial2.available())
{
char ch = Serial2.read();
string[i] = ch;
i++;
if(ch == -1)
break;
delay(5);
}
string[i] = 0;
if(strlen(string))
SerialUSB.print(string); //send data coming from Serial2 to USB(PC)
char* value = strstr(string, "=");
int angle = 50;
if(value)
{
value = value + 1;
angle = atoi(value);
if(angle < 0)
angle = 0;
if(angle >= 512)
angle = 512;
SerialUSB.print("angle=");
SerialUSB.print(angle);
}
if(strstr(string, "yaw="))
Dxl.setPosition(ID_NUM, angle, 70); // ID, position between 0 to 1023, speed between 0 to 100
else if(strstr(string, "roll="))
Dxl.setPosition(ID_NUM2, angle, 70);
else if(strstr(string, "left"))
Dxl.setPosition(ID_NUM, 0, 70); // ID, position between 0 to 1023, speed between 0 to 100
else if(strstr(string, "right"))
Dxl.setPosition(ID_NUM, 512, 70); // ID, position between 0 to 1023, speed between 0 to 100
delay(1000);// it has more delay time for slow movement
}
로봇 암 무선 제어 결과
5. 마무리
이제 무선으로 로봇 암과 같은 엑추에이터를 제어할 수 있다. 로버나 드론에 무선 제어를 할 수 있는 로봇 암을 마운팅하고, 로봇 암에 여러가지 인스펙션 센서나 그립을 부착하면, 다양한 응용 로봇을 만들 수 있다.
오픈소스 기반 로버 개발 사례
드론에 2 DoF 로봇암 마운팅 사례
안녕하세요. opencm공부중인 학생입니다. 이 과정을 블루투스통신없이
답글삭제시리얼 통신으로만 제어하고 싶습니다. 혹시 도와 주실수이싸요?
안녕하세요. 답글이 늦었습니다.
삭제Serial 통신 관련해 OpenCM예제가 있었던 것으로 기억합니다. loop()에서 Serial 값을 읽어, 다이나믹셀에 명령을 전달하는 방식이라 아두이노 Serial 통신 예제와 거의 비슷해요.
다이나믹셀 시리얼 통시 라이브러리도 GitHub에 올려져 있으니 참고하시길 바랍니다.
https://github.com/zcshiner/Dynamixel_Serial
아래는 아두이노 이용한 제어 예입니다.
http://robottini.altervista.org/dynamixel-ax-12a-and-arduino-how-to-use-the-serial-port
https://github.com/zcshiner/Dynamixel_Serial
답변 정말 감사드립니다.~~~
삭제