|
LONG DISTANCE 8채널 및 디지털 트림 리모콘 만들기. DIY RC | 파트 -2
100mW NRF24L01 PA LN(E01-ML01DP5) 2.4Ghz 모듈 및 Arduino로 장거리 원격 제어를 만드는 방법.
총 8개의 채널이 있습니다. 6개의 채널이 비례적으로 작동합니다. 한편, 2개의 채널은 스위치로 제어되며 온/오프로 작동합니다. 또한 이 원격 제어 회로에 3채널용 디지털 트림을 추가했습니다.
이 트림은 에일러론(롤), 엘리베이터(피치) 및 방향타(요) 채널에서 작동합니다.
이 RC 회로의 첫 번째 부분에서는 "PART-1"에서 1 채널이 활성화 된 기본 설정을 보여주었습니다. PART-2에서는 7개의 채널을 더 추가하여 8개의 채널로 완성하고 디지털 트림을 추가했습니다.
PART-1에서 언급했듯이 이러한 송신기 및 수신기 회로와 다른 Arduino 원격 제어 회로의 가장 큰 차이점은 내가 사용하는 E01-ML01DP5 모듈입니다. 이 모듈은 기본적으로 NRF24L01 PA LN과 동일합니다. 그러나 그들은 더 강력합니다. 송신기로 사용하면 100mW(20dBm)에서 작동할 수 있습니다. 이론적으로 범위는 2100 미터입니다. 수신기로 사용하면 절반의 전력으로 작동합니다. 또한 금속 케이스 덕분에 전기적 노이즈의 영향을 덜 받습니다. 이런 식으로 더 안정적으로 작동할 수 있습니다.
8 채널 리모콘 구성을위한 몇 가지 옵션을 제시합니다. 원하는 사람은 8 채널 또는 8 채널 + 트림 만 만들 수 있습니다. 또한 NRF24 모듈이 arduino 5V 핀 또는 외부 전원 공급 장치에서 직접 공급되는 옵션 버전을 공유했습니다.
필요한 자료 : 2 x PS4 아날로그 조이스틱 : https://s.click.aliexpress.com/e/_DBSn2AB 2 x 토글 스위치: https://s.click.aliexpress.com/e/_DCd5Pzh 2 x 100mW NRF24L01 PA LN(E01-ML01DP5): https://s.click.aliexpress.com/e/_DmEoWQf 2 x 아두이노 나노: https://s.click.aliexpress.com/e/_DlhwLS3 2 x NRF24 무선 3.3v 어댑터:
https://s.click.aliexpress.com/e/_DlmATh1
2 x 100uF 전해 콘덴서 : https://s.click.aliexpress.com/e/_DBJpcn1
4 x 암 헤더 핀 (15 핀) : https://s.click.aliexpress.com/e/_DDqmgbh
2 x 10K 전위계: https://s.click.aliexpress.com/e/_DCV1V11
범용 PCB 보드: https://s.click.aliexpress.com/e/_DF8xNJ9
AA Pil Kutusu (6xAA 셀) : https://s.click.aliexpress.com/e/_DFMnduf
veya 18650 필 쿠투 : https://s.click.aliexpress.com/e/_DERuJnl
5mm LED: https://s.click.aliexpress.com/e/_DB6EXhh
330R 크기: https://s.click.aliexpress.com/e/_DFkljF9
로커 부톤 (10x15mm) : https://s.click.aliexpress.com/e/_DDvMlXd
택트 부톤 (6x6x7) :
https://s.click.aliexpress.com/e/_Dm2yUBt 나사 : https://s.click.aliexpress.com/e/_DEvN4J9
8 채널 송신기 (TX) 회로 :
8채널 송신기(TX) 코드(트림 없음):
8채널 송신기(트림 없음) | 8 Kanal Verici (트림 요크)
입력 핀 A5
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
상수 uint64_t pipeOut = 000322; // 참고: 수신기 000322에서와 동일 | Alıcı kodundaki adres ile aynı olmalı
RF24 라디오(9, 10); // CE,CSN 핀 선택 | CE ve CSN pinlerin seçimi
struct 신호 {
바이트 스로틀;
바이트 피치;
바이트 롤;
바이트 요;
바이트 AUX1;
바이트 AUX2;
바이트 AUX3;
바이트 AUX4;
};
신호 데이터;
'선언 Sub ResetData()
{
데이터. 스로틀 = 0;
데이터. 피치 = 127;
데이터. 롤 = 127;
데이터. 요 = 127;
데이터. 보조1 = 0; // 신호 손실 위치 | Sinyal kesildiğindeki pozisyon
데이터. 보조2 = 0;
데이터. 보조3 = 0;
데이터. 보조4 = 0;
}
무효 설정()
{
NRF24 모듈 구성 | NRF24 modül konfigürasyonu
라디오. 시작되다();
라디오. openWritingPipe(pipeOut);
라디오. setAutoAck(거짓);
라디오. setDataRate(RF24_250KBPS)입니다. // 보다 안정적인 통신을 위한 가장 낮은 데이터 전송률 값 | Daha kararlı iletişim için en düşük veri hızı.
라디오. setPALevel(RF24_PA_MAX); 출력 전력이 최대로 설정됨 | Çıkış gücü maksimum için ayarlanıyor.
라디오. stopListening()입니다. 송신기에 대한 무선 통신 시작 | Verici için sinyal iletişimini başlatır.
리셋 데이터();
}
조이스틱 중심과 그 경계 | Joystick merkez ve sınırları
int Border_Map(int val, int lower, int middle, int upper, bool reverse)
{
val = constrain(val, lower, upper);
if ( val < 중간 )
val = map(val, lower, middle, 0, 128);
다른
val = map(val, 중간, 상위, 128, 255);
반환(역 ? 255 - 발 : 발 );
}
void 루프()
{
채널에 대한 조종 스틱 보정 | Her bir kanal için kumanda Kol Kalibrasyonları
데이터. 롤 = Border_Map( analogRead( A3), 0, 512, 1023 , 참); // 신호 방향에 대한 "true" 또는 "false" | "true" veya "false" sinyal yönünü belirler
데이터. 피치 = Border_Map( analogRead( A2), 0, 512, 1023 , 참 );
데이터. 스로틀 = Border_Map( analogRead(A1),570, 800, 1023, 거짓); // 단면 ESC용 | Tek yönlü ESC için
data.throttle = Border_Map( analogRead(A1),0, 512, 1023, 거짓); 양방향 ESC용 | Çift yönlü ESC için
데이터. 요 = Border_Map( analogRead(A0), 0, 512, 1023 , 참 );
데이터. aux1 = Border_Map( analogRead(A4), 0, 512, 1023 , 참); // 신호 방향 변경에 대한 "true" 또는 "false" | "true" veya "false" sinyal yönünü değiştirir.
데이터. aux2 = Border_Map( analogRead(A5), 0, 512, 1023 , 참); // 신호 방향 변경에 대한 "true" 또는 "false" | "true" veya "false" sinyal yönünü değiştirir.
데이터. aux3 = 디지털 읽기(7);
데이터. aux4 = 디지털 읽기(8);
라디오. write(&data, sizeof(신호));
}
메모: "true"와 "false"라는 단어는 서보의 방향을 결정합니다. "true" 대신 "false"라고 쓰면 신호 방향이 바뀌고 서보가 반대쪽으로 이동합니다. 따라서 "역방향" 명령이 작동합니다.
트림이 있는 8채널 송신기용 회로:
트림이 있는 8채널 송신기용 코드:
8 채널 송신기 및 트림 | 8 Kanal Verici ve Trimler
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <EEPROM.h>
상수 uint64_t pipeOut = 000322; // 참고: 수신기 000322에서와 동일 | Alıcı kodundaki adres ile aynı olmalı
RF24 라디오(9, 10); // CE,CSN 핀 선택 | CE ve CSN pinlerin seçimi
#define trimbut_1 1 // 트림 버튼 1 / 핀 D1
#define trimbut_2 2 // 트림 버튼 2 / 핀 D2
#define trimbut_3 3 // 트림 버튼 3 / 핀 D3
#define trimbut_4 4 // 트림 버튼 4 / 핀 D4
#define trimbut_5 5 // 트림 버튼 5 / 핀 D5
#define trimbut_6 6 // 트림 버튼 6 / 핀 D6
int tvalue1 = EEPROM입니다. 읽기(1) * 4; // Eprom에서 트림 값 읽기 | Trim değerlerinin Epromdan okunması
int tvalue2 = EEPROM입니다. 읽기(3) * 4;
int tvalue3 = EEPROM입니다. 읽기(5) * 4;
struct 신호 {
바이트 스로틀;
바이트 피치;
바이트 롤;
바이트 요;
바이트 AUX1;
바이트 AUX2;
바이트 AUX3;
바이트 AUX4;
};
신호 데이터;
'선언 Sub ResetData()
{
데이터. 스로틀 = 512; // 신호 손실 위치 | Sinyal kesildiğindeki pozisyon
데이터. 피치 = 127;
데이터. 롤 = 127;
데이터. 요 = 127;
데이터. 보조1 = 0;
데이터. 보조2 = 0;
데이터. 보조3 = 0;
데이터. 보조4 = 0;
}
무효 설정()
{
NRF24 모듈 구성 | NRF24 modül konfigürasyonu
라디오. 시작되다();
라디오. openWritingPipe(pipeOut);
라디오. setAutoAck(거짓);
라디오. setDataRate(RF24_250KBPS)입니다. // 보다 안정적인 통신을 위한 가장 낮은 데이터 전송률 값 | Daha kararlı iletişim için en düşük veri hızı.
라디오. setPALevel(RF24_PA_MAX); 출력 전력이 최대로 설정됨 | Çıkış gücü maksimum için ayarlanıyor.
라디오. stopListening()입니다. 송신기에 대한 무선 통신 시작 | Verici için sinyal iletişimini başlatır.
리셋 데이터();
pinMode(trimbut_1, INPUT_PULLUP);
pinMode(trimbut_2, INPUT_PULLUP);
pinMode(trimbut_3, INPUT_PULLUP);
pinMode(trimbut_4, INPUT_PULLUP);
pinMode(trimbut_5, INPUT_PULLUP);
pinMode(trimbut_6, INPUT_PULLUP);
tvalue1= EEPROM입니다. 읽기(1) * 4;
tvalue2= EEPROM입니다. 읽기(3) * 4;
tvalue3= EEPROM입니다. 읽기(5) * 4;
}
조이스틱 중심과 그 경계 | Joystick merkez ve sınırları
int Border_Map(int val, int lower, int middle, int upper, bool reverse)
{
val = constrain(val, lower, upper);
if ( val < 중간 )
val = map(val, lower, middle, 0, 128);
다른
val = map(val, 중간, 상위, 128, 255);
반환(역 ? 255 - 발 : 발 );
}
void 루프()
{
트림 및 트림 값 제한 | Trimler ve Trim değerlerini sınırlandırma
if(digitalRead(trimbut_1)==LOW 및 tvalue1 < 630) {
tvalue1=tvalue1+15;
EEPROM입니다. 쓰기(1,tvalue1/4);
지연(130);
}
if(digitalRead(trimbut_2)==LOW 및 tvalue1 > 280){
tvalue1=tvalue1-15;
EEPROM입니다. 쓰기(1,tvalue1/4);
지연(130);
}
if(digitalRead(trimbut_3)==LOW 및 tvalue2 < 630) {
tvalue2=tvalue2+15;
EEPROM입니다. 쓰기(3,tvalue2/4);
지연(130);
}
if(digitalRead(trimbut_4)==LOW 및 tvalue2 > 280){
tvalue2=tvalue2-15;
EEPROM입니다. 쓰기(3,tvalue2/4);
지연(130);
}
if(digitalRead(trimbut_5)==LOW 및 tvalue3 < 630) {
tvalue3=tvalue3+15;
EEPROM입니다. 쓰기(5,tvalue3/4);
지연(130);
}
if(digitalRead(trimbut_6)==LOW 및 tvalue3 > 280){
tvalue3=tvalue3-15;
EEPROM입니다. 쓰기(5,tvalue3/4);
지연(130);
}
채널에 대한 조종 스틱 보정 | Her bir kanal için kumanda Kol Kalibrasyonları
데이터. 롤 = Border_Map( analogRead( A3), 0, tvalue1, 1023, 참); // 신호 방향에 대한 "true" 또는 "false" | "true" veya "false" sinyal yönünü belirler
데이터. 피치 = Border_Map( analogRead( A2), 0, tvalue2, 1023, 참 );
데이터. 스로틀 = Border_Map( analogRead(A1),570, 800, 1023, 거짓); // 단면 ESC용 | Tek yönlü ESC için
data.throttle = Border_Map( analogRead(A1),0, 512, 1023, 거짓); 양방향 ESC용 | Çift yönlü ESC için
데이터. 요 = Border_Map( analogRead(A0), 0, tvalue3, 1023, 참 );
데이터. aux1 = Border_Map( analogRead(A4), 0, 512, 1023 , 참 );
데이터. aux2 = Border_Map( analogRead(A5), 0, 512, 1023 , 참 );
데이터. aux3 = 디지털 읽기(7);
데이터. aux4 = 디지털 읽기(8);
라디오. write(&data, sizeof(신호));
}
참고 :
– 스로틀 제어에 사용하는 PS4 조이스틱에는 스프링이 장착되어 있기 때문에 레버에서 손을 떼면 중앙으로 돌아갑니다. 이 상황은 단방향 ESC에는 적합하지 않습니다. 따라서 스로틀 채널(3차 채널)을 제어하는 암은 중앙에 있을 때 최소 위치에 있는 것처럼 조정해야 합니다. "data.throttle" 줄의 처음 두 값 "570, 800"은 이를 제공합니다. 양방향 ESC(예: 자동차 및 보트 ESC)의 경우 다른 채널에서와 같이 "0, 512" 값이 사용됩니다.
– 롤, 피치 및 요 라인에서 첫 번째 값은 "tvalue"라는 변수입니다. 이 변수는 트림 컨트롤 버튼의 값을 저장합니다. 이 값은 채널의 중심 위치를 변경합니다.
트림 값은 eprom에 저장됩니다.
8채널 수신기(RX) 순환:
8 채널 수신기(RX) 코드:
8 채널 수신기 | 8 채널 Alıcı
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <Servo.h>
정수 ch_width_1 = 0;
정수 ch_width_2 = 0;
정수 ch_width_3 = 0;
정수 ch_width_4 = 0;
정수 ch_width_5 = 0;
정수 ch_width_6 = 0;
정수 ch_width_7 = 0;
정수 ch_width_8 = 0;
서보 ch1;
서보 ch2;
서보 ch3;
서보 ch4;
서보 ch5;
서보 ch6;
서보 ch7;
서보 ch8;
struct 신호 {
바이트 스로틀;
바이트 피치;
바이트 롤;
바이트 요;
바이트 AUX1;
바이트 AUX2;
바이트 AUX3;
바이트 AUX4;
};
신호 데이터;
상수 uint64_t pipeIn = 000322;
RF24 라디오(9, 10);
'선언 Sub ResetData()
{
데이터. 스로틀 = 0;
데이터. 롤 = 127;
데이터. 피치 = 127;
데이터. 요 = 127;
데이터. 보조1 = 0; // 각 데이터 입력의 고유 값을 정의합니다. | Veri girişlerinin başlangıç değerleri
데이터. 보조2 = 0;
데이터. 보조3 = 0;
데이터. 보조4 = 0;
}
무효 설정()
{
각 PWM 신호에 대한 핀 설정 | Her bir PWM sinyal için pinler belirleniyor.
CH1입니다. 첨부(0);
CH2입니다. 첨부(2);
CH3입니다. 첨부(3);
CH4입니다. 첨부(4);
CH5입니다. 첨부(5);
CH6입니다. 첨부(6);
CH7입니다. 첨부(7);
CH8입니다. 첨부(8);
리셋데이터(); NRF24 모듈 구성 | NRF24 Modül konfigürasyonu
라디오. 시작되다();
라디오. openReadingPipe(1,pipeIn);
라디오. setAutoAck(거짓);
라디오. setDataRate(RF24_250KBPS)입니다. // 보다 안정적인 통신을 위한 가장 낮은 데이터 전송률 값 | Daha kararlı iletişim için en düşük veri hızı.
라디오. setPALevel(RF24_PA_MAX); 출력 전력이 최대로 설정됨 | Çıkış gücü maksimum için ayarlanıyor.
라디오. 시작듣기(); // 수신기용 라디오 통신 시작 | Alıcı için sinyal iletişimini başlatır.
}
부호 없는 긴 lastRecvTime = 0;
'선언 Sub recvData()
{
동안 ( 라디오. 이용할 수 있는() ) {
라디오. read(&data, sizeof(신호));
lastRecvTime = 밀리(); // 데이터 수신 | Data alınıyor
}
}
void loop()
{
recvData();
unsigned long now = millis();
if ( now - lastRecvTime > 1000 ) {
ResetData(); // Signal lost.. Reset data | Sinyal kayıpsa data resetleniyor
}
ch_width_1 = map(data.roll, 0, 255, 1000, 2000);
ch_width_2 = map(data.pitch, 0, 255, 1000, 2000);
ch_width_3 = map(data.throttle, 0, 255, 1000, 2000);
ch_width_4 = map(data.yaw, 0, 255, 1000, 2000);
ch_width_5 = map(data.aux1, 0, 255, 1000, 2000);
ch_width_6 = map(data.aux2, 0, 255, 1000, 2000);
ch_width_7 = map(data.aux3, 0, 1, 1000, 2000);
ch_width_8 = map(data.aux4, 0, 1, 1000, 2000);
ch1.writeMicroseconds(ch_width_1); // Write the PWM signal | PWM sinyaller çıkışlara gönderiliyor
ch2.writeMicroseconds(ch_width_2);
ch3.writeMicroseconds(ch_width_3);
ch4.writeMicroseconds(ch_width_4);
ch5.writeMicroseconds(ch_width_5);
ch6.writeMicroseconds(ch_width_6);
ch7.writeMicroseconds(ch_width_7);
ch8.writeMicroseconds(ch_width_8);
}
NOTE: The values “1000” and “2000” in the map command of the receiver code determine the maximum movement limits of the servo. With 1000 and 2000 values, 120° servo movement is obtained. For example, if you change these values to 800 and 2300, the servo can move 180° in total. You can change these values according to your needs. (Min 800, can be max 2300)
OPTIONAL ADDITIONS:
If you want to use the receiver circuit with 3S – 6S LiPo, it will be necessary to add a voltage reducer (Regulator) circuit. Because Arduino nano can work directly with a maximum of 10V.
Below is a diagram showing the 9V voltage regulator circuit and its attached to the receiver circuit.
NOTE: The maximum continuous current support for the 5V pin of the Arduino is 20mA (Momentary 40mA). The NRF module, on the other hand, draws about 12.32 mA as I showed in the video. That’s why I didn’t add an external power supply. But when I searched the technical specifications for the E01-ML01DP5 NRF24 module, it was given a maximum of 20mA when used as a receiver, and a maximum of 130mA when used as a transmitter. But I could not find the official manufacturer site or a datasheet showing the technical specifications for this version of NRF24. Therefore, I took into account the current value I measured myself and did not use an external power supply.
For those who still prefer an external power supply, I have shared the relevant circuit diagrams below.
Step-down regulator circuit and transmitter circuit diagram for 5V (Optional):
Required materials for regulators:
1uF electrolytic capacitors : https://s.click.aliexpress.com/e/_DDVm071
10uF electrolytic capacitors: https://s.click.aliexpress.com/e/_Ddfia2R
100nF ceramic capacitor: https://s.click.aliexpress.com/e/_Dd496aB
7805 5V Regulator IC: https://s.click.aliexpress.com/e/_DDvYt5v
7809 9V Regulator IC: https://s.click.aliexpress.com/e/_DlXmEG7
80W 납땜 인두: https://s.click.aliexpress.com/e/_DD75tWX 디지털 멀티미터 AC DC A830L : https://s.click.aliexpress.com/e/_DmjzgOJ
Profesyonel
디지털 멀티미터 테스터: https://s.click.aliexpress.com/e/_DmtkrmJ