코어리스 DC 모터 및 nRF24L01 RF 모듈을 사용하여 가장 빠른 Arduino RC 차량 만들기
RC차는 항상 함께 놀기 즐겁습니다. 저는 개인적으로 이 원격조종 자동차들의 열렬한 팬이고 그들과 광범위하게 놀았습니다. 오늘날 대부분의 이 차들은 거친 지형을 다루기 위해 엄청난 토크를 제공하지만, 항상 뒤처져 있던 무언가가 있습니다. 속도!! 그래서 이 프로젝트에서 우리는 아르뒤노를 이용하여 전혀 다른 종류의 RC차를 만들 것입니다. 이 차의 주요 목적은 최대 속도를 달성하는 것입니다. 그래서 저는 RC차에 사용할 코어리스 DC 모터를 시험해 보기로 했습니다. 이 모터들은 보통 드론에 사용되며 39,000RPM의 정격으로 속도 갈증을 해소하기에 충분합니다. 이 차량은 소형 리튬 배터리로 구동되며, nRF24L01 RF 모듈을 사용하여 원격으로 제어할 수 있습니다. 또는 간단한 것을 찾는 경우 이 간단한 RF 로봇 및 Raspberry Pi Bluetooth Car 프로젝트를 확인할 수도 있습니다.
RC 자동차용 코어리스 DC 모터
이 프로젝트에 사용되는 코어리스 DC 모터는 아래 그림에 나와 있습니다. 미니 드론에 널리 쓰이기 때문에 쉽게 찾을 수 있습니다. 8520 Magnetic Micro Coreless Motor를 찾으시면 이것들을 보실 수 있습니다.
자, RC 자동차에 DC 모터를 사용하는 것에는 몇 가지 단점이 있습니다. 첫 번째 방법은 시동 토크가 매우 낮기 때문에 RC 차량은 최대한 가벼워야 한다는 것입니다. 이것이 제가 SMD 부품을 사용하여 PCB 위에 전체 자동차를 만들고 보드 크기를 최대한 줄이기로 결정한 이유입니다. 두 번째 문제는 고속인 39000RPM(축의 RPM)은 다루기 어렵기 때문에 MOSFET를 사용하여 만든 Arduino 쪽에 속도 제어 회로가 필요합니다. 세 번째는 이 모터들이 작동 전압이 3.6V에서 4.2V 사이인 리튬 폴리머 배터리로 구동되기 때문에 3.3V에서 작동하도록 회로를 설계해야 한다는 것입니다. 이것이 우리가 3.3V Arduino Pro 미니를 RC 자동차의 두뇌로 사용한 이유입니다. 이러한 문제들이 해결되었으니, 이 프로젝트를 만드는 데 필요한 자료들을 살펴볼까요?
재료가 필요합니다.
3.3V Arduino Pro Mini
아두이노
NRF24L01 – 2pcs
조이스틱 모듈
SI2302 MOSFET
1N5819 다이오드
코어리스 BLDC 모터스
AMS1117-3입니다.3V
리튬 폴리머 배터리
저항자, 캐패시터
와이어를 연결합니다.
RC 차량용 RF 조이스틱은 Arduino를 사용합니다.
앞서 언급한 바와 같이 RC 차량은 RF 조이스틱을 사용하여 원격으로 제어됩니다. 또한 이 조이스틱은 nRF24L01 RF 모듈과 함께 Arduino를 사용하여 제작됩니다. 또한 조이스틱 모듈을 사용하여 필요한 방향으로 RC를 제어했습니다. 이 두 모듈을 완전히 처음 접하는 경우, nRF24L01과 함께 Interface Arduino 및 Arduino 기사와 Interface Joystick을 읽고 작동 방식과 사용 방법을 학습할 수 있습니다. Arduino RF 원격 조이스틱을 제작하려면 아래 회로 다이어그램을 따라 할 수 있습니다.
RF 조이스틱 회로는 나노 보드의 USB 포트를 사용하여 전원을 켤 수 있습니다. nRF24L01 모듈은 3.3V에서만 작동하므로 3개를 사용했습니다.아두이노에 3V 핀을 꽂았어요 회로가 빵판에 구성되어 있고 아래처럼 보입니다. 필요할 경우 PCB도 만들 수 있습니다.
RF 조이스틱 회로용 Arduino 코드는 매우 간단합니다. 조이스틱에서 X 값과 Y 값을 판독하여 nRF24L01을 통해 RC 차량에 전송해야 합니다. 이 회로의 전체 프로그램은 이 페이지 하단에서 확인할 수 있습니다. 위에서 공유한 인터페이스 프로젝트 링크에서 이미 논의하였으므로 이에 대한 설명은 하지 않겠습니다.
Arduino RC 차량 회로도
원격 제어 Arduino 차량에 대한 전체 회로도는 다음과 같습니다. 회로 다이어그램에는 차량에 두 개의 TCRT5000 IR 모듈을 추가하는 옵션도 포함되어 있습니다. 이것은 RC차가 로봇을 따라가는 선으로 작동하여 외부적으로 제어되지 않고 스스로 작동할 수 있도록 하기 위해 계획되었습니다. 하지만, 이 프로젝트를 위해 우리는 그것에 집중하지 않을 것입니다. 우리는 "가장 빠른 선로봇"을 만들려고 노력할 또 다른 프로젝트 튜토리얼을 계속 시청할 것입니다. 단일 PCB의 두 회로를 모두 결합하여 쉽게 만들 수 있습니다. 이 프로젝트의 IR 센서 및 Op-amp 섹션을 무시할 수 있습니다.
RC 차량은 단자 P1에 연결된 리포 배터리에 의해 구동됩니다. AMS117-3입니다.3V는 3을 조절하는 데 사용됩니다.3V는 nRF24L01과 프로 미니 보드용입니다. 또한 아두이노 보드의 전원을 원핀에 직접 공급할 수 있지만, 온보드 3에 전원을 공급할 수도 있습니다.프로 미니의 3V 전압 레귤레이터는 RF 모듈에 충분한 전류를 공급할 수 없기 때문에 외부 전압 레귤레이터를 사용했습니다.
BLDC 모터 2개를 구동하기 위해 SI2302 MOSFET 2개를 사용했습니다. 이러한 MOSFETS를 3.3V로 구동할 수 있는지 확인하는 것이 중요합니다. 동일한 부품 번호를 찾을 수 없는 경우 아래 전송 특성을 가진 동등한 MOSFET를 찾을 수 있습니다.
모터는 최대 7A까지 피크 전류를 소비할 수 있으므로(계속 부하 시 3A로 테스트됨), MOSFET 배출 전류가 7A 이상이어야 하며 3.3V에서 완전히 켜져야 합니다. 보시다시피, 저희가 선택한 MOSFET는 2.25V에서도 10A를 제공할 수 있으므로 이상적인 선택입니다.
Arduino RC 카의 PCB를 제작합니다.
이 프로젝트에서 재미있는 부분은 PCB 개발입니다. 여기 PCB는 회로를 형성할 뿐만 아니라 자동차의 섀시 역할도 합니다. 그래서 우리는 모터를 쉽게 장착할 수 있는 옵션이 있는 자동차 모양을 계획했습니다. 위의 회로를 사용하여 직접 PCB를 설계하거나 아래와 같은 PCB 설계를 사용할 수도 있습니다.
보시다시피 저는 배터리, 모터 및 기타 구성 요소를 쉽게 장착할 수 있도록 PCB를 설계했습니다. 링크에서 이 PCB의 Gerber 파일을 다운로드할 수 있습니다. 일단 게르버 파일을 준비했으면, 그것을 조작할 때이다. PCB를 PCBGOGO에서 쉽게 수행하려면 다음 단계를 따릅니다.
1단계: www.pcbgogo.com에 접속하여 처음 가입하는 경우 등록합니다. 그런 다음 PCB 프로토타입 탭에서 PCB의 치수, 계층 수 및 필요한 PCB 수를 입력합니다. 저의 PCB는 80cmx80cm 이므로 아래 탭은 이와 같습니다.
2단계: 지금 견적 버튼을 클릭하여 계속 진행합니다. 사용된 트랙 간격 등과 같이 필요한 경우 몇 개의 추가 파라미터를 설정하는 페이지로 이동합니다. 그러나 대부분 기본값은 정상적으로 작동합니다. 여기서 고려해야 할 것은 가격과 시간입니다. 보시는 바와 같이 제조 시간은 2~3일밖에 되지 않으며 PSB는 5달러밖에 들지 않습니다. 그런 다음 요구 사항에 따라 원하는 배송 방법을 선택할 수 있습니다.
3단계: 마지막 단계는 Gerber 파일을 업로드하고 결제를 진행하는 것입니다. 프로세스가 원활한지 확인하기 위해 PCBGOGO는 결제를 진행하기 전에 Gerber 파일이 유효한지 확인합니다. 이렇게 하면 PCB가 제작에 적합한지 확인할 수 있으며 약속된 대로 사용자에게 연락할 수 있습니다.
PCB를 조립합니다.
보드가 주문된 후, 잘 포장된 박스에 배달원이 몇 일 후에 도착했는데, PCB의 품질은 항상 최고였어요. 아래 게시판에 대한 몇 장의 사진을 공유하여 귀하가 판단하실 수 있도록 하겠습니다.
저는 납땜봉을 켜고 보드를 조립하기 시작했습니다. 발판, 패드, 바이아스, 실크스크린 등이 모양과 크기가 딱 맞기 때문에 보드를 조립하는 데 문제가 없었습니다. 상자를 여는 시각에서 불과 10분 만에 보드가 준비됐습니다.
납땜 후 보드 사진 몇 장이 아래에 나와 있습니다.
3D 프린팅 휠 및 모터 장착입니다.
위의 그림에서 보셨겠지만, 우리는 로봇을 위해 모터 마운트와 바퀴를 3D로 만들어야 합니다. 위에서 공유한 PCB Gerber 파일을 사용했다면 이 thingVership 링크에서 다운로드하여 3D 모델을 사용하는 것이 좋습니다.
저는 쿠라를 사용하여 모델을 슬라이스하고 Tevo Terantuala로 프린팅했습니다. Tevo Terantuala는 지지대 없이 0% 주입하여 무게를 줄였습니다. 프린터에 맞게 설정을 변경할 수 있습니다. 모터가 매우 빨리 회전하기 때문에, 저는 모터 샤프트에 꼭 맞는 휠을 설계하는 것이 어렵다는 것을 알았습니다. 그래서 저는 드론 날을 바퀴 안에 사용하기로 했습니다. 아래에 보시는 것처럼요.
저는 이것이 더 믿을만하고 튼튼하다는 것을 알았습니다. 하지만, 다른 바퀴 디자인으로 실험을 해 보았고, 무엇이 여러분에게 도움이 되었는지 코멘트 섹션에 알려주세요.
아두이노를 프로그래밍하고 있습니다.
이 프로젝트의 전체 프로그램(아두이노 나노와 프로 미니 둘 다)은 이 페이지 하단에서 확인할 수 있습니다. RC 프로그램에 대한 설명은 다음과 같습니다.
필요한 헤더 파일을 포함하여 프로그램을 시작합니다. nRF24l01 모듈을 사용하려면 Arduino IDE에 라이브러리를 추가해야 합니다. 이 링크를 사용하여 Github에서 RF24 라이브러리를 다운로드할 수 있습니다. 그것과는 별도로, 우리는 이미 로봇의 최소 속도와 최대 속도를 정의했습니다. 최소 및 최대 범위는 각각 0 ~ 1024입니다.
#define min_speed 200
#define max_speed 800
#include <SPI.h>
#include "RF24.h"
RF24 myRadio (7, 8);
그런 다음 설정 기능 내에서 nRF24L01 모듈을 초기화합니다. 115개의 밴드는 혼잡하지 않고 모듈을 저전력으로 작동하도록 설정했기 때문에 이러한 설정으로 재생할 수도 있습니다.
void setup() {
Serial.begin (9600);
myRadio.begin();
myRadio.setChannel(115); //115 band above WIFI signals
myRadio.setPALevel(RF24_PA_MIN); //MIN power low rage
myRadio.setDataRate( RF24_250KBPS ) ; //Minimum speed
}
다음으로 메인 루프 기능에서는 송신기 조이스틱 모듈에서 전송된 값을 지속적으로 읽어 들이는 ReadData 기능만 실행합니다. 프로그램에서 언급한 파이프 주소는 송신기 프로그램에 언급된 파이프 주소와 동일해야 합니다. 디버깅을 위해 받는 값도 인쇄했습니다. 값이 성공적으로 판독되면 제어 차량 기능을 실행하여 RC 차량을 제어합니다.
Rf 모듈입니다.
void ReadData()
{
myRadio.openReadingPipe(1, 0xF0F0F0F0AA); //Which pipe to read, 40 bit Address
myRadio.startListening(); //Stop Transminting and start Reveicing
if ( myRadio.available())
{
while (myRadio.available())
{
myRadio.read( &data, sizeof(data) );
}
Serial.print("\nReceived:");
Serial.println(data.msg);
received = data.msg;
Control_Car();
}
}
Control Car 기능 내부에서는 아날로그 쓰기 기능을 사용하여 PWM 핀에 연결된 모터를 제어합니다. 저희 송신기 프로그램에서 아날로그 값을 나노의 A0 및 A1 핀에서 1 - 10, 11 - 20, 21 - 30 및 31 - 40으로 변환하여 차량을 전방, 후진, 좌측 및 우측으로 각각 제어했습니다. 아래 프로그램은 로봇을 전방으로 제어하는 데 사용됩니다.
if (received>=1 && received <=10) // Move Forward
{
int PWM_Value = map (received, 1, 10, min_speed, max_speed);
analogWrite(R_MR,PWM_Value);
analogWrite(L_MR,PWM_Value);
}
마찬가지로, 아래와 같이 역, 좌, 우의 세 가지 기능을 더 작성할 수 있습니다.
if (received>=11 && received <=20) // Break
{
int PWM_Value = map (received, 11, 20, min_speed, max_speed);
analogWrite(R_MR,0);
analogWrite(L_MR,0);
}
if (received>=21 && received <=30) // Turn left
{
int PWM_Value = map (received, 21, 30, min_speed, max_speed);
analogWrite(R_MR,PWM_Value);
analogWrite(L_MR,0);
}
if (received>=31 && received <=40) // Turn Right
{
int PWM_Value = map (received, 31, 40, min_speed, max_speed);
analogWrite(R_MR,0);
analogWrite(L_MR,PWM_Value);
}
Arduino RC 카
코드를 완료한 후, 프로 미니 보드에 업로드합니다. 테스트를 위해 FTDI 모듈을 통해 배터리와 보드를 분리합니다. 코드를 실행하고 직렬 배터리를 열면 송신기 조이스틱 모듈에서 값을 수신해야 합니다. 배터리를 연결하면 모터도 회전해야 합니다.
프로젝트의 전체 작업은 이 페이지 하단에 연결된 비디오에서 찾을 수 있습니다. 질문이 있으시면 댓글란에 남겨주세요. 또한 포럼을 사용하여 다른 기술 질문에 대한 빠른 답변을 얻을 수 있습니다.
Code
RF Remote Joystick
/*Code to transmit RF values to Arduino
*
* Pin Conections
* CE - 7
MISO - 12
MOSI - 11
SCK - 13
CS - 8
A0 - JoyX
A1 - JoyY
*/
#include <SPI.h>
#include "RF24.h"
RF24 myRadio (7, 8);
struct package
{
int msg = 0;
};
byte addresses[][6] = {"0"};
typedef struct package Package;
Package data;
void setup()
{
Serial.begin(9600);
myRadio.begin();
myRadio.setChannel(115); //115 band above WIFI signals
myRadio.setPALevel(RF24_PA_MAX); //MAX power long rage
myRadio.setDataRate( RF24_250KBPS ) ; //Minimum speed
delay(500);
Serial.print("Remote Initialized");
}
int forward;
int reverse;
int left;
int right;
void loop()
{
int xValue = analogRead(A0); //Read JoyX value
int yValue = analogRead(A1); //Read JoyY Value
//Serial.print(xValue); Serial.print(" , "); Serial.println(yValue);
if (xValue>560 && xValue<1000) // Filter JoyX for up
{
forward = map (xValue, 560, 1000, 1, 10); //Convert Joyx-up to 0-10
//Serial.print("F="); Serial.println(forward);
data.msg = forward; WriteData(); delay(50);
}
if (xValue<500 && xValue > 10) // Filter JoyX for break
{
reverse = map (xValue, 10, 500, 20, 11); //Convert JoyX-down to 11-20
//Serial.print("B="); Serial.println(reverse);
data.msg = reverse; WriteData(); delay(50);
}
else if (yValue>600 && yValue<1000) // Filter JoyY for right
{
right = map (yValue, 600, 1000, 21, 30); //Convert JoyY-right to 21-30
//Serial.print("R="); Serial.println(right);
data.msg = right; WriteData(); delay(50);
}
else if (yValue<450 && yValue > 10) // Filter JoyY for left
{
left = map (yValue, 10, 450, 40, 31); //Convert JoyY-left to 31-40
//Serial.print("L="); Serial.println(left);
data.msg = left; WriteData(); delay(50);
}
/* else
{
Serial.println("Rest");
data.msg = 0; WriteData(); delay(50);
}
*/
}
void WriteData()
{
myRadio.stopListening(); //Stop Receiving and start transminitng
myRadio.openWritingPipe( 0xF0F0F0F0AA); //Sends data on this 40-bit address
myRadio.write(&data, sizeof(data));
//Serial.print("\nSent:");
//Serial.println(data.msg);
delay(50);
}
void ReadData()
{
myRadio.openReadingPipe(1, 0xF0F0F0F066); // Which pipe to read, 40 bit Address
myRadio.startListening(); //Stop Transminting and start Reveicing
if ( myRadio.available())
{
while (myRadio.available())
{
myRadio.read( &data, sizeof(data) );
}
Serial.print("\nReceived:");
Serial.println(data.msg);
}
}
BLDC Motor
/*CE - 7
MISO - 12
MOSI - 11
SCK - 13
CS - 8
Recently tested with nano
*/
/*PIN DEFANITIONS*/
#define R_IR 3
#define L_IR 4
#define L_MR 5
#define R_MR 6
#define min_speed 200
#define max_speed 800
#include <SPI.h>
#include "RF24.h"
RF24 myRadio (7, 8);
struct package
{
int msg;
};
typedef struct package Package;
Package data;
byte addresses[][6] = {"0"};
void setup() {
pinMode(R_IR, INPUT);
pinMode(L_IR, INPUT);
pinMode(L_MR, OUTPUT);
pinMode(R_MR, OUTPUT);
Serial.begin (9600);
myRadio.begin();
myRadio.setChannel(115); //115 band above WIFI signals
myRadio.setPALevel(RF24_PA_MIN); //MIN power low rage
myRadio.setDataRate( RF24_250KBPS ) ; //Minimum speed
}
int received;
void loop() {
ReadData();
}
void Control_Car()
{
if (received>=1 && received <=10) // Move Forward
{
int PWM_Value = map (received, 1, 10, min_speed, max_speed);
analogWrite(R_MR,PWM_Value);
analogWrite(L_MR,PWM_Value);
}
if (received>=11 && received <=20) // Break
{
int PWM_Value = map (received, 11, 20, min_speed, max_speed);
analogWrite(R_MR,0);
analogWrite(L_MR,0);
}
if (received>=21 && received <=30) // Turn Right
{
int PWM_Value = map (received, 21, 30, min_speed, max_speed);
analogWrite(R_MR,PWM_Value);
analogWrite(L_MR,0);
}
if (received>=31 && received <=40) // Turn Right
{
int PWM_Value = map (received, 31, 40, min_speed, max_speed);
analogWrite(R_MR,0);
analogWrite(L_MR,PWM_Value);
}
}
void ReadData()
{
myRadio.openReadingPipe(1, 0xF0F0F0F0AA); //Which pipe to read, 40 bit Address
myRadio.startListening(); //Stop Transminting and start Reveicing
if ( myRadio.available())
{
while (myRadio.available())
{
myRadio.read( &data, sizeof(data) );
}
Serial.print("\nReceived:");
Serial.println(data.msg);
received = data.msg;
Control_Car();
}
else //If not data from RF
{
//analogWrite(R_MR,0);
//analogWrite(L_MR,0);
}
}
void WriteData()
{
myRadio.stopListening(); //Stop Receiving and start transminitng
myRadio.openWritingPipe(0xF0F0F0F066);//Sends data on this 40-bit address
myRadio.write(&data, sizeof(data));
Serial.print("\nSent:");
Serial.println(data.msg);
delay(300);
}
댓글