Rc helicopter: rc receiver gives to high value when controlling servo

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 I get when I am not sending anything to my servos. These values are in microseconds

Ch1       Ch2      Ch3      Ch4   
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.

Ch1        Ch2       Ch3      Ch4
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.
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
double volatile rc_start[RC_NUM_CHANNELS];
double volatile rc_shared[RC_NUM_CHANNELS];
uint16_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[i], 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

#include <Arduino.h>
#include <PID_v1.h> //used in other code
#include <math.h> //used in other code
#include <Servo.h>
#include "RC_controller.h"
#include "mpu_read.h" //used in other code
#include "eeprom.h" //used in other code
#include <iterator> //used in other code

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();
}

Why do you have "main.cpp" in your program. Comment that out and see if it works better.

Paul

What are using to read the values from the receiver ? Are you aware that is PPM ?
Are you using PulseIn function ?

Why do you declare rc_start and rc_shared as double (double floats) ?. micros() is an uint32_t BTW.

What is this ?:

swasplate[0].write(rc_raw[0]);
swashplate[a].attach(10+a, 1200, 1800);

Paul_KD7HB

main.cpp is in the program because I am using platforio on atom.

raschemmel

I don’t really get what you are asking. I mean there is a receiver with wires: two power wires and 6 signal wires to the Arduino due pins 2, 3, 4, 5, 6, 7.

The reason I am not using PulseIn is that there are 6 more channels. It would significantly slow down the program to use PulseIn for all 6 channels.

ard_newbie

The reason I am using a double is for convenience, in the parts that are commented out I am doing a bunch of divisions. So instead of typecasting everything I just made it a double.

EDIT
Servo swasplate[3]; //create an array with 3 servo objects

for (int a = 0; a < 3; a++)
swasplate[a].attach(10+a, 1200, 1800);
//attach servos to pins 10 11 12
//prevent it from destroying my swashplate by setting limits 1200 1800

swasplate[0].write(rc_raw[0]);
//write the value of the receiver straight to the first servo in the array, so the servo with pin 10.

raschemmel:
What are using to read the values from the receiver ? Are you aware that is PPM ?

If you're reading from separate pins, it's PWM.
You'd only be decoding PPM (which is just a stream of PWM pulses), if you'd broken out the connection between the receiver and decoder on a single pin.

Have you successfully decoded any receiver signal thus far to verify that your coding scheme works ?

yes, everything worked perfectly fine. Until I switched out my breadboard with a soldered chip. The weird thing is the moment I went back to the breadboard it didn't work anymore.

What soldered chip ?
What is a soldered chip ? (as opposed to all other chips)
Do you mean you replaced a solderless breadboard with a PCB ?

But it isn't of much importance because I later removed it and it still didn't work. And if you think I broke something, I later used a different Arduino due without the soldered chip and it still didn't work.

It seems using longer wires from the arduino to the servo signal pins fixed the problem. First I thought it was the resistance but adding some resistors didn't fix anything.

Wires may behave as a low-pass filter since a long pair of wires is a distributed capacitor, but also a distributed inductor and resistor. Twisted wires would avoid some EMI too.