Mixing different rc signals

Hi,

I need to read two rc signals from a rc receiver, and one signal from a rc gyro. The three signals are going to be mixed into two servo outputs.

IN_1: Spektrum receiver signal 1
IN_2: Spektrum receiver signal 2
IN_3: Gyro signal
OUT_1: Spektrum receiver signal 1 + Gyro signal
OUT_2: Spektrum receiver signal 2 - Gyro signal

Does anyone know how to do this job?

As far as I know, I need to use some sort of interrupt handling to measure the three RC inputs. And this is where my arduino skills stops :frowning:

btw. hopefully this can be done in a arduino mini (because of the size and weight)

Some of these topics have been touched in this thread. Please let us know how far that applies to your situation.

Korman

It it sort of the same problems.
But i'm not quite sure how to do in real life.

ch1 & ch2 comes from the receiver, which means that they probably will arrive at the same time.
ch3 is not synchronized with the two other signals, so it can arrive at any time.

ch1 external interrupt 1 (probably the most precise way?)
ch2 external interrupt 2 (probably the most precise way?)
ch3 pulsein function (is pausing the program for up to 20 ms?)

I have created a simple layout of the function:
http://www.sendspace.com/file/0y3qm9

Normally, from the receiver, pulses would be consecutive, not simultaneous.
Have you checked with a scope?

Sorry but i dont have scope.

I have made this code (made from different code parts around this forum)

It works 95%, the only thing is that every time i connect pin 4 (pulsein) the servos start to jitter. It seems like the pulsein measurement is not very precise. Or perhaps i'm doing something wrong ?
I have tried with different timeout values on the pulsein instruction, but without any luck :frowning:

Any ideas how to get rid of the jittering ?

#include <math.h>
#include <Servo.h>
int Chan0Interrupt = 0; // pin 2
int Chan1Interrupt = 1; // pin 3
int Chan2Signal = 4; // pin 4
//float Chan0_scaled, Chan1_scaled, Chan2_scaled;
unsigned long Chan0_startPulse, Chan1_startPulse, servo0_value, servo1_value;
volatile double Chan0_val, Chan1_val, Chan2_val;
volatile double Chan0_val_last, Chan1_val_last, Chan2_val_last;
long StartMillis=0;
long FrameCounter=0;
long pulsemin=900;
long pulsecenter=1500;
long pulsemax=2100;
boolean led;
Servo ServoArray[2];
void setup()
{
attachInterrupt(Chan0Interrupt, Chan0_begin, RISING);
attachInterrupt(Chan1Interrupt, Chan1_begin, RISING);

Chan0_val_last = pulsecenter;
Chan1_val_last = pulsecenter;
Chan2_val_last = pulsecenter;

for (uint8_t i=0;i<2;i++)
ServoArray*.attach(5+i, pulsemin, pulsemax);

Serial.begin(115200);
StartMillis = millis();
}
void loop()
{
long LocalMillis;
long LocalFrameCounter;
LocalMillis = millis();

Chan2_val = pulseIn(Chan2Signal, HIGH,15000);
if (Chan2_val < pulsemin || Chan2_val > pulsemax) { Chan2_val = Chan2_val_last;}
else {Chan2_val_last = Chan2_val;}

servo0_value = Chan0_val + (Chan2_val - pulsecenter);
if (servo0_value < pulsemin) {servo0_value = pulsemin;}
if (servo0_value > pulsemax) {servo0_value = pulsemax;}

servo1_value = Chan1_val - (Chan2_val - pulsecenter);
if (servo1_value < pulsemin) {servo1_value = pulsemin;}
if (servo1_value > pulsemax) {servo1_value = pulsemax;}

LocalFrameCounter = (LocalMillis - StartMillis) / 20; // Update servo positionevery 20msec*
* if (LocalFrameCounter > FrameCounter)
{
FrameCounter = LocalFrameCounter;

ServoArray[0].writeMicroseconds(servo0_value);
ServoArray[1].writeMicroseconds(servo1_value);

digitalWrite(13,led); // Flash led for every cycle*
* led=!led;
}
}
void Chan0_begin() // enter Chan1_begin when interrupt pin goes HIGH.
{
Chan0_startPulse = micros(); // record microseconds() value as Chan1_startPulse*
* detachInterrupt(Chan0Interrupt); // after recording the value, detach the interrupt from Chan1_begin*
* attachInterrupt(Chan0Interrupt, Chan0_end, FALLING); // re-attach the interrupt as Chan1_end, so we can record the value when it goes low*
* }
void Chan0_end()
{
Chan0_val = micros() - Chan0_startPulse; // when interrupt pin goes LOW, record the total pulse length by subtracting previous start value from current micros() vlaue.
detachInterrupt(Chan0Interrupt); // detach and get ready to go HIGH again*
* attachInterrupt(Chan0Interrupt, Chan0_begin, RISING);
if (Chan0_val < pulsemin || Chan0_val > pulsemax) { Chan0_val = Chan0_val_last;}
else {Chan0_val_last = Chan0_val;}
}
void Chan1_begin() // enter Chan2_begin when interrupt pin goes HIGH.
{
Chan1_startPulse = micros(); // record microseconds() value as Chan2_startPulse*
* detachInterrupt(Chan1Interrupt); // after recording the value, detach the interrupt from Chan2_begin*
* attachInterrupt(Chan1Interrupt, Chan1_end, FALLING); // re-attach the interrupt as Chan2_end, so we can record the value when it goes low*
* }
void Chan1_end()
{
Chan1_val = micros() - Chan1_startPulse; // when interrupt pin goes LOW, record the total pulse length by subtracting previous start value from current micros() vlaue.
detachInterrupt(Chan1Interrupt); // detach and get ready to go HIGH again*
* attachInterrupt(Chan1Interrupt, Chan1_begin, RISING);
if (Chan1_val < pulsemin || Chan1_val > pulsemax) { Chan1_val = Chan1_val_last;}
else {Chan1_val_last = Chan1_val;}
}[/sup]*

Any ideas how to get rid of the jittering ?

How are you powering the servos?

im using an arduino diecimila board powered by usb.
Servos + receiver + gyro is powered from the arduino board.

I doesn't seems to be at power issue. Because when i remove the signal from the gyro pin 3 (and everything still powered) the jittering stops. Also when i switch pin 3 and 4, the problem moves to the transmitter signal.

I doesn't seems to be at power issue

I disagree. Not saying that this is absolute, but this is a fairly common problem. And most often, putting the servos on a separate power source (and remembering to connect all the grounds) fixes it.

4 AA batteries work.
Walwarts in the 4.5 to 5V range work.
RC receiver batteries work.

Give it a try.

I have now powered the setup by battery (2 x lipo cells) and there is no difference from usb power. The servo's still jitters :frowning:

I can see that the pulsein functions returns values which varies around +-10 usec. pulse length from 1480 - 1496.

But the interrupt functions are rocksolid, no difference at all

I have tried to make a deadband (+-10us) , but that just makes gyro more rough... because I only see changes > deadband.

Any ideas?

If there seems to be bias towards 1496 as the error with little other errors, I would guess that the 16µs are some 250 instructions of the interrupt service routine driving your servos. Check if it becomes worse at other servo PWM values. I ended up solving that problem by discarding erroneous values.

Korman