Segway의 RYNO 모터 및 기타 셀프 밸런싱 스쿠터에서 영감을받은 후 저는 항상 제 자신의 Arduino Segway 로봇 을 만들고 싶었습니다. 잠시 생각하면서 Arduino를 사용하여 자체 균형 로봇 을 만들기로 결정했습니다. 이렇게하면이 모든 스쿠터의 기본 개념을 파악하고 PID 알고리즘의 작동 방식을 배울 수 있습니다.
빌드를 시작하자이 봇이 빌드에 약간의 도전이라는 것을 깨달았습니다. 선택할 수있는 옵션이 너무 많기 때문에 혼란은 모터를 선택하는 것부터 시작하여 PID 값을 조정할 때까지 유지됩니다. 그리고 배터리 유형, 배터리 위치, 휠 그립, 모터 드라이버 유형, CoG (중력 중심) 유지 등 고려해야 할 사항이 너무 많습니다.
그러나 내가 당신에게 그것을 부수도록하겠습니다. 일단 당신이 그것을 만들면 당신은 그것이 들리는 것만 큼 어렵지 않다는 것에 동의 할 것입니다. 이 튜토리얼에서는 셀프 밸런싱 로봇을 제작 한 경험을 문서화하겠습니다. 당신은 막 시작하는 절대적인 초보자이거나 봇이 작동하지 않는다는 오랜 좌절 후에 여기에 도착했을 수도 있습니다. 이곳은 최종 목적지가되는 것을 목표로합니다. 그럼 시작합시다……
셀프 밸런싱 로봇 부품 선택
봇 구축을위한 모든 옵션을 설명하기 전에이 셀프 밸런싱 로봇 프로젝트에서 사용한 항목을 나열하겠습니다.
- Arduino UNO
- 기어드 DC 모터 (노란색) – 2Nos
- L298N 모터 드라이버 모듈
- MPU6050
- 한 쌍의 바퀴
- 7.4V 리튬 이온 배터리
- 전선 연결
- 3D 프린트 바디
자체 밸런싱 로봇 키트를 만들기 위해 가용성에 따라 위의 구성 요소를 혼합하고 선택할 수 있습니다. 구성 요소가 다음 기준에 맞는지 확인하십시오.
컨트롤러: 여기서 사용한 컨트롤러는 아두 이노 UNO인데, 사용하기가 쉽기 때문입니다. Arduino Nano 또는 Arduino mini를 사용할 수도 있지만 외부 하드웨어없이 직접 프로그래밍 할 수 있으므로 UNO를 고수하는 것이 좋습니다.
모터: 셀프 밸런싱 로봇에 사용할 수있는 최고의 모터 선택은 의심 할 여지없이 스테퍼 모터입니다. 하지만 간단하게하기 위해 DC 기어 모터를 사용했습니다. 예, 스테퍼가 필수는 아닙니다. 봇은 일반적으로 사용 가능한 저렴한 노란색 DC 기어 모터에서도 잘 작동합니다.
모터 드라이버: 저 와 같은 DC 기어 모터를 선택한 경우 저와 같은 L298N 드라이버 모듈을 사용하거나 L293D도 잘 작동합니다. L293D 및 Arduino를 사용한 DC 모터 제어에 대해 자세히 알아보십시오.
바퀴: 이 사람들을 과소 평가하지 마십시오. 나는 내 바퀴에 문제가 있다는 것을 알아 내기가 힘들었다. 따라서 바퀴가 사용중인 바닥을 잘 잡고 있는지 확인하십시오. 주의 깊게보십시오. 그립은 바퀴가 바닥에 미끄러지지 않도록하십시오.
가속도계 및 자이로 스코프: 봇을위한 최상의 가속도계 및 자이로 스코프는 MPU6050입니다. 따라서 ADXL345와 같은 일반 가속도계로 빌드하지 마십시오. 작동하지 않습니다. 이 기사의 끝에서 그 이유를 알게 될 것입니다. Arduino와 함께 MPU6050 사용에 대한 전용 기사를 확인할 수도 있습니다.
배터리: 부스트 모듈없이 Arduino에 직접 전원을 공급할 수 있도록 가능한 한 가벼운 배터리가 필요하고 작동 전압이 5V 이상이어야합니다. 따라서 이상적인 선택은 7.4V 리튬 폴리머 배터리입니다. 여기서는 7.4V 리튬 이온 배터리를 쉽게 사용할 수 있었기 때문에 사용했습니다. 그러나 Li-po가 Li-ion보다 유리하다는 것을 기억하십시오.
섀시: 타협해서는 안되는 또 다른 장소는 봇 섀시입니다. 골판지, 목재, 플라스틱은 무엇이든 잘 사용할 수 있습니다. 그러나 섀시가 튼튼하고 봇이 균형을 잡으려고 할 때 흔들리지 않아야합니다. 다른 봇에서 추론하여 Solidworks에서 자체 섀시로 디자인하고 3D 인쇄했습니다. 프린터가있는 경우 디자인을 인쇄 할 수도 있습니다. 디자인 파일은 다음 제목에 첨부됩니다.
3D 프린팅 및 자체 균형 로봇 조립
봇을 구축하는 데 사용하는 것과 동일한 섀시를 3D 프린팅하기로 결정한 경우 STL 파일을 thingiverse에서 다운로드 할 수 있습니다. 또한 설계 파일도 함께 추가하여 개인 선호도에 따라 수정할 수 있습니다.
부품에는 돌출 된 구조가 없으므로 지지대없이 쉽게 인쇄 할 수 있으며 25 %의 충진도 잘 작동합니다. 디자인은 매우 단순하며 모든 기본 프린터는 쉽게 처리 할 수 있어야합니다. Cura 소프트웨어를 사용하여 모델을 슬라이스하고 Tevo Tarantula를 사용하여 인쇄했습니다. 설정은 아래와 같습니다.
4 개의 모터 장착 부품과 함께 본체 부품을 인쇄해야합니다. 조립은 매우 간단합니다. 3mm 너트와 볼트를 사용하여 모터와 보드를 제자리에 고정합니다. 조립 후 아래 그림과 같이 보일 것입니다.
실제 설계는 위 그림과 같이 하단 랙에있는 L298N 드라이브 모듈과 그 상단에있는 배터리로 계획되었습니다. 동일한 순서를 따르는 경우 제공된 구멍을 통해 보드를 직접 나사로 조이고 Li-po 배터리 용 와이어 태그를 사용할 수 있습니다. 나중에 변경해야하는 슈퍼 플레인 휠을 제외하고이 배열도 작동합니다.
내 봇에서 프로그래밍의 용이성을 위해 배터리와 Arduino UNO 보드의 위치를 바꿨고 연결을 완료하기 위해 성능 보드도 도입해야했습니다. 그래서 내 봇은 초기 단계에서 계획 한대로 보이지 않았습니다. 배선 프로그래밍 테스트와 모든 것을 완료 한 후 두 바퀴 로봇은 마침내 다음과 같이 보입니다.
회로도
이 Arduino 기반 셀프 밸런싱 로봇을 연결하는 것은 매우 간단합니다. 이것은 Arduino 및 MPU6050을 사용 하는 자체 균형 로봇 이므로 MPU6050을 Arduino와 인터페이스하고 모터 드라이버 모듈을 통해 모터를 연결합니다. 전체 설정은 7.4V 리튬 이온 배터리로 구동됩니다. 동일한 회로도는 아래와 같습니다.
Arduino 및 L298N 모터 드라이버 모듈은 각각 Vin 핀과 12V 단자를 통해 직접 전원이 공급됩니다. Arduino 보드의 온보드 레귤레이터는 입력 7.4V를 5V로 변환하고 ATmega IC 및 MPU6050에 의해 전원이 공급됩니다. DC 모터는 5V ~ 12V 전압에서 작동 할 수 있습니다. 그러나 배터리의 7.4V 양극선을 모터 드라이버 모듈의 12V 입력 단자에 연결합니다. 이렇게하면 모터가 7.4V로 작동합니다. 다음 표는 MPU6050 및 L298N 모터 드라이버 모듈이 Arduino와 연결되는 방식을 나열합니다.
부품 핀 |
Arduino 핀 |
MPU6050 |
|
Vcc |
+ 5V |
바닥 |
Gnd |
SCL |
A5 |
SDA |
A4 |
INT |
D2 |
L298N |
|
IN1 |
D6 |
IN2 |
D9 |
IN3 |
D10 |
IN4 |
D11 |
MPU6050은 I2C 인터페이스를 통해 Arduino와 통신하므로 Arduino의 SPI 핀 A4 및 A5를 사용합니다. DC 모터는 PWM 핀 D6, D9 D10 및 D11에 각각 연결됩니다. PWM 신호의 듀티 사이클을 변경하여 DC 모터의 속도를 제어 할 것이기 때문에 PWM 핀에 연결해야합니다. 이 두 구성 요소에 익숙하지 않은 경우 MPU6050 Interfacing 및 L298N 모터 드라이버 자습서를 읽는 것이 좋습니다.
자기 균형 로봇 코드
이제 로봇의 균형을 맞추기 위해 Arduino UNO 보드를 프로그래밍해야합니다. 이것은 모든 마법이 일어나는 곳입니다. 그 뒤에있는 개념은 간단합니다. MPU6050을 사용하여 봇이 앞쪽 또는 뒤쪽으로 기울어 져 있는지 확인한 다음 앞쪽으로 기울어지면 바퀴를 앞쪽으로 회전해야하고 뒤쪽으로 기울어지면 바퀴를 회전해야합니다. 반대 방향으로.
동시에 우리는 바퀴가 회전하는 속도도 제어 해야합니다. 봇이 중앙 위치에서 약간 방향을 잃으면 바퀴가 천천히 회전하고 중앙 위치에서 멀어 질수록 속도가 증가합니다. 이 논리를 달성하기 위해 중앙 위치를 설정 점으로, 방향 감각 상실 수준을 출력으로 갖는 PID 알고리즘을 사용합니다.
봇의 현재 위치를 파악하기 위해 6 축 가속도계와 자이로 스코프 센서가 결합 된 MPU6050 을 사용합니다. 센서에서 신뢰할 수있는 위치 값을 얻으려면 가속도계와 자이로 스코프의 값을 모두 사용해야합니다. 가속도계의 값에는 노이즈 문제가 있고 자이로 스코프의 값은 시간에 따라 드리프트하는 경향이 있기 때문입니다. 따라서 두 가지를 결합하여 로봇의 요 피치와 롤 값을 가져와야합니다.이 값 중 요 값만 사용합니다.
머리가 약간 감긴 것 같나요? 하지만 걱정하지 마세요. Arduino 커뮤니티 덕분에 PID 계산을 수행하고 MPU6050에서 yaw 값을 가져올 수있는 라이브러리를 쉽게 사용할 수 있습니다. 라이브러리는 각각 br3ttb와 jrowberg에 의해 개발되었습니다. 계속하기 전에 다음 링크에서 라이브러리를 다운로드하고 Arduino lib 디렉토리에 추가하십시오.
github.com/br3ttb/Arduino-PID-Library/blob/master/PID_v1.h
github.com/jrowberg/i2cdevlib/tree/master/Arduino/MPU6050
이제 Arduino IDE에 라이브러리가 추가되었습니다. 셀프 밸런싱 로봇에 대한 프로그래밍을 시작하겠습니다. 항상 그렇듯이 MPU6050 밸런싱 로봇 의 전체 코드 는이 페이지의 끝에 제공됩니다. 여기서는 코드에서 가장 중요한 스 니펫을 설명합니다. 앞서 말한 A 코드는 MPU6050 예제 코드를 기반으로 빌드되었으며 우리의 목적에 맞게 코드를 최적화하고 자체 균형 로봇을위한 PID 및 제어 기술을 추가 할 것입니다.
먼저이 프로그램이 작동하는 데 필요한 라이브러리 를 포함합니다. 여기에는 방금 다운로드 한 내장 I2C 라이브러리, PID 라이브러리 및 MPU6050 라이브러리가 포함됩니다.
#include "I2Cdev.h" #include
그런 다음 MPU6050 센서에서 데이터를 가져 오는 데 필요한 변수를 선언합니다. 중력 벡터와 쿼터니언 값을 모두 읽은 다음 봇의 요 피치와 롤 값을 계산합니다. 플로트 배열 YPR는 최종 결과를 저장한다.
// MPU 제어 / 상태 vars bool dmpReady = false; // DMP 초기화가 성공하면 true로 설정 uint8_t mpuIntStatus; // MPU의 실제 인터럽트 상태 바이트를 보유합니다 . uint8_t devStatus; // 각 장치 작업 후 상태 반환 (0 = 성공,! 0 = 오류) uint16_t packetSize; // 예상되는 DMP 패킷 크기 (기본값은 42 바이트) uint16_t fifoCount; // 현재 FIFO에 있는 모든 바이트 수 uint8_t fifoBuffer; // FIFO 저장 버퍼 // 방향 / 동작 vars Quaternion q; // 쿼터니언 컨테이너 VectorFloat gravity; // 중력 벡터 float ypr; // 요 / 피치 / 롤 컨테이너 및 중력 벡터
다음은 코드의 매우 중요한 부분이며, 여기 에서 올바른 값 세트를 조정 하는 데 오랜 시간을 소비하게 됩니다. 로봇이 매우 좋은 무게 중심으로 제작되고 구성 요소가 대칭으로 배열되어 있으면 (대부분의 경우 그렇지 않음) 설정 점 값은 180이됩니다. 그렇지 않으면 로봇을 Arduino 직렬 모니터에 연결하고 좋은 밸런싱 위치를 찾고 직렬 모니터에 표시된 값을 읽으면 이것이 설정 포인트 값입니다. Kp, Kd 및 Ki의 값은 봇에 따라 조정되어야합니다. 두 개의 동일한 봇은 Kp, Kd 및 Ki 값이 같지 않으므로 탈출 할 수 없습니다. 이 값을 조정하는 방법에 대한 아이디어를 얻으려면이 페이지 끝에 있는 비디오 를보십시오.
/ ********* BOT에 대해이 4 가지 값을 조정 ********* / 이중 설정 값 = 176; 보트가 수직 인 경우 // 값을 설정 접지 직렬 모니터를 사용. // 이러한 값을 설정하는 방법을 배우려면 circuitdigest.com의 프로젝트 문서를 읽으십시오. double Kp = 21; //이 첫 번째 double 설정 Kd = 0.8; //이 secound 설정 double Ki = 140; // 마지막으로 설정 / ****** 값의 끝 설정 ********* /
다음 줄 에서 입력 변수 input, output, set point, Kp, Ki 및 Kd를 전달하여 PID 알고리즘을 초기화합니다. 이 중에서 이미 위의 코드 스 니펫에서 설정 점 Kp, Ki 및 Kd의 값을 설정했습니다. 입력 값은 MPU6050 센서에서 읽은 yaw의 현재 값이되고 출력 값은 PID 알고리즘에 의해 계산 된 값이됩니다. 따라서 기본적으로 PID 알고리즘은 입력 값을 설정 값에 가깝게 수정하는 데 사용해야하는 출력 값을 제공합니다.
PID pid (& input, & output, & setpoint, Kp, Ki, Kd, DIRECT);
void 설정 기능 내에서 DMP (Digital Motion Processor) 를 구성하여 MPU6050을 초기화합니다. 이는 가속도계 데이터를 자이로 스코프 데이터와 결합하는 데 도움이되고 Yaw, Pitch 및 Roll의 신뢰할 수있는 값을 제공합니다. 주제를 훨씬 넘어 설 것이기 때문에 우리는 이것에 대해 깊이 들어 가지 않을 것입니다. 어쨌든 설정 기능에서 찾아봐야하는 코드의 한 부분은 자이로 오프셋 값입니다. 각 MPU6050 센서에는 자체 오프셋 값이 있으므로이 Arduino 스케치를 사용하여 센서의 오프셋 값을 계산하고 그에 따라 프로그램에서 다음 행을 업데이트 할 수 있습니다.
// 여기에 최소 감도에 맞게 조정 된 자체 자이로 오프셋을 제공합니다 . mpu.setXGyroOffset (220); mpu.setYGyroOffset (76); mpu.setZGyroOffset (-85); mpu.setZAccelOffset (1688);
또한 모터를 연결하는 데 사용 하는 디지털 PWM 핀 을 초기화해야 합니다. 우리의 경우 D6, D9, D10 및 D11입니다. 따라서 출력 핀이 기본적으로 LOW로 만들 때 이러한 핀을 초기화합니다.
// 모터 출력 핀 초기화 pinMode (6, OUTPUT); pinMode (9, OUTPUT); pinMode (10, OUTPUT); pinMode (11, OUTPUT); // 기본적으로 두 모터를 모두 끕니다. analogWrite (6, LOW); analogWrite (9, LOW); analogWrite (10, LOW); analogWrite (11, LOW);
메인 루프 기능 내에서 MPU6050의 데이터를 읽을 준비가되었는지 확인합니다. 그렇다면 PID 값을 계산하는 데 사용하고 PID가 어떻게 응답하는지 확인하기 위해 직렬 모니터에 PID의 입력 및 출력 값을 표시합니다. 그런 다음 출력 값에 따라 봇이 앞으로 또는 뒤로 이동해야하는지 아니면 가만히 서 있어야하는지 결정합니다.
봇이 똑바로있을 때 MPU6050이 180을 반환한다고 가정하기 때문입니다. 봇이 앞쪽으로 떨어지면 보정 값이 양수이고 봇이 뒤쪽으로 떨어지면 음수 값을 얻습니다. 따라서이 조건을 확인하고 적절한 함수를 호출하여 봇을 앞뒤로 이동합니다.
while (! mpuInterrupt && fifoCount <packetSize) { // mpu 데이터 없음-PID 계산을 수행하고 모터에 출력 pid.Compute (); // 입력 및 출력 값을 직렬 모니터에 인쇄하여 작동 방식을 확인합니다. Serial.print (input); Serial.print ("=>"); Serial.println (출력); if (input> 150 && input <200) {// 봇이 떨어지면 if (output> 0) // 앞쪽으로 떨어지기 Forward (); // 바퀴를 앞으로 회전 else if (output <0) // 뒤로 떨어짐 Reverse (); // 바퀴를 뒤로 회전 } else // 봇이 떨어지지 않는 경우 Stop (); // 바퀴를 움직이지 않음 }
PID 출력 변수는 모터가 회전하는 얼마나 빨리 결정한다. 로봇이 떨어지려고하면 바퀴를 천천히 돌려서 약간의 수정을합니다. 이러한 사소한 수정이 작동하고 여전히 봇이 떨어지면 모터의 속도를 높입니다. 바퀴가 회전하는 속도는 PI 알고리즘에 의해 결정됩니다. Reverse 함수의 경우 음수 값을 양수로 변환 할 수 있도록 출력 값에 -1을 곱했습니다.
void Forward () // 휠을 앞으로 회전시키는 코드 { analogWrite (6, output); analogWrite (9,0); analogWrite (10, 출력); analogWrite (11,0); Serial.print ("F"); // 디버깅 정보 } void Reverse () // 휠을 회전시키는 코드 Backward { analogWrite (6,0); analogWrite (9, 출력 * -1); analogWrite (10,0); analogWrite (11, 출력 * -1); Serial.print ("R"); } void Stop () // 두 바퀴를 모두 정지시키는 코드 { analogWrite (6,0); analogWrite (9,0); analogWrite (10,0); analogWrite (11,0); Serial.print ("S"); }
Arduino Self Balancing 로봇 작동
하드웨어가 준비되면 Arduino 보드에 코드를 업로드 할 수 있습니다. 리튬 이온 배터리를 사용하고 있으므로 연결이 올바른지 확인하십시오. 극도의주의가 필요합니다. 따라서 단락이 있는지 다시 확인하고 봇이 약간의 영향을받는 경우에도 터미널이 접촉하지 않도록하십시오. 모듈의 전원을 켜고 직렬 모니터를 엽니 다. Arduino가 MPU6050과 성공적으로 통신 할 수 있고 모든 것이 예상대로 작동하면 다음 화면이 표시됩니다.
여기서는 input => output 형식으로 PID 알고리즘의 입력 및 출력 값을 볼 수 있습니다. 봇이 완벽하게 균형을 이루면 출력 값은 0이 됩니다. 입력 값은 MPU6050 센서의 현재 값입니다. 알파벳 "F"는 봇이 앞으로 이동하고 있음을 나타내고 "R"은 봇이 역방향으로 이동 함을 나타냅니다.
PID 초기 단계에서는 입력 및 출력 값을 쉽게 모니터링 할 수 있고 Kp, Ki 및 Kd 값에 대한 프로그램을 쉽게 수정하고 업로드 할 수 있도록 Arduino 케이블을 봇에 연결된 상태로 두는 것이 좋습니다. 쇼 봇의 전체 작업 아래에 비디오 당신의 PID 값을 수정하는 방법도 보여줍니다.
작동하는 데 문제가있는 경우 자체 밸런싱 로봇을 구축하는 데 도움이되기를 바라며, 아래 댓글 섹션에 질문을 남기거나 더 기술적 인 질문에 대한 포럼을 사용하십시오. 더 많은 재미를 원한다면 동일한 논리를 사용하여 볼 밸런싱 로봇 을 만들 수도 있습니다.