반응형

자 어느새 목표했던 RC headtracking FPV 만들기의 종착역을 다가가고 있습니다.

앞서 소개해 드렸던 2축 서보마운트 제작 및 서보컨트롤과 mpu6050 을 이용하여 2축 서보모터를 제어하는 내용은 잘 보셨나요? 아직 못보신분은 아래 글을 참고 부탁드립니다

2022.01.31 - [DIY/Arduino] - [아두이노]2축 서보모터 초간단 제어하기, 간단한 프레임 제작까지

 

[아두이노]2축 서보모터 초간단 제어하기, 간단한 프레임 제작까지

뭔가 목표가 생기면 과정이 분명해 진다. RC 카에 헤드트래킹을 이용한 FPV 를 구현하려는 목표가 생기고나니 과정을 잘 정리하는게 필요하겠다 싶어 포스트를 남깁니다. 우선 첫번째 스텝으로 2

diy-dev-design.tistory.com

2022.01.31 - [DIY/Arduino] - [아두이노]mpu6050 을 이용하여 2축 서보모터 제어하기

 

[아두이노]mpu6050 을 이용하여 2축 서보모터 제어하기

아두이노와 같은 마이크로 칩을 이용하여 무엇인가를 해보다 보면 정말 놀라운 경험들을 많이 하게 됩니다. 그 중 하나가 바로 mpu6050 같은 센서가 될 수 있겠습니다. 요 조그만 칩을 이용하여 기

diy-dev-design.tistory.com

 

반응형

 

오늘은 앞에서 소개해드린 mp6050 을 이용하여 측정한 회전 정보를 이용하여 서보모터를 제어하는 것을 응용하여 무선으로 서보모터를 제어하는 과정을 소개해 드릴 예정인데요, 여기에서는 아주아주 놀랍고 멋진 무선 송수신 칩인 nrf24L01 칩을 이용하여 구현을 할 계획입니다.

nrf24L01 칩의 경우 저렴하면서도 놀라운 성능을 보여주는 아주아주 애정하는 부품입니다.

실제로 해당 칩을 이용하여 RC 카 조종장치와 수신 장치를 만들기도 한적이 있습니다. 제어되는 범위, 거리도 아주 훌륭하고 신호 수준도 좋으며 중요한 것은 1개의 송신부에서 여러개의 수신장치를 제어할 수 있는 멋진 칩 입니다. 게다가 송신과 수신을 하나의 칩에서 지원하고 있으므로 양방향 통신을 구현하는데에도 어려움이 없습니다.

일단 오늘 도전할 목표는 앞서 말씀 드렸던것 처럼 mp6050 자이로 센서에서 측정된 회전 값을 NRF24L01 칩을 이용하여 보내고 또다른 NRF24L01 칩에서 이 신호를 받아 2축 서보모터를 제어하는 과제가 되겠습니다.

이전 포스팅에서 소개해 드린 것에서 무선 송수신이 추가만 되었을 뿐 크게 달라지는 건 없습니다.

무선 송수신을 위한 라이브러리는 웹상에도 많이 있고요, 아래 첨부해둔 라이브러리를 받으셔서 바로 내문서-아두이노 폴더에 넣으셔도 됩니다.

RF24-master.zip
0.39MB
SPI.zip
0.01MB

 

자 이젠 무선 송수신 칩이 들어오면서 배선이 조금 복잡해 집니다.

차근차근 따라 오시면 됩니다.

 

NRF24L01 칩에 대하여

여기서 NRF24L01 칩 외에 추가 준비물이 필요한데요, 준비물은 바로 10uf 전해콘덴서 입니다. 이 전해 콘덴서를 nrf24l01 의 전원 (3.3v) 단에 연결을 해 주셔야 문제 없이 잘 동작합니다. 용량은 가능하면 10uf 로 준비해 주세요, 제가 처음 테스트 할 때 전해 콘덴서 용량이야 뭔들 중요하랴... 싶어 용량이 안 맞는 부품을 적당히 연결해서 해보았지만 잘 안되서 정말 골머리를 썩었는데요, 10uf 콘덴서를 달면 정말 거짓말처럼 동작이 잘 됩니다. 

물론 소스코드나 배선에 실수는 없어야 겠지요.

 

한가지더, nrf24l01 칩은 몇가지 타입이 있는데요, 크기가 작은 SMD 타입과 일반 핀이 달려있는 Dip 타입, 그리고 원거리 송수신이 가능한 PA LN 타입이 있습니다. 핀 구성은 모두 동일하고 배열만 약간 차이가 있으며 코드는 모두 동일하게 지원 합니다. 저는 소형화된 부품이 좋아 보통은 SMD 타입 부품을 사용하고요, 배선이 일렬로 되어 있어 브래드 보드 등에 테스트 하기도 편리한 점이 장점이라 할 수 있습니다. 해외 어떤 사용자 분은 성능도 SMD 타입이 좋다고 하시는데.. 실제로 그런지는 잘 모르겠습니다. (- -)>;;

DIP 타입을 이용하실 경우 확장 보드가 있으면 조금더 편리하게 사용하실 수 있지만 부피가 조금 커진다고 보시면 되고, PA-LNA 보드는 DIP 타입의 확장보드와 호환이 가능하며 아래쪽에 SMD 타입과 같은 보드 실장을 위한 연결 단자가 있으므로 보드에 바로 연결이 가능합니다. PA-LNA 보드의 경우 NRF24L01 칩이 기본 탑제되어 있고 위에서 말씀드린것과 같이 코드 및 배선은 동일하게 하시면 되며 원거리까지 송수신이 가능하므로 무선으로 멀리까지 신호를 보내고 받아야 하는 경우 사용하시면 되겠습니다.

 

배선 시작

자 이제 배선을 해보겠습니다.

 

먼저 제가 사용할 SMD 타입은 만능기판에 바로 핀을 꼽기가 어려운데요. 그래서 생각해낸 것이 아래와 같은부품을 이용하는 것 입니다.

14pin smd 부품을 만능기판에 사용하기 위한 pcb 보드

가운데 있는 보드를 가운데를 잘라주고 반쪽만 사용하게 되는데요, 이 pcb 를 이용하면 NRF24L01 SMD 칩의 핀 간격과 정확히 일치 하게 되며 실제로 사용하지 않는 가장 오른쪽 IRQ 는 무시하고 왼쪽부터 맞추어 납을 흘려넣어 납땜을 해주면 됩니다.

하단의 구멍에는 1.24mm pin 이 정확히 맞으므로 일렬로 배열된 핀을 만능기판에 꼽아 사용할 수 있게 됩니다.

위에서 말씀드린 10uF 전해 콘덴서까지 연결하게 되면 아래와 같은 모양이 됩니다.

만능기판용으로 제작된 SMD 타입의 NRF24L01 칩

 

NRF24L01 칩은 아래와 같은 핀 구성을 하고 있고요, 각각 아두이노와 그림처럼 연결하시면 됩니다.

NRF24L01 SMD PINOUT

 

아두이노 핀 연결방법

 

CE, CSN 은 각각 7번 8번에 연결하여야 하는데 이 두핀은 위치가 바뀌어도 상관 없습니다. 코드상에서 정의해준 핀의 번호와 일치하기만 하면 되고요, 나머지 핀은 지정된 핀에 연결하시면 됩니다.

저처럼 SMD 타입을 사용할 경우 전원은 아두이노의 반드시 3.3V 에 연결해 주셔야 하고 dip 타입을 사용하시는 경우 확장보드를 이용하시면 5V 를 바로 연결하셔도 되며 10uf 전해 콘덴서는 필요 없습니다.

 

특별 초대손님이 있다고?

자~ 오늘의 특별 초대손님이 계신데요...

두구두구

두구

두구

 

 

아두이노 RC 카 수신기

짜잔~

네~ 바로 아두이노로 제작한 RC 카 수신기 입니다. 물론 송신기도 아두이노로 만들었었습니다.

해당 보드는 왼쪽 상단에 3핀 소켓을 통해 ESC 로부터 전원을 입력 받고 신호 선을 통해 모터스피드(속도)를 제어하게 되고요, 우측 아래 두개의 3핀 소켓을 통해 조향서보와 2-speed gear 의 조작용 서보에 연결하게 제작되었습니다. 오늘은 해당 두개의 서보모터 핀을 이용하여 x,y 축을 제어해 보도록 할 계획입니다. 보드 중간에 가로로 보이는 구멍이 NRF24L01 보드를 장착하기 위한 소켓입니다.

무선 모듈을 연결하면 아래와 같은 모양이 됩니다.

NRF24L01 보드가 장착된 아두이노 RC 카 수신기

한동안 즐겁게 가지고 놀았었는데요, 일반적인 RC 카 수신기에 비하면 덩치가 조금 크기는 하지만 4개의 2pin 포트를 통해 헤드라이트나 후미등, 좌우측 깜박이 등을 이 보드 하나로 제어할 수 있어 멀펑 보드가 별도로 필요하지 않으므로 나름 쓸만하다고 할 수 있겠습니다. 

언제 시간이 나면 핀 사진의 커넥터 대신 일반 적인 RC 카에 많이 사용하는 후타바 짹이나 JR 커넥터 등을 이용하여 부피를 줄여볼 계획입니다. 나중에 작업하게 되면 소개해 드리겠습니다.,

 

배선은 송신부, 수신부 두개의 아두이노에 동일하게 해주시면 되고 송신부와 수신부는 코드에서 정의를 해주게 됩니다.

 

배선이 완료된 송신부 입니다.

아두이노나노, NRF24L01, MPU6050 이 연결되어 있다.

네 사진상으로는 조금 복잡하지만 기존 설명드린데로 잘 연결 하셨다면 어려움 없이 잘 하실 수 있으리라 믿습니다.

 

수신기 쪽을 볼까요?

아두이노 나노, NRF24L01, 2개의 서보모터가 연결되어 있다

네 수신부에는 예상하시다 시피 두개의 서보모터와 NRF24L01 보드가 연결되어 있습니다.

 

 

코딩을 해보자

코드를 볼까요?

 

먼저 송신부 입니다. 기존 작성해 놓은 mp6050 코드에 무선 송수신 코드만 추가할 예정입니다.

// init for nrf24L01 
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

RF24 radio(8,7);  //  CE, CSN 
const byte address[6] = "00001"; //송신기와 수신기 동일한 주소 사용
int msg[8]; 


//pinout smd version
//3.3v  --- 3.3v
//GND  ---  GND
//CE   ---  8
//CSN  ---  7
//SCK  ---  13
//MOSI ---  11
//MISO ---  12
//IRQ  ---  none

// init for mpu6050
#include "I2Cdev.h"
#include "MPU6050_6Axis_MotionApps_V6_12.h"
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
#include "Wire.h"
#endif

MPU6050 mpu;
#define OUTPUT_READABLE_YAWPITCHROLL
#define INTERRUPT_PIN 2  // use pin 2 on Arduino Uno & most boards
#define LED_PIN 13 // (Arduino is 13, Teensy is 11, Teensy++ is 6)
bool blinkState = false;

// MPU control/status vars
bool dmpReady = false;  // set true if DMP init was successful
uint8_t mpuIntStatus;   // holds actual interrupt status byte from MPU
uint8_t devStatus;      // return status after each device operation (0 = success, !0 = error)
uint16_t packetSize;    // expected DMP packet size (default is 42 bytes)
uint16_t fifoCount;     // count of all bytes currently in FIFO
uint8_t fifoBuffer[64]; // FIFO storage buffer

// orientation/motion vars
Quaternion q;           // [w, x, y, z]         quaternion container
VectorInt16 aa;         // [x, y, z]            accel sensor measurements
VectorInt16 gy;         // [x, y, z]            gyro sensor measurements
VectorInt16 aaReal;     // [x, y, z]            gravity-free accel sensor measurements
VectorInt16 aaWorld;    // [x, y, z]            world-frame accel sensor measurements
VectorFloat gravity;    // [x, y, z]            gravity vector
float euler[3];         // [psi, theta, phi]    Euler angle container
float ypr[3];           // [yaw, pitch, roll]   yaw/pitch/roll container and gravity vector

volatile bool mpuInterrupt = false;     // indicates whether MPU interrupt pin has gone high
void dmpDataReady() {
  mpuInterrupt = true;
}

void setup() {

  // join I2C bus (I2Cdev library doesn't do this automatically)
  #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
    Wire.begin();
    Wire.setClock(400000); // 400kHz I2C clock. Comment this line if having compilation difficulties
  #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
    Fastwire::setup(400, true);
  #endif
  
  Serial.begin(115200);
  while (!Serial); // wait for Leonardo enumeration, others continue immediately

 
  // initialize device
  Serial.println(F("Initializing I2C devices..."));
  mpu.initialize();
  pinMode(INTERRUPT_PIN, INPUT);

  // verify connection
  Serial.println(F("Testing device connections..."));
  Serial.println(mpu.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed"));

  // wait for ready
  Serial.println(F("\nSend any character to begin DMP programming and demo: "));
  //while (Serial.available() && Serial.read()); // empty buffer
  //while (!Serial.available());                 // wait for data
  //while (Serial.available() && Serial.read()); // empty buffer again

  // load and configure the DMP
  Serial.println(F("Initializing DMP..."));
  devStatus = mpu.dmpInitialize();

  // supply your own gyro offsets here, scaled for min sensitivity
  mpu.setXGyroOffset(51);
  mpu.setYGyroOffset(8);
  mpu.setZGyroOffset(21);
  mpu.setXAccelOffset(1150);
  mpu.setYAccelOffset(-50);
  mpu.setZAccelOffset(1060);
  // make sure it worked (returns 0 if so)
  if (devStatus == 0) {
    // Calibration Time: generate offsets and calibrate our MPU6050
    mpu.CalibrateAccel(6);
    mpu.CalibrateGyro(6);
    Serial.println();
    mpu.PrintActiveOffsets();
    // turn on the DMP, now that it's ready
    Serial.println(F("Enabling DMP..."));
    mpu.setDMPEnabled(true);

    // enable Arduino interrupt detection
    Serial.print(F("Enabling interrupt detection (Arduino external interrupt "));
    Serial.print(digitalPinToInterrupt(INTERRUPT_PIN));
    Serial.println(F(")..."));
    attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), dmpDataReady, RISING);
    mpuIntStatus = mpu.getIntStatus();

    // set our DMP Ready flag so the main loop() function knows it's okay to use it
    Serial.println(F("DMP ready! Waiting for first interrupt..."));
    dmpReady = true;

    // get expected DMP packet size for later comparison
    packetSize = mpu.dmpGetFIFOPacketSize();
  } else {
    // ERROR!
    // 1 = initial memory load failed
    // 2 = DMP configuration updates failed
    // (if it's going to break, usually the code will be 1)
    Serial.print(F("DMP Initialization failed (code "));
    Serial.print(devStatus);
    Serial.println(F(")"));
  }

  // Radio setup
  //setupRadio();
  
  msg[0] = 0; 
  msg[1] = 0; 
  msg[2] = 0; 
  msg[3] = 0;
  msg[4] = 0; 
  msg[5] = 0; 
  msg[6] = 0; 
  msg[7] = 0;
  
  radio.begin();
  radio.openWritingPipe(address); //이전에 설정한 5글자 문자열인 데이터를 보낼 수신의 주소를 설정
  radio.setPALevel(RF24_PA_MIN); //전원공급에 관한 파워레벨을 설정합니다. 모듈 사이가 가까우면 최소로 설정합니다.
  radio.stopListening();  //모듈을 송신기로 설정
}

void loop() {

  // if programming failed, don't try to do anything
  if (!dmpReady) return;
  // read a packet from FIFO
  if (mpu.dmpGetCurrentFIFOPacket(fifoBuffer)) { // Get the Latest packet 

  #ifdef OUTPUT_READABLE_YAWPITCHROLL
    // display Euler angles in degrees
    mpu.dmpGetQuaternion(&q, fifoBuffer);
    mpu.dmpGetGravity(&gravity, &q);
    mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
    
    float angle_x = (ypr[0] * 180 / M_PI) * -1 + 90 ; //* -1 + 90;
    float angle_y = (ypr[1] * 180 / M_PI) + 90 ; //* -1 + 30;    
   
    if (angle_y < 60) angle_y = 60;
    if (angle_y > 120) angle_y = 120;
    
    if (angle_x < 30) angle_x = 30;
    if (angle_x > 150) angle_x = 150;

    msg[0] = int(angle_x);
    msg[1] = int(angle_y);
    
    radio.write(&msg, sizeof(msg)); //해당 메시지를 수신기로 보냄
    
    Serial.print("ypr\tx:");
    Serial.print(int(angle_x));
    Serial.print("\ty:");
    Serial.print(int(angle_y));
    Serial.print("\t");
    
    

  #endif
  }
  Serial.println(".");
  delay(10);
  
}

아무래도 셋업해주는 부분이 약간 생소할 수 있겠습니다만 저도 인터넷에서 긁어 모은 코드를 조합하였을 뿐 상세하게는 모른답니다. 중요한 것은 노드의 이름을 정해주었는데요, 수신부에서도 동일한 이름을 지정해 주어야 한다는 점과, 다른 분들과의 혼선을 막기 위하여는 해당 이름을 유니크한 이름으로 정해주는 것이 좋다는 것 정도 입니다.

제가 사용한 코드는 (존경하는)새다리 님의 코드를 참고 하였고 NRF24L01 로 검색하시면 해외 여러 개발자 분들이 올려주신 멋진 코드들이 많이 있으므로 참고하시면 좋을 것 같습니다.

 

이번에는 수신부 입니다.

 #include <SPI.h> 
#include <nRF24L01.h>
#include <RF24.h>

RF24 radio(8,7); //  CE, CSN 
const byte address[6] = "00001"; //송신기와 수신기 동일한 주소 사용
int msg[8]; 

//pinout smd version
//NRF24L01    ARDUINO
//3.3v    ---   3.3v
//GND     ---   GND
//CE      ---   8
//CSN     ---   7
//SCK     ---   13
//MOSI    ---   11
//MISO    ---   12
//IRQ     ---   none

#include <Servo.h>

Servo myservo_LR;   
Servo myservo_UD; 

int pin_servo_LR = 9;
int pin_servo_UD = 10;

void setup() {
  radio.begin();
  radio.openReadingPipe(1, address);
  radio.setPALevel(RF24_PA_MIN); //
  // RF24_PA_MIN / RF24_PA_LOW / RF24_PA_HIGH / RF24_PA_MAX
  radio.startListening(); //수신기로 설정
  
  //setting 2 servo
  myservo_LR.attach(pin_servo_LR);
  myservo_LR.write (90);
  myservo_UD.attach(pin_servo_UD);
  myservo_UD.write (90);
}

void loop() {

  if (radio.available()) {
    radio.read(&msg, sizeof(msg));
    for(int i = 0; i < 8 ; i ++)
    {
      Serial.print(msg[i]);
      Serial.print("\t");
    }

    int angle_x = int(msg[0]);
    int angle_y = int(msg[1]);
    
    if (angle_x < 150 && angle_x > 30)
    {
      myservo_LR.write (angle_x);          
    }
    if (angle_y < 120 && angle_y > 60)
    {
      myservo_UD.write(angle_y);
    }
  }
}

수신부는 서보모터 제어코드와 무선 수신 코드가 있는데요, 송신부에 비하면 간단하게 구성되어 있습니다.

무선 패킷이 들어오면 동작하도록 되어 있으므로 수신에 실패하면 아무런 동작도 하지 않도록 되어 있으며 만약을 대비하여 잘못된 값이 수신되더라도 서보모터에 전달되지 않도록 최대, 최소 범위를 제한하여 서보에 입력되도록 하였습니다.

 

과연 잘 동작 할런지???

동작하는 모습을 볼까요?

 

 

ㅋㅋ 네 잘 되는군요. 이제 뭐 거의 다 온 것 같습니다.

다음 편에는 카메라를 연결하고 차량안에 장착할 준비를 한번 해봐야 겠습니다.

머릿속에 아주 좋은 그림이 있거든요~ ㅎㅎ

기대해 주세요 ~ ^^

2022.01.31 - [DIY/Arduino] - [아두이노]2축 서보모터 초간단 제어하기, 간단한 프레임 제작까지

 

[아두이노]2축 서보모터 초간단 제어하기, 간단한 프레임 제작까지

뭔가 목표가 생기면 과정이 분명해 진다. RC 카에 헤드트래킹을 이용한 FPV 를 구현하려는 목표가 생기고나니 과정을 잘 정리하는게 필요하겠다 싶어 포스트를 남깁니다. 우선 첫번째 스텝으로 2

diy-dev-design.tistory.com

2022.01.31 - [DIY/Arduino] - [아두이노]mpu6050 을 이용하여 2축 서보모터 제어하기

 

[아두이노]mpu6050 을 이용하여 2축 서보모터 제어하기

아두이노와 같은 마이크로 칩을 이용하여 무엇인가를 해보다 보면 정말 놀라운 경험들을 많이 하게 됩니다. 그 중 하나가 바로 mpu6050 같은 센서가 될 수 있겠습니다. 요 조그만 칩을 이용하여 기

diy-dev-design.tistory.com

 

2020.10.29 - [DIY] - [DIY] 오래된 다목적 캠핑용 랜턴 ▶ LED 램프, 충전식으로 교체하기

 

[DIY] 오래된 다목적 캠핑용 랜턴 ▶ LED 램프, 충전식으로 교체하기

처갓집 구석에서 재미있는 물건을 하나 발견했습니다. 마침 캠핑 전용 랜턴이 하나 있었으면 하는 차에 이게 왠 떡인가요 ㅋ 언제부터 처갓집에 있었는지는 모르겠지만 사용하지 않는 것이 분

diy-dev-design.tistory.com

 

2019.10.13 - [DIY] - [DIY] 아이방 수면등 만들기 (feat. 아이그림)

 

[DIY] 아이방 수면등 만들기 (feat. 아이그림)

아이들은 창의적이다. 시키지도 않았던 생각치도 않았던 아무 많은 그림을 시도 때도 없이 시간과 장소 불문, 심지어는 종이를 불문하고 마구마구 그려댄다. 그래서 A4 용지를 내주었더니 그럴

diy-dev-design.tistory.com

 

반응형
반응형

중국산 FPV 카메라를 구입했습니다. 알리에서.

이유는 RC 카에서 1인칭 뷰로 운전을 해보고 싶었기 때문입니다.

 

과연 중국산 FPV 카메라는 쓸만할까요?

RC 카에서 일인칭 뷰로 운전하는건 기대했던 만큼 재미있는 경험이었을까요?

 

 

우선 알리에서 FPV camera 를 검색해보니 아주 많은 제품이 검색되었습니다. 저는 FPV 에 대해 잘 모르므로 일단 아래와 같이 full set 로 구성된 제품을 구입하기로 마음먹었습니다. 생각보다 가격도 많이 비싸지 않아 가벼운 마음으로 구입을 하였습니다.

 

 

약 2주만에 배송받은 FPV 세트

구성품은 

  • 카메라
  • 송신기
  • 수신기겸 핸드폰 USB 영상 전송 장치
  • OSD 조이스틱
  • 카메라 고정용 부품
  • 각종 연결 케이블
  • 휴대폰 연결 케이블 (b type, c type)

요렇게 준비되어 있고요.

판매자의 영상을 보면 핸드폰 충전 단자에 케이블을 연결하면 카메라에서 전송하는 영상을 휴대폰으로 볼 수 있는 것 같았습니다.

저는 집에 싸구려 VR 고글이 있기 때문에 휴대폰으로 연결해서 카드보드 기능으로 보면 되겠다 싶었습니다.

 

일단 판매자의 글에서 본것 처럼 스펙은 7~24V 로 되어 있지만 12V 를 추천하였기에 12V 파워서플라이에 물려서 테스트 해보니 잘 동작하였습니다.

하지만 전 RC 카에서 사용할 것이므로 12V 파워 서플라이를 연결할 수 는 없으니 2S 1P 배터리를 연결해봅니다.

이론적으로 2S1P 배터리면 실제 RC 카 사용 전압을 고려했을 때 최소 7.2V ~ 8.4V 정도의 구간이 나오므로 7V~ 24V 제품 동작에 문제가 없다고 판단했습니다. 

연결해보니 ...

안되네요.

신호가 잡히질 않습니다. 흠.. 

 

그럼 여기서 포기해야 할까요?

카메라를 위해 3S 배터리를 다시 만들어야 할지 고민되었습니다. 굴러다니는 18650 배터리가 몇개 있으니 3S 배터리를 만드는건 어려운 일은 아니었으나 카메라만을 위해 배터리를 장착하는건 좀 무리라는 생각이 드는 찰나!

제 부품 꾸러미 중에 DC 승압보드가 있는게 생각났습니다.

오케이. 

2S 배터리 (만충 시 8.4V)를 승압보드에 연결하고 승압 보드의 가변저항을 조절해서 약 13V 정도 출력이 되도록 조정한뒤 카메라에 연결을 해보았습니다.

굳!

잘 되네요.

 

일단 그럼 당장 밖으로 나가 봐야 겠죠?

 

먼저 거북이 처럼 느릿느릿한 SCX10 에 장착해 보았습니다.

일단은 보닛 위에 카메라를 붙이고 핸드폰으로 보이는 화면을 조정한 뒤 주행을 해보았습니다.

 

 

 

흠 터레스팅...

 

 

괜찮은듯 괜찮지 않은 듯 묘한 느낌이네요.

기분이 좋은듯 나쁜,,, 똥을 누고 있는데 똥이 마려운 그런 느낌이랄까요? 

일단은 화질이 생각보다 구립니다.

화질이 많이 구려서 직접 운전하는거랑은 차이가 많이 나네요.

화면도 너무 밝아서 조금만 밝은 곳으로 가도 뭐가 뭔지 구분이 잘 안되네요.

둘째는 카메라가 고정되어 있으니 엄청 답답합니다.

우리가 운전할 때 앞만 보고 운전하지 않는 것처럼 시야가 고정되어 있으니 매우 답답한 느낌입니다.

옆도 좀 보이고 하면 좋겠다는 생각이 들었고요.

셋째는 수신 거리가 상당히 짧습니다. 장애물만 있어도 화면이 금방 지직 거리고 나무나 바위 같은 장애물이 좀 있으면 50m 만 떨어져도 거의 운전이 불가능한 상황이었습니다.

이런.. 

판매자 글을 보니 제가 구입한 600mw 제품은 1km 이상까지도 신호가 간다고 써있는데 아마 수신기의 성능도 좋아야 하나 봅니다. 게다가 보통 드론용으로 사용되기 때문에 허공에 떠있는 드론에 비하면 지상에서 움직이는 RC 카는 상대적으로 장애물이 많을 수 밖에 없겠다는 생각이 들었습니다.

 

 

어쨌든 이런 불편함으로 인해 포기할 제가 아니지 않겠습니까?

 

우선은 모든 문제를 개선할수는 없을 것 같고요. 해볼 수 있는걸 해 봐야 겠습니다.

1. 화질 개선하기

- 카메라와 함께 배송된 OSD 스위치 인줄 알았던 초소형 조이스틱 보드가 있습니다. 어떻게 사용하는지 몰랐는데 그냥 카메라에 연결하고 버튼을 누르면 메뉴가 나타납니다.

여기서 색상, 밝기, 자동 밝기 조절 등 훌륭하지는 않지만 기본적인 화면 조절 기능을 이용하여 화면을 조절해 봅니다.

밝기와 화이트 밸런스도 고정으로 변경하였습니다. 

 

2. 답답한 카메라의 시야각을 조정하기

- 카메라의 시야각을 바꾼다고요? 네 당연히 하드웨어를 변경하는건 논외 입니다. 그럼 어떻게 하는게 좋을까요? 

저는 어짜피 VR 헤드셋을 사용할 것이기 때문에 헤드 트래킹을 사용해 보기로 하였습니다. 마치 제가 RC 카의 운전석에 앉아 있는 듯 제가 바라보는 방향으로 운전석의 카메라를 움직이는 것이죠. 

과연 이게 가능할까요? 제가 할 수 있을까요? 

어떤 원리로 동작을 시킬지 구상을 해 봅니다.

나 : VR 헤드셋 + mp6050 (지자기+기울기센서) + 아두이노 + nrf24L01 (무선 송수신기) / 영상수신기 + VR 헤드셋

자동차 : nrf24l01 (무선 송수신기) + 아두이노 + x,y축 서보모터 + 카메라 + 영상 송신기

 

위와 같은 부품을 통하여 가능할 것 같지 않습니까?

VR 헤드셋은 항상 제 머리에 부착되어 있는 상태로 머리의 회전각도를 구할 수 있을 것이고 이를 이용하여 아두이노에서 nrf24l01 과 같은 무선 송신기를 통하여 현재 제 머리의 방향을 송출하게 됩니다. 그럼 송출된 신호를 RC 카에 있는 아두이노와 nrf24l01 을 이용하여 수신한 뒤 수신한 각도를 이용하여 케메라를 부착하고 있는 서보 모터를 움직이는 것이죠.

 

생각보다 간단한 개념이죠? 안 간단하다고요?

자 그럼 이제 슬슬 구현을 해보기로 하겠습니다.

한스텝 한스텝 따라오실 수 있도록 한번 포스팅을 해보도록 하겠습니다.

 

다음 포스트를 기대해 주세요~

 

 

1단계 : 2축 제어 서보모터 마운트 만들기

2022.01.31 - [DIY/Arduino] - [아두이노]2축 서보모터 초간단 제어하기, 간단한 프레임 제작까지

 

[아두이노]2축 서보모터 초간단 제어하기, 간단한 프레임 제작까지

뭔가 목표가 생기면 과정이 분명해 진다. RC 카에 헤드트래킹을 이용한 FPV 를 구현하려는 목표가 생기고나니 과정을 잘 정리하는게 필요하겠다 싶어 포스트를 남깁니다. 우선 첫번째 스텝으로 2

diy-dev-design.tistory.com

 

2단계 : mpu6050 자이로 센서를 이용하여 2축 서보모터 제어하기

2022.01.31 - [DIY/Arduino] - [아두이노]mpu6050 을 이용하여 2축 서보모터 제어하기

 

[아두이노]mpu6050 을 이용하여 2축 서보모터 제어하기

아두이노와 같은 마이크로 칩을 이용하여 무엇인가를 해보다 보면 정말 놀라운 경험들을 많이 하게 됩니다. 그 중 하나가 바로 mpu6050 같은 센서가 될 수 있겠습니다. 요 조그만 칩을 이용하여 기

diy-dev-design.tistory.com

 

3단계 : nrf24l01 과 mpu6050 을 이용하여 무선으로 헤드트래킹 정보 송신하기

2022.01.31 - [DIY/Arduino] - [아두이노]NRF24L01을 이용하여 무선으로 mpu6050 신호 전달하기

 

[아두이노]NRF24L01을 이용하여 무선으로 mpu6050 신호 전달하기

자 어느새 목표했던 RC headtracking FPV 만들기의 종착역을 다가가고 있습니다. 앞서 소개해 드렸던 2축 서보마운트 제작 및 서보컨트롤과 mpu6050 을 이용하여 2축 서보모터를 제어하는 내용은 잘 보

diy-dev-design.tistory.com

 

4단계 : RC 차량 조종석에 헤드트래킹 카메라 설치하기

기대해 주세요~

 

 

반응형
반응형

아도이노는 DIY 인 들에게 없어서는 안될 단물 같은 장치이다. 물론 요즘은 프로그래밍 교육용으로도 사용되고 미디어 아티스트들에게도 자주 사용되는 놀라운 장치이다. 간단한 코딩 만으로 하드웨어 지식이 거의 없더라고 다양한 레퍼런스를 이용하여 손쉽게 무엇인가 로지컬하게 동작하는 장치를 만들어 낼 수 있기 때문이다.

 

이번에 도전하게 된 것은 Arduino Nano 를 이용하여 RC 카 구동을 위한 무선 송수신기를 제작하는 것이다.

 

보통은 RC 카를 구성하는 송신기 (트랜스미터, Transmitter) 와 수신기 (리시버, receiver) 를 세트로 구입하여 모터와 ESC 에 연결하여 사용하는 것이 일반적이지만 직접 만들어 보는 것도 재미있을 것 같아 도전을 하게 되었다. RC 카의 차체와 모터 등은 기성품을 이용하여 가지고 놀기에도 좋아야 하며 송수신기 모듈만 아두이노를 이용하여 만드는 것을 목표로 하고 있다.

 

먼저 첫번째 시간으로 수신기 만들어 보자

 

완성된 2.4Ghz 무선 RC 수신기의 모습 (아두이노 나노 + NRF24L01)

 

필요한 부품

 

  • Arduino nano (atmega328p, 16MHz)
  • NRF24L01 SMD 버전
  • 10 uF 전해콘덴서
  • 점퍼용 선들
  • 모터 / 서보 / ESC 연결용 2핀, 3핀 소켓 (만능기판 장착용, 2.54mm)
  • 만능기판(양면) 8 * 24
  • SMD to DIP Adapter socket (1.27mm to 2.54mm, SOP14 규격) : 10개에 1 달러 미만 

아두이노 나노에 대한 설명은 넣어두고 무선 연동을 위한 NRF24L01 보드가 필요하다.

해당 보드는 알리익스프레스에서 개당 1000원 미만으로 구입할 수 있다. 보통 무선 연동은 트랜스미터와 리시버가 각각 역할을 분담하는 형태로 모듈이 만들어져 있는데 이 제품은 하나의 제품이 송신과 수신을 할수 있는 제품으로 일명 트랜시버 라고 부르기도 한다. 2.4GHz 대역을 사용하여 신호의 정확도가 좋다고 한다.

이번 DIY 를 위하여 SMD 타입을 구입하였는데 일반 보드는 4x2 형태의 핀 배열을 가지고 있어 브래드 보드를 통한 테스트가 쉽지 않은 반면 SMD 타입은 1열로 핀이 배열되어 있어 약간의 꼼수를 부리면 사용이 간편한 장점이 있다.

 

NRF24L01 보드에 꼭 필요한 부품이 있으니 바로 10uF 전해 콘덴서

 

NRF24L01 보드에 꼭 필요한 부품이 있으니 바로 10uF 전해 콘덴서이다. 처음 이 프로젝트를 도전하였을때 상당히 많은 실패를 경험했는데 결과적으로는 이 전해콘덴서를 연결하지 않은 부분과 정확한 3.3V 를 인가하지 않은데서 기인했다고 생각된다. 지금은 단 한번의 실패도 없이 잘되는 것을 생각하면 정말 어의가 없지만 거의 2개월 정도를 이 문제 해결을위해 소모하였다. 이 글을 보는 당신도 도전할 생각이 있다면 반드시 10uF전해 콘덴서를 미리 준비해놓자. 47uf 도 100uf 도 1uf 도 아닌 반드시 10 uf 로 준비하자. 알리에서 사면 몇푼 하지도 않을 뿐더러 무료배송인 판매자도 많다. 전해 콘데서는 극성이 있는 제품이다. 띠 무늬가 있는 부분이 - 극 (GND) 다른 부분이 아두이노의 3.3V 또는 NRF24L01 의 +부분에 연결이 되어 있어야 한다.

 

10 uf 전해 콘젠서를 3.3v 와 GND 에 연결한 모습

사진에 제일 위층에 얹어진 검정색 PCB 보드가 NRF24L01 보드이다. 뒤쪽에 초록색으로 보여지는 보드는 작업의 편의 성을 위하여 붙인 것으로 원래는 14 pin Attiny84 smd 타입을 일반 만능기판에 연결할 수 있도록 사용하는 아답터 보드인데 이것을 반을 자르면 7핀을 이용하는 NRF24L01 보드의 확장용 보드로 사용이 가능할 것 같아 납땜하여 붙여서 사용해보았고 아주 만족스러운 호환성을 보여주었다.

 

아래와 같은 형태의 보드인데 반을 자른 후 NRF24L01 칩을 납땜하여 붙여주면 1열로 된 핀 배열 구성이 가능하게 되어 브래드 보드에서 바로 테스트가 가능하다. 참고로 NRF4L01 은 총 8개의 연결핀이 있는데 위에서 봤을때 가장 오른쪽 핀은 사용할 필요가 없는 핀 이므로 아래 아답터 보드를 반으로 자른후 좌측부터 7개의 단자와 납땜을해서 붙이면 정확하게 딱 맞는 결과물을 얻을 수 있다.

앞뒤가 각각 규격으로 제작이 됨. NRF24L01 은 좌측(앞) 규격에 부착

 

 

NRF 24L01 SMD 타입과 DIP 타입 이미지 추가

 

NRF24L01 을 보드에 장착한 이미지 추가

 

 

아래 그림은 NRF24L01+ SMD 의 핀 배열임. 참고하시길

각각의 핀은 아두이노 나노와 아래와 같이 연결이 된다.

NRF24L01 + ////		Arduino Nano

3.3V 		-> 		3.3V
GND 		-> 		GND
CE 		-> 		8
CSN 		-> 		7
SCK 		-> 		13
MOSI 		-> 		11
MISO 		-> 		12

중요한 것은 위에도 언급한 것과 같이 우측의 아두이노 3.3V 와 GND 사이에 10uf 전해 캐패시터를 연결해야 한다는 점 이다.

 

필자는 어려 차례 시도해 보았기 때문에 한번에 잘 되었지만 본 블로그를 보고 처음 따라 하는 분은 브래드 보드에 우선 테스트 해보시기를 권장한다.

 

추가로 방향 조정용 서보모터와 모터 속도 컨트롤용, 그리고 2단 변속기를 사용할 것이므로 변속기용 서보는 아래와 같이 각각 핀을 지정하였다.

servoPin = 9; 			//steering servo
speedServoPin = 10; 	// gear high / low
accelloPin = 6; 		// main motor (ESC)

3 pin 소켓을 3개 연결해야 하는데. 위와 같이 핀에 연결해주면 된다.

소켓의 3 pin 은 각각 신호(흰색 또는 노랑) , V+(빨강) , GND(검정 또는 갈색) 순으로 연결 해주면 된다. 여기서 신호에 해당되는 부분이 위에 정의한 핀과 연결이 되는 것임. 대부분의 3핀 선은 위와 같은 색상으로 이루어져 있으니 참고할 것.

 

 

납땜이 끝난 보드 아래쪽을 보면 아래와 같이 엉망 징창임.

 

지저분 하지만 어쩔수 없다. 똥 손의 한계 입니다.

 

코드는 나중에 트렌스미터 부분 설명이 완료 되면 한번에 올려보겠다.

뎃글, 공감 은 블로그 작성자에게 큰 힘이 된답니다. 
도움이 되었다 생각되시면 클릭!!  부탁드려요~

 

이만.

 

 

 

 

반응형

+ Recent posts