Using Arduino to read, and output ppm from RC receiver FS-iA6B

I want to use Arduino to read the ppm value from RC receiver FS-iA6B, print the ppm value and output it back in ppm format. The connection between Arduino and the RC receiver is fairly simple, the ppm signal from the Rc receiver is connected to pin 2 Arduino (Uno), and pin 3 will be connected to the drone flight controller. 5v and ground for RC receiver can either be connected to 5v/ground Arduino or directly to 5v/ground flight controller. The purpose of this project is so I can modify and rewrite the output ppm value to the drone flight controller if my lidar sensor detects obstacles during flight.
This is my current code so far, but the problem I faced now is

  1. in void loop(), on TCNT1 = 0; line, if I comment the line drone is able to be armed, but no response from the Serial monitor.
  2. If I didn't put a comment on the line (void loop(), on TCNT1 = 0;), the serial monitor able to show 8 channel ppm value, but the drone is unable to be armed.

Please help me with how I can read, print, and output the ppm value to the flight controller and able to arm the drone. Thank you.

this is the code

volatile uint16_t ppm_buffer[8];   // buffer array to store PPM signal
volatile uint8_t  ppm_channel = 0; // current channel
volatile uint32_t ppm_last_time;   // last time PPM signal updated

const int PPM_PIN = 3; //19 for mega, 3 for uno
unsigned long previousMillis = 0; 
const unsigned long interval = 1000; 

void setup() {
  pinMode(2, INPUT); // 18 for mega, 2 for uno
  pinMode(PPM_PIN, OUTPUT);
  Serial.begin(115200);
  // configure timer1 to trigger every 20ms for PPM signal output
  attachInterrupt(digitalPinToInterrupt(2), ppm_isr, CHANGE); 

  //timer1 setup configuration
  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1  = 0;
  OCR1A = 39999;  // 20ms = 40000 / 16MHz
  TCCR1B |= (1<< WGM12);
  TCCR1B |= (1<< CS11);
  TIMSK1 |= (1<< OCIE1A);}


void ppm_isr() { //function to read signal from rc receiver
  uint32_t now = micros(); // current time
  int32_t duration = now - ppm_last_time;
  ppm_last_time = now;

  if (duration > 5000) {
    ppm_channel = 0;
  } else {
    ppm_buffer[ppm_channel]= duration;
    ppm_channel++;
  }
  }

ISR(TIMER1_COMPA_vect) { //function to output signal from rc receiver
  static uint8_t ppm_index = 0;
  static uint32_t last_micros = 0;
  uint16_t pulse_width = ppm_buffer[ppm_index];
  uint32_t now_micros = micros();
  uint32_t elapsed_micros = now_micros - last_micros;

  if (elapsed_micros >= pulse_width) {
    
    digitalWrite(PPM_PIN, LOW);
  }

  if (elapsed_micros >=20000) {
    
    digitalWrite(PPM_PIN, HIGH);
    last_micros = now_micros;
    ppm_index++;
    if (ppm_index >= 8) {
      ppm_index = 0;
    }
  }
}

void loop() { 

  unsigned long currentMillis = millis(); 
 
    if (currentMillis - previousMillis >= interval) {
      if (ppm_channel == 8) { 
        previousMillis = currentMillis; 
        Serial.print("PPM:");
        for (int i = 0; i < 8; i++) {
          Serial.print(" ");
          Serial.print(ppm_buffer[i]);
        }
        Serial.println();
        ppm_channel = 0;
    }
  }
 

  TCNT1  = 0; //if comment this, drone able to armed,but no response on serial monitor
  // reset timer1 counter

  OCR1A = 39999; 
  // set timer1 output compare register

  TIFR1 |= (1<< OCF1A); 
  // clear timer1 output compare match flag
  //TCNT1 = 0;

}

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.