지난번에는 기본적인 통신 테스트를 마쳤고 이번에는 고정된 테스트값이 아니라 정말로 아날로그 스틱에서 값을 읽어와 NRF24L01 모듈로 송수신하여 테스트 해봤다.
일단 내가 만들고자 하는 V1.0 의 송수신기는 아래 그림과 같다.
2축 스틱으로 Steering 과 Accelerometer 를 제어하고 (채널1, 2), 스틱을 누르면 채널3 으로 디지털 입력을 받을 예정이다.
채널 4,5,6 중 채널 4는 아날로그 값을 Volume 으로 받고, 5,6 은 DIGITAL 로 받으려 한다. 마지막으로, V1.0 에서는 간단히 스틱의 입력값 범위를 설정하기 위한 Function S/W 를 하나 달아줄 것이다. 무쟈게 심플하다. Trim 이나 EPA 도 없다.
전원은 집에있는 USB 보조배터리를 사용하도록 하고, 손잡이 부분에 넣도록 할 것이다.
기구는 집에있는 OC 마네킹 3D 프린터로 찍어볼것이다. 그런데 이게 도면 그리는게 쉽지 않을듯 하다.
자 일단 스틱을 붙였다. 인터넷으로 주문 가능한 바로 그 스틱이다. 뭐 얼마 하지도 않는다. VCC, GND, VRX, VRY, SW 이렇게 4선이 있다.
나노에 연결하고 지난번 만들었던 코드를 수정했다.
송신기쪽 코드이다
큰 변화라면, 이전에 사용하던 TX_DATA 구조체 내에 accel, steering, ch3, ... 변수를 그냥 배열로 바꾸어 취급하기로 했다. 변수명을 하나씩 써주니 코드도 지저분해져서 배열로 만들고 Loop 로 돌려서 Analog 입력을 받아 저장하고 수신기 쪽으로 보낸다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | /* * TX 에서 Steering(ch1), Acceleration(ch2), ch3, ch4, ch5, ch6 값을 * 1000 (uS) ~ 2000(uS) 값으로 전달한다 */ #include <SPI.h> #include <RF24_config.h> #include <RF24.h> #include <nRF24L01.h> #include "joon_nrf24l01_config.h" #include "joon_transmitter_packet.h" #define PIN_VRX A0 #define PIN_VRY A1 #define PIN_SW 2 #define IN_STEER PIN_VRX #define IN_ACCEL PIN_VRY #define IN_CH3 PIN_SW #define IN_CH4 3 #define IN_CH5 4 #define IN_CH6 5 RF24 radio(PIN_CE, PIN_CSN); TX_DATA tx; unsigned long g_lStartTimeUs = 0; int g_channels[] = { IN_STEER, IN_ACCEL, IN_CH3, IN_CH4, IN_CH5, IN_CH6 }; int g_analogChannels[] = { IN_STEER, IN_ACCEL }; void setup() { Serial.begin(115200); while (!Serial); Serial.println( "TX Serial Ready" ); // 기본 채널 76 // 기본 D/R 1Mbps radio.begin(); // 우선 아두이노의 핀 당 출력이 40mA 이고 전체 200mA 를 넘으면 불안해지므로 // 일단 외부 전원 없이 사용하기 위해 LOW 모드로 세팅한다 radio.setPALevel(RF24_PA_LOW); radio.openWritingPipe(TX_WRITE_CHANNEL); //radio.openReadingPipe(1,TX_READ_CHANNEL); //radio.startListening(); for ( int nChannelIndex = 0; nChannelIndex < sizeof (g_channels); nChannelIndex++) pinMode(g_analogChannels[nChannelIndex], INPUT); } void loop() { g_lStartTimeUs = micros(); // Transmitter 읽기 readTransmitter(&tx); // 보내기 if (!radio.write(&tx, sizeof (tx))) Serial.println( "FAILED : TX Transmission failed" ); Serial.print( "\n####### " ); Serial.print(micros() - g_lStartTimeUs); Serial.println( " uS #######" ); } void readTransmitter(LPTX_DATA lpData) { // Read Steering int val = analogRead(g_channels[0]); Serial.print( "STEER : " ); Serial.print(val); lpData->channel[0] = val; // Read Accel val = analogRead(g_channels[1]); Serial.print( " | ACCEL : " ); Serial.print(val); lpData->channel[1] = val; // Read Ch3 ~ 6 Digital Pins for ( int nChannelIndex = sizeof (g_analogChannels)/ sizeof ( int ); nChannelIndex < sizeof (g_channels)/ sizeof ( int ) ; nChannelIndex++) { val = digitalRead(g_channels[nChannelIndex]); Serial.print( " | CH" ); Serial.print(nChannelIndex+1); Serial.print( " : " ); Serial.print(val); lpData->channel[nChannelIndex] = val; } } |
아래는 수신기쪽 코드이다
수신쪽 코드는 크게 변한것이 없고, 송신쪽에서 받은 배열값을 화면에 출력한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | /* Name: SX_RF24RX.ino Created: 10/30/2015 11:12:14 PM Author: korean44 */ // the setup function runs once when you press reset or power the board #include <SPI.h> #include <RF24_config.h> #include <RF24.h> #include <printf.h> #include <nRF24L01.h> #include "../joon_nrf24l01_config.h" #include "../joon_transmitter_packet.h" RF24 radio(PIN_CE, PIN_CSN); TX_DATA data; // 각 출력 채널의 출력 핀 번호 및 DIGITAL, ANALOG 타입 설정 CHANNEL g_outputChannelTypes[MAX_CHANNELS] = { {3,PIN_MODE::ANALOG} , {} }; void setup() { Serial.begin(115200); while (!Serial); Serial.println( "RX Serial Ready" ); radio.begin(); radio.setPALevel(RF24_PA_LOW); radio.openReadingPipe(1, RX_READ_CHANNEL); radio.startListening(); } // the loop function runs over and over again until power down or reset void loop() { unsigned long start_wait_us = micros(); bool timeout = false ; while (!radio.available()) { if (micros() - start_wait_us > RF24_TIMEOUT_US) { timeout = true ; Serial.println( "--TIMEOUT--" ); break ; } } if (!timeout) { radio.read(&data, sizeof (data)); unsigned long read_time_us = micros(); Serial.print( "Steering : " ); Serial.print(data.channel[0]); Serial.print( "/ Accel : " ); Serial.print(data.channel[1]); Serial.print( "/ CH3 : " ); Serial.print(data.channel[2]); Serial.print( "/ CH4 : " ); Serial.print(data.channel[3]); Serial.print( "/ CH5 : " ); Serial.print(data.channel[4]); Serial.print( "/ CH6 : " ); Serial.println(data.channel[5]); Serial.print( "== Receive Delay : " ); Serial.print(read_time_us - start_wait_us); Serial.println( " uS" ); } } |
그런데 이상한 현상이 발생한다. Transmission Fail 이 계속 떨어지고, 전송 속도가 무려 40ms 정도가 걸린다. 뭔가 특이한것도 없는데 이렇다.. 혹시 콘덴서 안달아서 이러는가 싶기도 하지만 PA Level 을 LOW 로 주었는데도 이런거면 큰일이다.. 우선 값이 전달되는건 되는걸 확인하고 일단 닫았다.
다음날 저녁에 퇴근하고 집에와서 애들 자는거 보고 또 열었다. 그리고 원래 있던 코드를 손도 안대고 돌려본다. 그런데 갑자기 FAIL 이 안뜬다.. 뭐 이런경우가.. 어제 저녁에는 100% 오류가 나더니.. (기분탓인가.. 그러기에는 저렇게 확연한 증거가 있는데..)
브래드보드에서 실제 기구에 이식할때에는 꼭 콘덴서 달아주리라 마음먹고 오늘은 이쯤한다.
다음에는 출력쪽을 다루어야 하고, 회로도도 그려서 올려야겠다.
지금까지의 회로도는 아래와 같다
'Software Development > IoT, Arduino, RasberryPi' 카테고리의 다른 글
아두이노 송수신기 만들기 #서보&모터 테스트 (3) | 2015.11.15 |
---|---|
아두이노 송수신기 만들기 #수신기 회로 (0) | 2015.11.08 |
아두이노 송수신기 만들기 #통신모듈 테스트 (3) | 2015.10.31 |
NRF24L01 모듈 #2 - 소프트웨어 (4) | 2015.10.31 |
nRF24L01 모듈 #1 - 소개 및 하드웨어 (5) | 2015.10.29 |