If you are unfortunate enough to own a dragonlink and would like to get the 12ch PPM signal output working with a MultiWii board then you have come to the right place.
The dragonlink 12ch PPM stream doesn't work correctly. Take a moment to look at this diagram explaining the PPM stream.
In this case it is explaining a 6ch PPM stream.
A standard servo output ("t1", "t2", etc) must be between 1ms and 2ms. So for a 12ch stream we need a minimum of 24ms (12 outputs x 2ms) just for the servo stream. Then a PPM frame must have a Frame Space ("Synchro Blank Time") of a minimum of ~4ms. This frame space is required so the Flight Controller (or whatever else needs to decode the PPM stream) knows when one frame ends and another begins.
So a 12ch PPM stream needs an absolute minimum of 28ms frame length ("Period") (12 outputs x 2ms + 4ms Frame Space). In the case of MultiWii, any frame space lower than 3ms but higher than 2.2ms will cause the failsafe count within MultiWii to increase. If the frame space is lower than 2.2ms MultiWii can't differentiate between the end of the frame and just another channel within the stream.
In the case of dragonlink, the outputted frame length is 22ms, we can see where that would cause problems. When the sum of all of the servo outputs is below about 18-19ms, it doesn't cause any problems, the frame space is fine. As you increase the value of individual channels, the frame space decreases in order to maintain the 22ms frame length. Once the frame space decrease below 3ms (in the case of MultiWii), the connected devices can't distinguish between the frame space or another channel.
Even worse, as you keep increasing individual channels (raising throttle or turning on a switch for example) the frame space continues to decrease until it reaches about 360us (0.36ms), after which the Frame Length will double (!) to 44ms in order to fit all of the servo channel data into the PPM stream.
Anything you have reading the PPM stream will either failsafe, or read the channel data wrong. In the case of MultiWii, it reads the channels wrong and they vary all over the place. I hope you aren't in the air at the time! One second the MultiWii will read the Aileron as your throttle and the next it will read your autolevel switch as your elevator (for example).
The dragonlink PPM stream will work fine for 9 channels or less because there is enough time for 9 channels to fit into the 22ms frame with a long enough frame space. Though that is like buying a ferrari and not being able to use a quarter of its gears.
I have modified the MultiWii code in order to be able to read the buggy PPM stream correctly and I hope to be able to help others use a MultiWii with the dragonlink if they need to.
This is for MultiWii 2.2 or 2.3. I haven't checked earlier versions to see if they implement PPM the same.
Ok here for the instructions:
1. Open up your MultiWii sketch in Arduino.
2. Open the tab called "RX.cpp".
3. Scroll down about a third of the way and find the heading "PPM SUM RX Pin reading" or press ctrl+f and search for the heading title.
4. Find the function with the heading "// Read PPM SUM RX Data".
5. Delete everything from the next line which begins with "#if defined(SERIAL_SUM_PPM)" to the last line which ends in "#endif" (just before the next heading).
6. Replace it with this:
Code: Select all
#if defined(SERIAL_SUM_PPM)
void rxInt(void) {
uint16_t now,diff;
static uint16_t last = 0;
static uint8_t chan = 0;
#if defined(FAILSAFE)
static uint8_t GoodPulses;
#endif
now = micros();
sei();
diff = now - last;
last = now;
if(diff>3000 || chan==12){
chan = 0;
}
else if (chan<12) {
if(900<diff && diff<2200 && chan<RC_CHANS ) { //Only if the signal is between these values it is valid, otherwise the failsafe counter should move up
rcValue[chan] = diff;
#if defined(FAILSAFE)
if(chan<4 && diff>FAILSAFE_DETECT_TRESHOLD) GoodPulses |= (1<<chan); // if signal is valid - mark channel as OK
if(GoodPulses==0x0F) { // If first four chanells have good pulses, clear FailSafe counter
GoodPulses = 0;
if(failsafeCnt > 20) failsafeCnt -= 20; else failsafeCnt = 0;
}
#endif
}
chan++;
}
}
#endif
7. Now you should be able to read the buggy PPM stream correctly! Edit: After uploading to your MultiWii board obviously.
My modified version of the code counts the channels instead of waiting for the correct length frame space (which may not come until after you have crashed). It will only work for 12 channels but is easy to change for less (or more). It does need at least one correct frame space at the start though so it knows where to start counting the channels from. If it loses sync (which it never should once it has it), it will only need one correct frame space to regain it and keep counting correctly.
I have been using this code for a couple of months without any problems and have never lost sync so it is pretty-well tested.
We shouldn't have to modify MultiWii code to read a PPM stream correctly but if you must use the dragonlink for the moment this is a good workaround.
If you want to use PPM for anything other than MultiWii then tough luck! Use 9 channels or less or upgrade your dragonlink to something else.
If you are trying to implement this yourself and have any problems just ask