DIY receiver input lag arducopter

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++;
    }     
  }
}

ArduCopter 3.2.1 runs on an outdated 8bit processor (APM 2.8) that is no longer supported.
Nevertheless, no one reported RC lags on that code. You are the first one.

So there is a big probability that the problem is your own DIY RC transceiver. Please investigate that further.

Thank you !

I tried PWM base receiver configuration. It works fine now. No lag observed.
Could be PPM encoding delay issue with the receiver.