Hi !
I built my own diy receiver and transmitter using Arduinos and NRF24l01 transceivers.
I’m using Ardupilot APM 2.8. Arducopter v3.2.1
PPM output of the receiver is connected to the input of Arducopter. But the output response of Arducopter is very sluggish (takes approx. ~1s to do the action after any transmission form remote).
I’ve tried direct PWM inputs to ESC from receiver. But there is no delay.
Delay occurs somewhere only in case of Arducopter.
I varied Arduino loop delays (from 0-50ms), but nothing changed.
Can anyone suggest any idea to shorten the response delay to minimum. Thank you.
Processing: receiver_code.ino…
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
////////////////////// PPM CONFIGURATION//////////////////////////
#define CHANNEL_NUMBER 6 //set the number of chanels
#define CHANNEL_DEFAULT_VALUE 1500 //set the default servo value
#define FRAME_LENGTH 22500 //set the PPM frame length in microseconds (1ms = 1000µs)
#define PULSE_LENGTH 300 //set the pulse length
#define onState 1 //set polarity of the pulses: 1 is positive, 0 is negative
#define sigPin 3 //set PPM signal output pin on the arduino
int ppm[CHANNEL_NUMBER];
RF24 radio(7, 8); // CE, CSN pins
const byte address[6] = "00001";
float count=0;
int cc=0;
struct PacketData
{
float throttle; //throttle value (potentiometer 0-1023)
float joy_x; //joystick x-axis resistance value (0-1023)
float joy_y; //joystick y-axis resistance value (0-1023)
float yaw_left; //tail left button 0-1
float yaw_right; //tail right button 0-1
float ENDX; //EMERGENCY STOP switch 0-1
float potentiometer_1_trim;
float potentiometer_2_trim;
};
PacketData data;
void setup()
{
for(int i=0; i<CHANNEL_NUMBER; i++)
{
ppm[i]= CHANNEL_DEFAULT_VALUE;
}
data.throttle= 0;
data.joy_x= 510;
data.joy_y=512;
data.yaw_left=0;
data.yaw_right=0;
data.ENDX=0;
data.potentiometer_1_trim = 512;
data.potentiometer_2_trim = 512;
radio.begin(); //start radio module
radio.setDataRate( RF24_250KBPS ); //set radio transfer speed (paste 1 of following) : RF24_250KBPS for 250kbs, RF24_1MBPS for 1Mbps, or RF24_2MBPS for 2Mbps
radio.openReadingPipe(0, address); //open reading channel at pipe-0 at address mentioned above (row# 9)
radio.setPALevel(RF24_PA_MIN);
radio.setAutoAck(false); //set radio transmission power (range) (paste 1 of following) : RF24_PA_MIN -18dBm, RF24_PA_LOW -12dBm, RF24_PA_HIGH -6dBm, and RF24_PA_MAX 0dBm
radio.setChannel(100); //set channel between 2.400 - 2.524 GHz (0-124 channels)
radio.startListening(); //start radio listening
pinMode(sigPin, OUTPUT);
digitalWrite(sigPin, !onState); //set the PPM signal pin to the default state (off)
cli();
TCCR1A = 0; // set entire TCCR1 register to 0
TCCR1B = 0;
OCR1A = 100; // compare match register, change this
TCCR1B |= (1 << WGM12); // turn on CTC mode
TCCR1B |= (1 << CS11); // 8 prescaler: 0,5 microseconds at 16mhz
TIMSK1 |= (1 << OCIE1A); // enable timer compare interrupt
sei();
}
void loop()
{
if ( radio.available() ) //if radio signals are available at receiver, then read those signals
{
radio.read(&data, sizeof(PacketData)); //read and store the received information at "PacketData" structure in "data"
cc=0;
}
if(!radio.available())
{
cc=cc+1;
}
ppm[0] = map(data.joy_x, 0,1023, 1000,2000);
ppm[1] = map(data.joy_y, 0,1023, 1000,2000);
if (data.potentiometer_1_trim<=512)
{
if (cc<35)
{
ppm[2] = map(data.throttle, 0,1023, 1000,2000);
}
if(cc>35)
{
ppm[2]=(960);
}
}
if (data.potentiometer_1_trim>512 && data.potentiometer_1_trim<= 1000)
{
if (cc<35)
{
ppm[2] = map(data.throttle, 0,1023, 1000,1300);
}
if(cc>35)
{
ppm[2]=(960);
}
}
if (data.potentiometer_1_trim>1000)
{
if (cc<35)
{
ppm[2] = map(data.throttle, 0,1023, 1000,1200);
}
if(cc>35)
{
ppm[2]=(960);
}
}
int yaww=2;
{
if (data.yaw_left==1 && data.yaw_right==0)
{
yaww=1;
}
if (data.yaw_left==0 && data.yaw_right==1)
{
yaww=3;
}
if (data.yaw_left==0 && data.yaw_right==0)
{
yaww=2;
}
}
ppm[3] = map(yaww, 1,3, 1000,2000);
ppm[4] = map(data.ENDX, 0,1, 1000, 1500);
ppm[5]=1000;
delay(20);
}
ISR(TIMER1_COMPA_vect){ //leave this alone
static boolean state = true;
TCNT1 = 0;
if (state) { //start pulse
digitalWrite(sigPin, onState);
OCR1A = PULSE_LENGTH * 2;
state = false;
} else{ //end pulse and calculate when to start the next pulse
static byte cur_chan_numb;
static unsigned int calc_rest;
digitalWrite(sigPin, !onState);
state = true;
if(cur_chan_numb >= CHANNEL_NUMBER){
cur_chan_numb = 0;
calc_rest = calc_rest + PULSE_LENGTH;//
OCR1A = (FRAME_LENGTH - calc_rest) * 2;
calc_rest = 0;
}
else{
OCR1A = (ppm[cur_chan_numb] - PULSE_LENGTH) * 2;
calc_rest = calc_rest + ppm[cur_chan_numb];
cur_chan_numb++;
}
}
}