diff --git a/src/shared/sensors/UbloxGPS/UBXUnpackedFrame.h b/src/shared/sensors/UbloxGPS/UBXUnpackedFrame.h
deleted file mode 100644
index ff3e1c83d3499f443de147b79996735208713988..0000000000000000000000000000000000000000
--- a/src/shared/sensors/UbloxGPS/UBXUnpackedFrame.h
+++ /dev/null
@@ -1,120 +0,0 @@
-/* Copyright (c) 2021 Skyward Experimental Rocketry
- * Author: Damiano Amatruda
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#pragma once
-
-#include <algorithm>
-
-namespace Boardcore
-{
-
-static constexpr uint16_t UBX_MAX_PAYLOAD_LENGTH = 92;
-static constexpr uint16_t UBX_MAX_FRAME_LENGTH   = UBX_MAX_PAYLOAD_LENGTH + 8;
-static constexpr uint8_t UBX_VALID_PREAMBLE[]    = {0xb5, 0x62};
-
-struct UBXUnpackedFrame
-{
-    uint8_t preamble[2];
-    uint8_t cls;
-    uint8_t id;
-    uint8_t payload[UBX_MAX_PAYLOAD_LENGTH];
-    uint16_t payloadLength;
-    uint8_t checksum[2];
-
-    UBXUnpackedFrame() = default;
-
-    UBXUnpackedFrame(uint8_t cls, uint8_t id, const uint8_t* payload,
-                     uint16_t payloadLength)
-        : cls(cls), id(id), payloadLength(payloadLength)
-    {
-        memcpy(preamble, UBX_VALID_PREAMBLE, 2);
-
-        memcpy(this->payload, payload,
-               std::min(payloadLength, UBX_MAX_PAYLOAD_LENGTH));
-
-        calcChecksum(checksum);
-    }
-
-    inline uint16_t getFrameLength() const { return payloadLength + 8; }
-
-    inline bool isValid() const
-    {
-        if (memcmp(preamble, UBX_VALID_PREAMBLE, 2) != 0)
-        {
-            return false;
-        }
-
-        if (payloadLength > UBX_MAX_PAYLOAD_LENGTH)
-        {
-            return false;
-        }
-
-        uint8_t validChecksum[2];
-        calcChecksum(validChecksum);
-        return memcmp(checksum, validChecksum, 2) == 0;
-    }
-
-    inline void writePacked(uint8_t* frame) const
-    {
-        memcpy(frame, preamble, 2);
-        frame[2] = cls;
-        frame[3] = id;
-        memcpy(&frame[4], &payloadLength, 2);
-        memcpy(&frame[6], payload, payloadLength);
-        memcpy(&frame[6 + payloadLength], checksum, 2);
-    }
-
-    inline void readPacked(const uint8_t* frame)
-    {
-        memcpy(preamble, frame, 2);
-        cls = frame[2];
-        id  = frame[3];
-        memcpy(&payloadLength, &frame[4], 2);
-        memcpy(payload, &frame[6],
-               std::min(payloadLength, UBX_MAX_PAYLOAD_LENGTH));
-        memcpy(checksum, &frame[6 + payloadLength], 2);
-    }
-
-    inline void calcChecksum(uint8_t* checksum) const
-    {
-        uint8_t data[UBX_MAX_FRAME_LENGTH];
-        data[0] = cls;
-        data[1] = id;
-        memcpy(&data[2], &payloadLength, 2);
-        memcpy(&data[4], payload,
-               std::min(payloadLength, UBX_MAX_PAYLOAD_LENGTH));
-
-        uint16_t dataLength =
-            std::min(payloadLength, UBX_MAX_PAYLOAD_LENGTH) + 4;
-
-        checksum[0] = 0;
-        checksum[1] = 0;
-
-        for (uint8_t i = 0; i < dataLength; ++i)
-        {
-            checksum[0] += data[i];
-            checksum[1] += checksum[0];
-        }
-    }
-};
-
-}  // namespace Boardcore
diff --git a/src/shared/sensors/UbloxGPS/UbloxGPS.cpp b/src/shared/sensors/UbloxGPS/UbloxGPS.cpp
index 3bc0879ad7138d4a49b3c5860357a14f431eb3ed..dff24046dfefeca63f88c4499f1d0b2bf4c9f9ce 100644
--- a/src/shared/sensors/UbloxGPS/UbloxGPS.cpp
+++ b/src/shared/sensors/UbloxGPS/UbloxGPS.cpp
@@ -1,5 +1,5 @@
 /* Copyright (c) 2021 Skyward Experimental Rocketry
- * Authors: Davide Bonomini, Davide Mor, Alberto Nidasio, Damiano Amatruda
+ * Authors: Davide Bonomini, Davide Mor, Alberto Nidasio
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to deal
@@ -28,27 +28,39 @@
 #include <fcntl.h>
 #include <filesystem/file_access.h>
 
+using namespace miosix;
+
 namespace Boardcore
 {
 
-using namespace miosix;
+UbloxGPS::UbloxGPS(int baudrate_, uint8_t sampleRate_, int serialPortNum_,
+                   const char* serialPortName_, int defaultBaudrate_)
+    : baudrate(baudrate_), sampleRate(sampleRate_),
+      serialPortNumber(serialPortNum_), serialPortName(serialPortName_),
+      defaultBaudrate(defaultBaudrate_)
+{
+    // Prepare the gps file path with the specified name
+    strcpy(gpsFilePath, "/dev/");
+    strcat(gpsFilePath, serialPortName);
+}
 
 bool UbloxGPS::init()
 {
     // Change the baud rate from the default value
-    if (!setupCommunication())
+    if (!serialCommuinicationSetup())
     {
         return false;
     }
 
+    Thread::sleep(10);
+
     // Reset configuration to default
+    // TODO: maybe move this on serial communication setup
     if (!resetConfiguration())
     {
         return false;
     }
 
-    Thread::sleep(100);
-
     // Disable NMEA messages
     if (!disableNMEAMessages())
     {
@@ -73,8 +85,8 @@ bool UbloxGPS::init()
 
     Thread::sleep(100);
 
-    // Set sample rate
-    if (!setSampleRate())
+    // Set rate
+    if (!setRate())
     {
         return false;
     }
@@ -86,57 +98,200 @@ bool UbloxGPS::selfTest() { return true; }
 
 UbloxGPSData UbloxGPS::sampleImpl()
 {
-    Lock<FastMutex> l(sampleMutex);
-    return lastSample;
+    Lock<FastMutex> l(mutex);
+    return threadSample;
 }
 
 void UbloxGPS::run()
 {
-    UBXUnpackedFrame frame;
+    /**
+     * UBX message structure:
+     * - 2B: Preamble
+     * - 1B: Message class
+     * - 1B: Message id
+     * - 2B: Payload length
+     * - lB: Payload
+     * - 2B: Checksum
+     */
+    uint8_t message[6 + UBX_MAX_PAYLOAD_LENGTH + 2];
+    uint16_t payloadLength;
 
     while (!shouldStop())
     {
         StackLogger::getInstance().updateStack(THID_GPS);
 
         // Try to read the message
-        if (!readUBXFrame(frame))
+        if (!readUBXMessage(message, payloadLength))
         {
             LOG_DEBUG(logger, "Unable to read a UBX message");
             continue;
         }
 
         // Parse the message
-        if (!parseUBXFrame(frame))
+        if (!parseUBXMessage(message))
         {
-            LOG_DEBUG(
-                logger,
-                "UBX message not recognized (class: {:#02x}, id: {:#02x})",
-                frame.cls, frame.id);
+            LOG_DEBUG(logger,
+                      "UBX message not recognized (class:0x{02x}, id: 0x{02x})",
+                      message[2], message[3]);
         }
     }
 }
 
-bool UbloxGPS::resetConfiguration()
+void UbloxGPS::ubxChecksum(uint8_t* msg, int len)
+{
+    uint8_t ck_a = 0, ck_b = 0;
+
+    // The length must be valid, at least 8 bytes (preamble, msg, length,
+    // checksum)
+    if (len <= 8)
+    {
+        return;
+    }
+
+    // Checksum calculation from byte 2 to end of payload
+    for (int i = 2; i < len - 2; i++)
+    {
+        ck_a = ck_a + msg[i];
+        ck_b = ck_b + ck_a;
+    }
+
+    msg[len - 2] = ck_a;
+    msg[len - 1] = ck_b;
+}
+
+bool UbloxGPS::writeUBXMessage(uint8_t* message, int length)
+{
+    // Compute the checksum
+    ubxChecksum(message, length);
+
+    // Write configuration
+    if (write(gpsFile, message, length) < 0)
+    {
+        LOG_ERR(logger,
+                "Failed to write ubx message (class:0x{02x}, id: 0x{02x})",
+                message[2], message[3]);
+        return false;
+    }
+
+    return true;
+}
+
+bool UbloxGPS::serialCommuinicationSetup()
 {
-    static constexpr uint16_t payloadLength = 4;
+    intrusive_ref_ptr<DevFs> devFs = FilesystemManager::instance().getDevFs();
+
+    // Change the baudrate only if it is different than the default
+    if (baudrate != defaultBaudrate)
+    {
+        // Close the gps file if already opened
+        devFs->remove(serialPortName);
+
+        // Open the serial port device with the default boudrate
+        if (!devFs->addDevice(serialPortName,
+                              intrusive_ref_ptr<Device>(new STM32Serial(
+                                  serialPortNumber, defaultBaudrate))))
+        {
+            LOG_ERR(logger,
+                    "[gps] Faild to open serial port {0} with baudrate {1} as "
+                    "file {2}",
+                    serialPortNumber, defaultBaudrate, serialPortName);
+            return false;
+        }
+
+        // Open the gps file
+        if ((gpsFile = open(gpsFilePath, O_RDWR)) < 0)
+        {
+            LOG_ERR(logger, "Failed to open gps file {}", gpsFilePath);
+            return false;
+        }
+
+        // Change boudrate
+        if (!setBaudrate())
+        {
+            return false;
+        };
+
+        // Close the gps file
+        if (close(gpsFile) < 0)
+        {
+            LOG_ERR(logger, "Failed to close gps file {}", gpsFilePath);
+            return false;
+        }
+
+        // Close the serial port
+        if (!devFs->remove(serialPortName))
+        {
+            LOG_ERR(logger, "Failed to close serial port {} as file {}",
+                    serialPortNumber, serialPortName);
+            return false;
+        }
+    }
+
+    // Reopen the serial port with the configured boudrate
+    if (!devFs->addDevice(serialPortName,
+                          intrusive_ref_ptr<Device>(
+                              new STM32Serial(serialPortNumber, baudrate))))
+    {
+        LOG_ERR(logger,
+                "Faild to open serial port {} with baudrate {} as file {}\n",
+                serialPortNumber, defaultBaudrate, serialPortName);
+        return false;
+    }
+
+    // Reopen the gps file
+    if ((gpsFile = open(gpsFilePath, O_RDWR)) < 0)
+    {
+        LOG_ERR(logger, "Failed to open gps file {}", gpsFilePath);
+        return false;
+    }
+
+    return true;
+}
 
-    uint8_t payload[payloadLength] = {
+bool UbloxGPS::resetConfiguration()
+{
+    uint8_t ubx_cfg_prt[RESET_CONFIG_MSG_LEN] = {
+        0Xb5, 0x62,  // Preamble
+        0x06, 0x04,  // Message UBX-CFG-RST
+        0x04, 0x00,  // Length
         0x00, 0x00,  // navBbrMask (Hot start)
         0x00,        // Hardware reset immediately
-        0x00         // Reserved
+        0x00,        // Reserved
+        0xff, 0xff   // Checksum
     };
 
-    UBXUnpackedFrame frame{0x06, 0x04,  // Message UBX-CFG-RST
-                           payload, payloadLength};
+    return writeUBXMessage(ubx_cfg_prt, RESET_CONFIG_MSG_LEN);
+}
 
-    return writeUBXFrame(frame);
+bool UbloxGPS::setBaudrate()
+{
+    uint8_t ubx_cfg_prt[SET_BAUDRATE_MSG_LEN] = {
+        0Xb5, 0x62,              // Preamble
+        0x06, 0x8a,              // Message UBX-CFG-VALSET
+        0x0c, 0x00,              // Length
+        0x00,                    // Version
+        0xff,                    // All layers
+        0x00, 0x00,              // Reserved
+        0x01, 0x00, 0x52, 0x40,  // Configuration item key ID
+        0xff, 0xff, 0xff, 0xff,  // Value
+        0xff, 0xff               // Checksum
+    };
+
+    // Prepare boud rate
+    ubx_cfg_prt[14] = baudrate;
+    ubx_cfg_prt[15] = baudrate >> 8;
+    ubx_cfg_prt[16] = baudrate >> 16;
+    ubx_cfg_prt[17] = baudrate >> 24;
+
+    return writeUBXMessage(ubx_cfg_prt, SET_BAUDRATE_MSG_LEN);
 }
 
 bool UbloxGPS::disableNMEAMessages()
 {
-    static constexpr uint16_t payloadLength = 34;
-
-    uint8_t payload[payloadLength] = {
+    uint8_t ubx_cfg_valset[DISABLE_NMEA_MESSAGES_MSG_LEN] = {
+        0Xb5, 0x62,              // Preamble
+        0x06, 0x8a,              // Message UBX-CFG-VALSET
+        0x22, 0x00,              // Length
         0x00,                    // Version
         0xff,                    // All layers
         0x00, 0x00,              // Reserved
@@ -151,146 +306,208 @@ bool UbloxGPS::disableNMEAMessages()
         0xac, 0x00, 0x91, 0x20,  // CFG-MSGOUT-NMEA_ID_RMC_UART1 key ID
         0x00,                    // CFG-MSGOUT-NMEA_ID_RMC_UART1 value
         0xb1, 0x00, 0x91, 0x20,  // CFG-MSGOUT-NMEA_ID_VTG_UART1 key ID
-        0x00                     // CFG-MSGOUT-NMEA_ID_VTG_UART1 value
+        0x00,                    // CFG-MSGOUT-NMEA_ID_VTG_UART1 value
+        0xff, 0xff               // Checksum
     };
 
-    UBXUnpackedFrame frame{0x06, 0x8a,  // Message UBX-CFG-VALSET
-                           payload, payloadLength};
-
-    return writeUBXFrame(frame);
+    return writeUBXMessage(ubx_cfg_valset, DISABLE_NMEA_MESSAGES_MSG_LEN);
 }
 
 bool UbloxGPS::setGNSSConfiguration()
 {
-    static constexpr uint16_t payloadLength = 9;
-
-    uint8_t payload[payloadLength] = {
+    uint8_t ubx_cfg_valset[SET_GNSS_CONF_LEN] = {
+        0Xb5, 0x62,              // Preamble
+        0x06, 0x8a,              // Message UBX-CFG-VALSET
+        0x09, 0x00,              // Length
         0x00,                    // Version
         0x07,                    // All layers
         0x00, 0x00,              // Reserved
         0x21, 0x00, 0x11, 0x20,  // CFG-NAVSPG-DYNMODEL key ID
-        0x08                     // CFG-NAVSPG-DYNMODEL value
+        0x08,                    // CFG-NAVSPG-DYNMODEL value
+        0xff, 0xff               // Checksum
     };
 
-    UBXUnpackedFrame frame{0x06, 0x8a,  // Message UBX-CFG-VALSET
-                           payload, payloadLength};
-
-    return writeUBXFrame(frame);
+    return writeUBXMessage(ubx_cfg_valset, SET_GNSS_CONF_LEN);
 }
 
 bool UbloxGPS::enableUBXMessages()
 {
-    static constexpr uint16_t payloadLength = 9;
-
-    uint8_t payload[payloadLength] = {
+    uint8_t ubx_cfg_valset[ENABLE_UBX_MESSAGES_MSG_LEN] = {
+        0Xb5, 0x62,              // Preamble
+        0x06, 0x8a,              // Message UBX-CFG-VALSET
+        0x09, 0x00,              // Length
         0x00,                    // Version
         0xff,                    // All layers
         0x00, 0x00,              // Reserved
         0x07, 0x00, 0x91, 0x20,  // CFG-MSGOUT-UBX_NAV_PVT_UART1 key ID
-        0x01                     // CFG-MSGOUT-UBX_NAV_PVT_UART1 value
+        0x01,                    // CFG-MSGOUT-UBX_NAV_PVT_UART1 value
+        0xff, 0xff               // Checksum
     };
 
-    UBXUnpackedFrame frame{0x06, 0x8a,  // Message UBX-CFG-VALSET
-                           payload, payloadLength};
-
-    return writeUBXFrame(frame);
+    return writeUBXMessage(ubx_cfg_valset, ENABLE_UBX_MESSAGES_MSG_LEN);
 }
 
-bool UbloxGPS::setSampleRate()
+bool UbloxGPS::setRate()
 {
-    static constexpr uint16_t payloadLength = 10;
+    uint16_t rate = 1000 / sampleRate;
+    LOG_DEBUG(logger, "Rate: {}", rate);
 
-    uint8_t payload[payloadLength] = {
+    uint8_t ubx_cfg_valset[SET_RATE_MSG_LEN] = {
+        0Xb5, 0x62,              // Preamble
+        0x06, 0x8a,              // Message UBX-CFG-VALSET
+        0x0a, 0x00,              // Length
         0x00,                    // Version
         0x07,                    // All layers
         0x00, 0x00,              // Reserved
         0x01, 0x00, 0x21, 0x30,  // CFG-RATE-MEAS key ID
-        0xff, 0xff               // CFG-RATE-MEAS value (placeholder)
+        0xff, 0xff,              // CFG-RATE-MEAS value
+        0xff, 0xff               // Checksum
     };
-    memcpy(&payload[8], &samplerate, 2);
 
-    UBXUnpackedFrame frame{0x06, 0x8a,  // Message UBX-CFG-VALSET
-                           payload, payloadLength};
+    // Prepare rate
+    ubx_cfg_valset[14] = rate;
+    ubx_cfg_valset[15] = rate >> 8;
 
-    return writeUBXFrame(frame);
+    return writeUBXMessage(ubx_cfg_valset, SET_RATE_MSG_LEN);
 }
 
-bool UbloxGPS::parseUBXFrame(const UBXUnpackedFrame& frame)
+bool UbloxGPS::readUBXMessage(uint8_t* message, uint16_t& payloadLength)
 {
-    switch (frame.cls)  // Message class
+    // Read preamble
+    do
+    {
+        // Read util the first byte of the preamble
+        do
+        {
+            if (read(gpsFile, &message[0], 1) <= 0)  // No more data available
+            {
+                return false;
+            }
+        } while (message[0] != PREAMBLE[0]);
+
+        // Read the next byte
+        if (read(gpsFile, &message[1], 1) <= 0)  // No more data available
+        {
+            return false;
+        }
+    } while (message[1] != PREAMBLE[1]);  // Continue
+
+    // Read message class and ID
+    if (read(gpsFile, &message[2], 1) <= 0)
+    {
+        return false;
+    }
+    if (read(gpsFile, &message[3], 1) <= 0)
+    {
+        return false;
+    }
+
+    // Read length
+    if (read(gpsFile, &message[4], 2) <= 0)
+    {
+        return false;
+    }
+    payloadLength = message[4] | (message[5] << 8);
+    if (payloadLength > UBX_MAX_PAYLOAD_LENGTH)
+    {
+        return false;
+    }
+
+    // Read paylaod and checksum
+    for (auto i = 0; i < payloadLength + 2; i++)
+    {
+        if (read(gpsFile, &message[6 + i], 1) <= 0)
+        {
+            return false;
+        }
+    }
+
+    // Verify the checksum
+    uint8_t msgChecksum1 = message[6 + payloadLength];
+    uint8_t msgChecksum2 = message[6 + payloadLength + 1];
+    ubxChecksum(message, 6 + payloadLength + 2);
+    if (msgChecksum1 != message[6 + payloadLength] ||
+        msgChecksum2 != message[6 + payloadLength + 1])
+    {
+        LOG_ERR(logger, "Message checksum verification failed");
+        return false;
+    }
+
+    return true;
+}
+
+bool UbloxGPS::parseUBXMessage(uint8_t* message)
+{
+    switch (message[2])  // Message class
     {
         case 0x01:  // UBX-NAV
-            return parseUBXNAVFrame(frame);
+            return parseUBXNAVMessage(message);
         case 0x05:  // UBX-ACK
-            return parseUBXACKFrame(frame);
+            return parseUBXACKMessage(message);
     }
     return false;
 }
 
-bool UbloxGPS::parseUBXNAVFrame(const UBXUnpackedFrame& frame)
+bool UbloxGPS::parseUBXNAVMessage(uint8_t* message)
 {
-    switch (frame.id)  // Message ID
+    switch (message[3])  // Message id
     {
         case 0x07:  // UBX-NAV-PVT
-            // Lock the lastSample variable
-            Lock<FastMutex> l(sampleMutex);
+            // Lock the threadSample variable
+            Lock<FastMutex> l(mutex);
 
             // Latitude
-            int32_t rawLatitude = frame.payload[28] | frame.payload[29] << 8 |
-                                  frame.payload[30] << 16 |
-                                  frame.payload[31] << 24;
-            lastSample.latitude = (float)rawLatitude / 1e7;
+            int32_t rawLatitude = message[6 + 28] | message[6 + 29] << 8 |
+                                  message[6 + 30] << 16 | message[6 + 31] << 24;
+            threadSample.latitude = (float)rawLatitude / 1e7;
 
             // Longitude
-            int32_t rawLongitude = frame.payload[24] | frame.payload[25] << 8 |
-                                   frame.payload[26] << 16 |
-                                   frame.payload[27] << 24;
-            lastSample.longitude = (float)rawLongitude / 1e7;
+            int32_t rawLongitude = message[6 + 24] | message[6 + 25] << 8 |
+                                   message[6 + 26] << 16 |
+                                   message[6 + 27] << 24;
+            threadSample.longitude = (float)rawLongitude / 1e7;
 
             // Height
-            int32_t rawHeight = frame.payload[32] | frame.payload[33] << 8 |
-                                frame.payload[34] << 16 |
-                                frame.payload[35] << 24;
-            lastSample.height = (float)rawHeight / 1e3;
+            int32_t rawHeight = message[6 + 32] | message[6 + 33] << 8 |
+                                message[6 + 34] << 16 | message[6 + 35] << 24;
+            threadSample.height = (float)rawHeight / 1e3;
 
             // Velocity north
-            int32_t rawVelocityNorth =
-                frame.payload[48] | frame.payload[49] << 8 |
-                frame.payload[50] << 16 | frame.payload[51] << 24;
-            lastSample.velocityNorth = (float)rawVelocityNorth / 1e3;
+            int32_t rawVelocityNorth = message[6 + 48] | message[6 + 49] << 8 |
+                                       message[6 + 50] << 16 |
+                                       message[6 + 51] << 24;
+            threadSample.velocityNorth = (float)rawVelocityNorth / 1e3;
 
             // Velocity east
-            int32_t rawVelocityEast =
-                frame.payload[52] | frame.payload[53] << 8 |
-                frame.payload[54] << 16 | frame.payload[55] << 24;
-            lastSample.velocityEast = (float)rawVelocityEast / 1e3;
+            int32_t rawVelocityEast = message[6 + 52] | message[6 + 53] << 8 |
+                                      message[6 + 54] << 16 |
+                                      message[6 + 55] << 24;
+            threadSample.velocityEast = (float)rawVelocityEast / 1e3;
 
             // Velocity down
-            int32_t rawVelocityDown =
-                frame.payload[56] | frame.payload[57] << 8 |
-                frame.payload[58] << 16 | frame.payload[59] << 24;
-            lastSample.velocityDown = (float)rawVelocityDown / 1e3;
+            int32_t rawVelocityDown = message[6 + 56] | message[6 + 57] << 8 |
+                                      message[6 + 58] << 16 |
+                                      message[6 + 59] << 24;
+            threadSample.velocityDown = (float)rawVelocityDown / 1e3;
 
             // Speed
-            int32_t rawSpeed = frame.payload[60] | frame.payload[61] << 8 |
-                               frame.payload[62] << 16 |
-                               frame.payload[63] << 24;
-            lastSample.speed = (float)rawSpeed / 1e3;
+            int32_t rawSpeed = message[6 + 60] | message[6 + 61] << 8 |
+                               message[6 + 62] << 16 | message[6 + 63] << 24;
+            threadSample.speed = (float)rawSpeed / 1e3;
 
             // Track (heading of motion)
-            int32_t rawTrack = frame.payload[64] | frame.payload[65] << 8 |
-                               frame.payload[66] << 16 |
-                               frame.payload[67] << 24;
-            lastSample.track = (float)rawTrack / 1e5;
+            int32_t rawTrack = message[6 + 64] | message[6 + 65] << 8 |
+                               message[6 + 66] << 16 | message[6 + 67] << 24;
+            threadSample.track = (float)rawTrack / 1e5;
 
             // Number of satellite
-            lastSample.satellites = (uint8_t)frame.payload[23];
+            threadSample.satellites = (uint8_t)message[6 + 23];
 
             // Fix (every type of fix accepted)
-            lastSample.fix = frame.payload[20] != 0;
+            threadSample.fix = message[6 + 20] != 0;
 
             // Timestamp
-            lastSample.gpsTimestamp =
+            threadSample.gpsTimestamp =
                 TimestampTimer::getInstance().getTimestamp();
 
             return true;
@@ -299,209 +516,22 @@ bool UbloxGPS::parseUBXNAVFrame(const UBXUnpackedFrame& frame)
     return false;
 }
 
-bool UbloxGPS::parseUBXACKFrame(const UBXUnpackedFrame& frame)
+bool UbloxGPS::parseUBXACKMessage(uint8_t* message)
 {
-    switch (frame.id)  // Message ID
+    switch (message[3])  // Message id
     {
         case 0x00:  // UBX-ACK-NAC
             LOG_DEBUG(logger,
-                      "Received NAC for message (class: {:#02x}, id: {:#02x})",
-                      frame.cls, frame.id);
+                      "Received NAC for message (class:0x{02x}, id: 0x{02x})",
+                      message[6], message[7]);
             return true;
         case 0x01:  // UBX-ACK-ACK
             LOG_DEBUG(logger,
-                      "Received ACK for message (class: {:#02x}, id: {:#02x})",
-                      frame.cls, frame.id);
+                      "Received ACK for message (class:0x{02x}, id: 0x{02x})",
+                      message[6], message[7]);
             return true;
     }
     return false;
 }
 
-bool UbloxGPS::writeUBXFrame(const UBXUnpackedFrame& frame)
-{
-    if (!frame.isValid())
-    {
-        LOG_ERR(logger, "UBX frame to write is invalid");
-        return false;
-    }
-
-    uint8_t packedFrame[UBX_MAX_FRAME_LENGTH];
-    frame.writePacked(packedFrame);
-
-    writeRaw(packedFrame, frame.getFrameLength());
-
-    return true;
-}
-
-bool UbloxGPS::readUBXFrame(UBXUnpackedFrame& frame)
-{
-    bool synchronized = false;
-    while (!synchronized)
-    {
-        synchronized = true;
-        for (uint16_t i = 0; synchronized && i < 2; ++i)
-        {
-            if (!readRaw(&frame.preamble[i], 1))
-                return false;
-
-            if (frame.preamble[i] != UBX_VALID_PREAMBLE[i])
-                synchronized = false;
-        }
-    }
-
-    if (!readRaw(&frame.cls, 1) || !readRaw(&frame.id, 1) ||
-        !readRaw((uint8_t*)&frame.payloadLength, 2) ||
-        !readRaw(frame.payload, frame.payloadLength) ||
-        !readRaw(frame.checksum, 2))
-        return false;
-
-    if (!frame.isValid())
-    {
-        LOG_ERR(logger, "UBX frame to read is invalid");
-        return false;
-    }
-
-    return true;
-}
-
-UbloxGPSSPI::UbloxGPSSPI(SPIBusInterface& spiBus, GpioPin spiCs,
-                         SPIBusConfig spiConfig, uint8_t samplerate)
-    : UbloxGPS(samplerate), spiSlave(spiBus, spiCs, spiConfig)
-{
-}
-
-SPIBusConfig UbloxGPSSPI::getDefaultSPIConfig()
-{
-    SPIBusConfig spiConfig{};
-    spiConfig.clockDivider = SPI::ClockDivider::DIV_32;
-    spiConfig.mode         = SPI::Mode::MODE_1;
-    return spiConfig;
-}
-
-bool UbloxGPSSPI::writeRaw(uint8_t* data, size_t size)
-{
-    SPITransaction spi{spiSlave};
-    spi.write(data, size);
-    return true;
-}
-
-bool UbloxGPSSPI::readRaw(uint8_t* data, size_t size)
-{
-    SPITransaction spi{spiSlave};
-    spi.read(data, size);
-    return true;
-}
-
-UbloxGPSSerial::UbloxGPSSerial(int serialBaudrate, uint8_t samplerate,
-                               int serialDefaultBaudrate, int serialPortNumber,
-                               const char* serialPortName)
-    : UbloxGPS(samplerate), serialPortNumber(serialPortNumber),
-      serialPortName(serialPortName), serialBaudrate(serialBaudrate),
-      serialDefaultBaudrate(serialDefaultBaudrate)
-{
-    strcpy(serialFilePath, "/dev/");
-    strcat(serialFilePath, serialPortName);
-}
-
-bool UbloxGPSSerial::setupCommunication()
-{
-    intrusive_ref_ptr<DevFs> devFs = FilesystemManager::instance().getDevFs();
-
-    // Close the serial file if already opened
-    devFs->remove(serialPortName);
-
-    // Change the baudrate only if it is different than the default
-    if (serialBaudrate != serialDefaultBaudrate)
-    {
-        // Open the serial port device with the default baudrate
-        if (!devFs->addDevice(serialPortName,
-                              intrusive_ref_ptr<Device>(new STM32Serial(
-                                  serialPortNumber, serialDefaultBaudrate))))
-        {
-            LOG_ERR(logger,
-                    "[gps] Faild to open serial port {} with baudrate {} as "
-                    "file {}",
-                    serialPortNumber, serialDefaultBaudrate, serialPortName);
-            return false;
-        }
-
-        // Open the serial file
-        if ((serialFile = open(serialFilePath, O_RDWR)) < 0)
-        {
-            LOG_ERR(logger, "Failed to open serial file {}", serialFilePath);
-            return false;
-        }
-
-        // Change baudrate
-        if (!setBaudrate())
-        {
-            return false;
-        }
-
-        // Close the serial file
-        if (close(serialFile) < 0)
-        {
-            LOG_ERR(logger, "Failed to close serial file {}", serialFilePath);
-            return false;
-        }
-
-        // Close the serial port
-        if (!devFs->remove(serialPortName))
-        {
-            LOG_ERR(logger, "Failed to close serial port {} as file {}",
-                    serialPortNumber, serialPortName);
-            return false;
-        }
-    }
-
-    // Reopen the serial port with the configured baudrate
-    if (!devFs->addDevice(serialPortName,
-                          intrusive_ref_ptr<Device>(new STM32Serial(
-                              serialPortNumber, serialBaudrate))))
-    {
-        LOG_ERR(logger,
-                "Faild to open serial port {} with baudrate {} as file {}\n",
-                serialPortNumber, serialDefaultBaudrate, serialPortName);
-        return false;
-    }
-
-    // Reopen the serial file
-    if ((serialFile = open(serialFilePath, O_RDWR)) < 0)
-    {
-        LOG_ERR(logger, "Failed to open serial file {}", serialFilePath);
-        return false;
-    }
-
-    return true;
-}
-
-bool UbloxGPSSerial::setBaudrate()
-{
-    static constexpr uint16_t payloadLength = 12;
-
-    uint8_t payload[payloadLength] = {
-        0x00,                    // Version
-        0xff,                    // All layers
-        0x00, 0x00,              // Reserved
-        0x01, 0x00, 0x52, 0x40,  // Configuration item key ID
-        0xff, 0xff, 0xff, 0xff   // Value (placeholder)
-    };
-    memcpy(&payload[8], &serialBaudrate, 4);
-
-    UBXUnpackedFrame frame{0x06, 0x8a,  // Message UBX-CFG-VALSET
-                           payload, payloadLength};
-
-    return writeUBXFrame(frame);
-}
-
-bool UbloxGPSSerial::writeRaw(uint8_t* data, size_t size)
-{
-    return write(serialFile, data, size) >= 0;
-}
-
-bool UbloxGPSSerial::readRaw(uint8_t* data, size_t size)
-{
-    return read(serialFile, data, size) >= 0;
-}
-
 }  // namespace Boardcore
diff --git a/src/shared/sensors/UbloxGPS/UbloxGPS.h b/src/shared/sensors/UbloxGPS/UbloxGPS.h
index 6d980d6420cf64441b46df319d8a904bdd930002..3f7a1616ef1c0c732527b91ed209964d9af3c893 100644
--- a/src/shared/sensors/UbloxGPS/UbloxGPS.h
+++ b/src/shared/sensors/UbloxGPS/UbloxGPS.h
@@ -1,5 +1,5 @@
 /* Copyright (c) 2021 Skyward Experimental Rocketry
- * Authors: Davide Bonomini, Davide Mor, Alberto Nidasio, Damiano Amatruda
+ * Authors: Davide Bonomini, Davide Mor, Alberto Nidasio
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to deal
@@ -24,57 +24,87 @@
 
 #include <ActiveObject.h>
 #include <diagnostic/PrintLogger.h>
-#include <drivers/spi/SPIDriver.h>
+#include <miosix.h>
 #include <sensors/Sensor.h>
 
-#include "UBXUnpackedFrame.h"
 #include "UbloxGPSData.h"
 
 namespace Boardcore
 {
 
 /**
- * @brief Sensor for Ublox GPS.
+ * @brief Driver for Ublox GPSs
  *
- * This sensor handles communication and setup with Ublox GPSs. It uses the
+ * This driver handles communication and setup with Ublox GPSs. It uses the
  * binary UBX protocol to retrieve and parse navigation data quicker than using
  * the string based NMEA.
  *
- * At initialization it configures the device with the specified sample rate,
- * resets the configuration and sets up UBX messages and GNSS parameters.
+ * At initialization it configures the device with the specified baudrate, reset
+ * the configuration and sets up UBX messages and GNSS parameters.
  *
- * Communication with the device is performed through SPI.
+ * Communication with the device is performed through a file, the driver opens
+ * the serial port under the filepath /dev/<serialPortName>.
+ * There is no need for the file to be setted up beforhand.
  *
  * This driver was written for a NEO-M9N gps with the latest version of UBX.
  */
 class UbloxGPS : public Sensor<UbloxGPSData>, public ActiveObject
 {
 public:
-    explicit UbloxGPS(uint8_t samplerate) : samplerate(samplerate) {}
+    /**
+     * @brief Construct a new UbloxGPS object
+     *
+     * @param boudrate_ Baudrate to communicate with the device (max: 921600,
+     * min: 4800 for NEO-M9N)
+     * @param sampleRate_ GPS sample rate (max: 25 for NEO-M9N)
+     * @param serialPortName_ Name of the file for the gps device
+     * @param defaultBaudrate_ Startup baudrate (38400 for NEO-M9N)
+     */
+    UbloxGPS(int boudrate_ = 921600, uint8_t sampleRate_ = 10,
+             int serialPortNumber_ = 2, const char *serialPortName_ = "gps",
+             int defaultBaudrate_ = 38400);
 
     /**
-     * @brief Disables the NMEA messages, configures GNSS options and enables
-     * UBX-PVT message
+     * @brief Sets up the serial port baudrate, disables the NMEA messages,
+     * configures GNSS options and enables UBX-PVT message
      *
      * @return True if the operation succeeded
      */
-    virtual bool init() override;
+    bool init() override;
 
     /**
-     * @brief Reads a single message form the GPS, waits 2 sample cycles.
+     * @brief Read a single message form the GPS, waits 2 sample cycle
      *
      * @return True if a message was sampled
      */
     bool selfTest() override;
 
-protected:
+private:
     UbloxGPSData sampleImpl() override;
 
     void run() override;
 
+    void ubxChecksum(uint8_t *msg, int len);
+
+    /**
+     * @brief Compute the checksum and write the message to the device
+     */
+    bool writeUBXMessage(uint8_t *message, int length);
+
+    /**
+     * @brief Sets up the serial port with the correct baudrate
+     *
+     * Opens the serial port with the defaul baudrate and changes it to
+     * the value specified in the constructor, then it reopens the serial port.
+     * If the device is already using the correct baudrate this won't have
+     * effect. However if the gps is using a different baudrate the diver won't
+     * be able to communicate.
+     */
+    bool serialCommuinicationSetup();
+
     bool resetConfiguration();
 
-    virtual bool setupCommunication() { return true; }
+    bool setBaudrate();
 
     bool disableNMEAMessages();
 
@@ -82,101 +112,40 @@ protected:
 
     bool enableUBXMessages();
 
-    bool setSampleRate();
-
-    bool parseUBXFrame(const UBXUnpackedFrame& frame);
-
-    bool parseUBXNAVFrame(const UBXUnpackedFrame& frame);
-
-    bool parseUBXACKFrame(const UBXUnpackedFrame& frame);
-
-    bool writeUBXFrame(const UBXUnpackedFrame& frame);
-
-    bool readUBXFrame(UBXUnpackedFrame& frame);
-
-    virtual bool writeRaw(uint8_t* data, size_t size) = 0;
-
-    virtual bool readRaw(uint8_t* data, size_t size) = 0;
-
-    const uint8_t samplerate;  // [Hz]
-
-    mutable miosix::FastMutex sampleMutex;
-    UbloxGPSData lastSample{};
-
-    PrintLogger logger = Logging::getLogger("ubloxgps");
-};
+    bool setRate();
 
-class UbloxGPSSPI : public UbloxGPS
-{
-public:
-    /**
-     * @brief Constructor.
-     *
-     * @param bus The Spi bus.
-     * @param cs The CS pin to lower when we need to sample.
-     * @param config The SPI configuration.
-     * @param samplerate Sample rate to communicate with the device
-     */
-    UbloxGPSSPI(SPIBusInterface& spiBus, miosix::GpioPin spiCs,
-                SPIBusConfig spiConfig = getDefaultSPIConfig(),
-                uint8_t samplerate     = 250);
+    bool readUBXMessage(uint8_t *message, uint16_t &payloadLength);
 
-    /**
-     * Constructs the default config for SPI Bus.
-     *
-     * @returns The default SPIBusConfig.
-     */
-    static SPIBusConfig getDefaultSPIConfig();
+    bool parseUBXMessage(uint8_t *message);
 
-private:
-    virtual bool writeRaw(uint8_t* data, size_t size) override;
+    bool parseUBXNAVMessage(uint8_t *message);
 
-    virtual bool readRaw(uint8_t* data, size_t size) override;
+    bool parseUBXACKMessage(uint8_t *message);
 
-    SPISlave spiSlave;
-};
+    const int baudrate;        // [baud]
+    const uint8_t sampleRate;  // [Hz]
+    const int serialPortNumber;
+    const char *serialPortName;
+    const int defaultBaudrate;  // [baud]
 
-class UbloxGPSSerial : public UbloxGPS
-{
-public:
-    /**
-     * @brief Serial constructor.
-     *
-     * @param serialPortNumber Number of the serial port
-     * @param serialPortName Name of the file for the gps device
-     * @param serialBaudrate Baudrate to communicate with the device (max:
-     * 921600, min: 4800 for NEO-M9N)
-     * @param samplerate GPS sample rate (max: 25 for NEO-M9N)
-     * @param serialDefaultBaudrate Startup baudrate (38400 for NEO-M9N)
-     */
-    UbloxGPSSerial(int serialBaudrate = 921600, uint8_t samplerate = 10,
-                   int serialDefaultBaudrate = 38400, int serialPortNumber = 2,
-                   const char* serialPortName = "gps");
+    char gpsFilePath[16];  ///< Allows for a filename of up to 10 characters
+    int gpsFile;
 
-private:
-    /**
-     * @brief Sets up the serial port with the correct baudrate
-     *
-     * Opens the serial port with the default baudrate and changes it to
-     * the value specified in the constructor, then it reopens the serial port.
-     * If the device is already using the correct baudrate this won't have
-     * effect. However if the gps is using a different baudrate the diver won't
-     * be able to communicate.
-     */
-    virtual bool setupCommunication() override;
+    mutable miosix::FastMutex mutex;
+    UbloxGPSData threadSample{};
 
-    bool setBaudrate();
+    static constexpr int SET_BAUDRATE_MSG_LEN          = 20;
+    static constexpr int RESET_CONFIG_MSG_LEN          = 12;
+    static constexpr int DISABLE_NMEA_MESSAGES_MSG_LEN = 42;
+    static constexpr int SET_GNSS_CONF_LEN             = 17;
+    static constexpr int ENABLE_UBX_MESSAGES_MSG_LEN   = 17;
+    static constexpr int SET_RATE_MSG_LEN              = 18;
 
-    virtual bool writeRaw(uint8_t* data, size_t size) override;
+    static constexpr uint8_t PREAMBLE[] = {0xb5, 0x62};
 
-    virtual bool readRaw(uint8_t* data, size_t size) override;
+    static constexpr int UBX_MAX_PAYLOAD_LENGTH = 92;
 
-    const int serialPortNumber;
-    const char* serialPortName;
-    const int serialBaudrate;         // [baud]
-    const int serialDefaultBaudrate;  // [baud]
-    char serialFilePath[16];  // Allows for a filename of up to 10 characters
-    int serialFile = -1;
+    PrintLogger logger = Logging::getLogger("ubloxgps");
 };
 
 }  // namespace Boardcore
diff --git a/src/shared/sensors/UbloxGPS/UbloxGPSData.h b/src/shared/sensors/UbloxGPS/UbloxGPSData.h
index f61d4fc00ab8f682c1d4afd18b3cb4d6c1ac1e0a..7f5570000b78b915a956b96e754d784e08f7611f 100644
--- a/src/shared/sensors/UbloxGPS/UbloxGPSData.h
+++ b/src/shared/sensors/UbloxGPS/UbloxGPSData.h
@@ -31,8 +31,8 @@ struct UbloxGPSData : public GPSData
 {
     static std::string header()
     {
-        return "gpsTimestamp,latitude,longitude,height,velocityNorth,"
-               "velocityEast,velocityDown,speed,track,satellites,fix\n";
+        return "gps_timestamp,latitude,longitude,height,velocity_north,"
+               "velocity_east,velocity_down,speed,track,num_satellites,fix\n";
     }
 
     void print(std::ostream &os) const
diff --git a/src/tests/sensors/test-ubloxgps.cpp b/src/tests/sensors/test-ubloxgps.cpp
index 1bf036893f5cd3463252d1b6d4a06a3da582b75f..0c611daf4e7ffc2ccabcc56da70d989496e1d45f 100644
--- a/src/tests/sensors/test-ubloxgps.cpp
+++ b/src/tests/sensors/test-ubloxgps.cpp
@@ -1,5 +1,5 @@
 /* Copyright (c) 2021 Skyward Experimental Rocketry
- * Authors: Davide Bonomini, Davide Mor, Alberto Nidasio, Damiano Amatruda
+ * Authors: Davide Bonomini, Davide Mor, Alberto Nidasio
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to deal
@@ -21,87 +21,69 @@
  */
 
 #include <drivers/timer/TimestampTimer.h>
+#include <miosix.h>
 #include <sensors/UbloxGPS/UbloxGPS.h>
 #include <utils/Debug.h>
 
-using namespace miosix;
+#include <cstdio>
+
 using namespace Boardcore;
+using namespace miosix;
+
+#define RATE 4
 
 int main()
 {
-    static constexpr uint8_t SAMPLE_RATE = 4;
-
-    PrintLogger logger = Logging::getLogger("test-ubloxgps");
-
-#if defined(USE_SPI)
-    SPIBus bus(SPI1);
-    GpioPin spiSck(GPIOA_BASE, 5);
-    GpioPin spiMiso(GPIOA_BASE, 6);
-    GpioPin spiMosi(GPIOA_BASE, 7);
-    GpioPin cs(GPIOA_BASE, 3);
-
-    spiSck.mode(Mode::ALTERNATE);
-    spiSck.alternateFunction(5);
-    spiMiso.mode(Mode::ALTERNATE);
-    spiMiso.alternateFunction(5);
-    spiMosi.mode(miosix::Mode::ALTERNATE);
-    spiMosi.alternateFunction(5);
-    cs.mode(Mode::OUTPUT);
-    cs.high();
-
-    UbloxGPSSPI sensor{bus, cs, UbloxGPSSPI::getDefaultSPIConfig(),
-                       SAMPLE_RATE};
-#elif defined(_BOARD_STM32F429ZI_SKYWARD_DEATHST_X)
-    // Keep GPS baud SAMPLE_RATE at default for easier testing
-    UbloxGPSSerial sensor{2, "gps", 921600, 38400, SAMPLE_RATE};
-#else
-    GpioPin tx(GPIOB_BASE, 6);
-    GpioPin rx(GPIOB_BASE, 7);
+    (void)TimestampTimer::getInstance();
 
-    tx.mode(miosix::Mode::ALTERNATE);
-    rx.mode(miosix::Mode::ALTERNATE);
+    printf("Welcome to the ublox test\n");
 
-    tx.alternateFunction(7);
-    rx.alternateFunction(7);
+    // Keep GPS baud rate at default for easier testing
+    UbloxGPS gps(921600, RATE, 2, "gps", 38400);
+    UbloxGPSData dataGPS;
+    printf("Gps allocated\n");
 
-    UbloxGPSSerial sensor{91600, SAMPLE_RATE, 38400, 1, "gps"};
-#endif
-
-    LOG_INFO(logger, "Initializing sensor...\n");
-
-    if (!sensor.init())
+    // Init the gps
+    if (gps.init())
     {
-        LOG_ERR(logger, "Initialization failed!\n");
-        return -1;
+        printf("Successful gps initialization\n");
+    }
+    else
+    {
+        printf("Failed gps initialization\n");
     }
 
-    LOG_INFO(logger, "Performing self-test...\n");
-
-    if (!sensor.selfTest())
+    // Perform the selftest
+    if (gps.selfTest())
+    {
+        printf("Successful gps selftest\n");
+    }
+    else
     {
-        LOG_ERR(logger, "Self-test failed! (code: %d)\n",
-                sensor.getLastError());
-        return -1;
+        printf("Failed gps selftest\n");
     }
 
-    // Start the sensor thread
-    LOG_INFO(logger, "Starting sensor...\n");
-    sensor.start();
+    // Start the gps thread
+    gps.start();
+    printf("Gps started\n");
 
     while (true)
     {
-        long long lastTick = miosix::getTick();
+        // Give time to the thread
+        Thread::sleep(1000 / RATE);
 
-        sensor.sample();
-        GPSData sample __attribute__((unused)) = sensor.getLastSample();
+        // Sample
+        gps.sample();
+        dataGPS = gps.getLastSample();
 
+        // Print out the latest sample
         TRACE(
-            "timestamp: %4.3f, fix: %01d, lat: %f, lon: %f, height: %4.1f, "
-            "nsat: %2d, speed: %3.2f, velN: %3.2f, velE: %3.2f, track %3.1f\n",
-            (float)sample.gpsTimestamp / 1000000, sample.fix, sample.latitude,
-            sample.longitude, sample.height, sample.satellites, sample.speed,
-            sample.velocityNorth, sample.velocityEast, sample.track);
-
-        Thread::sleepUntil(lastTick + 1000 / SAMPLE_RATE);  // Sample period
+            "[gps] timestamp: % 4.3f, fix: %01d lat: % f lon: % f "
+            "height: %4.1f nsat: %2d speed: %3.2f velN: % 3.2f velE: % 3.2f "
+            "track %3.1f\n",
+            (float)dataGPS.gpsTimestamp / 1000000, dataGPS.fix,
+            dataGPS.latitude, dataGPS.longitude, dataGPS.height,
+            dataGPS.satellites, dataGPS.speed, dataGPS.velocityNorth,
+            dataGPS.velocityEast, dataGPS.track);
     }
 }