이 프로젝트 정보
Instructables Robotics Contest 2016의 우승자 중 한 명으로서 저는 iRobot Roomba Create2를 상품으로 받았습니다. 약 200달러의 비용이 드는 로봇 공학 개발을 위한 훌륭하고 매우 저렴한 플랫폼입니다. Create 2는 다양한 프로그래밍 방법을 허용합니다. 처음에는 Arduino 및 Android APP와 함께 사용하여 로봇을 이리저리 움직였습니다. 이 첫 번째 자습서에서는 직렬 포트를 통해 Arduino를 Roomba에 연결하는 방법과 모터, LED 및 사운드를 명령하는 방법을 살펴보겠습니다. 향후 프로젝트에서 센서를 탐색하고 Raspberry Pi를 사용하여 Roomba를 인터넷에 연결하겠습니다.
Bellow, Roomba 로봇을 프로그래밍한 첫 번째 결과를 보여주는 비디오:
1단계:BOM
<울> 아이로봇 크리에이트2
<울> 아두이노 UNO
<울> 블루투스 모듈 HC-06
<울> 푸시 버튼
2단계:룸바 Create2
그림>
룸바는 바퀴 2개와 프론트 캐스터가 있는 차동 구동 로봇입니다. 속도는 최대 500mm/s이며 위쪽 또는 뒤쪽으로 이동하도록 명령할 수 있습니다.
신호화를 위해 4개의 7개 세그먼트 디스플레이와 5개의 LED로 셀 수 있습니다(그림 참조).
<울> 깨끗함
<울> 스팟
<울> 도크
<울> 경고/확인
<울> 먼지/파편
내부 센서로는 다음이 있습니다.
<울> 절벽 감지기(앞에 4개)
<울> 범프 감지기(앞에 2개)
<울> 휠 인코더
프로그래밍의 경우 문서:iRobot® Create® 2 OI(Open Interface)를 사용해야 합니다. Roomba는 3가지 모드로 프로그래밍할 수 있습니다.
패시브 모드:
<울> 시작 명령 또는 청소 모드 명령(예:Spot, Clean, Seek Dock) 중 하나를 보내면 OI는 수동 모드로 들어갑니다. OI가 수동 모드에 있을 때 센서 명령을 사용하여 센서 데이터를 요청하고 수신할 수 있지만 액추에이터(모터, 스피커, 조명, 로우 사이드 드라이버, 디지털 출력)에 대한 현재 명령 매개변수를 다른 것으로 변경할 수 없습니다. .
안전 모드:다음 안전 관련 조건을 제외하고 Roomba를 완전히 제어할 수 있습니다.
<울> 충전기가 연결되어 있고 전원이 공급됩니다.
<울> 휠 낙하 감지(모든 휠에서).
<울> 전진 중(또는 작은 회전 반경, 로봇 반경 1 미만으로 후진) 중 절벽 감지.
<울> OI가 안전 모드에 있는 동안 위의 안전 관련 조건 중 하나가 발생하면 Roomba는 모든 모터를 중지하고 수동 모드로 되돌아갑니다.
전체 모드:
<울> 전체 모드가 절벽, 휠 드롭 및 내부 충전기 안전 기능을 차단하므로 OI가 안전 모드일 때 제한되는 Roomba, 모든 액추에이터 및 모든 안전 관련 조건을 완벽하게 제어할 수 있습니다. .
3단계:직렬 연결
그림>
그림>
Roomba와 Arduino 간의 통신을 위해 직렬 포트가 사용됩니다. 기본적으로 Roomba는 115,200 baud로 통신하지만 Arduino와 통신하기 위해 19,200 baud로 전환합니다.
Roomba 전송 속도를 설정하는 두 가지 방법이 있습니다.
<울> 룸바의 전원을 끄는 동안 조명이 꺼진 후 청소/전원 버튼을 계속 누르고 있습니다. 약 10초 후에 Roomba가 내림차순 음조를 연주합니다. Roomba는 프로세서가 배터리 전원을 잃거나 전송 속도가 OI를 통해 명시적으로 변경될 때까지 19,200 전송으로 통신합니다.
<울> 전송 속도 변경 핀(Mini-DIN 커넥터의 핀 5)을 사용하여 Roomba의 전송 속도를 변경합니다. Roomba를 켠 후 2초 동안 기다린 다음 Baud Rate Change를 낮게 세 번 펄스합니다. 각 펄스는 50~500밀리초 동안 지속되어야 합니다. Roomba는 프로세서의 배터리 전원이 꺼지거나 전송 속도가 OI를 통해 명시적으로 변경될 때까지 19200 전송으로 통신합니다.
위의 다이어그램은 Arduino가 Roomba Mini-DIN 커넥터에 연결되는 방법을 보여줍니다.
4단계:Roomba 시작
Roomba를 프로그래밍할 때 가장 먼저 수행해야 하는 작업은 다음과 같습니다.
<울> 로봇 "일어나기"
<울> 모드 정의(안전 또는 전체)
아래 기능과 같이 Mini-DIN 핀 5(장치 입력 감지)에 Low 펄스를 전송하여 "Wake-up"할 수 있습니다.
<사전><코드> 무효 웨이크업(무효){ setWarningLED(ON); 디지털 쓰기(ddPin, HIGH); 지연(100); 디지털 쓰기(ddPin, LOW); 지연(500); 디지털 쓰기(ddPin, HIGH); 지연(2000);}
Roomba를 시작하려면 항상 "START"[128] 및 모드(이 경우 "SAFE MODE"[131])의 2가지 코드를 전송해야 합니다. "전체 모드"를 원하면 코드 [132]를 대신 보내야 합니다.
<사전><코드> 무효 startSafe(){ Roomba.write(128); //룸바 시작.write(131); //안전 모드 지연(1000);}
5단계:LED 및 디스플레이 켜기
그림>
LED 켜기
소개에서 설명한 대로 Roomba에는 5개의 LED가 있습니다.
<울> 파워/클린(2색 빨강/녹색 및 강도 제어)
<울> 스팟(녹색, 고정 강도)
<울> 도크(녹색, 고정 강도)
<울> 경고/확인(주황색, 고정 강도)
<울> 먼지/파랑(파란색, 고정 강도)
모든 LED는 코드 [139]를 사용하여 명령할 수 있습니다. 전원 LED를 제어하려면 "color" 및 "intensity"라는 2개의 데이터 바이트를 Roomba에 보내야 합니다.
색상:
<울> 녹색 =0
<울> 주황색 =128
<울> 빨간색=255
강도:
<울> 낮음=0
<울> 최대=255
setPowerLED(바이트 setColor, 바이트 setIntensity) 기능 합니까:
void setDigitLEDs(byte digit1, byte digit2, byte digit3, byte digit4){ Roomba.write(163); Roomba.write(digit1); 룸바.쓰기(digit2); 룸바.쓰기(digit3); Roomba.write(digit4);}
예를 들어, 강도의 절반에서 주황색으로 POWER LED를 켜려면 아래와 같이 함수를 호출할 수 있습니다.
setPowerLED(128, 128);
나머지 4개의 LED를 켜려면 다음 기능을 사용해야 합니다.
<사전><코드>setDebrisLED(ON);setDockLED(ON); setSpotLED(켜기); setWarningLED(ON);
위의 모든 함수에는 다음과 유사한 코드가 있습니다.
무효 setDebrisLED(bool 활성화){debrisLED =활성화; 룸바.write(139); Roomba.write((debrisLED ? 1:0) + (spotLED ? 2:0) + (dockLED ? 4:0) + (warningLED ? 8:0)); Roomba.write((바이트) 색상); Roomba.write((바이트) 강도);}
기본적으로 차이점은 다음과 같습니다.
debrisLED =활성화;
각각의 다른 LED(spotLED, dockLED, warningLED)를 활성화하도록 변경해야 합니다. ).
표시할 메시지 보내기
Roomba에는 두 가지 방법으로 메시지를 보내는 데 사용할 수 있는 4개의 7 세그먼트 디스플레이가 있습니다.
<울> 코드 [163]:숫자 LED 원시(숫자)
<울> 코드 [164]:숫자 LED ASCII(문자 및 특수 코드의 근사치)
숫자를 표시하는 것은 매우 쉽습니다. 표시할 4자리 다음에 코드 [163]을 보내야 합니다. 기능:setDigitLEDs(바이트 digit1, 바이트 digit2, 바이트 digit3, 바이트 digit4) 당신을 위해 이것을 합니까:
void setDigitLEDs(byte digit1, byte digit2, byte digit3, byte digit4){ Roomba.write(163); Roomba.write(digit1); 룸바.쓰기(digit2); 룸바.쓰기(digit3); Roomba.write(digit4);}
예를 들어 "1, 2, 3, 4"를 표시하려면 다음 함수를 호출해야 합니다.
setDigitLEDs(1, 2, 3, 4);
코드 [164]를 사용하면 ASCII 근사치를 보낼 수 있습니다. setDigitLEDFromASCII(바이트 숫자, 문자) 함수 우리에게 이렇게 합니까:
void setDigitLEDFromASCII(byte digit, char letter){ switch (digit){ case 1:digit1 =letter; 부서지다; 경우 2:digit2 =문자; 부서지다; 경우 3:digit3 =문자; 부서지다; 경우 4:digit4 =문자; 부서지다; } 룸바.write(164); Roomba.write(digit1); 룸바.쓰기(digit2); 룸바.쓰기(digit3); Roomba.write(digit4);}
단순화하기 위해 4자리 숫자를 동시에 보내는 새 함수를 만듭니다.
writeLED 무효화(char a, char b, char c, char d){ setDigitLEDFromASCII(1, a); setDigitLEDFromASCII(2, b); setDigitLEDFromASCII(3, c); setDigitLEDFromASCII(4, d);}
예를 들어 "STOP"을 표시하려면 다음 함수를 호출해야 합니다.
writeLED('s', 't', 'o', 'p');
6단계:Roomba 이동
이동성을 위해 Roomba에는 최대 500mm/s로 작동하도록 프로그래밍할 수 있는 2개의 독립적인 DC 모터가 있습니다. 로봇을 구동하는 데 사용할 수 있는 몇 가지 명령이 있습니다. 주요 내용은 다음과 같습니다.
<울> 코드 [137]:드라이브 ==> +/- 속도(mm/s) 및 +/- 반경(mm)을 보내야 함
<울> 코드 [145]:Drive Direct ==> 왼쪽/오른쪽 속도를 mm/s 단위로 보내야 합니다(앞으로 +, 뒤로 -)
<울> 코드 [146]:PWM 구동 ==> 왼쪽 및 오른쪽 바퀴에 대해 +/- PWM 데이터를 보내야 함
다음은 해당 3가지 옵션에 대한 코드입니다.
void drive(int velocity, int 반경){ clamp(속도, -500, 500); //def 최대 및 최소 속도(mm/s) clamp(radius, -2000, 2000); //def 최대 및 최소 반경(mm) Roomba.write(137); Roomba.write(속도>> 8); Roomba.write(속도); Roomba.write(반지름>> 8); Roomba.write(radius);}//---------------------------------------- ----------------------- 무효 driveWheels(int right, int left){ clamp(right, -500, 500); 클램프(왼쪽, -500, 500); 룸바.write(145); Roomba.write(오른쪽>> 8); Roomba.write(오른쪽); Roomba.write(왼쪽>> 8); Roomba.write(왼쪽); }//----------------------------------------------- ---------------- 무효 driveWheelsPWM(int rightPWM, int leftPWM){ clamp(rightPWM, -255, 255); 클램프(왼쪽 PWM, -255, 255); 룸바.write(146); Roomba.write(rightPWM>> 8); Roomba.write(rightPWM); Roomba.write(왼쪽 PWM>> 8); Roomba.write(leftPWM);}
"clamp" 기능은 입력이 허용되는 최대값과 최소값을 정의합니다. 이 함수는 rombaDefines.h: 파일에 정의되어 있습니다.
#define clamp(값, 최소, 최대) (값 <최소 ? 최소 :값> 최대 ? 최대 :값)
위의 코드를 사용하여 Roomba를 구동하는 더 간단한 기능을 만들 수 있습니다.
<사전><코드>/------------------------------------------- --------------------void turnCW(unsigned short velocity, unsigned short degree){ drive(velocity, -1); 클램프(속도, 0, 500); 지연(6600); 드라이브(0,0);}//---------------------------------------- ----------------------- 무효 turnCCW(unsigned short velocity, unsigned short degree){ drive(velocity, 1); 클램프(속도, 0, 500); 지연(6600); 드라이브(0,0);}//---------------------------------------- ----------------------- 무효 driveStop(무효){ 드라이브(0,0);}//----------- -------------------------------------------------- --void driveLeft(int left){ driveWheels(left, 0);}//--------------------------------------------- -------------------------------- 무효 driveRight(int right){ driveWheels(0, right);}
각도를 바꾸려면 "지연" 인수를 주어진 속도에 대해 구체적으로 계산해야 합니다. 모터 테스트에 사용할 수 있는 몇 가지 예는 다음과 같습니다.
turnCW(40, 180); // 시계 방향으로 180도 회전하고 stopdriveWheels(20, -20); // 스핀 driveLeft(20); // 좌회전
모터를 테스트하려면 외부 푸시 버튼(내 경우에는 Arduino 핀 12에 연결됨)을 추가하는 것이 좋습니다. 따라서 Arduino에 코드를 다운로드하여 Roomba를 시작하지만 푸시 버튼을 누를 때까지 실행을 중지할 수 있습니다. 일반적으로 모터 테스트의 경우 코드의 설정 부분에서 수행할 수 있습니다.
예를 들어 아래의 간단한 Arduino 코드를 참조하십시오(코드는 이전에 개발된 기능과 정의를 사용함).
#include "roombaDefines.h#include // Roomba Create2 connectionint rxPin=10;int txPin=11;SoftwareSerial Roomba(rxPin,txPin);//------ --------------------------------------- 무효 setup() { Roomba.begin(19200); 핀모드(dd핀, 출력); 핀모드(버튼핀, INPUT_PULLUP); // Arduino 핀 12에 연결하고 "시작" delay(2000)에 사용합니다. 깨우다 (); // 룸바 깨우기 startSafe(); // 안전 모드에서 Roomba 시작 while (digitalRead(buttonPin)) { } // 연속 실행 코드가 눌러질 때까지 대기 turnCW (40, 180); //룸바가 시계 방향으로 180도 회전하는지 테스트하고 중지}//------------------------------------------------- ---------- 무효 루프() { }
7단계:Bluetooth를 통해 Roomba 제어
그림>
그림>
프로젝트의 첫 번째 부분을 완료하기 위해 Arduino에 Bluetooth 모듈(HC-06)을 설치해 보겠습니다. 위의 다이어그램은 수행 방법을 보여줍니다. 일반적으로 HC-06은 9,600 보드율로 공장에서 정착됩니다. 아두이노-룸바 통신속도와 호환되도록 19,200으로 변경하는 것이 중요합니다. 모듈에 AT 명령을 보낼 수 있습니다(AT+BAUD5 여기서 "5"는 19,200에 대한 코드임).
HC-06의 작동 방식에 대해 의문이 있는 경우 Bluetooth / Android / Arduino를 통해 "물건" 연결하기 튜토리얼을 참조하세요.
Roomba를 제어하기 위해 MIT AppInventor 2:"MJRoBot BT Remote Control"을 사용하여 모바일 로봇을 제어하기 위해 제가 개발한 일반 앱을 사용합니다. 앱은 다음 링크를 통해 Google 스토어에서 무료로 다운로드할 수 있습니다. 앱:MJRoBot BT Remote Control.
앱에는 간단한 인터페이스가 있어 TEXT 모드에서 또는 사전 프로그래밍된 버튼을 통해 직접 BT 모듈에 명령을 보낼 수 있습니다(버튼을 누를 때마다 문자가 전송됨):
<울> w:앞으로
<울> s:뒤로
<울> d:오른쪽
<울> a:왼쪽
<울> f:중지
<울> p:ON / OFF(이 첫 번째 부분에서는 사용되지 않음)
<울> m:수동 / 자동(안전 모드에서 절벽과 같은 장애물이 발견되면 Roomba를 다시 시작하는 데 사용)
<울> +:속도 +
<울> -:속도 -
필요한 경우 다른 명령을 텍스트로 보낼 수도 있습니다. BT 모듈에서 수신된 메시지에 대한 텍스트 창도 있습니다. 이 기능은 테스트 단계에서 매우 중요하며 "직렬 모니터"와 같은 방식으로 사용할 수 있습니다.
루프() 코드의 일부는 블루투스 장치를 "수신"하고 수신된 명령에 따라 조치를 취합니다.
void 루프() { checkBTcmd(); // BT 리모콘에서 명령이 수신되었는지 확인 manualCmd();}
checkBTcmd() 기능 아래에 표시됩니다:
void checkBTcmd() // BT 리모콘에서 명령어 수신 여부 확인 { if (BT1.available()) { command =BT1.read(); BT1.flush(); } }코드>
명령이 수신되면 함수 manualCmd() 적절한 조치를 취할 것입니다:
void manualCmd(){ switch (command) { case 'm':startSafe(); Serial.print("안전 모드의 룸바"); BT1.print("룸바 BT Ctrl OK - 안전 모드"); BT1.println('\n'); 명령 ='f'; 플레이사운드(3); 부서지다; 케이스 'f':driveStop(); // 두 모터를 모두 끕니다. writeLED('s', 't', 'o', 'p'); 상태 =명령; 부서지다; case 'w':드라이브(motorSpeed, 0); writeLED(' ', 'g', 'o', ' '); 상태 =명령; 부서지다; 케이스 'd':driveRight(motorSpeed); writeLED('r', 'i', 'g', 'h'); 부서지다; 케이스 'a':driveLeft(motorSpeed); writeLED('l', 'e', 'f', 't'); 부서지다; case 's':드라이브(-motorSpeed, 0); writeLED('b', 'a', 'c', 'k'); 상태 =명령; 부서지다; case '+':if (state =='w') { motorSpeed =motorSpeed + 10; if (motorSpeed > MAX_SPEED) { motorSpeed =MAX_SPEED; } 명령 ='w'; } else {명령 =상태;} 중단; case '-':if (state =='w') { motorSpeed =motorSpeed - 10; } if (motorSpeed
8단계:결론
여기에 사용된 전체 Arduino 코드 및 관련 문서는 내 GITHUB:Roomba_BT_Ctrl에서 찾을 수 있습니다.
모든 Roomba 액추에이터가 이 튜토리얼에 언급된 것은 아닙니다. 청소에 사용되는 다른 모터, 일정에 사용되는 다른 LED, 버튼, 센서 등이 있습니다.
내 프로그램에서 만든 여러 기능은 Dom Amato에서 개발한 Create 2 라이브러리를 기반으로 했습니다. 전체 라이브러리는 https://github.com/brinnLabs/Create2에서 다운로드할 수 있습니다. .
여기에서 내 의도는 간단하게 유지하고 Roomba를 사용하기 시작할 수 있는 시작 플랫폼을 제공하는 것입니다. 앞으로는 Raspberry-Pi를 사용하여 Roomba를 인터넷에 연결하고 센서를 읽는 등 다른 자습서를 게시하는 척합니다.
늘 그렇듯이 이 프로젝트가 다른 사람들이 전자 및 로봇 공학의 흥미진진한 세계에서 길을 찾는 데 도움이 되기를 바랍니다.
더 많은 프로젝트를 보려면 내 블로그(포르투갈어)를 방문하십시오:
MJRoBot.org
세계 남쪽에서 온 살루도스!
다음 튜토리얼에서 만나요!
감사합니다
마르셀로
섹션> <섹션 클래스="섹션 컨테이너 섹션 축소 가능" id="코드"> 코드
깃허브
https://github.com/Mjrovai/Roomba_BT_Ctrl