diff --git a/src/filewriter.cpp b/src/filewriter.cpp
index d5fa7ccd27d04cfca610210686d0ce4a65839b5a..c97ba448489e0264ca49009b64b10d0213f313f7 100644
--- a/src/filewriter.cpp
+++ b/src/filewriter.cpp
@@ -6,7 +6,8 @@
  */
 
 #include "filewriter.h"
-#include "Macros.h"
+#include "macros.h"
+#include "decoder.h"
 #include <stdexcept>
 #include <vector>
 #include <iostream>
@@ -124,11 +125,24 @@ void WavFileWriter::write(uint8_t *samples, size_t num_samples, uint8_t *imu_dat
 
 IMUFileWriter::IMUFileWriter(std::string &filename_template, size_t num_channels, size_t sample_rate,size_t depth, size_t timestamp) :
         FileWriter(filename_template, num_channels, sample_rate, depth),
-        outfile(generate_filename(), std::ios::out | std::ios::trunc),
-        last_timestamp(0) {
+        outfile(generate_filename(),
+        std::ios::out | std::ios::trunc),
+        last_timestamp(0),
+        rcvState(StateReception::Waiting),
+        msgDecodedFunction(0),
+        msgDecodedPayloadLength(0),
+        msgDecodedPayload(nullptr),
+        msgDecodedPayloadIndex(0),
+        msgDecoded(0) {
         outfile << header;
 }
 
+IMUFileWriter::~IMUFileWriter() {
+    if (msgDecodedPayload) {
+        free(msgDecodedPayload);
+    }
+}
+
 inline float le16tof(uint8_t *array){
     return static_cast<float>(static_cast<int16_t>(__builtin_bswap16(*reinterpret_cast<uint16_t*>(array))));
 }
@@ -143,115 +157,375 @@ float IMUFileWriter::GetFloatSafe(const unsigned char *p, int index) {
     return result;
 }
 
-void IMUFileWriter::write(uint8_t *sample, size_t size, uint8_t *imu_data) {
-    uint8_t *imu_data_cur(imu_data);
+unsigned char IMUFileWriter::CalculateChecksum(int msgFunction,
+                int msgPayloadLength, const unsigned char msgPayload[])
+{
+    unsigned char checksum = 0;
+    checksum ^= static_cast<unsigned char>(0xFE);
+    checksum ^= static_cast<unsigned char>(msgFunction >> 8);
+    checksum ^= static_cast<unsigned char>(msgFunction >> 0);
+    checksum ^= static_cast<unsigned char>(msgPayloadLength >> 8);
+    checksum ^= static_cast<unsigned char>(msgPayloadLength >> 0);
+    for (int i = 0; i < msgPayloadLength; i++) {
+        checksum ^= msgPayload[i];
+    }
+    return checksum;
+}
 
-    while(imu_data_cur + frame_size + 5 < imu_data + additional_data_size){
-        IMUFileWriter::SensorType sensorType = static_cast<SensorType>(imu_data_cur[0]);
-        unsigned char id = imu_data_cur[1];
-        unsigned char nbChannels = imu_data_cur[2];
-        float rangeScale = GetFloatSafe(imu_data_cur, 3);
-        unsigned char resolutionBits = imu_data_cur[7];
-        float samplingFrequency = GetFloatSafe(imu_data_cur, 8);
-        unsigned short nbSamples = imu_data_cur[12];
-
-        int lengthPerSample = nbChannels * resolutionBits / 8 + 4;
-        double dataMaxValue = std::pow(2, resolutionBits) / 2.0;
-        
-        for(int i = 0; i < nbSamples && size >= static_cast<size_t>(lengthPerSample * i + 13); i++) {
-            uint32_t timeStamp = BUILD_UINT32(imu_data_cur[13 + i * lengthPerSample+3],imu_data_cur[13 + i * lengthPerSample+2],imu_data_cur[13 + i * lengthPerSample+1],imu_data_cur[13 + i * lengthPerSample]);
-            outfile << timeStamp;
-            switch(sensorType) {
-                case IMUFileWriter::SensorType::Accel:
-                        if (lastAccelTimeStamp >= 500000000)
-                            lastAccelTimeStamp = 0;
-                        if (timeStamp > lastAccelTimeStamp) {
-                            lastAccelTimeStamp = timeStamp;
-                            outfile << "ACCEL, " << timeStamp / 1000.0;
-                            outfile << ", " << BUILD_INT16(imu_data_cur[17 + i * lengthPerSample],imu_data_cur[17 + i * lengthPerSample+1]) * ( rangeScale / dataMaxValue );
-                            outfile << ", " << BUILD_INT16(imu_data_cur[17 + size+ i * lengthPerSample],imu_data_cur[17 +size+ i * lengthPerSample+1]) * ( rangeScale / dataMaxValue );
-                            outfile << ", " << BUILD_INT16(imu_data_cur[17 + 2*size+ i * lengthPerSample],imu_data_cur[17 +2*size+ i * lengthPerSample+1]) * ( rangeScale / dataMaxValue );
+void IMUFileWriter::DecodeMessage(unsigned char c) {
+        switch (rcvState) {
+            case StateReception::Waiting:
+                if (c == 0xFE)
+                    rcvState = StateReception::FunctionMSB;
+                break;
+            case StateReception::FunctionMSB:
+                msgDecodedFunction = static_cast<int>(c << 8);
+                rcvState = StateReception::FunctionLSB;
+                break;
+            case StateReception::FunctionLSB:
+                msgDecodedFunction += static_cast<int>(c << 0);
+                rcvState = StateReception::PayloadLengthMSB;
+                break;
+            case StateReception::PayloadLengthMSB:
+                msgDecodedPayloadLength = static_cast<int>(c << 8);
+                rcvState = StateReception::PayloadLengthLSB;
+                break;
+            case StateReception::PayloadLengthLSB:
+                msgDecodedPayloadLength += static_cast<int>(c << 0);
+                if (msgDecodedPayloadLength > 0) {
+                    if (msgDecodedPayloadLength < 1024) {
+                        msgDecodedPayloadIndex = 0;
+                        msgDecodedPayload = static_cast<unsigned char*>(malloc(msgDecodedPayloadLength));
+                        if (msgDecodedPayload == nullptr) {
+                            throw std::bad_alloc(); // Handle memory allocation failure
+                        }
+                        rcvState = StateReception::Payload;
+                    } else {
+                        rcvState = StateReception::Waiting;
+                    }
+                } else
+                    rcvState = StateReception::CheckSum;
+                break;
+            case StateReception::Payload:
+                if (msgDecodedPayloadIndex > msgDecodedPayloadLength)
+                {
+                    //Erreur
+                    msgDecodedPayloadIndex = 0;
+                    rcvState = StateReception::Waiting;
+                }
+                msgDecodedPayload[msgDecodedPayloadIndex++] = c;
+                if (msgDecodedPayloadIndex >= msgDecodedPayloadLength)
+                {
+                    rcvState = StateReception::CheckSum;
+                    msgDecodedPayloadIndex = 0;
+                }
+                break;
+            case StateReception::CheckSum:
+            {
+                unsigned char calculatedChecksum = CalculateChecksum(msgDecodedFunction, msgDecodedPayloadLength, msgDecodedPayload);
+                unsigned char receivedChecksum = c;
+                if (calculatedChecksum == receivedChecksum) {
+                    //Lance l'event de fin de decodage
+                    ProcessDecodedMessage(msgDecodedFunction, msgDecodedPayloadLength, msgDecodedPayload);
+                    msgDecoded++;
+                } else {
+                    std::cerr << "Checksum error" << std::endl;
+                }
+                rcvState = StateReception::Waiting;
+            }
+            break;
+            default:
+                rcvState = StateReception::Waiting;
+                break;
+        }
+}
+
+void IMUFileWriter::ProcessDecodedMessage(int msgFunction, int msgPayloadLength, const unsigned char* msgPayload) {
+    unsigned int timeStamp = 0;
+    switch(static_cast<short>(command)) {
+        case static_cast<short>(HS_DATA_PACKET_FULL_TIMESTAMP): {
+            /*
+            IMUFileWriter::SensorType sensorType = static_cast<SensorType>(msgPayload[0]);
+            unsigned char id = msgPayload[1];
+            unsigned char nbChannels = msgPayload[2];
+            unsigned char range = msgPayload[3];
+            unsigned char resolutionBits = msgPayload[4];
+            unsigned short samplingFrequency = BUILD_UINT16(msgPayload[6], msgPayload[5]);
+            unsigned short nbSamples = BUILD_UINT16(msgPayload[8], msgPayload[7]);
+
+            int lengthPerSample = nbChannels * resolutionBits / 8 + 4;
+            double accelMaxValue = pow(2, resolutionBits)/2;
+            double gyroMaxValue = pow(2, resolutionBits) / 2;
+            double gyroRange = 250.0;       //Hardcode pour le moment
+            double magRange = 4900.0;       //Fixe
+
+            for(int i=0; i < nbSamples && msgPayloadLength >= lengthPerSample * i + 9; i++) {
+                timeStamp = BUILD_UINT32(9 + i * lengthPerSample, 9 + i * 9 + i * lengthPerSample+1, 9 + i * lengthPerSample+2, 9 + i * lengthPerSample+3);
+
+                if(timeStamp > lastTimeStamp): {
+                    lastTimeStamp = timeStamp;
+                    switch(sensorType) {
+                        case IMUFileWriter::SensorType::IMU: {
+                            outfile << timeStamp;
+                            outfile << ", " << BUILD_UINT16(13 + i * lengthPerSample,13 + i * lengthPerSample+1); // AccelX
+                            outfile << ", " << BUILD_UINT16(15 + i * lengthPerSample,15 + i * lengthPerSample+1); // AccelY
+                            outfile << ", " << BUILD_UINT16(17 + i * lengthPerSample,17 + i * lengthPerSample+1); // AccelZ
+                            outfile << ", " << BUILD_UINT16(19 + i * lengthPerSample,19 + i * lengthPerSample+1); // GyroX
+                            outfile << ", " << BUILD_UINT16(21 + i * lengthPerSample,21 + i * lengthPerSample+1); // GyroY
+                            outfile << ", " << BUILD_UINT16(23 + i * lengthPerSample,23 + i * lengthPerSample+1); // GyroZ
+                            outfile << ", " << BUILD_UINT16(25 + i * lengthPerSample,25 + i * lengthPerSample+1); // MagX
+                            outfile << ", " << BUILD_UINT16(27 + i * lengthPerSample,27 + i * lengthPerSample+1); // MagY
+                            outfile << ", " << BUILD_UINT16(29 + i * lengthPerSample,29 + i * lengthPerSample+1); // MagZ
+                            outfile << std::endl;
+                        }
+                        break;
+                        case IMUFileWriter::SensorType::Accel:
+                            break;
+                        case IMUFileWriter::SensorType::Gyro:
+                            break;
+                        case IMUFileWriter::SensorType::Mag:
+                            break;
+                        case IMUFileWriter::SensorType::Temperature:
+                            break;
+                        case IMUFileWriter::SensorType::Pressure:
+                            break;
+                        case IMUFileWriter::SensorType::Light:
+                            break;
+                        default:
+                            break;
+                    }
+                } else {
+                    outfile << "TS IMU Error" << std::endl;
+                }
+            }*/
+           outfile << "Not implemented yet. Deprecated version?" << std::endl; // Commented block added by Philémon Prévot 29/08/2024
+        }
+        break;
+        case static_cast<short>(HS_DATA_PACKET_FULL_TIMESTAMP_V2): {
+            IMUFileWriter::SensorType sensorType = static_cast<SensorType>(msgPayload[0]);
+            unsigned char id = msgPayload[1];
+            unsigned char nbChannels = msgPayload[2];
+            float rangeScale = GetFloatSafe(msgPayload, 3);
+            unsigned char resolutionBits = msgPayload[7];
+            float samplingFrequency = GetFloatSafe(msgPayload, 8);
+            unsigned short nbSamples = msgPayload[12];
+
+            int lengthPerSample = nbChannels * resolutionBits / 8 + 4;
+            double dataMaxValue = std::pow(2, resolutionBits) / 2.0;
+            
+            for(int i = 0; i < nbSamples && size >= static_cast<size_t>(lengthPerSample * i + 13); i++) {
+                uint32_t timeStamp = BUILD_UINT32(msgPayload[13 + i * lengthPerSample+3],msgPayload[13 + i * lengthPerSample+2],msgPayload[13 + i * lengthPerSample+1],msgPayload[13 + i * lengthPerSample]);
+                switch(sensorType) {
+                    case IMUFileWriter::SensorType::Accel:
+                            if (lastAccelTimeStamp >= 500000000)
+                                lastAccelTimeStamp = 0;
+                            if (timeStamp > lastAccelTimeStamp) {
+                                lastAccelTimeStamp = timeStamp;
+                                outfile << "ACCEL, " << timeStamp / 1000.0;
+                                outfile << ", " << BUILD_INT16(msgPayload[17 + i * lengthPerSample],msgPayload[17 + i * lengthPerSample+1]) * ( rangeScale / dataMaxValue );
+                                outfile << ", " << BUILD_INT16(msgPayload[17 + size+ i * lengthPerSample],msgPayload[17 +size+ i * lengthPerSample+1]) * ( rangeScale / dataMaxValue );
+                                outfile << ", " << BUILD_INT16(msgPayload[17 + 2*size+ i * lengthPerSample],msgPayload[17 +2*size+ i * lengthPerSample+1]) * ( rangeScale / dataMaxValue );
+                                outfile << std::endl;
+                            }
+                            else {
+                                //printf("TS Accel Error\n");
+                            }
+                        break;
+                    case IMUFileWriter::SensorType::Gyro:
+                            if (lastGyroTimeStamp >= 500000000)
+                                lastGyroTimeStamp = 0;
+                            if (timeStamp > lastGyroTimeStamp) {
+                                lastGyroTimeStamp = timeStamp;
+                                outfile << "GYRO, " << timeStamp;
+                                outfile << ", " << BUILD_INT16(msgPayload[17 + i * lengthPerSample],msgPayload[17 + i * lengthPerSample+1]) * ( rangeScale / dataMaxValue);
+                                outfile << ", " << BUILD_INT16(msgPayload[17 + size+ i * lengthPerSample],msgPayload[17 +size+ i * lengthPerSample+1]) * ( rangeScale / dataMaxValue);
+                                outfile << ", " << BUILD_INT16(msgPayload[17 + 2*size+ i * lengthPerSample],msgPayload[17 +2*size+ i * lengthPerSample+1]) * ( rangeScale / dataMaxValue);
+                                outfile << std::endl;
+                            }
+                            else {
+                                //printf("TS Gyro Error\n");
+                            }
+                        break;
+                    case IMUFileWriter::SensorType::Mag:
+                            if (lastMagTimeStamp >= 500000000)
+                                lastMagTimeStamp = 0;
+                            if (timeStamp > lastMagTimeStamp) {
+                                lastMagTimeStamp = timeStamp;
+                                outfile << "MAG, " << timeStamp;
+                                outfile << ", " << BUILD_INT16(msgPayload[17 + i * lengthPerSample+1],msgPayload[17 + i * lengthPerSample]) * ( rangeScale / dataMaxValue);
+                                outfile << ", " << BUILD_INT16(msgPayload[17 + size+ i * lengthPerSample+1],msgPayload[17 +size+ i * lengthPerSample]) * ( rangeScale / dataMaxValue);
+                                outfile << ", " << BUILD_INT16(msgPayload[17 + 2*size+ i * lengthPerSample+1],msgPayload[17 +2*size+ i * lengthPerSample]) * ( rangeScale / dataMaxValue);
+                                outfile << std::endl;
+                            }
+                            else {
+                                //printf("TS Mag Error\n");
+                            }
+                        break;
+                    case IMUFileWriter::SensorType::Temperature:
+                        if (lastTemperatureTimeStamp >= 500000000)
+                            lastTemperatureTimeStamp = 0;
+                        if (timeStamp > lastTemperatureTimeStamp) {
+                            lastTemperatureTimeStamp = timeStamp;
+                            outfile << "TEMP, " << timeStamp;
+                            outfile << ", " << GetFloatSafe(msgPayload,17 + i * lengthPerSample);
                             outfile << std::endl;
                         }
                         else {
-                            //printf("TS Accel Error\n");
+                            //printf("TS Temperature Error\n");
                         }
-                    break;
-                case IMUFileWriter::SensorType::Gyro:
-                        if (lastGyroTimeStamp >= 500000000)
-                            lastGyroTimeStamp = 0;
-                        if (timeStamp > lastGyroTimeStamp) {
-                            lastGyroTimeStamp = timeStamp;
-                            outfile << "GYRO, " << timeStamp;
-                            outfile << ", " << BUILD_INT16(imu_data_cur[17 + i * lengthPerSample],imu_data_cur[17 + i * lengthPerSample+1]) * ( rangeScale / dataMaxValue);
-                            outfile << ", " << BUILD_INT16(imu_data_cur[17 + size+ i * lengthPerSample],imu_data_cur[17 +size+ i * lengthPerSample+1]) * ( rangeScale / dataMaxValue);
-                            outfile << ", " << BUILD_INT16(imu_data_cur[17 + 2*size+ i * lengthPerSample],imu_data_cur[17 +2*size+ i * lengthPerSample+1]) * ( rangeScale / dataMaxValue);
+                        break;
+                    case IMUFileWriter::SensorType::Pressure:
+                        if (lastPressureTimeStamp >= 500000000)
+                            lastPressureTimeStamp = 0;
+                        if (timeStamp > lastPressureTimeStamp) {
+                            lastPressureTimeStamp = timeStamp;
+                            outfile << "PRESSURE, " << timeStamp;
+                            outfile << ", " << IMUFileWriter::GetFloatSafe(msgPayload,17 + i * lengthPerSample);
                             outfile << std::endl;
                         }
                         else {
-                            //printf("TS Gyro Error\n");
+
                         }
-                    break;
-                case IMUFileWriter::SensorType::Mag:
-                        if (lastMagTimeStamp >= 500000000)
-                            lastMagTimeStamp = 0;
-                        if (timeStamp > lastMagTimeStamp) {
-                            lastMagTimeStamp = timeStamp;
-                            outfile << "MAG, " << timeStamp;
-                            outfile << ", " << BUILD_INT16(imu_data_cur[17 + i * lengthPerSample+1],imu_data_cur[17 + i * lengthPerSample]) * ( rangeScale / dataMaxValue);
-                            outfile << ", " << BUILD_INT16(imu_data_cur[17 + size+ i * lengthPerSample+1],imu_data_cur[17 +size+ i * lengthPerSample]) * ( rangeScale / dataMaxValue);
-                            outfile << ", " << BUILD_INT16(imu_data_cur[17 + 2*size+ i * lengthPerSample+1],imu_data_cur[17 +2*size+ i * lengthPerSample]) * ( rangeScale / dataMaxValue);
+                        break;
+                    case IMUFileWriter::SensorType::Light:
+                        if (lastLightTimeStamp >= 500000000)
+                            lastLightTimeStamp = 0;
+                        if (timeStamp > lastLightTimeStamp) {
+                            lastLightTimeStamp = timeStamp;
+                            outfile << "LIGHT, " << timeStamp;
+                            outfile << ", " << BUILD_UINT16(msgPayload[17 + i * lengthPerSample],msgPayload[17 + i * lengthPerSample+1]);
+                            outfile << ", " << BUILD_UINT16(msgPayload[17 + size+i * lengthPerSample],msgPayload[17 +size+ i * lengthPerSample+1]);
                             outfile << std::endl;
                         }
                         else {
-                            //printf("TS Mag Error\n");
+                            //printf("TS Light Error\n");
                         }
-                    break;
-                case IMUFileWriter::SensorType::Temperature:
-                    if (lastTemperatureTimeStamp >= 500000000)
-                        lastTemperatureTimeStamp = 0;
-                    if (timeStamp > lastTemperatureTimeStamp) {
-                        lastTemperatureTimeStamp = timeStamp;
-                        outfile << "TEMP, " << timeStamp;
-                        outfile << ", " << GetFloatSafe(imu_data_cur,17 + i * lengthPerSample);
+                        break;
+                    case IMUFileWriter::SensorType::Unknown:
+                        outfile << "UNKNOWN, " << timeStamp;
                         outfile << std::endl;
-                    }
-                    else {
-                        //printf("TS Temperature Error\n");
-                    }
-                    break;
-                case IMUFileWriter::SensorType::Pressure:
-                    if (lastPressureTimeStamp >= 500000000)
-                        lastPressureTimeStamp = 0;
-                    if (timeStamp > lastPressureTimeStamp) {
-                        lastPressureTimeStamp = timeStamp;
-                        outfile << "PRESSURE, " << timeStamp;
-                        outfile << ", " << IMUFileWriter::GetFloatSafe(imu_data_cur,17 + i * lengthPerSample);
-                        outfile << std::endl;
-                    }
-                    else {
+                    default:
+                        break;
+                }
+            }
+        }
+        break;
+        case static_cast<short>(GPS_DATA_PACKET): {
+            IMUFileWriter::GPSDatas gpsDatas;
+            unsigned short ms = BUILD_UINT16(payload[3], payload[4]);
+            if(ms > 999) {
+                ms = 0;
+            }
 
-                    }
-                    break;
-                case IMUFileWriter::SensorType::Light:
-                    if (lastLightTimeStamp >= 500000000)
-                        lastLightTimeStamp = 0;
-                    if (timeStamp > lastLightTimeStamp) {
-                        lastLightTimeStamp = timeStamp;
-                        outfile << "LIGHT, " << timeStamp;
-                        outfile << ", " << BUILD_UINT16(imu_data_cur[17 + i * lengthPerSample],imu_data_cur[17 + i * lengthPerSample+1]);
-                        outfile << ", " << BUILD_UINT16(imu_data_cur[17 + size+i * lengthPerSample],imu_data_cur[17 +size+ i * lengthPerSample+1]);
-                        outfile << std::endl;
-                    }
-                    else {
-                        //printf("TS Light Error\n");
-                    }
-                    break;
-                case IMUFileWriter::SensorType::Unknown:
-                    outfile << "UNKNOWN, " << timeStamp;
+            gps.Datas.dateOfFix.year = payload[7];
+            gpsDatas.dateOfFix.month = payload[6];
+            gpsDatas.dateOfFix.day = payload[5];
+            gpsDatas.dateOfFix.hour = payload[0];
+            gpsDatas.dateOfFix.minute = payload[1];
+            gpsDatas.dateOfFix.second = payload[2];
+
+            gpsDatas.fix = payload[8] != 0;
+            gpsDatas.fixQuality = payload[9];
+            gpsDatas.latitude = GetFloatSafe(payload.data(), 10);
+            gpsDatas.latitudeDirection = static_cast<char>(payload[14]);
+            gpsDatas.longitude = GetFloatSafe(payload.data(), 15);
+            gpsDatas.longitudeDirection = static_cast<char>(payload[19]);
+            gpsDatas.speed = GetFloatSafe(payload.data(), 20);
+            gpsDatas.angle = GetFloatSafe(payload.data(), 24);
+            gpsDatas.altitude = GetFloatSafe(payload.data(), 28);
+            gpsDatas.satellites = payload[32];
+            gpsDatas.antenna = payload[33];
+
+            if (lastGPSDate.year != gpsDatas.dateOfFix.year ||lastGPSDate.month != gpsDatas.dateOfFix.month ||lastGPSDate.day != gpsDatas.dateOfFix.day || 
+                lastGPSDate.hour!=gpsDatas.dateOfFix.hour || lastGPSDate.minute!=gpsDatas.dateOfFix.minute || lastGPSDate.second!=gpsDatas.dateOfFix.second): {
+                lastGPSDate = gpsDatas.dateOfFix;
+                outfile << "GPS, " << gpsDatas.dateOfFix.year;
+                outfile << "/" << gpsDatas.dateOfFix.month;
+                outfile << "/" << gpsDatas.dateOfFix.day;
+                outfile << " " << gpsDatas.dateOfFix.hour;
+                outfile << ":" << gpsDatas.dateOfFix.minute;
+                outfile << ":" << gpsDatas.dateOfFix.second;
+                outfile << " fix:" << gpsDatas.fix;
+                outfile << ", fixQual:" << gpsDatas.fixQuality;
+                outfile << ", Lat:" << gpsDatas.latitude;
+                outfile << " " << gpsDatas.latitudeDirection;
+                outfile << ", Lon:" << gpsDatas.longitude;
+                outfile << " " << gpsDatas.longitudeDirection;
+                outfile << ", speed:" << gpsDatas.speed;
+                outfile << ", ang:" << gpsDatas.angle;
+                outfile << ", alt:" << gpsDatas.altitude;
+                outfile << ", sat:" << gpsDatas.satellites;
+                outfile << std::endl;
+            }
+        }
+        break;
+        case static_cast<short>(GPS_PPS_PACKET): {
+            uint64_t PPSTimeStamp = BUILD_UINT64(payload[7], payload[6], payload[5], payload[4],
+                                          payload[3], payload[2], payload[1], payload[0]);
+
+            PPSTimeStamp *= 10; // Convert to nanoseconds (assuming internal clock frequency is 100MHz)
+
+            if(PPSTimeStamp>lastPPSTimeStampNS): {
+                lastPPSTimeStampNS = PPSTimeStamp;
+                outfile << "PPS: " << PPSTimeStamp;
+                outfile << std::endl;
+            }
+        }
+        break;
+        default: break;
+    }
+}
+
+void IMUFileWriter::write(uint8_t *sample, size_t size, uint8_t *imu_data) {
+    uint8_t *imu_data_cur(imu_data);
+
+    while(imu_data_cur + frame_size + 5 < imu_data + additional_data_size){
+        softwareMajorRev=sample[5];
+        softwareMinorRev=sample[6];
+
+        if(softwareMajorRev>=2) {
+            //On recupere l'instant de fin du paquet courant
+            timeStamp100MHzCurrentPacket=BUILD_UINT64(sample[14],
+                        sample[13],
+                        sample[12],
+                        sample[11],
+                        sample[10],
+                        sample[9],
+                        sample[8],
+                        sample[7]);
+            timeStamp100MHzCurrentPacket*=10;     //To put the ts in ns
+            enteteSize=16;
+
+            for(int i=enteteSize;i<hdr.sizeOfAdditionnalDataBuffer-enteteSize; i++)
+            {
+                DecodeMessage(sample[i]);
+            }
+        }
+        else {
+            uint8_t *imu_data_cur(imu_data);
+            while(imu_data_cur + frame_size + 5 < imu_data + additional_data_size){
+                if(!(imu_data_cur[0]==0xFE && imu_data_cur[1]==0x0A && imu_data_cur[2]==0x0A && imu_data_cur[5]==0x08)){
+                // skip trame if header is incorrect
+                imu_data_cur += frame_size + 5;
+                continue;
+                }
+                imu_data_cur += 5; // skip frame header
+                auto timestamp = static_cast<int32_t>(__builtin_bswap32(*reinterpret_cast<uint32_t*>(imu_data_cur + 9)));
+                if (timestamp > last_timestamp) {
+                    last_timestamp = timestamp;
+                    outfile << timestamp;
+                    outfile << "," << le16tof(imu_data_cur + 13) / 32756 * 19.62;   // ax resolution +- 2g
+                    outfile << "," << le16tof(imu_data_cur + 15) / 32756 * 19.62;   // ay resolution +- 2g
+                    outfile << "," << le16tof(imu_data_cur + 17) / 32756 * 19.62;   // az resolution +- 2g
+                    outfile << "," << le16tof(imu_data_cur + 19) / 32756 * 250;     // gx resolution +- 255deg/sec
+                    outfile << "," << le16tof(imu_data_cur + 21) / 32756 * 250;     // gy resolution +- 255deg/sec
+                    outfile << "," << le16tof(imu_data_cur + 23) / 32756 * 250;     // gz resolution +- 255deg/sec
+                    outfile << "," << le16tof(imu_data_cur + 25) / 32756 * 4900.;    // mx +- 4900µTesla
+                    outfile << "," << le16tof(imu_data_cur + 27) / 32756 * (-4900.); // my +- 4900µTesla
+                    outfile << "," << le16tof(imu_data_cur + 29) / 32756 * (-4900.); // mz +- 4900µTesla
                     outfile << std::endl;
-                default:
-                    break;
+                }
+                imu_data_cur += frame_size;
             }
         }
         imu_data_cur += frame_size;
diff --git a/src/filewriter.h b/src/filewriter.h
index 317b54591fa0f5fa2b6e2503ddc3bb1b4db40b55..7d03242ab768c09548c6bacbfa4f4f3a3875b25e 100644
--- a/src/filewriter.h
+++ b/src/filewriter.h
@@ -12,6 +12,12 @@
 #include <string>
 #include <vector>
 #include <fstream>
+#include <iostream>
+#include <cstdio>
+#define HS_DATA_PACKET_FULL_TIMESTAMP 0x0A0A
+#define HS_DATA_PACKET_FULL_TIMESTAMP_V2 0x0A0C
+#define GPS_DATA_PACKET 0x0A0D
+#define GPS_PPS_PACKET 0x0A0E
 
 
 /** Abstract base class for writing sample data to files.
@@ -151,7 +157,8 @@ private:
         Temperature = 4,
         Pressure = 5,
         Light = 6,
-        Piezo = 7
+        Piezo = 7,
+        IMU = 8
     };
     struct DateTime {
         unsigned short year;
@@ -162,6 +169,21 @@ private:
         unsigned char minute;
         unsigned char second;
     };
+    struct GPSDatas {
+        DateTime dateOfFix;
+        bool fix;
+        unsigned char fixQuality;
+        double latitude;
+        char latitudeDirection;
+        double longitude;
+        char longitudeDirection;
+        double speed;
+        double angle;
+        double altitude;
+        unsigned char satellites;
+        unsigned char antenna;
+    };
+
     std::ofstream outfile;
     size_t last_timestamp;
     unsigned int lastAccelTimeStamp;
@@ -173,6 +195,27 @@ private:
     unsigned int lastTimeStamp;
     DateTime lastGPSDate;
     double lastPPSTimeStampNS;
+
+    enum class StateReception {
+        Waiting;
+        FunctionMSB;
+        FunctionLSB;
+        PayloadLengthMSB;
+        PayloadLengthLSB;
+        Payload;
+        CheckSum;
+    };
+
+    StateReception rcvState;
+    int msgDecodedFunction;
+    int msgDecodedPayloadLength;
+    unsigned char *msgDecodedPayload;
+    int msgDecodedPayloadIndex;
+    unsigned int msgDecoded;
+
+    void ProcessDecodedMessage(int msgFunction, int msgPayloadLength,
+                               const unsigned char* msgPayload);
+    float GetFloatSafe(const unsigned char *p, int index);
 public:
     /** Instantiates a splitted wave file writer.
      * \param[in] filename_template The name of the file to write to. Will be
@@ -189,7 +232,12 @@ public:
      * \param[in] samples_per_file The target number of samples (per channel)
      * that will be written to a file before starting the next one.
      */
+    unsigned char CalculateChecksum(int msgFunction,
+                int msgPayloadLength, unsigned char msgPayload[]);
+    void DecodeMessage(unsigned char c);
+
     IMUFileWriter(std::string &filename_template, size_t num_channels, size_t sample_rate, size_t depth, size_t timestamp);
+    ~IMUFileWriter();
     void write(uint8_t *samples, size_t num_samples, uint8_t *imu_data) override;
     size_t get_last_timestamp();
     float GetFloatSafe(const unsigned char *p, int index);