Trying to log data from UM6 sensor with GPS receiver LS20031. I have two problems: - I can't log to file at a fast rate (<0.5s) without data values freezing to a fixed value. Print to pc screen it works fine. Ideally I would do this with an interrupt (e.g. ticker) so that the time of each reading is a fixed interval - I removed this as I thought this was causing the problem. - I want to record GPS lat and long. I have setup the GPS ground speed so I know the sensor are communicating. So I possibly havent set the config file to correctly interpet these two signals.

Dependencies:   MODSERIAL mbed

Fork of UM6_IMU_AHRS_2012 by lhiggs CSUM

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers UM6_config.h Source File

UM6_config.h

00001 /* ------------------------------------------------------------------------------
00002   File: UM6_config.h
00003   Author: CH Robotics, edited by Nathan Ewin
00004   Version: 1.0
00005 
00006   Description: Preprocessor definitions and function declarations for UM6 configuration
00007   
00008   // added configuration for GPS signals from LS20031 sensor connected to UM6
00009   // GPS ground speed and heading angle setup outputs data
00010   // GPS latitude and longitude not setup correctly
00011 ------------------------------------------------------------------------------ */
00012 #ifndef __UM6_CONFIG_H
00013 #define __UM6_CONFIG_H
00014 
00015 #include "UM6_usart.h"
00016 
00017 
00018 
00019 MODSERIAL um6_uart(p9, p10);    // UM6 SERIAL OVER UART PINS 26 & 25
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 // CONFIG_ARRAY_SIZE and DATA_ARRAY_SIZE specify the number of 32 bit configuration and data registers used by the firmware
00029 // (Note: The term "register" is used loosely here.  These "registers" are not actually registers in the same sense of a
00030 // microcontroller register.  They are simply index locations into arrays stored in global memory.  Data and configuration
00031 // parameters are stored in arrays because it allows a common communication protocol to be used to access all data and
00032 // configuration.  The software communicating with the sensor needs only specify the register address, and the communication
00033 // software running on the sensor knows exactly where to find it - it needn't know what the data is.  The software communicatin
00034 // with the sensor, on the other hand, needs to know what it is asking for (naturally...)
00035 // This setup makes it easy to make more data immediately available when needed - simply increase the array size, add code in
00036 // the firmware that writes data to the new array location, and then make updates to the firmware definition on the PC side.
00037 #define    CONFIG_ARRAY_SIZE        44
00038 #define    DATA_ARRAY_SIZE          36
00039 #define    COMMAND_COUNT             9
00040 
00041 // original data array size 32
00042 //
00043 #define    CONFIG_REG_START_ADDRESS       0
00044 #define    DATA_REG_START_ADDRESS        85    
00045 #define    COMMAND_START_ADDRESS        170
00046 
00047 // hex 0x55 = dec 85 
00048 // hex 0xAA = dec 170
00049 // These preprocessor definitions make it easier to access specific configuration parameters in code
00050 // They specify array locations associated with each register name.  Note that in the comments below, many of the values are
00051 // said to be 32-bit IEEE floating point.  Obviously this isn't directly the case, since the arrays are actually 32-bit unsigned
00052 // integer arrays.  Bit for bit, the data does correspond to the correct floating point value.  Since you can't cast ints as floats,
00053 // special conversion has to happen to copy the float data to and from the array.
00054 // Starting with configuration register locations...
00055 
00056 
00057 // Now for data register locations.
00058 // In the communication protocol, data registers are labeled with number ranging from 128 to 255.  
00059 // The value of 128 will be subtracted from these numbers
00060 // to produce the actual array index labeled below
00061 #define    UM6_STATUS                DATA_REG_START_ADDRESS                // Status register defines error codes with individual bits
00062 #define    UM6_GYRO_RAW_XY        (DATA_REG_START_ADDRESS    + 1)        // Raw gyro data is stored in 16-bit signed integers
00063 #define    UM6_GYRO_RAW_Z            (DATA_REG_START_ADDRESS + 2)
00064 #define    UM6_ACCEL_RAW_XY        (DATA_REG_START_ADDRESS + 3)        // Raw accel data is stored in 16-bit signed integers
00065 #define    UM6_ACCEL_RAW_Z        (DATA_REG_START_ADDRESS + 4)
00066 #define    UM6_MAG_RAW_XY            (DATA_REG_START_ADDRESS + 5)        // Raw mag data is stored in 16-bit signed integers
00067 #define    UM6_MAG_RAW_Z            (DATA_REG_START_ADDRESS + 6)
00068 #define    UM6_GYRO_PROC_XY        (DATA_REG_START_ADDRESS + 7)        // Processed gyro data has scale factors applied and alignment correction performed.  Data is 16-bit signed integer.
00069 #define    UM6_GYRO_PROC_Z        (DATA_REG_START_ADDRESS + 8)
00070 #define    UM6_ACCEL_PROC_XY        (DATA_REG_START_ADDRESS + 9)        // Processed accel data has scale factors applied and alignment correction performed.  Data is 16-bit signed integer.
00071 #define    UM6_ACCEL_PROC_Z        (DATA_REG_START_ADDRESS + 10)
00072 #define    UM6_MAG_PROC_XY        (DATA_REG_START_ADDRESS + 11)        // Processed mag data has scale factors applied and alignment correction performed.  Data is 16-bit signed integer.
00073 #define    UM6_MAG_PROC_Z            (DATA_REG_START_ADDRESS + 12)
00074 #define    UM6_EULER_PHI_THETA    (DATA_REG_START_ADDRESS + 13)        // Euler angles are 32-bit IEEE floating point
00075 #define    UM6_EULER_PSI            (DATA_REG_START_ADDRESS + 14)
00076 #define    UM6_QUAT_AB                (DATA_REG_START_ADDRESS + 15)        // Quaternions are 16-bit signed integers.
00077 #define    UM6_QUAT_CD                (DATA_REG_START_ADDRESS + 16)
00078 #define    UM6_ERROR_COV_00        (DATA_REG_START_ADDRESS + 17)        // Error covariance is a 4x4 matrix of 32-bit IEEE floating point values
00079 #define    UM6_ERROR_COV_01        (DATA_REG_START_ADDRESS + 18)
00080 #define    UM6_ERROR_COV_02        (DATA_REG_START_ADDRESS + 19)
00081 #define    UM6_ERROR_COV_03        (DATA_REG_START_ADDRESS + 20)
00082 #define    UM6_ERROR_COV_10        (DATA_REG_START_ADDRESS + 21)
00083 #define    UM6_ERROR_COV_11        (DATA_REG_START_ADDRESS + 22)
00084 #define    UM6_ERROR_COV_12        (DATA_REG_START_ADDRESS + 23)
00085 #define    UM6_ERROR_COV_13        (DATA_REG_START_ADDRESS + 24)
00086 #define    UM6_ERROR_COV_20        (DATA_REG_START_ADDRESS + 25)
00087 #define    UM6_ERROR_COV_21        (DATA_REG_START_ADDRESS + 26)
00088 #define    UM6_ERROR_COV_22        (DATA_REG_START_ADDRESS + 27)
00089 #define    UM6_ERROR_COV_23        (DATA_REG_START_ADDRESS + 28)
00090 #define    UM6_ERROR_COV_30        (DATA_REG_START_ADDRESS + 29)
00091 #define    UM6_ERROR_COV_31        (DATA_REG_START_ADDRESS + 30)
00092 #define    UM6_ERROR_COV_32        (DATA_REG_START_ADDRESS + 31)
00093 #define    UM6_ERROR_COV_33        (DATA_REG_START_ADDRESS + 32)
00094 #define    UM6_GPS_LONGITUDE       (DATA_REG_START_ADDRESS + 34)
00095 #define    UM6_GPS_LATITUDE       (DATA_REG_START_ADDRESS + 35)
00096 #define    UM6_GPS_COURSE_SPEED      (DATA_REG_START_ADDRESS + 40)
00097 
00098 
00099 
00100 
00101 
00102 
00103 
00104 /*******************************************************************************
00105 * Function Name  : ComputeChecksum
00106 * Input          : USARTPacket* new_packet
00107 * Output         : None
00108 * Return         : uint16_t
00109 * Description    : Returns the two byte sum of all the individual bytes in the
00110                          given packet.
00111 *******************************************************************************/
00112 uint16_t ComputeChecksum( USARTPacket* new_packet ) {
00113     int32_t index;
00114     uint16_t checksum = 0x73 + 0x6E + 0x70 + new_packet->PT + new_packet->address;
00115 
00116     for ( index = 0; index < new_packet->data_length; index++ ) {
00117         checksum += new_packet->packet_data[index];
00118     }
00119     return checksum;
00120 }
00121 
00122 
00123 
00124 
00125 
00126 static USARTPacket new_packet;
00127 
00128 // Flag for storing the current USART state
00129 uint8_t gUSART_State = USART_STATE_WAIT;
00130 
00131 
00132 struct UM6{
00133 float Gyro_Proc_X;
00134 float Gyro_Proc_Y;
00135 float Gyro_Proc_Z;
00136 float Accel_Proc_X;
00137 float Accel_Proc_Y;
00138 float Accel_Proc_Z;
00139 float Mag_Proc_X;
00140 float Mag_Proc_Y;
00141 float Mag_Proc_Z;
00142 float Roll;
00143 float Pitch;
00144 float Yaw;
00145 float GPS_long;
00146 float GPS_lat;
00147 float GPS_course;
00148 float GPS_speed;
00149 };
00150 UM6 data;
00151 
00152 
00153 
00154 
00155 void Process_um6_packet() {
00156 
00157 int16_t MY_DATA_GYRO_PROC_X;
00158 int16_t MY_DATA_GYRO_PROC_Y;
00159 int16_t MY_DATA_GYRO_PROC_Z;
00160 int16_t MY_DATA_ACCEL_PROC_X;
00161 int16_t MY_DATA_ACCEL_PROC_Y;
00162 int16_t MY_DATA_ACCEL_PROC_Z;
00163 int16_t MY_DATA_MAG_PROC_X;
00164 int16_t MY_DATA_MAG_PROC_Y;
00165 int16_t MY_DATA_MAG_PROC_Z;
00166 int16_t MY_DATA_EULER_PHI;
00167 int16_t MY_DATA_EULER_THETA;
00168 int16_t MY_DATA_EULER_PSI;
00169 int32_t MY_DATA_GPS_LONG;
00170 int32_t MY_DATA_GPS_LAT;
00171 int16_t MY_DATA_GPS_COURSE;
00172 int16_t MY_DATA_GPS_SPEED;
00173 
00174 
00175 
00176 static uint8_t data_counter = 0;
00177 
00178 
00179 
00180             // The next action should depend on the USART state.
00181             switch ( gUSART_State ) {
00182                     // USART in the WAIT state.  In this state, the USART is waiting to see the sequence of bytes
00183                     // that signals a new incoming packet.
00184                 case USART_STATE_WAIT:
00185                     if ( data_counter == 0 ) {     // Waiting on 's' character
00186                         if ( um6_uart.getc() == 's' ) {
00187 
00188                             data_counter++;
00189                         } else {
00190                             data_counter = 0;
00191                         }
00192                     } else if ( data_counter == 1 ) {    // Waiting on 'n' character
00193                         if ( um6_uart.getc() == 'n' ) {
00194                             data_counter++;
00195 
00196                         } else {
00197                             data_counter = 0;
00198                         }
00199                     } else if ( data_counter == 2 ) {    // Waiting on 'p' character
00200                         if ( um6_uart.getc() == 'p' ) {
00201                             // The full 'snp' sequence was received.  Reset data_counter (it will be used again
00202                             // later) and transition to the next state.
00203                             data_counter = 0;
00204                             gUSART_State = USART_STATE_TYPE;
00205 
00206                         } else {
00207                             data_counter = 0;
00208                         }
00209                     }
00210                     break;
00211 
00212                     // USART in the TYPE state.  In this state, the USART has just received the sequence of bytes that
00213                     // indicates a new packet is about to arrive.  Now, the USART expects to see the packet type.
00214                 case USART_STATE_TYPE:
00215 
00216                     new_packet.PT = um6_uart.getc();
00217 
00218                     gUSART_State = USART_STATE_ADDRESS;
00219 
00220                     break;
00221 
00222                     // USART in the ADDRESS state.  In this state, the USART expects to receive a single byte indicating
00223                     // the address that the packet applies to
00224                 case USART_STATE_ADDRESS:
00225                     new_packet.address = um6_uart.getc();
00226                     
00227                     // For convenience, identify the type of packet this is and copy to the packet structure
00228                     // (this will be used by the packet handler later)
00229                     if ( (new_packet.address >= CONFIG_REG_START_ADDRESS) && (new_packet.address < DATA_REG_START_ADDRESS) ) {
00230                         new_packet.address_type = ADDRESS_TYPE_CONFIG;
00231                     } else if ( (new_packet.address >= DATA_REG_START_ADDRESS) && (new_packet.address < COMMAND_START_ADDRESS) ) {
00232                         new_packet.address_type = ADDRESS_TYPE_DATA;
00233                     } else {
00234                         new_packet.address_type = ADDRESS_TYPE_COMMAND;
00235                     }
00236 
00237                     // Identify the type of communication this is (whether reading or writing to a data or configuration register, or sending a command)
00238                     // If this is a read operation, jump directly to the USART_STATE_CHECKSUM state - there is no more data in the packet
00239                     if ( (new_packet.PT & PACKET_HAS_DATA) == 0 ) {
00240                         gUSART_State = USART_STATE_CHECKSUM;
00241                     }
00242 
00243                     // If this is a write operation, go to the USART_STATE_DATA state to read in the relevant data
00244                     else {
00245                         gUSART_State = USART_STATE_DATA;
00246                         // Determine the expected number of bytes in this data packet based on the packet type.  A write operation
00247                         // consists of 4 bytes unless it is a batch operation, in which case the number of bytes equals 4*batch_size,
00248                         // where the batch size is also given in the packet type byte.
00249                         if ( new_packet.PT & PACKET_IS_BATCH ) {
00250                             new_packet.data_length = 4*((new_packet.PT >> 2) & PACKET_BATCH_LENGTH_MASK);
00251 
00252                         } else {
00253                             new_packet.data_length = 4;
00254                         }
00255                     }
00256                     break;
00257 
00258                     // USART in the DATA state.  In this state, the USART expects to receive new_packet.length bytes of
00259                     // data.
00260                 case USART_STATE_DATA:
00261                     new_packet.packet_data[data_counter] =  um6_uart.getc();
00262                     data_counter++;
00263 
00264                     // If the expected number of bytes has been received, transition to the CHECKSUM state.
00265                     if ( data_counter == new_packet.data_length ) {
00266                         // Reset data_counter, since it will be used in the CHECKSUM state.
00267                         data_counter = 0;
00268                         gUSART_State = USART_STATE_CHECKSUM;
00269                     }
00270                     break;
00271 
00272 
00273 
00274                     // USART in CHECKSUM state.  In this state, the entire packet has been received, with the exception
00275                     // of the 16-bit checksum.
00276                 case USART_STATE_CHECKSUM:
00277                     // Get the highest-order byte
00278                     if ( data_counter == 0 ) {
00279                         new_packet.checksum = ((uint16_t)um6_uart.getc() << 8);
00280                         data_counter++;
00281                     } else { // ( data_counter == 1 )
00282                         // Get lower-order byte
00283                         new_packet.checksum = new_packet.checksum | ((uint16_t)um6_uart.getc() & 0x0FF);
00284 
00285                         // Both checksum bytes have been received.  Make sure that the checksum is valid.
00286                         uint16_t checksum = ComputeChecksum( &new_packet );
00287 
00288 
00289 
00290                         // If checksum does not match, exit function
00291                         if ( checksum != new_packet.checksum ) {
00292                             return;
00293                         }   // end if(checksum check)
00294 
00295 
00296 
00297                         else
00298 
00299                         {
00300 
00301                             //  Packet was received correctly.
00302 
00303                             //-----------------------------------------------------------------------------------------------
00304                             //-----------------------------------------------------------------------------------------------
00305                             //
00306                             // CHECKSUM WAS GOOD SO GET ARE DATA!!!!!!!!!!!!
00307 
00308 
00309                             // IF DATA ADDRESS
00310                             if  (new_packet.address_type == ADDRESS_TYPE_DATA) {
00311 
00312                                 //------------------------------------------------------------
00313                                 // UM6_GYRO_PROC_XY (0x5C)
00314                                 // To convert the register data from 16-bit 2's complement integers to actual angular rates in degrees
00315                                 // per second, the data should be multiplied by the scale factor 0.0610352 as shown below
00316                                 // angular_rate = register_data*0.0610352
00317 
00318                                 if (new_packet.address == UM6_GYRO_PROC_XY) {
00319 
00320                                     // GYRO_PROC_X
00321                                     MY_DATA_GYRO_PROC_X = (int16_t)new_packet.packet_data[0]<<8; //bitshift it
00322                                     MY_DATA_GYRO_PROC_X |= new_packet.packet_data[1];
00323                                     data.Gyro_Proc_X = MY_DATA_GYRO_PROC_X*0.0610352;
00324 
00325                                     MY_DATA_GYRO_PROC_Y = (int16_t)new_packet.packet_data[2]<<8; //bitshift it
00326                                     MY_DATA_GYRO_PROC_Y |= new_packet.packet_data[3];
00327                                     data.Gyro_Proc_Y = MY_DATA_GYRO_PROC_Y*0.0610352;
00328 
00329 
00330                                     //------------------------------------------------------------
00331 
00332 
00333                                     //------------------------------------------------------------
00334                                     // UM6_GYRO_PROC_Z (0x5D)
00335                                     // To convert the register data from a 16-bit 2's complement integer to the actual angular rate in
00336                                     // degrees per second, the data should be multiplied by the scale factor 0.0610352 as shown below.
00337 
00338 
00339                                     // GYRO_PROC_Z
00340                                     MY_DATA_GYRO_PROC_Z = (int16_t)new_packet.packet_data[4]<<8; //bitshift it
00341                                     MY_DATA_GYRO_PROC_Z |= new_packet.packet_data[5];;
00342                                     data.Gyro_Proc_Z = MY_DATA_GYRO_PROC_Z*0.0610352;
00343                                     
00344                                     
00345                                 }   // end if(MY_DATA_GYRO_PROC)
00346                                 //------------------------------------------------------------
00347 
00348 
00349                                 //------------------------------------------------------------
00350                                 // UM6_ACCEL_PROC_XY (0x5E)
00351                                 // To convert the register data from 16-bit 2's complement integers to actual acceleration in gravities,
00352                                 // the data should be multiplied by the scale factor 0.000183105 as shown below.
00353                                 // acceleration = register_data* 0.000183105
00354                                 if (new_packet.address == UM6_ACCEL_PROC_XY) {
00355 
00356                                     // ACCEL_PROC_X
00357                                     MY_DATA_ACCEL_PROC_X = (int16_t)new_packet.packet_data[0]<<8; //bitshift it
00358                                     MY_DATA_ACCEL_PROC_X |= new_packet.packet_data[1];
00359                                     data.Accel_Proc_X = MY_DATA_ACCEL_PROC_X*0.000183105;
00360 
00361                                     // ACCEL_PROC_Y
00362                                     MY_DATA_ACCEL_PROC_Y = (int16_t)new_packet.packet_data[2]<<8; //bitshift it
00363                                     MY_DATA_ACCEL_PROC_Y |= new_packet.packet_data[3];
00364                                     data.Accel_Proc_Y = MY_DATA_ACCEL_PROC_Y*0.000183105;
00365 
00366                                     //------------------------------------------------------------
00367 
00368 
00369                                     //------------------------------------------------------------
00370                                     // UM6_ACCEL_PROC_Z (0x5F)
00371                                     // To convert the register data from a 16-bit 2's complement integer to the actual acceleration in
00372                                     // gravities, the data should be multiplied by the scale factor 0.000183105 as shown below.
00373 
00374                                     // ACCEL_PROC_Z
00375                                     MY_DATA_ACCEL_PROC_Z = (int16_t)new_packet.packet_data[4]<<8; //bitshift it
00376                                     MY_DATA_ACCEL_PROC_Z |= new_packet.packet_data[5];
00377                                     data.Accel_Proc_Z = MY_DATA_ACCEL_PROC_Z*0.000183105;
00378                                     
00379                                 }   // end if(MY_DATA_ACCEL_PROC)
00380 
00381                                 //------------------------------------------------------------
00382 
00383 
00384                                 //------------------------------------------------------------
00385                                 // UM6_MAG_PROC_XY (0x60)
00386                                 // To convert the register data from 16-bit 2's complement integers to a unit-norm (assuming proper
00387                                 // calibration)  magnetic-field vector, the data should be multiplied by the scale factor 0.000305176 as
00388                                 // shown below.
00389                                 // magnetic field = register_data* 0.000305176
00390                                 if (new_packet.address == UM6_MAG_PROC_XY) {
00391 
00392                                     // MAG_PROC_X
00393                                     MY_DATA_MAG_PROC_X = (int16_t)new_packet.packet_data[0]<<8; //bitshift it
00394                                     MY_DATA_MAG_PROC_X |= new_packet.packet_data[1];
00395                                     data.Mag_Proc_X = MY_DATA_MAG_PROC_X*0.000305176;
00396                                     
00397 
00398                                     // MAG_PROC_Y
00399                                     MY_DATA_MAG_PROC_Y = (int16_t)new_packet.packet_data[2]<<8; //bitshift it
00400                                     MY_DATA_MAG_PROC_Y |= new_packet.packet_data[3];
00401                                     data.Mag_Proc_Y = MY_DATA_MAG_PROC_Y*0.000305176;
00402 
00403                                     //------------------------------------------------------------
00404 
00405 
00406                                     //------------------------------------------------------------
00407                                     // UM6_MAG_PROC_Z (0x61)
00408                                     // To convert the register data from 16-bit 2's complement integers to a unit-norm (assuming proper
00409                                     // calibration)  magnetic-field vector, the data should be multiplied by the scale factor 0.000305176 as
00410                                     // shown below.
00411                                     // magnetic field = register_data*0.000305176
00412 
00413                                     // MAG_PROC_Z
00414                                     MY_DATA_MAG_PROC_Z = (int16_t)new_packet.packet_data[4]<<8; //bitshift it
00415                                     MY_DATA_MAG_PROC_Z |= new_packet.packet_data[5];
00416                                     data.Mag_Proc_Z = MY_DATA_MAG_PROC_Z*0.000305176;
00417 
00418                                 }   // end if(UM6_MAG_PROC)
00419                                 //------------------------------------------------------------
00420 
00421 
00422 
00423                                 //------------------------------------------------------------
00424                                 // UM6_EULER_PHI_THETA (0x62)
00425                                 // Stores the most recently computed roll (phi) and pitch (theta) angle estimates.  The angle
00426                                 // estimates are stored as 16-bit 2's complement integers.  To obtain the actual angle estimate in
00427                                 // degrees, the register data should be multiplied by the scale factor 0.0109863 as shown below
00428                                 // angle estimate = register_data* 0.0109863
00429                                 if (new_packet.address == UM6_EULER_PHI_THETA) {
00430                                     // EULER_PHI (ROLL)
00431                                    MY_DATA_EULER_PHI = (int16_t)new_packet.packet_data[0]<<8; //bitshift it
00432                                    MY_DATA_EULER_PHI |= new_packet.packet_data[1];
00433                                    data.Roll = MY_DATA_EULER_PHI*0.0109863;
00434                                     
00435          
00436          
00437          
00438 
00439                                     // EULER_THETA (PITCH)
00440                                     MY_DATA_EULER_THETA = (int16_t)new_packet.packet_data[2]<<8; //bitshift it
00441                                     MY_DATA_EULER_THETA |= new_packet.packet_data[3];
00442                                     data.Pitch = MY_DATA_EULER_THETA*0.0109863;
00443 
00444                                     //------------------------------------------------------------
00445 
00446                                     //------------------------------------------------------------
00447                                     // UM6_EULER_PSI (0x63) (YAW)
00448                                     // Stores the most recently computed yaw (psi) angle estimate.  The angle estimate is stored as a 16-
00449                                     // bit 2's complement integer.  To obtain the actual angle estimate in degrees, the register data
00450                                     // should be multiplied by the scale factor 0.0109863 as shown below
00451 
00452                                     MY_DATA_EULER_PSI = (int16_t)new_packet.packet_data[4]<<8; //bitshift it
00453                                     MY_DATA_EULER_PSI |= new_packet.packet_data[5];
00454                                     data.Yaw = MY_DATA_EULER_PSI*0.0109863;
00455           
00456 
00457                                 } 
00458                                 
00459                                 //-------------------------------------------------------------------
00460                                 // GPS Ground/Speed
00461                                 if (new_packet.address == UM6_GPS_COURSE_SPEED) {
00462                                     // Ground course 
00463                                    MY_DATA_GPS_COURSE = (int16_t)new_packet.packet_data[0]<<8; //bitshift it
00464                                    MY_DATA_GPS_COURSE |= new_packet.packet_data[1];
00465                                    data.GPS_course = MY_DATA_GPS_COURSE;  // need to divide by 100 to get ground course in degrees
00466 
00467                                     // Speed
00468                                     MY_DATA_GPS_SPEED = (int16_t)new_packet.packet_data[2]<<8; //bitshift it
00469                                     MY_DATA_GPS_SPEED |= new_packet.packet_data[3];
00470                                     data.GPS_speed = MY_DATA_GPS_SPEED;
00471 
00472                                     //------------------------------------------------------------                             
00473                                 } 
00474                                 //-------------------------------------------------------------------
00475                                 // GPS long
00476                                if (new_packet.address == UM6_GPS_LONGITUDE) {
00477                                     // Longitude                                 
00478                                   data.GPS_long = MY_DATA_GPS_LONG;  
00479                                }  
00480                                 //------------------------------------------------------------
00481                                //-------------------------------------------------------------------
00482                                 // GPS lat
00483                                if (new_packet.address == UM6_GPS_LATITUDE) {
00484                                     // Latitude                                 
00485                                    data.GPS_lat = MY_DATA_GPS_LAT;  
00486                                }  
00487                                 //------------------------------------------------------------ 
00488                             }    // end if(ADDRESS_TYPE_DATA)
00489 
00490 
00491                             // A full packet has been received.
00492                             // Put the USART back into the WAIT state and reset
00493                             // the data_counter variable so that it can be used to receive the next packet.
00494                             data_counter = 0;
00495                             gUSART_State = USART_STATE_WAIT;
00496 
00497 
00498                         }      // end else(GET_DATA)
00499  
00500                     }
00501                     break;
00502             
00503             }   //  end switch ( gUSART_State )
00504         
00505 return;
00506    
00507  }       // end get_gyro_x()
00508 
00509 #endif