Advertisement
Guest User

Untitled

a guest
Jan 5th, 2015
58
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 11.88 KB | None | 0 0
  1.  
  2. /*
  3. APM2.5 Mavlink to FrSky X8R SPort interface using Teensy 3.1  http://www.pjrc.com/teensy/index.html
  4.  based on ideas found here http://code.google.com/p/telemetry-convert/
  5.  ******************************************************
  6.  Cut board on the backside to separate Vin from VUSB
  7.  
  8.  Connection on Teensy 3.1:
  9.  SPort S --> TX1
  10.  SPort + --> Vin
  11.  SPort  - --> GND
  12.  
  13.  APM Telemetry DF13-5  Pin 2 --> RX2
  14.  APM Telemetry DF13-5  Pin 3 --> TX2
  15.  APM Telemetry DF13-5  Pin 5 --> GND
  16.  
  17.  Note that when used with other telemetry device (3DR Radio 433 or 3DR Bluetooth tested) in parallel on the same port the Teensy should only Receive, so please remove it's TX output (RX input on PixHawk or APM)
  18.  
  19.  Analog input  --> A0 (pin14) on Teensy 3.1 ( max 3.3 V ) - Not used
  20.  
  21.  
  22.  This is the data we send to FrSky, you can change this to have your own
  23.  set of data
  24.  
  25. ******************************************************
  26. Data transmitted to FrSky Taranis:
  27.  
  28. Cell            ( Voltage of Cell=Cells/(Number of cells). [V])
  29. Cells           ( Voltage from LiPo [V] )
  30. A2              ( HDOP value * 25 - 8 bit resolution)
  31. A3              ( Roll angle from -Pi to +Pi radians, converted to a value between 0 and 1024)
  32. A4              ( Pitch angle from -Pi/2 to +Pi/2 radians, converted to a value between 0 and 1024)
  33. Alt             ( Altitude from baro.  [m] )
  34. GAlt            ( Altitude from GPS   [m])
  35. HDG             ( Compass heading  [deg]) v
  36. Rpm             ( Throttle when ARMED [%] *100 + % battery remaining as reported by Mavlink)
  37. VSpd            ( Vertical speed [m/s] )
  38. Speed           ( Ground speed from GPS,  [km/h] )
  39. T1              ( GPS status = ap_sat_visible*10) + ap_fixtype )
  40. T2              ( Armed Status and Mavlink Messages :- 16 bit value: bit 1: armed - bit 2-5: severity +1 (0 means no message - bit 6-15: number representing a specific text)
  41. Vfas            ( same as Cells )
  42. Longitud        ( Longitud )
  43. Latitud         ( Latitud )
  44. Dist            ( Will be calculated by FrSky Taranis as the distance from first received lat/long = Home Position )
  45. Fuel            ( Current Flight Mode reported by Mavlink )
  46.  
  47. AccX            ( X Axis average vibration m/s?)
  48. AccY            ( Y Axis average vibration m/s?)
  49. AccZ            ( Z Axis average vibration m/s?)
  50.  
  51. ******************************************************
  52.  
  53.  */
  54.  
  55. #include <GCS_MAVLink.h>
  56. #include "FrSkySPort.h"
  57.  
  58. //#define debugSerial           Serial
  59. #define _MavLinkSerial      Serial
  60. #define START                   1
  61. #define MSG_RATE            10              // Hertz
  62.  
  63. //#define DEBUG_VFR_HUD
  64. //#define DEBUG_GPS_RAW
  65. //#define DEBUG_ACC
  66. //#define DEBUG_BAT
  67. //#define DEBUG_MODE
  68. //#define DEBUG_STATUS
  69. //#define DEBUG_ATTITUDE
  70.  
  71. //#define DEBUG_FRSKY_SENSOR_REQUEST
  72.  
  73. //#define DEBUG_AVERAGE_VOLTAGE
  74. #define DEBUG_PARSE_STATUS_TEXT
  75.  
  76. // ******************************************
  77. // Message #0  HEARTHBEAT
  78. uint8_t    ap_type = 0;
  79. uint8_t    ap_autopilot = 0;
  80. uint8_t    ap_base_mode = 0;
  81. int32_t    ap_custom_mode = -1;
  82. uint8_t    ap_system_status = 0;
  83. uint8_t    ap_mavlink_version = 0;
  84.  
  85. // Message # 1  SYS_STATUS
  86. uint16_t   ap_voltage_battery = 0;       // 1000 = 1V
  87. int16_t    ap_current_battery = 0;      //  10 = 1A
  88. int8_t    ap_battery_remaining = 0;   // Remaining battery energy: (0%: 0, 100%: 100), -1: autopilot estimate the remaining battery
  89.  
  90. // Message #24  GPS_RAW_INT
  91. uint8_t    ap_fixtype = 3;                //   0= No GPS, 1 = No Fix, 2 = 2D Fix, 3 = 3D Fix
  92. uint8_t    ap_sat_visible = 0;            // number of visible satelites
  93.  
  94. // FrSky Taranis uses the first recieved lat/long as homeposition.
  95. int32_t    ap_latitude = 0;               // 585522540;
  96. int32_t    ap_longitude = 0;              // 162344467;
  97. int32_t    ap_gps_altitude = 0;           // 1000 = 1m
  98. int32_t    ap_gps_speed = 0;
  99. uint16_t   ap_gps_hdop = 255;             // GPS HDOP horizontal dilution of position in cm (m*100). If unknown, set to: 65535
  100. // uint16_t    ap_vdop=0;                 // GPS VDOP horizontal dilution of position in cm (m*100). If unknown, set to: 65535
  101. // uint16_t    ap_cog = 0;                // Course over ground (NOT heading, but direction of movement) in degrees * 100, 0.0..359.99 degrees. If unknown, set to: 65535
  102.  
  103.  
  104. // Message #74 VFR_HUD
  105. uint32_t  ap_groundspeed = 0;       // Current ground speed in m/s
  106. uint32_t  ap_heading = 0;           // Current heading in degrees, in compass units (0..360, 0=north)
  107. uint16_t  ap_throttle = 0;          // Current throttle setting in integer percent, 0 to 100
  108.  
  109. // uint32_t  ap_alt=0;             //Current altitude (MSL), in meters
  110. // int32_t   ap_airspeed = 0;      // Current airspeed in m/s
  111.  
  112.  
  113. // FrSky Taranis uses the first recieved value after 'PowerOn' or  'Telemetry Reset'  as zero altitude
  114. int32_t    ap_bar_altitude = 0;    // 100 = 1m
  115. int32_t    ap_climb_rate=0;        // 100= 1m/s
  116.  
  117. // Messages needed to use current Angles and axis speeds
  118. // Message #30 ATTITUDE           //MAVLINK_MSG_ID_ATTITUDE
  119.  
  120. int32_t ap_roll_angle = 0;    //Roll angle (deg -180/180)
  121. int32_t ap_pitch_angle = 0;   //Pitch angle (deg -180/180)
  122. uint32_t ap_yaw_angle = 0;     //Yaw angle (rad)
  123. uint32_t ap_roll_speed = 0;    //Roll angular speed (rad/s)
  124. uint32_t ap_pitch_speed = 0;   //Pitch angular speed (rad/s)
  125. uint32_t ap_yaw_speed = 0;     //Yaw angular speed (rad/s)
  126.  
  127.  
  128. // Message #253 MAVLINK_MSG_ID_STATUSTEXT
  129. uint16_t   ap_status_severity = 255;
  130. uint16_t   ap_status_send_count = 0;
  131. uint16_t   ap_status_text_id = 0;
  132. mavlink_statustext_t statustext;
  133.  
  134. /*
  135.  
  136.   MAV_SEVERITY_EMERGENCY=0, System is unusable. This is a "panic" condition.
  137.   MAV_SEVERITY_ALERT=1, Action should be taken immediately. Indicates error in non-critical systems.
  138.   MAV_SEVERITY_CRITICAL=2, Action must be taken immediately. Indicates failure in a primary system.
  139.   MAV_SEVERITY_ERROR=3, Indicates an error in secondary/redundant systems.
  140.   MAV_SEVERITY_WARNING=4, Indicates about a possible future error if this is not resolved within a given timeframe. Example would be a low battery warning.
  141.   MAV_SEVERITY_NOTICE=5, An unusual event has occured, though not an error condition. This should be investigated for the root cause.
  142.   MAV_SEVERITY_INFO=6, Normal operational messages. Useful for logging. No action is required for these messages.
  143.   MAV_SEVERITY_DEBUG=7, Useful non-operational messages that can assist in debugging. These should not occur during normal operation.
  144.   MAV_SEVERITY_ENUM_END=8,
  145.  
  146. */
  147.  
  148.  
  149. // ******************************************
  150. // These are special for FrSky
  151. int32_t     vfas = 0;                // 100 = 1,0V
  152. int32_t     gps_status = 0;     // (ap_sat_visible * 10) + ap_fixtype
  153. // ex. 83 = 8 sattelites visible, 3D lock
  154. uint8_t   ap_cell_count = 0;
  155.  
  156. // ******************************************
  157. uint8_t     MavLink_Connected;
  158. uint8_t     buf[MAVLINK_MAX_PACKET_LEN];
  159.  
  160. uint16_t  hb_count;
  161.  
  162. unsigned long MavLink_Connected_timer;
  163. unsigned long hb_timer;
  164.  
  165. int led = 13;
  166.  
  167. mavlink_message_t msg;
  168.  
  169. // ******************************************
  170. void setup()  {
  171.  
  172.   FrSkySPort_Init();
  173.   _MavLinkSerial.begin(57600);
  174.   //debugSerial.begin(57600);
  175.   MavLink_Connected = 0;
  176.   MavLink_Connected_timer=millis();
  177.   hb_timer = millis();
  178.   hb_count = 0;
  179.  
  180.  
  181.   pinMode(led,OUTPUT);
  182.   pinMode(12,OUTPUT);
  183.  
  184.   pinMode(14,INPUT);
  185.   analogReference(DEFAULT);
  186.  
  187. }
  188.  
  189.  
  190. // ******************************************
  191. void loop()  {
  192.   uint16_t len;
  193.  
  194.   if(millis()-hb_timer > 1500) {
  195.     hb_timer=millis();
  196.     if(!MavLink_Connected) {    // Start requesting data streams from MavLink
  197.       digitalWrite(led,HIGH);
  198.       mavlink_msg_request_data_stream_pack(0xFF,0xBE,&msg,1,1,MAV_DATA_STREAM_EXTENDED_STATUS, MSG_RATE, START);
  199.       len = mavlink_msg_to_send_buffer(buf, &msg);
  200.       _MavLinkSerial.write(buf,len);
  201.       delay(10);
  202.       mavlink_msg_request_data_stream_pack(0xFF,0xBE,&msg,1,1,MAV_DATA_STREAM_EXTRA2, MSG_RATE, START);
  203.       len = mavlink_msg_to_send_buffer(buf, &msg);
  204.       _MavLinkSerial.write(buf,len);
  205.       delay(10);
  206.       mavlink_msg_request_data_stream_pack(0xFF,0xBE,&msg,1,1,MAV_DATA_STREAM_RAW_SENSORS, MSG_RATE, START);
  207.       len = mavlink_msg_to_send_buffer(buf, &msg);
  208.       _MavLinkSerial.write(buf,len);
  209.       digitalWrite(led,LOW);
  210.     }
  211.   }
  212.  
  213.   if((millis() - MavLink_Connected_timer) > 1500)  {   // if no HEARTBEAT from APM  in 1.5s then we are not connected
  214.     MavLink_Connected=0;
  215.     hb_count = 0;
  216.   }
  217.  
  218.   _MavLink_receive();                   // Check MavLink communication
  219.  
  220.   FrSkySPort_Process();               // Check FrSky S.Port communication
  221.  
  222. }
  223.  
  224.  
  225.  
  226. void _MavLink_receive() {
  227.   mavlink_message_t msg;
  228.   mavlink_status_t status;
  229.  
  230.   while(_MavLinkSerial.available())
  231.   {
  232.     uint8_t c = _MavLinkSerial.read();
  233.     if(mavlink_parse_char(MAVLINK_COMM_0, c, &msg, &status))
  234.     {
  235.       switch(msg.msgid)
  236.       {
  237.       case MAVLINK_MSG_ID_HEARTBEAT:  // 0
  238.         ap_base_mode = (mavlink_msg_heartbeat_get_base_mode(&msg) & 0x80) > 7;
  239.         ap_custom_mode = mavlink_msg_heartbeat_get_custom_mode(&msg);
  240.         MavLink_Connected_timer=millis();
  241.         if(!MavLink_Connected);
  242.         {
  243.           hb_count++;  
  244.           if((hb_count++) > 10) {        // If  received > 10 heartbeats from MavLink then we are connected
  245.             MavLink_Connected=1;
  246.             hb_count=0;
  247.             digitalWrite(led,HIGH);      // LED will be ON when connected to MavLink, else it will slowly blink
  248.           }
  249.         }
  250.         break;
  251.       case MAVLINK_MSG_ID_SYS_STATUS :   // 1
  252.         //ap_voltage_battery = Get_Volt_Average(mavlink_msg_sys_status_get_voltage_battery(&msg));  // 1 = 1mV
  253.         //ap_current_battery = Get_Current_Average(mavlink_msg_sys_status_get_current_battery(&msg));     // 1=10mA
  254.  
  255.         storeVoltageReading(ap_voltage_battery);
  256.         storeCurrentReading(ap_current_battery);
  257.        
  258.         uint8_t temp_cell_count;
  259.         if(ap_voltage_battery > 21000) temp_cell_count = 6;
  260.         else if (ap_voltage_battery > 17500) temp_cell_count = 5;
  261.         else if(ap_voltage_battery > 12750) temp_cell_count = 4;
  262.         else if(ap_voltage_battery > 8500) temp_cell_count = 3;
  263.         else if(ap_voltage_battery > 4250) temp_cell_count = 2;
  264.         else temp_cell_count = 0;
  265.         if(temp_cell_count > ap_cell_count)
  266.           ap_cell_count = temp_cell_count;
  267.         break;
  268.       case MAVLINK_MSG_ID_GPS_RAW_INT:   // 24
  269.         ap_fixtype = mavlink_msg_gps_raw_int_get_fix_type(&msg);                               // 0 = No GPS, 1 =No Fix, 2 = 2D Fix, 3 = 3D Fix
  270.         ap_sat_visible =  mavlink_msg_gps_raw_int_get_satellites_visible(&msg);          // numbers of visible satelites
  271.         //ap_hdop = mavlink_msg_gps_raw_int_get_eph(&msg);                // GPS H.DOP
  272.         gps_status = ap_sat_visible;
  273.         if(ap_fixtype == 3)  {
  274.           ap_latitude = mavlink_msg_gps_raw_int_get_lat(&msg);
  275.           ap_longitude = mavlink_msg_gps_raw_int_get_lon(&msg);
  276.           ap_gps_altitude = mavlink_msg_gps_raw_int_get_alt(&msg);    // 1m =1000
  277.           ap_gps_speed = mavlink_msg_gps_raw_int_get_vel(&msg);         // 100 = 1m/s
  278.         }
  279.         else
  280.         {
  281.           ap_gps_speed = 0;  
  282.         }
  283.         break;
  284.       case MAVLINK_MSG_ID_RAW_IMU:   // 27
  285.         storeAccX(mavlink_msg_raw_imu_get_xacc(&msg) / 10);
  286.         storeAccY(mavlink_msg_raw_imu_get_yacc(&msg) / 10);
  287.         storeAccZ(mavlink_msg_raw_imu_get_zacc(&msg) / 10);
  288.         break;      
  289.       case MAVLINK_MSG_ID_VFR_HUD:   //  74
  290.         ap_groundspeed = mavlink_msg_vfr_hud_get_groundspeed(&msg);      // 100 = 1m/s
  291.         ap_heading = mavlink_msg_vfr_hud_get_heading(&msg);     // 100 = 100 deg
  292.         ap_throttle = mavlink_msg_vfr_hud_get_throttle(&msg);        //  100 = 100%
  293.         ap_bar_altitude = mavlink_msg_vfr_hud_get_alt(&msg) * 100;        //  m
  294.         ap_climb_rate=mavlink_msg_vfr_hud_get_climb(&msg) * 100;        //  m/s
  295.         break;
  296.       default:
  297.         break;
  298.       }
  299.  
  300.     }
  301.   }
  302. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement