Direct Frsky telemtry data from MW FC

copterrichie
Posts: 2261
Joined: Sat Feb 19, 2011 8:30 pm

Re: Direct Frsky telemtry data from MW FC

Post by copterrichie »

Make it universal and not just specific for Frsky, Heck ya!

Urbasik
Posts: 9
Joined: Mon Aug 13, 2012 2:40 pm
Location: Germany SW

Re: Direct Frsky telemtry data from MW FC

Post by Urbasik »

Tried it yesterday with a simple lvl converter/inverter and it works fine so far.
Soft Serial would be nice for for 2.2.

User avatar
IceWind
Posts: 115
Joined: Fri Mar 25, 2011 2:11 am
Contact:

Re: Direct Frsky telemtry data from MW FC

Post by IceWind »

I suspect you mean that for the MEGA's not for the ProMini's right?

copterrichie
Posts: 2261
Joined: Sat Feb 19, 2011 8:30 pm

Re: Direct Frsky telemtry data from MW FC

Post by copterrichie »

The Mega would not require a Soft Serial. heads up, the Arduino Softserial library does not work well with MWC, don't ask me how I know. :eek:
Last edited by copterrichie on Mon Jan 28, 2013 5:36 pm, edited 1 time in total.

User avatar
IceWind
Posts: 115
Joined: Fri Mar 25, 2011 2:11 am
Contact:

Re: Direct Frsky telemtry data from MW FC

Post by IceWind »

...

Sebbi
Posts: 478
Joined: Sun Jul 08, 2012 1:08 am
Location: Germany
Contact:

Re: Direct Frsky telemtry data from MW FC

Post by Sebbi »

copterrichie wrote:Make it universal and not just specific for Frsky, Heck ya!


And how would one do that? There is already LCD telemetry within MultiWii and FrSky telemetry is nothing like it ... Graupners Hott however, might be another story, but I don't have the hardware required to test this.

IceWind wrote:I suspect you mean that for the MEGA's not for the ProMini's right?

MEGA as well as ProMini or Leonardo. The TX-part of SoftSerial is very small and doesn't take too many bytes. It increases the cycle time, however.

copterrichie wrote:The Mega would not require a Soft Serial. heads up, the Arduino Softserial library does not work well with MWC, don't ask me how I know. :eek:

Sending with SoftSerial does work fine and I stripped the required code from that library, so it works for FrSky telemetry.

And including SoftSerial only requires additional 332 bytes ;-)

copterrichie
Posts: 2261
Joined: Sat Feb 19, 2011 8:30 pm

Re: Direct Frsky telemtry data from MW FC

Post by copterrichie »

Care to share the stripped down version of the SoftSerial Library? I have an need for it right now. :)

Sebbi
Posts: 478
Joined: Sun Jul 08, 2012 1:08 am
Location: Germany
Contact:

Re: Direct Frsky telemtry data from MW FC

Post by Sebbi »

copterrichie wrote:Care to share the stripped down version of the SoftSerial Library? I have an need for it right now. :)


I hope you find the needed parts in this code extract. initTelemetry() has to be called in setup() and write_softserial() writes a single byte on the configured pin with the desired baudrate (which is 9600 in case of FrSky). I attached the complete lookup tables below the code, so you can change it for whatever baudrate you need. And remember ... this is transmitting only and uses inverted logic. You have to switch the cases in tx_pin_write() to get normal serial logic.

Code: Select all

  #define TELEMETRY_FRSKY_PIN 4

  #if defined(TELEMETRY_FRSKY_PIN)
    uint8_t frsky_transmitBitMask;
    volatile uint8_t *frsky_transmitPortRegister; 
   
    #define TELEMETRY_FRSKY_WRITE(x) write_softserial(x)
   
    #if F_CPU == 16000000
    uint16_t frsky_tx_delay = 233;     // value from original SoftSerial for baudrate 9600
    const int frsky_XMIT_START_ADJUSTMENT = 5;
   
    #elif F_CPU == 8000000
    uint16_t frsky_tx_delay = 112;     // value from original SoftSerial for baudrate 9600
    const int frsky_XMIT_START_ADJUSTMENT = 4;
   
    #elif F_CPU == 20000000
    uint16_t frsky_tx_delay = 294;     // value from original SoftSerial for baudrate 9600
    const int frsky_XMIT_START_ADJUSTMENT = 6;
   
    #else
    #error SoftSerial (FrSky) supports only 20, 16 and 8MHz processors
    #endif
   
  #elif defined(TELEMETRY_FRSKY_SERIAL)
    #define TELEMETRY_FRSKY_WRITE(x) SerialWrite(TELEMETRY_FRSKY_SERIAL, x);
   
  #else
  #error FrSky telemetry requires either a pin (SoftSerial) or a real serial port being set in config.h
  #endif 
 
  #if defined(TELEMETRY_FRSKY_WRITE)
 
  void initTelemetry()
  {
    #if defined(TELEMETRY_FRSKY_PIN)
    // set pin to output and prepare bitmask
    pinMode(TELEMETRY_FRSKY_PIN, OUTPUT);
    digitalWrite(TELEMETRY_FRSKY_PIN, HIGH);
    frsky_transmitBitMask = digitalPinToBitMask(TELEMETRY_FRSKY_PIN);
    uint8_t port = digitalPinToPort(TELEMETRY_FRSKY_PIN);
    frsky_transmitPortRegister = portOutputRegister(port);

    #endif
    // initialisation when using serial port is done automatically
  }

  #if defined(TELEMETRY_FRSKY_PIN)
  void tx_pin_write(uint8_t pin_state)
  {
    if (pin_state == LOW)
      *frsky_transmitPortRegister &= ~frsky_transmitBitMask;
    else
      *frsky_transmitPortRegister |= frsky_transmitBitMask;
  }

  inline void tunedDelay(uint16_t delay) {
    uint8_t tmp=0;
 
    // +w instead of +r, because gcc complained
    asm volatile("sbiw    %0, 0x01 \n\t"
      "ldi %1, 0xFF \n\t"
      "cpi %A0, 0xFF \n\t"
      "cpc %B0, %1 \n\t"
      "brne .-10 \n\t"
      : "+w" (delay), "+a" (tmp)
      : "0" (delay)
      );
  }

  void write_softserial(uint8_t b) {
    uint8_t oldSREG = SREG;
    cli();  // turn off interrupts for a clean txmit

    // Write the start bit
    tx_pin_write(HIGH);
    tunedDelay(frsky_tx_delay + frsky_XMIT_START_ADJUSTMENT);   

    // Write each of the 8 bits
    for (byte mask = 0x01; mask; mask <<= 1)
    {
      if (b & mask) // choose bit
        tx_pin_write(LOW); // send 1
      else
        tx_pin_write(HIGH); // send 0
   
      tunedDelay(frsky_tx_delay);
    }

    tx_pin_write(LOW); // restore pin to natural state
 
    SREG = oldSREG; // turn interrupts back on
    tunedDelay(frsky_tx_delay);   
  }
  #endif


Code: Select all

//
// Lookup table
//
typedef struct _DELAY_TABLE
{
  long baud;
  unsigned short rx_delay_centering;
  unsigned short rx_delay_intrabit;
  unsigned short rx_delay_stopbit;
  unsigned short tx_delay;
} DELAY_TABLE;

#if F_CPU == 16000000

static const DELAY_TABLE PROGMEM table[] =
{
  //  baud    rxcenter   rxintra    rxstop    tx
  { 115200,   1,         17,        17,       12,    },
  { 57600,    10,        37,        37,       33,    },
  { 38400,    25,        57,        57,       54,    },
  { 31250,    31,        70,        70,       68,    },
  { 28800,    34,        77,        77,       74,    },
  { 19200,    54,        117,       117,      114,   },
  { 14400,    74,        156,       156,      153,   },
  { 9600,     114,       236,       236,      233,   },
  { 4800,     233,       474,       474,      471,   },
  { 2400,     471,       950,       950,      947,   },
  { 1200,     947,       1902,      1902,     1899,  },
  { 300,      3804,      7617,      7617,     7614,  },
};

const int XMIT_START_ADJUSTMENT = 5;

#elif F_CPU == 8000000

static const DELAY_TABLE table[] PROGMEM =
{
  //  baud    rxcenter    rxintra    rxstop  tx
  { 115200,   1,          5,         5,      3,      },
  { 57600,    1,          15,        15,     13,     },
  { 38400,    2,          25,        26,     23,     },
  { 31250,    7,          32,        33,     29,     },
  { 28800,    11,         35,        35,     32,     },
  { 19200,    20,         55,        55,     52,     },
  { 14400,    30,         75,        75,     72,     },
  { 9600,     50,         114,       114,    112,    },
  { 4800,     110,        233,       233,    230,    },
  { 2400,     229,        472,       472,    469,    },
  { 1200,     467,        948,       948,    945,    },
  { 300,      1895,       3805,      3805,   3802,   },
};

const int XMIT_START_ADJUSTMENT = 4;

#elif F_CPU == 20000000

// 20MHz support courtesy of the good people at macegr.com.
// Thanks, Garrett!

static const DELAY_TABLE PROGMEM table[] =
{
  //  baud    rxcenter    rxintra    rxstop  tx
  { 115200,   3,          21,        21,     18,     },
  { 57600,    20,         43,        43,     41,     },
  { 38400,    37,         73,        73,     70,     },
  { 31250,    45,         89,        89,     88,     },
  { 28800,    46,         98,        98,     95,     },
  { 19200,    71,         148,       148,    145,    },
  { 14400,    96,         197,       197,    194,    },
  { 9600,     146,        297,       297,    294,    },
  { 4800,     296,        595,       595,    592,    },
  { 2400,     592,        1189,      1189,   1186,   },
  { 1200,     1187,       2379,      2379,   2376,   },
  { 300,      4759,       9523,      9523,   9520,   },
};

const int XMIT_START_ADJUSTMENT = 6;

#else

#error This version of SoftwareSerial supports only 20, 16 and 8MHz processors

#endif
Last edited by Sebbi on Mon Jan 28, 2013 7:39 pm, edited 2 times in total.

User avatar
IceWind
Posts: 115
Joined: Fri Mar 25, 2011 2:11 am
Contact:

Re: Direct Frsky telemtry data from MW FC

Post by IceWind »

Sebbi wrote:
IceWind wrote:I suspect you mean that for the MEGA's not for the ProMini's right?

MEGA as well as ProMini or Leonardo. The TX-part of SoftSerial is very small and doesn't take too many bytes. It increases the cycle time, however.


Perfect. No problem in my case (unless the increase is huge) as I always have low cycle times due to never using anything else other than gyros.
The use case is to get GPS data, as I'll be using the I2C converter again the cycle time shouldn't suffer much.

copterrichie
Posts: 2261
Joined: Sat Feb 19, 2011 8:30 pm

Re: Direct Frsky telemtry data from MW FC

Post by copterrichie »

Thank you

QuadBow
Posts: 532
Joined: Fri Jan 04, 2013 10:06 am

Re: Direct Frsky telemtry data from MW FC

Post by QuadBow »

Hi guys,

I got one question as to FRSKY telemetry since the voltage stuff is still unclear to me.

Understanding that
ID_Volt 0x06
is related to FLVS-01 voltage sensor covering cells' voltage
I wonder if
ID_Voltage_Amp_bp 0x3A
and
ID_Voltage_Amp_ap 0x3B
are the same the built-in voltages A1 and A2.
Will they overwrite A1/A2 or are there more IDs for A1/A2 which are independend?

The Frsky documentation of the FLD-02 mentions a "rate", which is not included in the transfer protocol list.
Does anybody know more?

subaru4wd
Posts: 316
Joined: Sat Dec 08, 2012 2:16 am

Re: Direct Frsky telemtry data from MW FC

Post by subaru4wd »

larsm wrote:I wrote some instructions to do the mod: klick



This link no longer works.

Does anybody have a guide to this mod? I just ordered the converter & I am not sure where it needs to be installed.

QuadBow
Posts: 532
Joined: Fri Jan 04, 2013 10:06 am

Re: Direct Frsky telemtry data from MW FC

Post by QuadBow »

Yesterday, I worked a bit on the FRSKY telemetry integration into my multiwii configuration including the telemetry display FLD-02.
Thanks to the great job of others most of the functionalitys work already well.
In the current implementation rpm lies within the range of 1000 to 2000 in accordance to the multiwii motor[i] variable.
I wrote a small change of code in order to present the "real" rpm values.

void inline send_RPM(void)
{
uint16_t Data_RPM = 0;
float rpm;

for (uint8_t i=0; i<NUMBER_MOTOR; i++)
{
Data_RPM += motor[i] - MINCOMMAND;
}
#if defined(VBAT)
rpm = ((float) Data_RPM * (float) vbat * KV_MOTOR) / ((float) NUMBER_MOTOR * 300.0 * (float) (MAXTHROTTLE - MINCOMMAND));
#else
rpm = ((float) Data_RPM * 120.0 * KV_MOTOR) / ((float) NUMBER_MOTOR * 300.0 * (float) (MAXTHROTTLE - MINCOMMAND));
#endif
Data_RPM = (uint16_t) rpm;

sendDataHead(ID_RPM);
write_FrSky16(Data_RPM);
}

This is not a real measurement, but an estimation of the rpm. You have to define in config.h
#define KV_MOTOR 1500.0 // kv of motors in rpm/V
for motors which rotate with a kv-value of 1500.0 rpm per volt.
You should enable VBAT as well, the algorithm assumes a steady voltage of 12.0 V, which is not that accurate.
The rpm-value is divided by 30 (due to 300.0) in order to fit in the FLD-02 scheme.

Does anybody have other telemetry displays (e.g. telemetry integration into the turnigy 9x display) in order to make the code suitable for other configurations and therefore more universal?

QuadBow
Posts: 532
Joined: Fri Jan 04, 2013 10:06 am

Re: Direct Frsky telemtry data from MW FC

Post by QuadBow »

I found some issues within the already provided file "telemetry.ino" and fixed them for my purposes.

1. The altitude of baro based estimation accepts only one 16-bit number (before point). The after point part doesn't have any effect, so a abolished it.

void inline send_Altitude(void)
{
uint16_t Data_altitude;
static uint16_t Start_altitude;

if (!f.ARMED)
Start_altitude = EstAlt / 100;
Data_altitude = EstAlt / 100 - Start_altitude;

sendDataHead(ID_Altitude);
write_FrSky16(Data_altitude);
}

2. The Frsky telemetry protocol expects the speed in knots, not in kilometers per hour. I could confirm this expectation by testing.
Thus, I had to change the factor 0.036 (cm/s to km/h) to 0.019726 (cm/s to kn). Furthermore, I implemented the after point part for a better accuracy.

void send_GPS_speed(void)
{
if (f.GPS_FIX && GPS_numSat >= 4)
{
uint16_t temp;
uint16_t Datas_GPS_speed_bp;
uint16_t Datas_GPS_speed_ap;

temp = GPS_speed * 0.19726;
Datas_GPS_speed_bp = temp / 10;
Datas_GPS_speed_ap = temp % 10;

sendDataHead(ID_GPS_speed_bp);
write_FrSky16(Datas_GPS_speed_bp);
sendDataHead(ID_GPS_speed_ap);
write_FrSky16(Datas_GPS_speed_ap);
}
}

The fixed issues are related to FLD-02 v2.1. Are those issues also known for other devices / firmware versions?
I would be grateful receiving more information about other display devices in order to support the development of a Frsky telemetry integration to a more universal extend.

Action
Posts: 3
Joined: Tue Mar 26, 2013 12:18 pm

Re: Direct Frsky telemtry data from MW FC

Post by Action »

Hello all, I am kinda new to RC hobby and it looks like I have came in at a great time! I was looking around for the perfect radio system for the tricopter that I am about to build and came across this thread. I am currently in college taking computer programming classes, and hopefully I will be able to contribute to the community.

I am waiting on all my parts to come it right now to get started. I have the HK multiwii 328p on order for the flight control and a serial to bluetooth module to upgrade and make changes.

I was looking at getting a Turnigy 9x when I came across the new FrSky Taranis being discussed. It is supposed to be out in April, not sure of the price yet, but it has great potential. It has the FrSky Telemetry built in and has up to 16 channels. Nice backlit screen, plenty of switches and such. It has the open9x installed and can transmit user data over serial bus.
I think the addition of the code found in this thread along with this new radio will be a game changer, very exciting stuff.

We could probably connect a serial bluetooth module on the tranciever and be able to transfer data to the board through the receiver.

Hopefully the new controller uses the same method to broadcast the telemetry data as has been discusse here.

kataventos
Posts: 702
Joined: Sun Aug 28, 2011 8:14 pm
Contact:

Re: Direct Frsky telemtry data from MW FC

Post by kataventos »

@Quadbow,

nice of you to take some time with this and continue the developments.
I looked to your code lines and I will try asap the RPM mod ;) it sure looks nice. About speed, nice for the knots guys ;) on the altitude do not see problem on using what is done so far besides user´s that want to make this mod will need to change as follows either:

Code: Select all

  #define ID_Altitude_bp        0x10
  #define ID_Altitude_ap        0x21


to

Code: Select all

  #define ID_Altitude        0x10
  //#define ID_Altitude_ap        0x21


Anyway, some more changes have to be done in order to have it running with MWii 2.2 but they are easy to catch by the user.
About your question, I do have the 9X with ER9X and it is working just fine ;)

Cheers,
KV

mysku82
Posts: 17
Joined: Wed Oct 12, 2011 7:32 am
Location: Bucharest, Romania
Contact:

Direct Frsky telemtry data from MW FC r1391

Post by mysku82 »

It gives me error loading the r1391. Does anyone know why?

FrSkyTelemetry.ino: In function 'void send_Altitude()':
FrSkyTelemetry:251: error: 'EstAlt' was not declared in this scope
FrSkyTelemetry:254: error: 'EstAlt' was not declared in this scope
FrSkyTelemetry.ino: In function 'void send_Course()':
FrSkyTelemetry:320: error: 'heading' was not declared in this scope
FrSkyTelemetry.ino: In function 'void send_Accel()':
FrSkyTelemetry:357: error: 'accSmooth' was not declared in this scope
FrSkyTelemetry:357: error: 'acc_1G' was not declared in this scope
FrSkyTelemetry.ino: In function 'void send_Voltage_ampere()':
FrSkyTelemetry:395: error: 'vbat' was not declared in this scope

Thanks

Best Regards
Cosmin Miscu

kataventos
Posts: 702
Joined: Sun Aug 28, 2011 8:14 pm
Contact:

Re: Direct Frsky telemtry data from MW FC r1391

Post by kataventos »

mysku82 wrote:It gives me error loading the r1391. Does anyone know why?



Hi Cosmin,

what I said on my last post, they are easy to catch. Look at the MWii code and change on the FRSky_telemetry sketch accordingly.

Cheers,
KV

kataventos
Posts: 702
Joined: Sun Aug 28, 2011 8:14 pm
Contact:

Re: Direct Frsky telemtry data from MW FC

Post by kataventos »

OK got a few minutes into it, try this entire new sketch:

FrSky_telemetry

Code: Select all

// ****************************************************************
// FrSky telemetry
// Version: 0.2.2
// Date 26/04/2013
// KataVentos Changes: V0.2.2: - made it work with 2.2 (r1391) plus Quadbow RPM mod.
// ****************************************************************

#if defined(TELEMETRY_FRSKY)
  // user defines
  #define FAS_100  //if commment out, MultiWii vBat voltage will be send instead of FrSky FAS 100 voltage


  // Serial config datas
  #define TELEMETRY_FRSKY_SERIAL 3
  #define TELEMETRY_FRSKY_BAUD 9600 

  // Timing
  #define Time_telemetry_send 125000
  static uint8_t cycleCounter = 0;
  static uint32_t FrSkyTime  = 0;

  // Frame protocol
  #define Protocol_Header   0x5E
  #define Protocol_Tail      0x5E
 
 
  // Data Ids  (bp = before point; af = after point)
  // Official data IDs
  #define ID_GPS_altidute_bp    0x01
  #define ID_GPS_altidute_ap    0x09
  #define ID_Temprature1        0x02
  #define ID_RPM                0x03
  #define ID_Fuel_level         0x04
  #define ID_Temprature2        0x05
  #define ID_Volt               0x06
  #define ID_Altitude_bp        0x10
  #define ID_Altitude_ap        0x21
  #define ID_GPS_speed_bp       0x11
  #define ID_GPS_speed_ap       0x19
  #define ID_Longitude_bp       0x12
  #define ID_Longitude_ap       0x1A
  #define ID_E_W                0x22
  #define ID_Latitude_bp        0x13
  #define ID_Latitude_ap        0x1B
  #define ID_N_S                0x23
  #define ID_Course_bp          0x14
  #define ID_Course_ap          0x24
  #define ID_Date_Month         0x15
  #define ID_Year               0x16
  #define ID_Hour_Minute        0x17
  #define ID_Second             0x18
  #define ID_Acc_X              0x24
  #define ID_Acc_Y              0x25
  #define ID_Acc_Z              0x26
  #define ID_Voltage_Amp_bp     0x3A
  #define ID_Voltage_Amp_ap     0x3B
  #define ID_Current            0x28
  // User defined data IDs
  #define ID_Gyro_X             0x40
  #define ID_Gyro_Y             0x41
  #define ID_Gyro_Z             0x42

   // Main function FrSky telemetry
    void telemetry_frsky()
   {         
      if (currentTime > FrSkyTime ) //
      {         
         FrSkyTime = currentTime + Time_telemetry_send;
         cycleCounter++;
         // Datas sent every 125 ms
            //send_Accel();
            sendDataTail();   

         if ((cycleCounter % 4) == 0)
         {     
            // Datas sent every 500ms
            send_Altitude();
            send_RPM();
            send_Course();
            send_GPS_speed();
            //send_Cell_volt();       todo
            sendDataTail();   

         }
         if ((cycleCounter % 8) == 0)
         {     
            // Datas sent every 1s           
            //send_Time();
            send_GPS_position();
            send_GPS_altitude();
            send_Temperature2();  // Distance_to_home
            //send_Fuel_level();
            send_Voltage_ampere();
            send_Temperature1();  // num of Sats
            sendDataTail();           
         }

         if (cycleCounter == 40)
         {
            // Datas sent every 5s
            cycleCounter = 0;       
         }
      }
   }

   void write_FrSky8(uint8_t Data)
   {
      SerialWrite(TELEMETRY_FRSKY_SERIAL, Data);
   }

   void write_FrSky16(uint16_t Data)
   {
      uint8_t Data_send;
      Data_send = Data;     
      check_FrSky_stuffing(Data_send);
      Data_send = Data >> 8 & 0xff;
      check_FrSky_stuffing(Data_send);
   }
   
   void check_FrSky_stuffing(uint8_t Data) //byte stuffing
   {
      if (Data == 0x5E)   
      {
         write_FrSky8(0x5D);
         write_FrSky8(0x3E);
      }
      else if (Data == 0x5D)   
      {
         write_FrSky8(0x5D);
         write_FrSky8(0x3D);
      }
      else
      {
         write_FrSky8(Data);         
      }
   }

   static void sendDataHead(uint8_t Data_id)
   {
      write_FrSky8(Protocol_Header);
      write_FrSky8(Data_id);
   }

   static void sendDataTail(void)
   {
      write_FrSky8(Protocol_Tail);     
   }


   //*********************************************************************************
   //-----------------   Telemetrie Datas   ------------------------------------------   
   //*********************************************************************************

   // GPS altitude
   void send_GPS_altitude(void)
   {         
      if (f.GPS_FIX && GPS_numSat >= 4)
      {
         int16_t Datas_GPS_altidute_bp;
         uint16_t Datas_GPS_altidute_ap;

         Datas_GPS_altidute_bp = GPS_altitude;
         Datas_GPS_altidute_ap = 0;

         sendDataHead(ID_GPS_altidute_bp);
         write_FrSky16(Datas_GPS_altidute_bp);
         sendDataHead(ID_GPS_altidute_ap);
         write_FrSky16(Datas_GPS_altidute_ap);
      }
   }
   
   // Temperature
   void send_Temperature1(void)
   {
      int16_t Datas_Temprature1;

      Datas_Temprature1 = GPS_numSat;  // Number of Satalits alias Temp1

      sendDataHead(ID_Temprature1);
      write_FrSky16(Datas_Temprature1);
   }

   // RPM
   void inline send_RPM(void)
   {
       uint16_t Data_RPM = 0;
       float rpm;

       for (uint8_t i=0; i<NUMBER_MOTOR; i++)
 {
       Data_RPM += motor[i] - MINCOMMAND;
}
       #if defined(VBAT)
       rpm = ((float) Data_RPM * (float) analog.vbat * KV_MOTOR) / ((float) NUMBER_MOTOR * 300.0 * (float) (MAXTHROTTLE - MINCOMMAND));
       #else
       rpm = ((float) Data_RPM * 120.0 * KV_MOTOR) / ((float) NUMBER_MOTOR * 300.0 * (float) (MAXTHROTTLE - MINCOMMAND));
       #endif
       Data_RPM = (uint16_t) rpm;

       sendDataHead(ID_RPM);
       write_FrSky16(Data_RPM);
}


   // Fuel level
   void send_Fuel_level(void)
   {
      uint16_t Datas_Fuel_level;

      Datas_Fuel_level = 0;

      sendDataHead(ID_Fuel_level);
      write_FrSky16(Datas_Fuel_level);
   }

   // Temperature 2
   void send_Temperature2(void)
   {
      if (f.GPS_FIX_HOME)
      {
         int16_t Datas_Temprature2;

         Datas_Temprature2 = GPS_distanceToHome; // Distance to home alias Temp2

         sendDataHead(ID_Temprature2);
         write_FrSky16(Datas_Temprature2); 
      }     
   }

   // Cell voltage  todo !!!!!!!!!!!!!!!!!!
   void send_Cell_volt(void) // Datas FrSky FLVS-01 voltage sensor
   {
      uint16_t Datas_Volt;
      uint8_t number_of_cells = 0;   // LiPo 3S = 3; LiPo 4S = 4 ...
      static uint8_t cell = 0;
      if (cell >= number_of_cells); cell = 0;
     
      Datas_Volt = 0; // 0.01v / 0 ~ 4.2v

      sendDataHead(ID_Volt);
      write_FrSky16(Datas_Volt);
   }

   // Altitude
   void send_Altitude(void)
   {
      uint16_t Datas_altitude_bp;
      uint16_t Datas_altitude_ap;
      static uint16_t Start_altitude;

      if (!f.ARMED)
      {
         Start_altitude = alt.EstAlt / 100;
      }

      Datas_altitude_bp = (alt.EstAlt / 100) - Start_altitude;
      Datas_altitude_ap = (alt.EstAlt % 100);

      sendDataHead(ID_Altitude_bp);
      write_FrSky16(Datas_altitude_bp);
      sendDataHead(ID_Altitude_ap);
      write_FrSky16(Datas_altitude_ap);
   }

   // GPS speed
   void send_GPS_speed(void)
   {
      if (f.GPS_FIX && GPS_numSat >= 4)
      {           
         uint16_t Datas_GPS_speed_bp;
         uint16_t Datas_GPS_speed_ap;
         
         Datas_GPS_speed_bp = GPS_speed * 0.036;
         Datas_GPS_speed_ap = 0;
     
         sendDataHead(ID_GPS_speed_bp);
         write_FrSky16(Datas_GPS_speed_bp);
         sendDataHead(ID_GPS_speed_ap);
         write_FrSky16(Datas_GPS_speed_ap);
      }
   }

   // GPS position
   void send_GPS_position(void)
   {
   
         uint16_t Datas_Longitude_bp;
         uint16_t Datas_Longitude_ap;
         uint16_t Datas_E_W;
         uint16_t Datas_Latitude_bp;
         uint16_t Datas_Latitude_ap;
         uint16_t Datas_N_S;
         Datas_Longitude_bp = abs(GPS_coord[LON]) / 100000;
         Datas_Longitude_ap = abs((GPS_coord[LON])/10)  % 10000;
         Datas_E_W = GPS_coord[LON] < 0 ? 'W' : 'E';
         Datas_Latitude_bp = abs(GPS_coord[LAT]) / 100000;
         Datas_Latitude_ap = abs((GPS_coord[LAT])/10) % 10000;
         Datas_N_S = GPS_coord[LAT] < 0 ? 'S' : 'N';

         sendDataHead(ID_Longitude_bp);
         write_FrSky16(Datas_Longitude_bp);
         sendDataHead(ID_Longitude_ap);
         write_FrSky16(Datas_Longitude_ap);
         sendDataHead(ID_E_W);
         write_FrSky16(Datas_E_W);

         sendDataHead(ID_Latitude_bp);
         write_FrSky16(Datas_Latitude_bp);
         sendDataHead(ID_Latitude_ap);
         write_FrSky16(Datas_Latitude_ap);
         sendDataHead(ID_N_S);
         write_FrSky16(Datas_N_S);
     
   }

   // Course
   void send_Course(void)
   {
      uint16_t Datas_Course_bp;
      uint16_t Datas_Course_ap;

      Datas_Course_bp = att.heading;
      Datas_Course_ap = 0;

      sendDataHead(ID_Course_bp);
      write_FrSky16(Datas_Course_bp);
      sendDataHead(ID_Course_ap);
      write_FrSky16(Datas_Course_ap);
   }

   // Time
   void send_Time(void)
   {
      uint32_t seconds_since_start = millis() / 1000;
           
      uint16_t Datas_Date_month;
      uint16_t Datas_Year;
      uint16_t Datas_Minutes_hours;
      uint16_t Datas_seconds;
           
      Datas_Date_month = 0;
      Datas_Year = 12;
      Datas_Minutes_hours = (seconds_since_start / 60) % 60;
      Datas_seconds = seconds_since_start % 60;     
     
      sendDataHead(ID_Hour_Minute);
      write_FrSky16(Datas_Minutes_hours);
      sendDataHead(ID_Second);
      write_FrSky16(Datas_seconds);
   }

   // ACC
   /*void send_Accel(void)
   {
      int16_t Datas_Acc_X;
      int16_t Datas_Acc_Y;
      int16_t Datas_Acc_Z;

      Datas_Acc_X = ((float)accSmooth[0] / acc_1G) * 1000;
      Datas_Acc_Y = ((float)accSmooth[1] / acc_1G) * 1000;
      Datas_Acc_Z = ((float)accSmooth[2] / acc_1G) * 1000;

      sendDataHead(ID_Acc_X);
      write_FrSky16(Datas_Acc_X);
      sendDataHead(ID_Acc_Y);
      write_FrSky16(Datas_Acc_Y);
      sendDataHead(ID_Acc_Z);
      write_FrSky16(Datas_Acc_Z);     
   }*/

   // Voltage (Ampere Sensor) 
   void send_Voltage_ampere(void)
   {
   
      #if defined (FAS_100)   // todo   !!!!!!!!!!!!!!!!!
      {
         uint16_t Datas_Voltage_Amp_bp;
         uint16_t Datas_Voltage_Amp_ap;
         uint16_t Datas_Current;   

         Datas_Voltage_Amp_bp = 0;
         Datas_Voltage_Amp_ap = 0;   
         Datas_Current = 0;

         sendDataHead(ID_Voltage_Amp_bp);
         write_FrSky16(Datas_Voltage_Amp_bp);
         sendDataHead(ID_Voltage_Amp_ap);
         write_FrSky16(Datas_Voltage_Amp_ap);   
         sendDataHead(ID_Current);
         write_FrSky16(Datas_Current);
      }
      #else   // use vBat
      {
         uint16_t Datas_Voltage_vBat_bp;
         uint16_t Datas_Voltage_vBat_ap;   
         uint16_t voltage;
         voltage = (vbat * 110) / 21;         
         Datas_Voltage_vBat_bp = voltage / 100;
         Datas_Voltage_vBat_ap = ((voltage % 100) + 5) / 10;         

         sendDataHead(ID_Voltage_Amp_bp);
         write_FrSky16(Datas_Voltage_vBat_bp);
         sendDataHead(ID_Voltage_Amp_ap);
         write_FrSky16(Datas_Voltage_vBat_ap);   
      }
      #endif
   }

#endif


on main.ino (e.g) line 620

Code: Select all

#if defined(TELEMETRY_FRSKY) 
   telemetry_frsky();
  #endif



config.h (e.g) line 830

Code: Select all

    
  /********************************************************************/
  /********                   FrSky  telemetry                *********/
  /********************************************************************/
    #define TELEMETRY_FRSKY
    #define KV_MOTOR 1120.0       // kv of motors in rpm/V
   




It includes already the Quadbow RPM mod ;) not tested yet because I am with no time at all but it will compile just fine so, you tell me how it went :D

Fly safe.
Cheers,
KV

fadz
Posts: 2
Joined: Wed Apr 10, 2013 8:17 pm

Re: Direct Frsky telemtry data from MW FC

Post by fadz »

Here is the newst sketch comaptible with r1413 and with MultiWiiEzGui

Also flight tested with Turnigy 9xr and FrSky Telemetry Module.

Code: Select all

// ****************************************************************
// FrSky telemetry
// Version: 0.2.2
// Date 7/10/2012
// Changes: V0.2.2: - corrected ID_Course_ap is 0x1C not 0x24 protocol says 0x14+8
// Date 20/09/2012
// Changes: V0.2.1: - make it work with 2.1 (shared dev)
// Date: 14/08/2012
// Changes: V0.2: - Byte stuffing added
//                - vBat will be send, if "#define FAS_100" is comment out
//                V0.1: - First release
// ****************************************************************

#if defined(TELEMETRY_FRSKY)
  // user defines
  //#define FAS_100  //if commment out, MultiWii vBat voltage will be send instead of FrSky FAS 100 voltage


  // Serial config datas
  #define TELEMETRY_FRSKY_SERIAL 3
  #define TELEMETRY_FRSKY_BAUD 9600 

  // Timing
  #define Time_telemetry_send 125000
  static uint8_t cycleCounter = 0;
  static uint32_t FrSkyTime  = 0;

  // Frame protocol
  #define Protocol_Header   0x5E
  #define Protocol_Tail      0x5E
 
 
  // Data Ids  (bp = before point; af = after point)
  // Official data IDs
  #define ID_GPS_altidute_bp    0x01
  #define ID_GPS_altidute_ap    0x09
  #define ID_Temprature1        0x02
  #define ID_RPM                0x03
  #define ID_Fuel_level         0x04
  #define ID_Temprature2        0x05
  #define ID_Volt               0x06
  #define ID_Altitude_bp        0x10
  #define ID_Altitude_ap        0x21
  #define ID_GPS_speed_bp       0x11
  #define ID_GPS_speed_ap       0x19
  #define ID_Longitude_bp       0x12
  #define ID_Longitude_ap       0x1A
  #define ID_E_W                0x22
  #define ID_Latitude_bp        0x13
  #define ID_Latitude_ap        0x1B
  #define ID_N_S                0x23
  #define ID_Course_bp          0x14
  #define ID_Course_ap          0x24
  #define ID_Date_Month         0x15
  #define ID_Year               0x16
  #define ID_Hour_Minute        0x17
  #define ID_Second             0x18
  #define ID_Acc_X              0x24
  #define ID_Acc_Y              0x25
  #define ID_Acc_Z              0x26
  #define ID_Voltage_Amp_bp     0x3A
  #define ID_Voltage_Amp_ap     0x3B
  #define ID_Current            0x28
  // User defined data IDs
  #define ID_Gyro_X             0x40
  #define ID_Gyro_Y             0x41
  #define ID_Gyro_Z             0x42

  //Multiwii EZ-GUI
  #define ID_Ang_X             0x50
  #define ID_Ang_Y             0x51
  #define ID_Ang_Z             0x52

   // Main function FrSky telemetry
    void telemetry_frsky()
   {         
      if (currentTime > FrSkyTime ) //
      {         
         FrSkyTime = currentTime + Time_telemetry_send;
         cycleCounter++;
         // Datas sent every 125 ms
            send_Accel();
            sendAngles();
            sendDataTail();   

         if ((cycleCounter % 4) == 0)
         {     
            // Datas sent every 500ms
            send_Altitude();
            send_RPM();
            send_Course();
            send_GPS_speed();
            //send_Cell_volt();       todo
            sendDataTail();   

         }
         if ((cycleCounter % 8) == 0)
         {     
            // Datas sent every 1s           
            //send_Time();
            send_GPS_position();
            send_GPS_altitude();
            send_Temperature2();  // Distance_to_home
            //send_Fuel_level();
            send_Voltage_ampere();
            send_Temperature1();  // num of Sats
            sendDataTail();           
         }

         if (cycleCounter == 40)
         {
            // Datas sent every 5s
            cycleCounter = 0;       
         }
      }
   }

   void write_FrSky8(uint8_t Data)
   {
      SerialWrite(TELEMETRY_FRSKY_SERIAL, Data);
   }

   void write_FrSky16(uint16_t Data)
   {
      uint8_t Data_send;
      Data_send = Data;     
      check_FrSky_stuffing(Data_send);
      Data_send = Data >> 8 & 0xff;
      check_FrSky_stuffing(Data_send);
   }
   
   void check_FrSky_stuffing(uint8_t Data) //byte stuffing
   {
      if (Data == 0x5E)   
      {
         write_FrSky8(0x5D);
         write_FrSky8(0x3E);
      }
      else if (Data == 0x5D)   
      {
         write_FrSky8(0x5D);
         write_FrSky8(0x3D);
      }
      else
      {
         write_FrSky8(Data);         
      }
   }

   static void sendDataHead(uint8_t Data_id)
   {
      write_FrSky8(Protocol_Header);
      write_FrSky8(Data_id);
   }

   static void sendDataTail(void)
   {
      write_FrSky8(Protocol_Tail);     
   }


   //*********************************************************************************
   //-----------------   Telemetrie Datas   ------------------------------------------   
   //*********************************************************************************

   // GPS altitude
   void send_GPS_altitude(void)
   {         
      if (f.GPS_FIX && GPS_numSat >= 4)
      {
         int16_t Datas_GPS_altidute_bp;
         uint16_t Datas_GPS_altidute_ap;

         Datas_GPS_altidute_bp = GPS_altitude;
         Datas_GPS_altidute_ap = 0;

         sendDataHead(ID_GPS_altidute_bp);
         write_FrSky16(Datas_GPS_altidute_bp);
         sendDataHead(ID_GPS_altidute_ap);
         write_FrSky16(Datas_GPS_altidute_ap);
      }
   }
   
   // Temperature
   void send_Temperature1(void)
   {
      int16_t Datas_Temprature1;

      Datas_Temprature1 = GPS_numSat;  // Number of Satalits alias Temp1

      sendDataHead(ID_Temprature1);
      write_FrSky16(Datas_Temprature1);
   }

   // RPM
   void inline send_RPM(void)
   {
       uint16_t Data_RPM = 0;
       float rpm;

       for (uint8_t i=0; i<NUMBER_MOTOR; i++)
 {
       Data_RPM += motor[i] - MINCOMMAND;
}
       #if defined(VBAT)
       rpm = ((float) Data_RPM * (float) analog.vbat * KV_MOTOR) / ((float) NUMBER_MOTOR * 300.0 * (float) (MAXTHROTTLE - MINCOMMAND));
       #else
       rpm = ((float) Data_RPM * 120.0 * KV_MOTOR) / ((float) NUMBER_MOTOR * 300.0 * (float) (MAXTHROTTLE - MINCOMMAND));
       #endif
       Data_RPM = (uint16_t) rpm;

       sendDataHead(ID_RPM);
       write_FrSky16(Data_RPM);
}


   // Fuel level
   void send_Fuel_level(void)
   {
      uint16_t Datas_Fuel_level;

      Datas_Fuel_level = 0;

      sendDataHead(ID_Fuel_level);
      write_FrSky16(Datas_Fuel_level);
   }

   // Temperature 2
   void send_Temperature2(void)
   {
      if (f.GPS_FIX_HOME)
      {
         int16_t Datas_Temprature2;

         Datas_Temprature2 = GPS_distanceToHome; // Distance to home alias Temp2

         sendDataHead(ID_Temprature2);
         write_FrSky16(Datas_Temprature2); 
      }     
   }

   // Cell voltage  todo !!!!!!!!!!!!!!!!!!
   void send_Cell_volt(void) // Datas FrSky FLVS-01 voltage sensor
   {
      uint16_t Datas_Volt;
      uint8_t number_of_cells = 0;   // LiPo 3S = 3; LiPo 4S = 4 ...
      static uint8_t cell = 0;
      if (cell >= number_of_cells); cell = 0;
     
      Datas_Volt = 0; // 0.01v / 0 ~ 4.2v

      sendDataHead(ID_Volt);
      write_FrSky16(Datas_Volt);
   }

   // Altitude
   void send_Altitude(void)
   {
      uint16_t Datas_altitude_bp;
      uint16_t Datas_altitude_ap;
      static uint16_t Start_altitude;

      if (!f.ARMED)
      {
         Start_altitude = alt.EstAlt / 100;
      }

      Datas_altitude_bp = (alt.EstAlt / 100) - Start_altitude;
      Datas_altitude_ap = (alt.EstAlt % 100);

      sendDataHead(ID_Altitude_bp);
      write_FrSky16(Datas_altitude_bp);
      sendDataHead(ID_Altitude_ap);
      write_FrSky16(Datas_altitude_ap);
   }

   // GPS speed
   void send_GPS_speed(void)
   {
      if (f.GPS_FIX && GPS_numSat >= 4)
      {           
         uint16_t Datas_GPS_speed_bp;
         uint16_t Datas_GPS_speed_ap;
         
         Datas_GPS_speed_bp = GPS_speed * 0.036;
         Datas_GPS_speed_ap = 0;
     
         sendDataHead(ID_GPS_speed_bp);
         write_FrSky16(Datas_GPS_speed_bp);
         sendDataHead(ID_GPS_speed_ap);
         write_FrSky16(Datas_GPS_speed_ap);
      }
   }

   // GPS position
   void send_GPS_position(void)
   {
   
         uint16_t Datas_Longitude_bp;
         uint16_t Datas_Longitude_ap;
         uint16_t Datas_E_W;
         uint16_t Datas_Latitude_bp;
         uint16_t Datas_Latitude_ap;
         uint16_t Datas_N_S;
         Datas_Longitude_bp = abs(GPS_coord[LON]) / 100000;
         Datas_Longitude_ap = abs((GPS_coord[LON])/10)  % 10000;
         Datas_E_W = GPS_coord[LON] < 0 ? 'W' : 'E';
         Datas_Latitude_bp = abs(GPS_coord[LAT]) / 100000;
         Datas_Latitude_ap = abs((GPS_coord[LAT])/10) % 10000;
         Datas_N_S = GPS_coord[LAT] < 0 ? 'S' : 'N';

         sendDataHead(ID_Longitude_bp);
         write_FrSky16(Datas_Longitude_bp);
         sendDataHead(ID_Longitude_ap);
         write_FrSky16(Datas_Longitude_ap);
         sendDataHead(ID_E_W);
         write_FrSky16(Datas_E_W);

         sendDataHead(ID_Latitude_bp);
         write_FrSky16(Datas_Latitude_bp);
         sendDataHead(ID_Latitude_ap);
         write_FrSky16(Datas_Latitude_ap);
         sendDataHead(ID_N_S);
         write_FrSky16(Datas_N_S);
     
   }

   // Course
   void send_Course(void)
   {
      uint16_t Datas_Course_bp;
      uint16_t Datas_Course_ap;

      Datas_Course_bp = att.heading;
      Datas_Course_ap = 0;

      sendDataHead(ID_Course_bp);
      write_FrSky16(Datas_Course_bp);
      sendDataHead(ID_Course_ap);
      write_FrSky16(Datas_Course_ap);
   }

   // Time
   void send_Time(void)
   {
      uint32_t seconds_since_start = millis() / 1000;
           
      uint16_t Datas_Date_month;
      uint16_t Datas_Year;
      uint16_t Datas_Minutes_hours;
      uint16_t Datas_seconds;
           
      Datas_Date_month = 0;
      Datas_Year = 12;
      Datas_Minutes_hours = (seconds_since_start / 60) % 60;
      Datas_seconds = seconds_since_start % 60;     
     
      sendDataHead(ID_Hour_Minute);
      write_FrSky16(Datas_Minutes_hours);
      sendDataHead(ID_Second);
      write_FrSky16(Datas_seconds);
   }

   // ACC
   void send_Accel(void)
   {
      int16_t Datas_Acc_X;
      int16_t Datas_Acc_Y;
      int16_t Datas_Acc_Z;

      Datas_Acc_X = ((float)imu.accSmooth[0] / ACC_1G) * 1000;
      Datas_Acc_Y = ((float)imu.accSmooth[1] / ACC_1G) * 1000;
      Datas_Acc_Z = ((float)imu.accSmooth[2] / ACC_1G) * 1000;

      sendDataHead(ID_Acc_X);
      write_FrSky16(Datas_Acc_X);
      sendDataHead(ID_Acc_Y);
      write_FrSky16(Datas_Acc_Y);
      sendDataHead(ID_Acc_Z);
      write_FrSky16(Datas_Acc_Z);     
   }

   // angles EZ-GUI
   void sendAngles(void)
   {
       int16_t Datas_Ang_X;
       int16_t Datas_Ang_Y;
       int16_t Datas_Acc_Z;

       Datas_Ang_X = angle[0];//((float)accSmooth[0] / acc_1G) * 1000;
       Datas_Ang_Y = angle[1];//((float)accSmooth[1] / acc_1G) * 1000;
       Datas_Acc_Z = angle[2];//((float)accSmooth[2] / acc_1G) * 1000;

       sendDataHead(ID_Ang_X);
       write_FrSky16(Datas_Ang_X);
       sendDataHead(ID_Ang_Y);
       write_FrSky16(Datas_Ang_Y);
       sendDataHead(ID_Acc_Z);
       write_FrSky16(Datas_Acc_Z);     
   }

   // Voltage (Ampere Sensor) 
   void send_Voltage_ampere(void)
   {
   
      #if defined (FAS_100)   // todo   !!!!!!!!!!!!!!!!!
      {
         uint16_t Datas_Voltage_Amp_bp;
         uint16_t Datas_Voltage_Amp_ap;
         uint16_t Datas_Current;   

         Datas_Voltage_Amp_bp = 0;
         Datas_Voltage_Amp_ap = 0;   
         Datas_Current = 0;

         sendDataHead(ID_Voltage_Amp_bp);
         write_FrSky16(Datas_Voltage_Amp_bp);
         sendDataHead(ID_Voltage_Amp_ap);
         write_FrSky16(Datas_Voltage_Amp_ap);   
         sendDataHead(ID_Current);
         write_FrSky16(Datas_Current);
      }
      #else   // use vBat
      {
         uint16_t Datas_Voltage_vBat_bp;
         uint16_t Datas_Voltage_vBat_ap;   
         uint16_t voltage;
         voltage = (analog.vbat * 110) / 21;         
         Datas_Voltage_vBat_bp = voltage / 100;
         Datas_Voltage_vBat_ap = ((voltage % 100) + 5) / 10;         

         sendDataHead(ID_Voltage_Amp_bp);
         write_FrSky16(Datas_Voltage_vBat_bp);
         sendDataHead(ID_Voltage_Amp_ap);
         write_FrSky16(Datas_Voltage_vBat_ap);   
      }
      #endif
   }

#endif

kataventos
Posts: 702
Joined: Sun Aug 28, 2011 8:14 pm
Contact:

Re: Direct Frsky telemtry data from MW FC

Post by kataventos »

Hi fadz,

:roll: was not the posted sketch compatible with latest dev? I think that it is even without time to test it, but... it was nice of you to paste the "angles EZ-GUI" patch for the ones that have some "unreal" need for it.
Do not consume time useful for real flight features and needs!

Have fun and fly safe,
KV

QuadBow
Posts: 532
Joined: Fri Jan 04, 2013 10:06 am

Re: Direct Frsky telemtry data from MW FC

Post by QuadBow »

kataventos wrote:was not the posted sketch compatible with latest dev?

The code is actually quite independend of the mw version/release, since the whole design and the serial functions have not been changed.
Only a change of variables and parameters would have an impact, but that could be handled easily.

I propose to simplify the code in telemetry.ino in order to lighten this function:

Code: Select all

   // RPM
   void inline send_RPM(void)
   {
      uint16_t Data_RPM = 0;
     
      Data_RPM = rpm;

      sendDataHead(ID_RPM);
      write_FrSky16(Data_RPM);
   }


The relevant calculation are done in the annexCode section in multiwii.ino. The advantage is a reduction of the cycletime since the code should fit into the free part of the 650us timeframe. For this, rpm has to be defined at the beginning of multiwii.ino.

Code: Select all

static uint16_t rpm = 0


I improved the code taking care of the voltage drop caused by resistances of the motors, which have to be defined in milliohm in config.h:
#define R_MOTOR 162 // resistance of 0.162 ohm for one motor measured from one connector to the other
Note, that the changed code will only taken into account if a powermeter/current sensor is available and configured properly.
As a result, the displayed speed will be lower than before, but it will be more realistic.

Code: Select all

  #if defined(KV_MOTOR) 
    uint16_t vdelta = 0;
    float    frpm;
    for (uint8_t i=0; i<NUMBER_MOTOR; i++)
        {
        rpm += motor[i] - MINCOMMAND;
        }
  if (vbat > 50) {
     #if defined(POWERMETER)
         vdelta = ((R_MOTOR / NUMBER_MOTOR) * pCurrent) / 10000;
     #endif
     #if defined(VBAT)
         frpm = ((float) rpm * (float) (vbat - vdelta) * KV_MOTOR) / ((float) NUMBER_MOTOR * 300.0 * (float) (MAXTHROTTLE - MINCOMMAND));
     #else
         frpm = ((float) rpm * VBATNOMINAL * KV_MOTOR) / ((float) NUMBER_MOTOR * 300.0 * (float) (MAXTHROTTLE - MINCOMMAND));
     #endif
     rpm = (uint16_t) frpm;
     } else {
     rpm = 0;
     }
  debug[1] = 30 * rpm; // displays the speed in rotations per minute as debug-info
  #endif


For the current variable, you have to declare

Code: Select all

  static uint16_t pCurrent;
and to calculate it in

Code: Select all

  #if defined(POWERMETER_HARD)
    uint16_t pMeterRaw;               // used for current reading
    static uint16_t psensorTimer = 0;
    if (! (++psensorTimer % PSENSORFREQ)) {
      pMeterRaw =  analogRead(PSENSORPIN);
      //lcdprint_int16(pMeterRaw); LCDcrlf();
      powerValue = ( conf.psensornull > pMeterRaw ? conf.psensornull - pMeterRaw : pMeterRaw - conf.psensornull); // do not use abs(), it would induce implicit cast to uint and overrun
      if ( powerValue < I_MAX) {  // only accept reasonable values.
      #ifdef LCD_TELEMETRY
        if (powerValue > powerMax) powerMax = powerValue;
      #endif
      } else {
        powerValue = I_MAX;
      }       
      pCurrent = (powerValue * PINT2mA + 7 * pCurrent) / 8;  // result in 0.01A steps and filter
      pMeter[PMOTOR_SUM] += (uint32_t) powerValue;
    }
  #endif


Furthermore, we need to define I_MAX in config.h. Originally the value 333 was written in the code. It is the maximum current value, which depends on the current sensor. So, I set I_MAX to 675 in order to cover the full range of 3,3V at 90A for my current sensor.
Last edited by QuadBow on Sun Apr 28, 2013 5:33 pm, edited 2 times in total.

kataventos
Posts: 702
Joined: Sun Aug 28, 2011 8:14 pm
Contact:

Re: Direct Frsky telemtry data from MW FC

Post by kataventos »

OK I see that you have been really around it lately, good catch for the annex code on multiwii.ino. The improvement on the RPM function also excellent since you were meticulous to inclusive measure the impedance of the connectors... Did you compared the layout with an RPM meter also? It should be a nice way to tune it for accuracy.

As I use only ER9X and (at least on my version) do not seem to have the chance to see current consumption so never looked much to that function. Anyway, good work then, it seems that tomorrow I will have the chance to test it (had lots of work on past week).

KV

QuadBow
Posts: 532
Joined: Fri Jan 04, 2013 10:06 am

Re: Direct Frsky telemtry data from MW FC

Post by QuadBow »

Depending on the resolution of the current sensor an overrun might happen when calculating vdelta. Thus, I improved the code as follows:

Code: Select all

     #if defined(KV_MOTOR)
        uint16_t vdelta = 0;
        float    frpm;
        for (uint8_t i=0; i<NUMBER_MOTOR; i++)
            {
            rpm += motor[i] - MINCOMMAND;
            }
      if (vbat > 50) {
         #if defined(POWERMETER)
             vdelta = (uint8_t) (((R_MOTOR / NUMBER_MOTOR) * ((pCurrent - pCurInit) / 10)) / 1000);
             //vdelta = ((R_MOTOR / NUMBER_MOTOR) * pCurrent) / 10000;
         #endif
         #if defined(VBAT)
             frpm = ((float) rpm * (float) (vbat - vdelta) * KV_MOTOR) / ((float) NUMBER_MOTOR * 300.0 * (float) (MAXTHROTTLE - MINCOMMAND));
         #else
             frpm = ((float) rpm * VBATNOMINAL * KV_MOTOR) / ((float) NUMBER_MOTOR * 300.0 * (float) (MAXTHROTTLE - MINCOMMAND));
         #endif
         rpm = (uint16_t) frpm;
         } else {
         rpm = 0;
         }
      debug[1] = 30 * rpm; // displays the speed in rotations per minute as debug-info
      #endif

You will notice that there is an additional variable called pCurInit. This is the current consumption of the board, ESCs, and LEDs that is being subtracted. (It's only 0.2A for my board, so the difference in speed shouldn't be too much.)
For this you need to declare pCurInit at the same place as pCurrent (top of multiwii.ino)

Code: Select all

  static uint16_t pCurrent;                // current in 0.01A steps
  static uint16_t pCurInit = 0;            // current at arming

and to set up the value when arming (top of the function go_arm)

Code: Select all

inline void go_arm() {
  if(calibratingG == 0 && f.ACC_CALIBRATED
  #if defined(FAILSAFE)
    && failsafeCnt < 2
  #endif
    ) {
    if(!f.ARMED) { // arm now!
      f.ARMED = 1;
      headFreeModeHold = heading;
      #if defined(VBAT)
        if (vbat > conf.no_vbat) vbatMin = vbat;
      #endif
      #if defined (POWERMETER)
        pCurInit = pCurrent;
      #endif
     ...............

kataventos wrote:Did you compared the layout with an RPM meter also?

I don't have a RPM meter available. But, the provement with an oscilloscope shows (very rough) that the values fit to each other.
Despite all effort the RPM calculation will remain a estimate, since
- the measurement of vbat is noisy,
- the measurement of pCurrent is noisy,
- the resistances depend on the temperature
- we can only calculate an average RPM value of all motors
Thus, the benefit is more to gain a rough idea whether the speed range is appropriate and to detect the voltage lowering of the accu.
A more precise calculation could be done in the future by a bidirectional ESC protocol since each ESC knows the speed of the attached motor.

mysku82
Posts: 17
Joined: Wed Oct 12, 2011 7:32 am
Location: Bucharest, Romania
Contact:

Re: Direct Frsky telemtry data from MW FC

Post by mysku82 »

@kataventos

Thanks for help me
We introduced new settings and is ok. I was terrible at the modified code in arduino

Thanks

Best Regards
Cosmin Miscu

kataventos
Posts: 702
Joined: Sun Aug 28, 2011 8:14 pm
Contact:

Re: Direct Frsky telemtry data from MW FC

Post by kataventos »

mysku82 wrote:@kataventos

Thanks for help me
We introduced new settings and is ok. I was terrible at the modified code in arduino



Great ;) but you should use latest developments from QuadBow, he is really deep on lightening this up !

KV

EDIT: I am sure he is going to post detailed instructions for you and all users with some difficult on that matter :geek: because the steps have changed a little inclusive on MW code with some more adds. I could do that but, it is he´s credit´s :mrgreen: Awesome work.

mysku82
Posts: 17
Joined: Wed Oct 12, 2011 7:32 am
Location: Bucharest, Romania
Contact:

Re: Direct Frsky telemtry data from MW FC

Post by mysku82 »

@kataventos, @QuadBow
If you have time maybe you can help me with the code ready , with the latest changes from QuadBow

Thanks

Best Regards
Cosmin Miscu

iksbob
Posts: 3
Joined: Sat Apr 06, 2013 3:56 am

Re: Direct Frsky telemtry data from MW FC

Post by iksbob »

mysku82 wrote:@kataventos, @QuadBow
If you have time maybe you can help me with the code ready , with the latest changes from QuadBow
Yes please. The development process is a bit hard to follow and I'm getting compile errors when I try the last "full sketch". A fresh copy of the files and code additions needed to go from a fresh copy of 2.2 to a fairly current state of development would be awesome.

QuadBow
Posts: 532
Joined: Fri Jan 04, 2013 10:06 am

Re: Direct Frsky telemtry data from MW FC

Post by QuadBow »

mysku82 wrote:If you have time maybe you can help me with the code ready


As requested I make my changes available to those who are interested. Firstly, I would like to mention that my changes are not part of the official distribution. Thus, they are not tested to the most possible extend. Even if it is quite unlikely, that the telemetry integration results into unwanted flight situations or risks or damages, I would like to make you aware, that the integration will be done on your own risk.

You need following hardware:
- FRSKY telemetry transmitter and receiver ( http://www.frsky-rc.com/Products.asp?BigClassID=17 )
- an Mega Board based upon an Atmega 2560 (like the one I own http://flyduino.net/Flyduino-MEGA-Flight-Controller-CPU-Board )
- recommended: a display compatible with FRSKY telemetry (FLD-02 http://www.hobbyking.com/hobbyking/stor ... creen.html )
- optional: a current sensor (like http://www.rctimer.com/index.php?gOo=goods_details.dwt&goodsid=861&productname= )

In the attachment you find the mw release 2.2 with one added file ( telemetry.ino) and 2 changed files.
The file multiwii2_2.ino was changed regarding telemetry at four places, all changes are controled via TELEMETRY_FRSKY definitions.
It is defined in config.h:
#define TELEMETRY_FRSKY
#define TELEMETRY_FRSKY_SERIAL 3
#define KV_MOTOR 1000.0 // KV = RPM per Volt
#define R_MOTOR 162 // resistance of each motor in milliohm
If you comment out KV_MOTOR the average motor speed (rpm) will not be displayed.

For consideration of the actual voltage it is recommended to measure the voltage via
#define VBAT
You have to finetune the value VBATSCALE in order to receive the proper voltage.
In order to use the new value VBATSCALE you have to clean the EEPROM.
Remark: FRSKY telemetry receivers can receive the voltage directly without multiwii for displaying.
Without defining VBAT and measuring vbat the rpm will not be that accurate.

For better results, you can also measure and use he current by defining POWERMETER_HARD (with the appropriate hardware, of course) or
POWERMETER_SOFT (not integrated yet). An explanation of how to set up the parameters can be found here: http://www.multiwii.com/wiki/index.php?title=Powermeter In order to use the new parameters you have to clean the EEPROM again.

Have fun!
Attachments
MultiWii2_2.zip
FRSKY telemetry integration
- compatible with display FLD-02
- improved speed (to be sent in knots)
- optimized scheduler
- counts arming time
- displays numbers of satellites as fuel bar
- instead of altitude the distance to home can be displayed
- integration of VBAT and POWERMETER
QuadBow
(141.23 KiB) Downloaded 1621 times

MattC
Posts: 1
Joined: Thu May 02, 2013 7:48 am

Re: Direct Frsky telemtry data from MW FC

Post by MattC »

Hi QuadBow,

It would make my week if you could use the unused RX from the serial port that was sending data to the Frsky Receiver to receive data from to a Frsky FAS-100 current/voltage sensor. It is the same protocol as the FAS-100 connects in the same way using the serial port on the side of the RX. This would make the use of the analogue inputs for voltage etc redundant and keep it clean.

What do you think ?

Matt

QuadBow
Posts: 532
Joined: Fri Jan 04, 2013 10:06 am

Re: Direct Frsky telemtry data from MW FC

Post by QuadBow »

MattC wrote:It would make my week if you could use the unused RX from the serial port that was sending data to the Frsky Receiver to receive data from to a Frsky FAS-100 current/voltage sensor.


I understand you well, but I don't own a FAS-100 and I don't intend to buy one, neither. Without testing equipment it is very hard to develop such a quite complex functionality. Maybe someone else is interested and able to code it.

MattC wrote:What do you think ?

I think its worth to try.

Fastrack
Posts: 23
Joined: Tue May 14, 2013 5:36 am

Re: Direct Frsky telemtry data from MW FC

Post by Fastrack »

Hi,

I'm building my first quad.. I'm going with a witespy multiwii ez3. I was going to get a OrangeRX module/receiver for the 9xr until I read about signal quality issues. So I decided to go with Frsky..!

I've read this entire thread... I can't wait to try this. I'm getting a 9xr. Any idea what happened to tobi86? It seems he was working on the lipo sensor and current sensor on RX serial port 3. The code seems to still say todo, but the fas100 section has been removed completely? Is it not possible to do?

Quadbow I understand you do not have an FAS-100, so can not test it. How does the amp sensor you posted a link to from RCTimer connect to the Multiwii?

Thanks

Ben

QuadBow
Posts: 532
Joined: Fri Jan 04, 2013 10:06 am

Re: Direct Frsky telemtry data from MW FC

Post by QuadBow »

Fastrack wrote:How does the amp sensor you posted a link to from RCTimer connect to the Multiwii?

The current sensor at http://rctimer.com/index.php?gOo=goodsp ... oodsid=861 does have a GND pin, a voltage pin, and a current pin.
The Gnd pin has to be connected to the multiwii board Gnd.
The voltage pin has to be connected to A0, in order to make it work you have to define VBAT and set up the related parameters.
The current pin has to be connected to A2, in order to make it work you have to define POWERMETER and set up the related parameters.

Don't forget the level shifter (shown at viewtopic.php?f=7&t=1929&start=10 ) between multiwii board and telemetry input of the receiver.

Fastrack
Posts: 23
Joined: Tue May 14, 2013 5:36 am

Re: Direct Frsky telemtry data from MW FC

Post by Fastrack »

QuadBow wrote:
Fastrack wrote:How does the amp sensor you posted a link to from RCTimer connect to the Multiwii?

The current sensor at http://rctimer.com/index.php?gOo=goodsp ... oodsid=861 does have a GND pin, a voltage pin, and a current pin.
The Gnd pin has to be connected to the multiwii board Gnd.
The voltage pin has to be connected to A0, in order to make it work you have to define VBAT and set up the related parameters.
The current pin has to be connected to A2, in order to make it work you have to define POWERMETER and set up the related parameters.

Don't forget the level shifter (shown at viewtopic.php?f=7&t=1929&start=10 ) between multiwii board and telemetry input of the receiver.


I looked at the code and looks straight forward. However I'm not quite sure how the parameters for VBAT and POWERMETER work .. ie what do the values mean. But I'll do some more reading to see if I can figure it out.

The current/voltage sensor from RCTimer seems to eliminate the need for the FAS-100 and the Lipo Sensor?? (except the lipo shows per cell voltage..)

Thanks for the heads up on the level shifter. I was going to build the one shown as a schematic earlier in the thread.. Unless you recommend something else?
viewtopic.php?f=7&t=1929&start=70#p26160

Ben

QuadBow
Posts: 532
Joined: Fri Jan 04, 2013 10:06 am

Re: Direct Frsky telemtry data from MW FC

Post by QuadBow »

Fastrack wrote:However I'm not quite sure how the parameters for VBAT and POWERMETER work .. ie what do the values mean.

That's explained in the file "config.h":

Code: Select all

/* for V BAT monitoring
after the resistor divisor we should get [0V;5V]->[0;1023] on analog V_BATPIN
with R1 and R2
vbat = [0;1023]*16/VBATSCALE
must be associated with #define BUZZER ! */

Thus, you have to choose VBATSCALE in a way that a battery voltage of e.g. 12.6V results to 126.
You have to take into account the voltage devider in order to receive a specific adc value in the range from 0 to 1023.
This value should be multiplied by 16 and divided by VBATSCALE to get the required value of 126.

Setting up the powermeter is explained here http://www.multiwii.com/wiki/index.php?title=Powermeter .

Recall to reset the eeprom via multiwiiconf after having loaded the code with the changed parameters in order to enable them.

Fastrack wrote:The current/voltage sensor from RCTimer seems to eliminate the need for the FAS-100 and the Lipo Sensor??

Right, you save the FAS-100 and the effort to integrate it into multiwii.
Fastrack wrote:(except the lipo shows per cell voltage..)

However, you need another module FLVS-01 http://www.frsky-rc.com/ShowProducts.asp?id=111 to get the lipo voltages per cell.
You can also replace the FLVS-01 by some resistors (wired as voltage dividers) if you have two additional adc channels available (for an battery with three cells). However, the code has to be extended, since this part is still mentioned as "todo" in the file "telemetry.ino".

Code: Select all

// Cell voltage  todo !!!!!!!!!!!!!!!!!!
void inline send_Cell_volt(void) // Data FrSky FLVS-01 voltage sensor
{
   uint16_t Data_Volt;
   uint8_t number_of_cells = 0;   // LiPo 3S = 3; LiPo 4S = 4 ...
   static uint8_t cell = 0;

   if (cell >= number_of_cells)
      cell = 0;
   Data_Volt = 0; // 0.01v / 0 ~ 4.2v
   sendDataHead(ID_Volt);
   write_FrSky16(Data_Volt);
}

Fastrack
Posts: 23
Joined: Tue May 14, 2013 5:36 am

Re: Direct Frsky telemtry data from MW FC

Post by Fastrack »

QuadBow wrote:That's explained in the file "config.h":

Code: Select all

/* for V BAT monitoring
after the resistor divisor we should get [0V;5V]->[0;1023] on analog V_BATPIN
with R1 and R2
vbat = [0;1023]*16/VBATSCALE
must be associated with #define BUZZER ! */


Thus, you have to choose VBATSCALE in a way that a battery voltage of e.g. 12.6V results to 126.
You have to take into account the voltage devider in order to receive a specific adc value in the range from 0 to 1023.
This value should be multiplied by 16 and divided by VBATSCALE to get the required value of 126.


Yes I saw those settings. In config.h right now the value for VBATSCALE is 131. I guess the idea is.. you run the flight controller/receiver see what the voltage output is.. and compare it to real world using a Volt Meter?

QuadBow wrote:Setting up the powermeter is explained here http://www.multiwii.com/wiki/index.php?title=Powermeter .
Recall to reset the eeprom via multiwiiconf after having loaded the code with the changed parameters in order to enable them.


Looks straight forward.

QuadBow wrote:However, you need another module FLVS-01 http://www.frsky-rc.com/ShowProducts.asp?id=111 to get the lipo voltages per cell.
You can also replace the FLVS-01 by some resistors (wired as voltage dividers) if you have two additional adc channels available (for an battery with three cells). However, the code has to be extended, since this part is still mentioned as "todo" in the file "telemetry.ino".


Per cell voltage is not that much of a concern to me. They *should all drain equally... Pack voltage I think is more important, as my balanced charger will tell me if the battery is failing.

I guess all this eliminates the need for the FrSky sensor hub! Woohoo

I'm sure I'll have more questions once I actually get my flight controller and start using it.

Ben

kataventos
Posts: 702
Joined: Sun Aug 28, 2011 8:14 pm
Contact:

Re: Direct Frsky telemtry data from MW FC

Post by kataventos »

Fastrack wrote: Unless you recommend something else?
viewtopic.php?f=7&t=1929&start=70#p26160

Ben



Hi Ben,

that is the one a still use since that post and it is fitted in a tiny shrink tube , works just fine! but... there are other small and ready to go solutions as you may know at this time!
I am naturally a DIY´r so... before buy I look at my "junk" and search for the parts I need :D

Have fun,
KV

QuadBow
Posts: 532
Joined: Fri Jan 04, 2013 10:06 am

Re: Direct Frsky telemtry data from MW FC

Post by QuadBow »

Fastrack wrote:I guess the idea is.. you run the flight controller/receiver see what the voltage output is.. and compare it to real world using a Volt Meter?
Right. But, you have to clean the eeprom by pushing the reset button in multiwiiconf every time again.
Fastrack wrote:Per cell voltage is not that much of a concern to me. They *should all drain equally... Pack voltage I think is more important, as my balanced charger will tell me if the battery is failing.
I share your opinion. Therefore, I haven't tried to overcome the "todo"-issue...
Fastrack wrote:I guess all this eliminates the need for the FrSky sensor hub!
That is the intention. It is more effort to integrate the sensor hub data than using the data which are already available at multiwii.
Fastrack wrote:I'm sure I'll have more questions once I actually get my flight controller and start using it.
Don't hesitate to ask and have fun.

TimoS
Posts: 1
Joined: Mon May 20, 2013 8:20 am

Re: Direct Frsky telemtry data from MW FC

Post by TimoS »

Hello :)
I like Turnigy with FrSky on Multiwii.
I flash this things:
http://witespyquad.gostorego.com/flight ... oller.html
http://www.hobbyking.com/hobbyking/stor ... le_RX.html
http://www.hobbyking.com/hobbyking/stor ... dule_.html

with some MOD.

The reciver is flasht for SumSig and connect to first (throtle) pin. So i need only one wire and have some ADC free on Atmega.
Lipo is connect on A15 (CH8, last Reciver input) over 33k/51K resistor.

Telemetrie from MW over Transistor (inverter) to reciver.

On the transmitter normal "FrSky - MOD" with Rx and Tx with max232.

At moment Display like this:

telem1.jpg


@MultiWii-Code: (Arduino)
-Direct send vbat to rpmFrSky (3600=12 Volt)
-Direct send SAT (before (sat/2)*25) i think this was for Displaybar?! I will see a number.

@Er9x-Code: (WinAVR)
-Some display line changes
-Bat= rpm/30 = 120 (0.1V = 30)
-Sat= feul

Some things to do...
Thanks for all programmer to these projects.

Sorry for my english ;)

Fastrack
Posts: 23
Joined: Tue May 14, 2013 5:36 am

Re: Direct Frsky telemtry data from MW FC

Post by Fastrack »

Well it seems the new radio (Taranis) I was about to order comes with a an X8R receiver and it no longer has Analog or Digital input only a new port called a "SmartPort". So both this and the jdrones jd IO-board are out of the question to feed it telemetry data! So I'll have to order a D8R-II or a D8R-XP receiver if I want to feed it data.

Darn... why would a company do this... weird!

Ben

disq
Posts: 29
Joined: Tue May 21, 2013 2:11 am
Location: Northern Cyprus

Re: Direct Frsky telemtry data from MW FC

Post by disq »

Here is my branch, based on QuadBow's FrSky Telemetry code. https://github.com/disq/multiwii-firmwa ... /telemetry

I converted the code to be compatible with the latest Multiwii (r1424, but vbat/motors/rpm not tested) and also added Softserial support, using SendOnlySoftwareSerial. This way you don't need to dedicate a serial port for the telemetry, instead you can use a digital pin. I used D12 in my case. This also eliminates the need to use a TTL inverter, a simple wire connection between the Arduino pin and D8R Rx sideport is enough.

This is not flighttested, just benchtested on a Promini. Please be advised that with some setups or some boards, port D12 might not be available. The port is configurable, you will have to find a suitable (and output-capable) digital port and change the definition in config.h.

To enable Softserial, find the TELEMETRY_FRSKY keyword in config.h and set it up like this:

Code: Select all

  #define TELEMETRY_FRSKY
  //#define TELEMETRY_FRSKY_SERIAL 3
  #define TELEMETRY_FRSKY_SOFTSERIAL_PIN 12  // connect FrSky Receiver's Rx sideport to D12 without a ttl inverter
  #define TELEMETRY_FRSKY_SERIAL 9600  // if using softserial, set baudrate here (comment out "TELEMETRY_FRSKY_SERIAL 3" above)


Update: Turns out processing takes too long and messes with receiver input. So I modified SendOnlySoftwareSerial to not disable the interrupts (no cli() call) during transmission. That means the telemetry data might have some errors (or invalid packets, rather) in it, but at least the stability of the system is not adversely effected.

Update 2: Also added a Multiwii 2.2 based branch, at https://github.com/disq/multiwii-firmwa ... emetry_2.2
Last edited by disq on Mon May 27, 2013 8:32 pm, edited 2 times in total.

iksbob
Posts: 3
Joined: Sat Apr 06, 2013 3:56 am

Re: Direct Frsky telemtry data from MW FC

Post by iksbob »

Fastrack wrote:only a new port called a "SmartPort". [...] So I'll have to order a D8R-II or a D8R-XP receiver if I want to feed it data.
The D4R-II is also a nice compact option if you're using CPPM.
As for the Smart Port, it looks to me like an effort by FrSky to actually open up and expand the functionality of the two-way telemetry system. One of the device options is a two-way serial port for user data - that data could be the link between MultiWiiConf and the FCB, or the TX and FCB using the old FrSky protocol.

Fastrack
Posts: 23
Joined: Tue May 14, 2013 5:36 am

Re: Direct Frsky telemtry data from MW FC

Post by Fastrack »

Anyone have the docs posted by larsm here:
viewtopic.php?f=7&t=1929&start=90#p29129

His website:
http://multikopter.org/Turnigy%209x%20Mods/

Had some wiring diagrams etc...

Ben

BarneyG
Posts: 39
Joined: Tue May 07, 2013 4:42 pm

Re: Direct Frsky telemtry data from MW FC

Post by BarneyG »

I'm assuming you mean the dohicky to connect the Multiwii to the Frsky RX ?

I've been using this :

multiwii_to_frsky.png
(33.49 KiB) Not downloaded yet

disq
Posts: 29
Joined: Tue May 21, 2013 2:11 am
Location: Northern Cyprus

Re: Direct Frsky telemtry data from MW FC

Post by disq »

BarneyG wrote:I'm assuming you mean the dohicky to connect the Multiwii to the Frsky RX ?

I've been using this :

multiwii_to_frsky.png


That one works better than the PNP version that's been floating around on the interwebs so use it :)

Btw still, if you're short of serial ports but have a few kb of extra space, you can use the softserial version I posted a few messages up, and you don't need the extra hardware.

BarneyG
Posts: 39
Joined: Tue May 07, 2013 4:42 pm

Re: Direct Frsky telemtry data from MW FC

Post by BarneyG »

Is there any way we can get this included in Trunk ?

janekx
Posts: 63
Joined: Wed Sep 12, 2012 10:08 pm
Location: Brno, Czech Republic

Re: Direct Frsky telemtry data from MW FC

Post by janekx »

Yes why it is not a part of MW ? It is working code ....

Sebbi
Posts: 478
Joined: Sun Jul 08, 2012 1:08 am
Location: Germany
Contact:

Re: Direct Frsky telemtry data from MW FC

Post by Sebbi »

I agree ... i have FrSky hardware and plan to implement it in a more modular way (MultiWii doesn't use .ino files anymore) here viewtopic.php?f=8&t=3789

I am currently trying to find out what values come out what way on the FrSky telemetry display ...

QuadBow
Posts: 532
Joined: Fri Jan 04, 2013 10:06 am

Re: Direct Frsky telemtry data from MW FC

Post by QuadBow »

Sebbi wrote:I agree

I appreciate your effort to integrate Frsky telemetry functionality into the official Multiwii distribution.

Sebbi wrote:i have FrSky hardware and plan to implement it in a more modular way (MultiWii doesn't use .ino files anymore)

Based upon the file telemetry.ino of the former file scheme (only *.ino and *.h files) it should not be a big issue to rewrite it into *.c/*.h files.

Sebbi wrote:I am currently trying to find out what values come out what way on the FrSky telemetry display ...

The related information is provided due to http://www.frsky-rc.com/uploadfile/201107/20110727110301692.pdf but it is faulty.
The main issues I got rid of by rewriting the code. Please, find the related code attached.

The implementation of the Frsky byte stuffung method is working. A level converter is required, I recommended an hardware converter shown in http://www.multiwii.com/forum/viewtopic.php?f=7&t=1929&start=70 . A software serial implementations seems to mess up other sensitive timings.

Have fun.
Attachments
MultiWii2_2.zip
(141.23 KiB) Downloaded 1613 times

Sebbi
Posts: 478
Joined: Sun Jul 08, 2012 1:08 am
Location: Germany
Contact:

Re: Direct Frsky telemtry data from MW FC

Post by Sebbi »

Hi QuadBow,

thank you for the links. The issue is not in just rewriting the files, but to do it in a more modular way. I want the serial stuff (GUI & telemetry with different protocols) as interchangeable as possible. SoftwareSerial messes up RX timings that's why I use a custom version.

One problem remaining is the units of each datapoint (e.g. RPM and speed are weird). I have the FLD-02 display and it is not showing everything that's defined here http://frsky-rc.com/uploadfile/201211/2 ... 905895.pdf (newer version) ... no heading / GPS course, no GPS altitude, no voltage besides the one measured by the transmitter, no "behind the point" data for altitude, etc ...

Post Reply