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– Chris Stratton2018年05月01日 12:54:39 +00:00Commented May 1, 2018 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– MoneyMonkey2018年05月01日 13:02:37 +00:00Commented May 1, 2018 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– Chris Stratton2018年05月01日 13:03:40 +00:00Commented May 1, 2018 at 13:03
-
So when you make your own, you place the receiver and CPU on the same board?MoneyMonkey– MoneyMonkey2018年05月01日 13:10:06 +00:00Commented May 1, 2018 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– Chris Stratton2018年05月01日 13:17:44 +00:00Commented May 1, 2018 at 13:17
1 Answer 1
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();
}
Explore related questions
See similar questions with these tags.