0

So I'm building a helicopter. That why I need a receiver (tgy 9x) to read the values from my controller. Those values get passed to my Arduino due where some calculation happen and then get sent to the servos.

Now the problem is the moment I move my servo all the value I get from my receiver immediately become gibberish.

The values I should get and get when I am not sending anything to my servos. These values are in microseconds.

Channel1 Channel2 Channel3 Channel4 
1486     1484     1482     1472  
1486     1484     1482     1472  
1486     1484     1482     1472  
1486     1484     1482     1472 

What I get after moving the servo. These should be between 1000 and 2000.

Channel1 Channel2 Channel3 Channel4
1495     18660    1105     17182  
1495     2337     5667     3070 
8828     7674     8795     6198
10289    7674     8795     11404 

The Arduino gets power from the USB (at the moment) and the servo from the ESC of my motor. All the grounds are connected. There is only one servo hooked up and all wires from the receiver are not anywhere near any power lines or servos.

So the question is why is the receiver giving me gibberish and how do I fix it.

Right now I have commented everything out except this:

RC_controller.h

#ifndef RC_controller
#define RC_controller


#include <Arduino.h>
#include "eeprom.h"

void RC_init();
void calc_input0();
void calc_input1();
void calc_input2();
void calc_input3();
void calc_input4();
void calc_input5();
#endif

RC_controller.cpp

#define RC_NUM_CHANNELS  8
uint32_t volatile rc_start[RC_NUM_CHANNELS];
uint32_t volatile rc_shared[RC_NUM_CHANNELS];
uint32_t volatile rc_raw[RC_NUM_CHANNELS];

int rc_channels_pin[8] = {2, 3, 4, 5, 6, 7, 8, 9};

void calc_input0() {
 int identifyer = 0;
   if (digitalRead(rc_channels_pin[identifyer]) == HIGH) {
     rc_start[identifyer] = micros();
   } else {
     rc_raw[identifyer] = (uint16_t)(micros() - rc_start[identifyer]);
   }
}

...

void RC_init()
{

 for (byte i = 0; i > RC_NUM_CHANNELS; i++)
   pinMode(rc_channels_pin, INPUT);

 attachInterrupt(digitalPinToInterrupt(rc_channels_pin[0]), calc_input0, CHANGE);
 attachInterrupt(digitalPinToInterrupt(rc_channels_pin[1]), calc_input1, CHANGE);
 attachInterrupt(digitalPinToInterrupt(rc_channels_pin[2]), calc_input2, CHANGE);
 attachInterrupt(digitalPinToInterrupt(rc_channels_pin[3]), calc_input3, CHANGE);
 attachInterrupt(digitalPinToInterrupt(rc_channels_pin[4]), calc_input4, CHANGE);
 attachInterrupt(digitalPinToInterrupt(rc_channels_pin[5]), calc_input5, CHANGE);
}

main.cpp

...
void setup()
{
Serial.begin(115200);
  Wire.begin();
#if I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
    Fastwire::setup(400, true);
#endif
for (int a = 0; a < 3; a++)
  swashplate[a].attach(10+a, 1200, 1800);
RC_init();
}

void loop()
{
if (rc_raw[0] < 2000)
  {
    swasplate[0].write(rc_raw[0]);
  }

  Serial.print(rc_raw[0]);
  Serial.print("    ");
  Serial.print(rc_raw[1]);
  Serial.print("    ");
  Serial.print(rc_raw[2]);
  Serial.print("    ");
  Serial.print(rc_raw[3]);
  Serial.print("    ");
  Serial.print(rc_raw[4]);
  Serial.print("    ");
  Serial.print(rc_raw[5]);
  Serial.print("    ");
  Serial.println();
}
  • You could well have a problem with the servo introducing power supply noise. A literal Arduino is a very poor fit in this application - too big, too high a supply voltage, too unreliable in physical implementation. Typical solutions are more integrated with a lot more attention to the engineering of how the parts work together and avoid interfering with each other - the flight control projects that used Arduino back in their early era have long since moved on to more suitable custom boards. – Chris Stratton May 1 '18 at 12:54
  • Can you name an example of these "more suitable custom boards"? Do you mean preprogrammed flight controllers? The thing is I still want to program it myself ... – MoneyMonkey May 1 '18 at 13:02
  • Any relevant search engine or ecommerce site will be full of boards for the well known open source flight control projects; of course you need to pay attention to details and look at other's experience. I've always made my own, so no help there. At this point having a distinct radio receiver connected via PWM seems a bit antiquated compared to an onboard radio as well - part of the problem with stringing modules together is that it means a larger, heavier, more hazardous test aircraft, while compact solutions mean featherweight things you can fly off the lab bench. – Chris Stratton May 1 '18 at 13:03
  • So when you make your own, you place the receiver and CPU on the same board? – MoneyMonkey May 1 '18 at 13:10
  • Yes, like most now do. It's not only more compact but a more natural interface, without going through the legacy PWM or even still-multiplexed PPM. – Chris Stratton May 1 '18 at 13:17
0

I found the problem. The problem was with the interrupts when the program was running and doing calculations at that moment the Arduino would be interrupted and stop in the middle of it, and change the value it was doing calculations with. This somehow caused the Arduino to sent interference over the signal wires. Reading the signals with a reading guard fixed the problem.

void read_inputs()
{
  noInterrupts();

  byte identifyer = 0;
  rc_shared[identifyer] = rc_raw[identifyer];

  ...

  interrupts();
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.