Tutorial: Getting Dragonlink 12ch PPM to work with MultiWii

Post Reply
Dok
Posts: 6
Joined: Thu Nov 21, 2013 8:16 am

Tutorial: Getting Dragonlink 12ch PPM to work with MultiWii

Post by Dok »

Hi guys I am new to the MultiWii forums but have recently been active over at rcgroups. I have had a bit of a saga with MultiWii 12ch PPM and dragonlink in the last couple of weeks and have had to make a workaround to read the PPM stream properly. I thought it may come in handy for people here too. Ok here is the post from rcgroups:

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.
Image

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 :)

ardufriki
Posts: 88
Joined: Thu Dec 13, 2012 4:47 pm

Re: Tutorial: Getting Dragonlink 12ch PPM to work with Multi

Post by ardufriki »

Hi Dok,

I have been experimenting lately with my new orangerx system and openlrsng firmware. I have also flashed my turnigy 9x with er9x in order to get easier switches configuration.

What I`ve got is exactly the same as you. I tried to configure 12 channels (because in the code we have 12 channels:

Code: Select all

    /****************************    PPM Sum Reciver    ***********************************/
      /* The following lines apply only for specific receiver with only one PPM sum signal, on digital PIN 2
         Select the right line depending on your radio brand. Feel free to modify the order in your PPM order is different */
      //#define SERIAL_SUM_PPM         PITCH,YAW,THROTTLE,ROLL,AUX1,AUX2,AUX3,AUX4,8,9,10,11 //For Graupner/Spektrum
      #define SERIAL_SUM_PPM         ROLL,PITCH,THROTTLE,YAW,AUX1,AUX2,AUX3,AUX4,8,9,10,11 //For Robe/Hitec/Futaba
      //#define SERIAL_SUM_PPM         ROLL,PITCH,YAW,THROTTLE,AUX1,AUX2,AUX3,AUX4,8,9,10,11 //For Multiplex
      //#define SERIAL_SUM_PPM         PITCH,ROLL,THROTTLE,YAW,AUX1,AUX2,AUX3,AUX4,8,9,10,11 //For some Hitec/Sanwa/Others

      // Uncommenting following line allow to connect PPM_SUM receiver to standard THROTTLE PIN on MEGA boards (eg. A8 in CRIUS AIO)
      //#define PPM_ON_THROTTLE



but with 12 channels it has the same behaviour as yours. The channels go crazy if they get high values. It doesnt matter if I program my 9x with 8ch PPM, 12ch PPM, etc.

The only way it works is when I change my openlrsng configuration to 8ch.

May be I try your mod, I think it is not included in last releases of multiwii (I have 2.3 now).

Good job anyway !!

Post Reply