From 398bd3caaae3ec570dd94defbc369f32288e2295 Mon Sep 17 00:00:00 2001
From: Alberto Nidasio <alberto.nidasio@skywarder.eu>
Date: Sun, 17 Apr 2022 18:53:06 +0200
Subject: [PATCH] [logdecoder] Updated the logdecoder script with ALL the types
 defined in Boardcore

---
 .gitignore                                    |   2 +
 .vscode/c_cpp_properties.json                 |   3 +
 .vscode/settings.json                         |  14 +-
 libs/tscpp                                    |   2 +-
 scripts/logdecoder/Makefile                   |  10 +-
 scripts/logdecoder/logdecoder.cpp             | 178 ++++++++++----
 scripts/logdecoder/sample_no_cereal.dat.dat   | Bin 75450 -> 0 bytes
 scripts/logdecoder/xbee/.gitignore            |   1 -
 scripts/logdecoder/xbee/LogTypes.h            |  73 ------
 scripts/logdecoder/xbee/Makefile              |  13 --
 scripts/logdecoder/xbee/logdecoder.cpp        | 168 -------------
 src/shared/logger/Deserializer.h              | 221 +++++++++---------
 src/shared/logger/LogTypes.h                  | 125 ++++++++++
 src/shared/sensors/HX711/HX711Data.h          |  10 +-
 src/shared/sensors/MBLoadCell/MBLoadCell.cpp  |  20 +-
 src/shared/sensors/MBLoadCell/MBLoadCell.h    |  18 +-
 .../sensors/MBLoadCell/MBLoadCellData.h       |  47 ++--
 src/shared/sensors/SensorData.h               |  12 +-
 src/shared/sensors/analog/loadcell/LoadCell.h |   4 +-
 .../sensors/analog/loadcell/LoadCellData.h    |  44 ----
 src/shared/utils/CSVReader/CSVReader.h        |  12 +-
 21 files changed, 464 insertions(+), 513 deletions(-)
 delete mode 100644 scripts/logdecoder/sample_no_cereal.dat.dat
 delete mode 100644 scripts/logdecoder/xbee/.gitignore
 delete mode 100644 scripts/logdecoder/xbee/LogTypes.h
 delete mode 100644 scripts/logdecoder/xbee/Makefile
 delete mode 100644 scripts/logdecoder/xbee/logdecoder.cpp
 create mode 100644 src/shared/logger/LogTypes.h
 delete mode 100644 src/shared/sensors/analog/loadcell/LoadCellData.h

diff --git a/.gitignore b/.gitignore
index 9b89790f9..a9f1775b4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -32,3 +32,5 @@ core
 __pycache__
 /scripts/generators/generated
 /scripts/generators/scxmls
+
+scripts/logdecoder/logdecoder
diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json
index 83c45bdd3..78209a5f4 100644
--- a/.vscode/c_cpp_properties.json
+++ b/.vscode/c_cpp_properties.json
@@ -24,6 +24,7 @@
                 "${workspaceFolder}/libs/mavlink_skyward_lib",
                 "${workspaceFolder}/libs/fmt/include",
                 "${workspaceFolder}/libs/eigen",
+                "${workspaceFolder}/libs/tscpp",
                 "${workspaceFolder}/libs",
                 "${workspaceFolder}/src/shared",
                 "${workspaceFolder}/src/tests"
@@ -77,6 +78,7 @@
                 "${workspaceFolder}/libs/mavlink_skyward_lib",
                 "${workspaceFolder}/libs/fmt/include",
                 "${workspaceFolder}/libs/eigen",
+                "${workspaceFolder}/libs/tscpp",
                 "${workspaceFolder}/libs",
                 "${workspaceFolder}/src/shared",
                 "${workspaceFolder}/src/tests"
@@ -129,6 +131,7 @@
                 "${workspaceFolder}/libs/mavlink_skyward_lib",
                 "${workspaceFolder}/libs/fmt/include",
                 "${workspaceFolder}/libs/eigen",
+                "${workspaceFolder}/libs/tscpp",
                 "${workspaceFolder}/libs",
                 "${workspaceFolder}/src/shared",
                 "${workspaceFolder}/src/tests"
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 4c48cde6b..eff44bf31 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -124,6 +124,7 @@
         "atthr",
         "AVDD",
         "Baro",
+        "Corigliano",
         "CORTEXM",
         "cpitch",
         "croll",
@@ -135,8 +136,10 @@
         "Ecompass",
         "Eigen",
         "elfs",
+        "Erbetta",
         "Fatt",
         "Fatttr",
+        "fedetft's",
         "fiprintf",
         "Gatttr",
         "getdetahstate",
@@ -146,6 +149,8 @@
         "GPIOC",
         "gpstr",
         "Hatt",
+        "HSCMAND",
+        "HSCMRNN",
         "irqv",
         "Kalman",
         "Katt",
@@ -156,6 +161,7 @@
         "MEKF",
         "MINC",
         "miosix",
+        "MPXHZ",
         "NATT",
         "NBAR",
         "NDTR",
@@ -179,15 +185,21 @@
         "sqdip",
         "sqtrp",
         "sroll",
+        "SSCDANN",
+        "SSCDRRN",
+        "stof",
         "syaw",
         "TCIE",
         "TEIE",
         "testsuite",
+        "TSCPP",
+        "Ublox",
         "upcounter",
         "velnord",
         "Xbee",
         "xnord",
         "yned"
     ],
-    "cSpell.language": "en,it"
+    "cSpell.language": "en,it",
+    "cSpell.enabled": true
 }
diff --git a/libs/tscpp b/libs/tscpp
index c8674a48e..935bf1944 160000
--- a/libs/tscpp
+++ b/libs/tscpp
@@ -1 +1 @@
-Subproject commit c8674a48e794c246f79c56b163ebab72d3654846
+Subproject commit 935bf1944e1ddeaf51fd22cdce04a2a97762890f
diff --git a/scripts/logdecoder/Makefile b/scripts/logdecoder/Makefile
index 0a30ee85e..2523965cd 100644
--- a/scripts/logdecoder/Makefile
+++ b/scripts/logdecoder/Makefile
@@ -1,6 +1,12 @@
+BOARDCORE := ../../
 
 all:
-	g++ -std=c++11 -O2 -o logdecoder logdecoder.cpp ../libs/tscpp/stream.cpp  -I ../libs
-
+	g++ -std=c++17 -O2 -o logdecoder logdecoder.cpp \
+					-DCOMPILE_FOR_X86 \
+					$(BOARDCORE)libs/tscpp/tscpp/stream.cpp \
+	 				-I$(BOARDCORE)libs/mavlink_skyward_lib \
+	 				-I$(BOARDCORE)libs/eigen \
+	 				-I$(BOARDCORE)libs/tscpp \
+	 				-I$(BOARDCORE)src/shared
 clean:
 	rm logdecoder
diff --git a/scripts/logdecoder/logdecoder.cpp b/scripts/logdecoder/logdecoder.cpp
index 96b81e338..670873a18 100644
--- a/scripts/logdecoder/logdecoder.cpp
+++ b/scripts/logdecoder/logdecoder.cpp
@@ -1,59 +1,139 @@
-/***************************************************************************
- *   Copyright (C) 2018 by Terraneo Federico                               *
- *                                                                         *
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   This program is distributed in the hope that it will be useful,       *
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- *   GNU General Public License for more details.                          *
- *                                                                         *
- *   As a special exception, if other files instantiate templates or use   *
- *   macros or inline functions from this file, or you compile this file   *
- *   and link it with other works to produce a work based on this file,    *
- *   this file does not by itself cause the resulting work to be covered   *
- *   by the GNU General Public License. However the source code for this   *
- *   file must still be made available in accordance with the GNU General  *
- *   Public License. This exception does not invalidate any other reasons  *
- *   why a work based on this file might be covered by the GNU General     *
- *   Public License.                                                       *
- *                                                                         *
- *   You should have received a copy of the GNU General Public License     *
- *   along with this program; if not, see <http://www.gnu.org/licenses/>   *
- ***************************************************************************/
-
-/*
- * This is a stub program for the program that will decode the logged data.
- * Fill in the TODO to make it work.
+/* Copyright (c) 2018-2022 Skyward Experimental Rocketry
+ * Authors: Terrane Federico
+ *
+ * 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.
  */
 
-#include <iostream>
+#include <logger/Deserializer.h>
+#include <logger/LogTypes.h>
+#include <tscpp/stream.h>
+
 #include <fstream>
+#include <iostream>
 #include <stdexcept>
-#include <tscpp/stream.h>
+#include <string>
 
-//TODO: add here include files of serialized classes
-#include "../src/shared/logger/LogStats.h"
-#include "../src/entrypoints/test_logger.h"
+/**
+ * @brief Binary log files decoder.
+ *
+ * This program is to compile for you computer and decodes binary log files
+ * through the tscpp library.
+ *
+ * In LogTypes.h there should be included all the classes you want to
+ * deserialize.
+ */
 
-using namespace std;
 using namespace tscpp;
+using namespace Boardcore;
+
+void showUsage(string commandName);
+
+/**
+ * @brief Deserialize a file.
+ *
+ * @param fileName File name complete with extension.
+ * @return Whether the deserialization was successful.
+ */
+bool deserialize(string fileName);
+
+/**
+ * @brief Deserialize all log file in the directory. Assumes the log files named
+ * as logXX.dat.
+ *
+ * Scans for all the 100 possible log files and decode the ones found.
+ *
+ * @return False if an error was encountered.
+ */
+bool deserializeAll();
+
+int main(int argc, char* argv[])
+{
+    if (argc < 2)
+    {
+        showUsage(string(argv[0]));
+        return 1;  // Error
+    }
+
+    bool success = false;
+    string arg1  = string(argv[1]);
+
+    // Help message
+    if (arg1 == "-h" || arg1 == "--help")
+    {
+        showUsage(string(argv[0]));
+        return 0;
+    }
 
-int main(int argc, char *argv[])
-try {
-    TypePoolStream tp;
-    //TODO: Register the serialized classes
-    tp.registerType<LogStats>([](LogStats& t){ t.print(cout); cout<<'\n'; });
-    tp.registerType<Dummy>([](Dummy& t){ t.print(cout); cout<<'\n'; });
-
-    if(argc!=2) return 1;
-    ifstream in(argv[1]);
-    in.exceptions(ios::eofbit);
-    UnknownInputArchive ia(in,tp);
-    for(;;) ia.unserialize();
-} catch(exception&) {
+    // File deserialization
+    if (arg1 == "-a" || arg1 == "--all")
+        success = deserializeAll();
+    else
+        success = deserialize(arg1);
+
+    // End
+    if (success)
+        std::cout << "Deserialization completed successfully\n";
+    else
+        std::cout << "Deserialization ended with errors\n";
     return 0;
 }
+
+void showUsage(string commandName)
+{
+    std::cerr << "Usage: " << commandName << " {-a | <log_file_name> | -h}"
+              << "Options:\n"
+              << "\t-h,--help\t\tShow this help message\n"
+              << "\t-a,--all Deserialize all logs in the current directory "
+                 "named as logXX.dat\n"
+              << std::endl;
+}
+
+bool deserialize(string fileName)
+{
+    std::cout << "Deserializing " << fileName << "...\n";
+
+    Deserializer d(fileName);
+    LogTypes::registerTypes(d);
+
+    return d.deserialize();
+}
+
+bool deserializeAll()
+{
+    std::cout << "Deserializing all logs in the current directory...\n";
+
+    for (int i = 0; i < 100; i++)
+    {
+        char fileName[11];
+        sprintf(fileName, "log%02d.dat", i);
+        struct stat st;
+
+        // Check if the current logfile exists
+        if (stat(fileName, &st) != 0)
+            continue;
+
+        // File found
+        if (!deserialize(string(fileName)))
+            return false;
+
+        std::cout << fileName << " deserialized successfully";
+    }
+
+    return true;
+}
diff --git a/scripts/logdecoder/sample_no_cereal.dat.dat b/scripts/logdecoder/sample_no_cereal.dat.dat
deleted file mode 100644
index 23dff819fee59674f0cfff237b94fffa191d4a06..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 75450
zcmcEU$xjb1Nh~R5Xk}p_3Ltbea-eEpMCHPHrY@zqxs?oixgjE23=9mz0grlXD8=Gv
zYz@KKIy5|sj8Sh5i3$K(WQ@kvP>QYN!?Va3_10)29JppPv?Ls+iSW$uEHXyDHI#~s
z(byVFv2}5H78#@78cl=)-pUxJiSXL+EHXyDHI#~s(byVFv2}ZR78#@78cl=)-pUxJ
ziSWVjEHXyDHI#~s(byVFvGsI#78#@78cl=)-pUxJiSX6%EHXyDHI#~s(byVFvGsm<
z78#@78cl=)-pUxJiSWztEHXyDHI#~s(byVFvGsF!78#@78cl=)-pUxJiSXa>EHXyD
zHI#~s(byVFvBk_YEO)YwdTTTh4tOhLm?lDw;aOyidTS^Z8Kbc^lwyl_corF>-WpAW
z1K!FQrioB!corF>-Wp0p#%OE}rPvZ5o<+u}w?-4;fVVP+X(E&vo<+u}w}w)YF&bM#
zDYg`cXOS`Lt<gj{;H`{dnh4c~XOS`Lt)Wz8jK<bbiY@KoS!9fQYcvrKcq?O=CPIVZ
zS!9fQYbX^Nqp>xVV#{=R78#@78cl=)-pUxJiO_0z78#@78cIdRXlxCo*s>p<MaHPN
zMib$Hw=#xlB6Jy^MaHPNhEkC+8e2mtwmgStkumD6(L^}lt&Cxs2>pj=kumD6p;Tmy
z#@0}Zt>EEVWQ=-iG!YJXD`S`@!ieEnWQ=-iC>0r_u{D%pD|UDm8Kd4BO@ss9${41J
zFll%e8Kd4BN=3$KYz?K@N*|s@#;CVO6XAfjGKOg)%o(0V#;CW3QjswlTSF<f3WsNr
zG3u?+L^$BBjA5Dx%Z6u>G3u?MRAh|C)=-MA>fu>rjCyM{5e|4OW4I+k3!nV-;F83W
zVuo61sR6kIiGkrLjDbd*x|HVTRx&g|m1{8!T%1tT?on@1Gc;*!)@W?eI)tfdJ~Xyk
zhi8#7>aC&FE*Xujp%hzP!?Va3_10)29JppPv^pN9iLifo78#@78cIdRXlxCo*qSmt
zi;PikjV8hYZ)FVAL^yMJ78#@78cIdRXlxCo*qS#yi;PikjV8hYZ)FVAM7Vf(78#@7
z8cIdRXlxCo*jh0>i;PikjV8hYZ)FVAM7VZ%78#@78cIdRXlxCo*xEEai;PikjV8hY
zZ)FVAM7Vu;78#@78cIdRXlxCo*xEBZi;PikjV8hYZ)FVAM0jv`78#@78cIdRXlxCo
z*g7^mi;PikjV8hYZ)FVAM0k3578#@78cIdRXlxCo*t#%0i;PikjV8hYZ)FVAM0j<0
z78#@78cIdRXlxCo*t#`5i;PikjV8hYZ)FVAM0kIA78#@78cIdRXlxCo*m^QNi;Pik
zjV8hYZ)FVAMEG)e78#@78cIdRXlxCo*m^fSi;PikjV8hYZ)FVAMEH4l78#@78cIdR
zXlxCo*!nR%i;PikjV8hYZ)FVAMEG}j78#@78cIdRXlxCo*ka;^+@eO!Ta^aVEa(*y
zquv@#gah8n7^aDkeRvibquv@yMaF1s4W-!P8J<PPsJBKF;efX?hG`-c9G*qSsJDhv
zkue%uLn*ezhG&s6>aEd4IN+^};g$$3eDc$SOA<?p8DKtxjDs>TBr-BEFv2)UGyuiK
BD&PPB

diff --git a/scripts/logdecoder/xbee/.gitignore b/scripts/logdecoder/xbee/.gitignore
deleted file mode 100644
index 3e6fd1630..000000000
--- a/scripts/logdecoder/xbee/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-logdecoder
diff --git a/scripts/logdecoder/xbee/LogTypes.h b/scripts/logdecoder/xbee/LogTypes.h
deleted file mode 100644
index cb82189b4..000000000
--- a/scripts/logdecoder/xbee/LogTypes.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/* Copyright (c) 2015-2018 Skyward Experimental Rocketry
- * Author: Luca Erbetta
- *
- * 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 <logger/Deserializer.h>
-#include <logger/LogStats.h>
-#include <radio/Xbee/APIFramesLog.h>
-#include <radio/Xbee/Mark.h>
-#include <radio/Xbee/XbeeStatus.h>
-#include <radio/Xbee/XbeeTestData.h>
-
-#include <fstream>
-#include <iostream>
-
-// Serialized classes
-using std::ofstream;
-
-namespace Boardcore
-{
-
-template <typename T>
-void print(T& t, ostream& os)
-{
-    t.print(os);
-}
-
-template <typename T>
-void registerType(Deserializer& ds)
-{
-    ds.registerType<T>(print<T>, T::header());
-}
-
-void registerTypes(Deserializer& ds)
-{
-    registerType<LogStats>(ds);
-
-    registerType<Xbee::APIFrameLog>(ds);
-    registerType<Xbee::ATCommandFrameLog>(ds);
-    registerType<Xbee::ATCommandResponseFrameLog>(ds);
-    registerType<Xbee::ModemStatusFrameLog>(ds);
-    registerType<Xbee::TXRequestFrameLog>(ds);
-    registerType<Xbee::TXStatusFrameLog>(ds);
-    registerType<Xbee::RXPacketFrameLog>(ds);
-    registerType<Xbee::XbeeStatus>(ds);
-
-    registerType<TxData>(ds);
-    registerType<RxData>(ds);
-    registerType<Mark>(ds);
-    registerType<XbeeConfig>(ds);
-    registerType<EnergyScanData>(ds);
-}
-
-}  // namespace Boardcore
diff --git a/scripts/logdecoder/xbee/Makefile b/scripts/logdecoder/xbee/Makefile
deleted file mode 100644
index 47258b629..000000000
--- a/scripts/logdecoder/xbee/Makefile
+++ /dev/null
@@ -1,13 +0,0 @@
-BASE := ../../../../../
-
-all:
-	g++ -std=c++17 -O2 -o logdecoder logdecoder.cpp \
-					-DCOMPILE_FOR_X86 \
-					$(BASE)libs/tscpp/stream.cpp \
-	 				-I$(BASE)src/shared \
-	 				-I$(BASE)src/tests \
-					-I$(BASE)libs \
-					-I$(BASE)libs/miosix-kernel/miosix
-
-clean:
-	rm logdecoder
diff --git a/scripts/logdecoder/xbee/logdecoder.cpp b/scripts/logdecoder/xbee/logdecoder.cpp
deleted file mode 100644
index 40577eef2..000000000
--- a/scripts/logdecoder/xbee/logdecoder.cpp
+++ /dev/null
@@ -1,168 +0,0 @@
-/* Copyright (c) 2018 Skyward Experimental Rocketry
- * Author: Federico Terraneo
- *
- * 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.
- */
-
-/*
- * This is a stub program for the program that will decode the logged data.
- * You must first define a function
- *  "void registerTypes(Deserializer& ds);"
- *
- * that registers all the required log data types in the deserializer and then
- * INCLUDE this cpp file in your source. finally compile and run
- */
-
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <tscpp/stream.h>
-
-#include <filesystem>
-#include <fstream>
-#include <iostream>
-#include <stdexcept>
-#include <string>
-#include <vector>
-
-#include "LogTypes.h"
-
-using namespace std;
-using namespace tscpp;
-
-namespace fs = filesystem;
-
-void showHelp(string cmdName)
-{
-    std::cerr << "Usage: " << cmdName
-              << " {-a [logs_diretory] | <log_file_path> | -h}"
-              << "Options:\n"
-              << "\t-h,--help\t\tShow help message\n"
-              << "\t-a,--all [dir=\".\"] Deserialize all logs in the provided "
-                 "directory\n"
-              << std::endl;
-}
-
-vector<fs::path> listLogFiles(fs::path dir)
-{
-    vector<fs::path> out;
-    for (const auto& entry : fs::directory_iterator(dir))
-    {
-        if (entry.exists() && entry.is_regular_file())
-        {
-            if (entry.path().extension() == ".dat")
-            {
-                out.push_back(entry.path());
-            }
-        }
-    }
-    return out;
-}
-
-bool deserialize(fs::path log_path)
-{
-    cout << "Deserializing " << log_path << ".dat...\n";
-
-    // remove extension
-    log_path.replace_extension("");
-    Deserializer d(log_path);
-    registerTypes(d);
-
-    return d.deserialize();
-}
-
-bool deserializeAll(fs::path dir = ".")
-{
-    vector<fs::path> logs = listLogFiles(dir);
-    for (auto log : logs)
-    {
-        if (!deserialize(log.string()))
-        {
-            return false;
-        }
-    }
-
-    return true;
-}
-
-int main(int argc, char* argv[])
-{
-    if (argc < 2)
-    {
-        showHelp(string(argv[0]));
-        return 1;
-    }
-
-    bool success = false;
-    string arg1  = string(argv[1]);
-    if (arg1 == "-h" || arg1 == "--help")
-    {
-        showHelp(string(argv[0]));
-        return 0;
-    }
-
-    if (arg1 == "-a" || arg1 == "--all")
-    {
-        fs::path dir = ".";
-        if (argc == 3)
-        {
-            string arg2 = string(argv[2]);
-            fs::directory_entry entry(arg2);
-            if (entry.exists() && entry.is_directory())
-            {
-                dir = arg2;
-            }
-            else
-            {
-                cout << "Second argument after '-a' or '--all' must be a "
-                        "directory\n";
-                showHelp(string(argv[0]));
-                return 1;
-            }
-        }
-        cout << "Deserializing all logs...\n";
-        success = deserializeAll(dir);
-    }
-    else if (arg1[0] == '-')
-    {
-        cerr << "Unknown option\n";
-        return 1;
-    }
-    else
-    {
-        fs::directory_entry entry(arg1);
-        if (entry.exists() && entry.is_regular_file())
-        {
-            success = deserialize(arg1);
-        }
-        else
-        {
-            showHelp(string(argv[0]));
-            return 1;
-        }
-    }
-
-    if (success)
-    {
-        cout << "Deserialization completed successfully.\n";
-    }
-    else
-    {
-        cout << "Deserialization ended with errors.\n";
-    }
-}
diff --git a/src/shared/logger/Deserializer.h b/src/shared/logger/Deserializer.h
index 63bdfbe53..e0382dffc 100644
--- a/src/shared/logger/Deserializer.h
+++ b/src/shared/logger/Deserializer.h
@@ -27,6 +27,7 @@
 
 #include <cstdio>
 #include <fstream>
+#include <iostream>
 #include <limits>
 #include <ostream>
 #include <string>
@@ -51,151 +52,155 @@ typedef std::numeric_limits<float> flt;
 class Deserializer
 {
 public:
-    Deserializer(std::string logfile, std::string prefix = "")
-        : prefix(prefix), logFile(logfile),
-          logFileWithExt(prefix + logFile + ".dat")
-    {
-    }
+    Deserializer(std::string fileName);
 
-    ~Deserializer()
-    {
-        if (!closed)
-        {
-            for (auto it = fileStreams.begin(); it != fileStreams.end(); it++)
-            {
-                (*it)->close();
-                delete *it;
-            }
-        }
-    }
+    ~Deserializer();
 
     /**
-     * Register a type to be deserialized, and the associated print function
+     * Register a type to be deserialized, and the associated print function.
      *
-     * @param t the object to be deserialized
-     * @param fncPrint function that prints the deserialized data on the
+     * @param t The object to be deserialized.
+     * @param fncPrint Function that prints the deserialized data on the
      * provided output stream.
+     * @param header Optional CSV header text.
      */
     template <typename T>
     bool registerType(std::function<void(T& t, std::ostream& os)> fncPrint,
-                      std::string header = "")
-    {
-        if (closed)
-        {
-            printf("Error: Deserializer is closed.\n");
-            return false;
-        }
+                      std::string header = "");
 
-        char cFilename[128];
-        sprintf(cFilename, "%s%s_%s.csv", prefix.c_str(), logFile.c_str(),
-                typeid(T).name());
+    /**
+     * @brief Deserializes the provided file.
+     *
+     * @return Whether the deserialization was successful.
+     */
+    bool deserialize();
 
-        std::string filename(cFilename);
+    void close();
 
-        std::ofstream* stream = new std::ofstream();
-        stream->open(filename);
+private:
+    bool closed = false;
 
-        if (!stream->is_open())
-        {
-            printf("Error opening file %s.\n", filename.c_str());
-            perror("Error is:");
-            delete stream;
-            return false;
-        }
+    std::vector<std::ofstream*> fileStreams;
+    tscpp::TypePoolStream tps;
+
+    std::string fileName;
+};
+
+Deserializer::Deserializer(std::string fileName) : fileName(fileName) {}
 
-        fileStreams.push_back(stream);
-        stream->precision(flt::max_digits10);  // Set stream precision to
-                                               // maximum float precision
-        // Print the header
-        if (header.length() > 0)
+Deserializer::~Deserializer()
+{
+    if (!closed)
+        for (auto it = fileStreams.begin(); it != fileStreams.end(); it++)
         {
-            *stream << header;
+            (*it)->close();
+            delete *it;
         }
+}
 
-        using namespace std::placeholders;  // for _1
+template <typename T>
+bool Deserializer::registerType(
+    std::function<void(T& t, std::ostream& os)> fncPrint, std::string header)
+{
+    if (closed)
+    {
+        printf("Error: Deserializer is closed.\n");
+        return false;
+    }
 
-        std::function<void(T & t)> callback =
-            std::bind(fncPrint, _1, std::ref(*stream));
+    char cFilename[128];
+    sprintf(cFilename, "%s_%s.csv", fileName.c_str(), typeid(T).name());
 
-        tps.registerType<T>(callback);
+    std::string filename(cFilename);
 
-        return true;
+    std::ofstream* stream = new std::ofstream();
+    stream->open(filename);
+
+    if (!stream->is_open())
+    {
+        printf("Error opening file %s.\n", filename.c_str());
+        perror("Error is:");
+        delete stream;
+        return false;
     }
 
-    /**
-     * @brief Deserializes the provided file.
-     *
-     * @return Wheter the deserialization was successful.
-     */
-    bool deserialize()
+    fileStreams.push_back(stream);
+    stream->precision(flt::max_digits10);  // Set stream precision to
+                                           // maximum float precision
+    // Print the header
+    if (header.length() > 0)
     {
-        if (closed)
-        {
-            return false;
-        }
+        *stream << header;
+    }
+
+    using namespace std::placeholders;  // for _1
+
+    std::function<void(T & t)> callback =
+        std::bind(fncPrint, _1, std::ref(*stream));
 
-        bool success = true;
-        std::string unknownTypeName;
+    tps.registerType<T>(callback);
+
+    return true;
+}
+
+bool Deserializer::deserialize()
+{
+    if (closed)
+        return false;
+
+    bool success = true;
+    std::string unknownTypeName;
+
+    std::ifstream file(fileName);
+
+    // Check if the file exists
+    if (!file)
+    {
+        std::cout << fileName << " does not exists." << std::endl;
+        return false;
+    }
 
-        struct stat st;
-        if (stat(logFileWithExt.c_str(), &st) != 0)
+    tscpp::UnknownInputArchive ia(file, tps);
+    int i = 0;
+    while (success)
+    {
+        try
         {
-            printf("File %s does not exists.\n", logFileWithExt.c_str());
-            return false;
+            ia.unserialize();
         }
-
-        std::ifstream file(logFileWithExt);
-        // file.open;
-        tscpp::UnknownInputArchive ia(file, tps);
-        int i = 0;
-        while (success)
+        catch (tscpp::TscppException& ex)
         {
-            try
+            // Reached end of file
+            if (strcmp(ex.what(), "eof") == 0)
             {
-                ia.unserialize();
+                break;
             }
-            catch (tscpp::TscppException& ex)
+            else if (strcmp(ex.what(), "unknown type") == 0)
             {
-                // Reached end of file
-                if (strcmp(ex.what(), "eof") == 0)
-                {
-                    break;
-                }
-                else if (strcmp(ex.what(), "unknown type") == 0)
-                {
-                    unknownTypeName = ex.name();
-                    success         = false;
-                    printf("Unknown type found: %s\n", unknownTypeName.c_str());
-                    break;
-                }
+                unknownTypeName = ex.name();
+                success         = false;
+                std::cout << "Unknown type found: " << unknownTypeName
+                          << std::endl;
+                break;
             }
         }
-        file.close();
-        return success;
     }
 
-    void close()
+    file.close();
+    return success;
+}
+
+void Deserializer::close()
+{
+    if (!closed)
     {
-        if (!closed)
+        closed = true;
+        for (auto it = fileStreams.begin(); it != fileStreams.end(); it++)
         {
-            closed = true;
-            for (auto it = fileStreams.begin(); it != fileStreams.end(); it++)
-            {
-                (*it)->close();
-                delete *it;
-            }
+            (*it)->close();
+            delete *it;
         }
     }
-
-private:
-    bool closed = false;
-
-    std::vector<std::ofstream*> fileStreams;
-    tscpp::TypePoolStream tps;
-
-    std::string prefix;
-    std::string logFile;
-    std::string logFileWithExt;
-};
+}
 
 }  // namespace Boardcore
diff --git a/src/shared/logger/LogTypes.h b/src/shared/logger/LogTypes.h
new file mode 100644
index 000000000..3863ea5d5
--- /dev/null
+++ b/src/shared/logger/LogTypes.h
@@ -0,0 +1,125 @@
+/* Copyright (c) 2015-2022 Skyward Experimental Rocketry
+ * Author: Luca Erbetta, 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
+ * 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 <algorithms/ExtendedKalman/ExtendedKalmanState.h>
+#include <diagnostic/PrintLoggerData.h>
+#include <drivers/adc/InternalADCData.h>
+#include <events/EventData.h>
+#include <logger/Deserializer.h>
+#include <logger/LoggerStats.h>
+#include <radio/MavlinkDriver/MavlinkStatus.h>
+#include <radio/Xbee/XbeeStatus.h>
+#include <scheduler/TaskSchedulerData.h>
+#include <sensors/ADS1118/ADS1118Data.h>
+#include <sensors/ADS131M04/ADS131M04Data.h>
+#include <sensors/BME280/BME280Data.h>
+#include <sensors/BMP280/BMP280Data.h>
+#include <sensors/BMX160/BMX160Data.h>
+#include <sensors/BMX160/BMX160WithCorrectionData.h>
+#include <sensors/HX711/HX711Data.h>
+#include <sensors/L3GD20/L3GD20Data.h>
+#include <sensors/LIS3DSH/LIS3DSHData.h>
+#include <sensors/LIS3MDL/LIS3MDLData.h>
+#include <sensors/MBLoadCell/MBLoadCellData.h>
+#include <sensors/MPU9250/MPU9250Data.h>
+#include <sensors/MS5803/MS5803Data.h>
+#include <sensors/SensorData.h>
+#include <sensors/UbloxGPS/UbloxGPSData.h>
+#include <sensors/VN100/VN100Data.h>
+#include <sensors/analog/battery/BatteryVoltageSensorData.h>
+#include <sensors/analog/current/CurrentSensorData.h>
+#include <sensors/analog/pressure/MPXHZ6130A/MPXHZ6130AData.h>
+#include <sensors/analog/pressure/honeywell/HSCMAND015PAData.h>
+#include <sensors/analog/pressure/honeywell/HSCMRNN030PAData.h>
+#include <sensors/analog/pressure/honeywell/HSCMRNN160KAData.h>
+#include <sensors/analog/pressure/honeywell/SSCDANN030PAAData.h>
+#include <sensors/analog/pressure/honeywell/SSCDRRN015PDAData.h>
+
+#include <fstream>
+#include <iostream>
+
+/**
+ * @brief This file includes all the types the logdecoder script will decode.
+ *
+ * All logged classes inside Boardcore should be reported here.
+ */
+
+namespace Boardcore
+{
+
+namespace LogTypes
+{
+
+template <typename T>
+void print(T& t, std::ostream& os)
+{
+    t.print(os);
+}
+
+template <typename T>
+void registerType(Deserializer& ds)
+{
+    ds.registerType<T>(print<T>, T::header());
+}
+
+void registerTypes(Deserializer& ds)
+{
+    registerType<ExtendedKalmanState>(ds);
+    registerType<LoggingString>(ds);
+    registerType<InternalADCData>(ds);
+    registerType<EventData>(ds);
+    registerType<LoggerStats>(ds);
+    registerType<MavlinkStatus>(ds);
+    registerType<Xbee::XbeeStatus>(ds);
+    registerType<TaskStatsResult>(ds);
+    registerType<ADS1118Data>(ds);
+    registerType<ADS131M04Data>(ds);
+    registerType<BME280Data>(ds);
+    registerType<BMP280Data>(ds);
+    registerType<BMX160Data>(ds);
+    registerType<BMX160WithCorrectionData>(ds);
+    registerType<HX711Data>(ds);
+    registerType<L3GD20Data>(ds);
+    registerType<LIS3DSHData>(ds);
+    registerType<LIS3MDLData>(ds);
+    registerType<MBLoadCellData>(ds);
+    registerType<MPU9250Data>(ds);
+    registerType<MS5803Data>(ds);
+    registerType<TemperatureData>(ds);
+    registerType<UbloxGPSData>(ds);
+    registerType<VN100Data>(ds);
+    registerType<BatteryVoltageSensorData>(ds);
+    registerType<CurrentSensorData>(ds);
+    registerType<LoadCellData>(ds);
+    registerType<MPXHZ6130AData>(ds);
+    registerType<HSCMAND015PAData>(ds);
+    registerType<HSCMRNN030PAData>(ds);
+    registerType<HSCMRNN160KAData>(ds);
+    registerType<SSCDANN030PAAData>(ds);
+    registerType<SSCDRRN015PDAData>(ds);
+}
+
+}  // namespace LogTypes
+
+}  // namespace Boardcore
diff --git a/src/shared/sensors/HX711/HX711Data.h b/src/shared/sensors/HX711/HX711Data.h
index 6d4f49402..49e25db19 100644
--- a/src/shared/sensors/HX711/HX711Data.h
+++ b/src/shared/sensors/HX711/HX711Data.h
@@ -32,17 +32,17 @@ struct HX711Data : public LoadCellData
 {
     HX711Data() : LoadCellData{0, 0} {}
 
-    HX711Data(uint64_t weightTimestamp, float weight)
-        : LoadCellData{weightTimestamp, weight}
+    HX711Data(uint64_t loadTimestamp, float load)
+        : LoadCellData{loadTimestamp, load}
     {
     }
 
-    static std::string header() { return "weightTimestamp,weight\n"; }
+    static std::string header() { return "loadTimestamp,load\n"; }
 
     void print(std::ostream& os) const
     {
-        os << weightTimestamp << "," << weight << "\n";
+        os << loadTimestamp << "," << load << "\n";
     }
 };
 
-}  // namespace Boardcore
\ No newline at end of file
+}  // namespace Boardcore
diff --git a/src/shared/sensors/MBLoadCell/MBLoadCell.cpp b/src/shared/sensors/MBLoadCell/MBLoadCell.cpp
index 1874fff78..4e2a6fa7c 100644
--- a/src/shared/sensors/MBLoadCell/MBLoadCell.cpp
+++ b/src/shared/sensors/MBLoadCell/MBLoadCell.cpp
@@ -165,15 +165,15 @@ void MBLoadCell::printData()
     }
 }
 
-Data MBLoadCell::getMaxWeight() { return maxWeight; }
+MBLoadCellData MBLoadCell::getMaxWeight() { return maxWeight; }
 
-Data MBLoadCell::getMinWeight() { return minWeight; }
+MBLoadCellData MBLoadCell::getMinWeight() { return minWeight; }
 
 bool MBLoadCell::selfTest() { return true; }
 
-Data MBLoadCell::sampleImpl()
+MBLoadCellData MBLoadCell::sampleImpl()
 {
-    Data value;
+    MBLoadCellData value;
     switch (settings.mode)
     {
         case LoadCellModes::CONT_MOD_T:
@@ -217,23 +217,23 @@ Data MBLoadCell::sampleImpl()
     return value;
 }
 
-Data MBLoadCell::sampleContModT()
+MBLoadCellData MBLoadCell::sampleContModT()
 {
     DataModT data;
     receive(&data);
 
-    return Data(atof(data.weight) / 10.0);
+    return MBLoadCellData(atof(data.weight) / 10.0);
 }
 
-Data MBLoadCell::sampleContModTd()
+MBLoadCellData MBLoadCell::sampleContModTd()
 {
     DataModTd data;
     receive(&data);
 
-    return Data(atof(data.weightT) / 10.0);
+    return MBLoadCellData(atof(data.weightT) / 10.0);
 }
 
-Data MBLoadCell::sampleAsciiModTd()
+MBLoadCellData MBLoadCell::sampleAsciiModTd()
 {
     DataAsciiRequest request;
 
@@ -262,7 +262,7 @@ Data MBLoadCell::sampleAsciiModTd()
     else
     {
         // Taking the value returned
-        return Data(stof(response.substr(3, 6)) / 10.0);
+        return MBLoadCellData(stof(response.substr(3, 6)) / 10.0);
     }
 }
 
diff --git a/src/shared/sensors/MBLoadCell/MBLoadCell.h b/src/shared/sensors/MBLoadCell/MBLoadCell.h
index aefe3c680..d8e57f5f6 100644
--- a/src/shared/sensors/MBLoadCell/MBLoadCell.h
+++ b/src/shared/sensors/MBLoadCell/MBLoadCell.h
@@ -47,7 +47,7 @@ namespace Boardcore
  * - ASCII-modTd: bidirectional mode that consists in sending a request and
  * receiving a response with the data requested or an error message
  */
-class MBLoadCell : public Sensor<Data>
+class MBLoadCell : public Sensor<MBLoadCellData>
 {
 public:
     /**
@@ -86,12 +86,12 @@ public:
     /**
      * @brief Returns a copy of the max weight detected.
      */
-    Data getMaxWeight();
+    MBLoadCellData getMaxWeight();
 
     /**
      * @brief Returns a copy of the min weight detected.
      */
-    Data getMinWeight();
+    MBLoadCellData getMinWeight();
 
     bool selfTest() override;
 
@@ -102,22 +102,22 @@ protected:
      *
      * @return The weight measured from the load cell.
      */
-    Data sampleImpl() override;
+    MBLoadCellData sampleImpl() override;
 
     /**
      * @brief Sampling in the "continuous Mod T" mode.
      */
-    Data sampleContModT(void);
+    MBLoadCellData sampleContModT(void);
 
     /**
      * @brief Sampling in the "continuous Mod Td" mode.
      */
-    Data sampleContModTd(void);
+    MBLoadCellData sampleContModTd(void);
 
     /**
      * @brief Sampling in the "ASCII Mod Td" mode.
      */
-    Data sampleAsciiModTd(void);
+    MBLoadCellData sampleAsciiModTd(void);
 
     /**
      * @brief Forges a request for the ascii mode.
@@ -158,8 +158,8 @@ protected:
 
 private:
     MBLoadCellSettings settings;  ///< Contains all the configuration
-    Data maxWeight;               ///< Maximum weight detected by the load cell
-    Data minWeight;               ///< Minimum weight detected by the load cell
+    MBLoadCellData maxWeight;     ///< Maximum weight detected by the load cell
+    MBLoadCellData minWeight;     ///< Minimum weight detected by the load cell
     bool maxSetted;
     bool maxPrint;
     bool minSetted;
diff --git a/src/shared/sensors/MBLoadCell/MBLoadCellData.h b/src/shared/sensors/MBLoadCell/MBLoadCellData.h
index c576fa20e..3c9c12495 100644
--- a/src/shared/sensors/MBLoadCell/MBLoadCellData.h
+++ b/src/shared/sensors/MBLoadCell/MBLoadCellData.h
@@ -22,9 +22,9 @@
 
 #pragma once
 
-#include <drivers/timer/TimestampTimer.h>
 #include <utils/Debug.h>
 
+#include <cstdio>
 #include <map>
 
 #include "sensors/SensorData.h"
@@ -87,24 +87,25 @@ enum ReturnsStates
  * @brief Structure that stores a data value, with his timestamp and his
  * validity.
  */
-struct Data : public LoadCellData
+struct MBLoadCellData : public LoadCellData
 {
     bool valid = false;
 
-    Data() : LoadCellData{0, 0.0}, valid(false) {}
+    MBLoadCellData() : LoadCellData{0, 0.0}, valid(false) {}
 
-    explicit Data(float data)
-        : LoadCellData{TimestampTimer::getInstance().getTimestamp(), data},
-          valid(true)
+    explicit MBLoadCellData(float data) : MBLoadCellData{0, data} {}
+
+    explicit MBLoadCellData(uint64_t loadTimestamp, float data)
+        : LoadCellData{loadTimestamp, data}, valid(true)
     {
     }
 
-    static std::string header() { return "weightTimestamp,weight\n"; }
+    static std::string header() { return "loadTimestamp,weight\n"; }
 
     void print(std::ostream& os) const
     {
         if (valid)
-            os << weightTimestamp / 1000000.0 << "," << weight << "\n";
+            os << loadTimestamp / 1000000.0 << "," << load << "\n";
     }
 };
 
@@ -115,10 +116,10 @@ struct MBLoadCellSettings
 {
     LoadCellModes mode;
     bool grossMode;
-    Data peakWeight;
-    Data setpoint1;
-    Data setpoint2;
-    Data setpoint3;
+    MBLoadCellData peakWeight;
+    MBLoadCellData setpoint1;
+    MBLoadCellData setpoint2;
+    MBLoadCellData setpoint3;
 
     /**
      * @brief Updates the correct value with the data passed. Also, memorizes
@@ -129,16 +130,16 @@ struct MBLoadCellSettings
         switch (val)
         {
             case PEAK_WEIGHT:
-                peakWeight = Data(data);
+                peakWeight = MBLoadCellData(data);
                 break;
             case GET_SETPOINT_1:
-                setpoint1 = Data(data);
+                setpoint1 = MBLoadCellData(data);
                 break;
             case GET_SETPOINT_2:
-                setpoint2 = Data(data);
+                setpoint2 = MBLoadCellData(data);
                 break;
             case GET_SETPOINT_3:
-                setpoint3 = Data(data);
+                setpoint3 = MBLoadCellData(data);
                 break;
             default:
                 break;
@@ -151,22 +152,22 @@ struct MBLoadCellSettings
     void print() const
     {
         /*if (netWeight.valid)
-            TRACE("Net Weight     : %f [Kg]\n", netWeight.data);
+            TRACE("Net Weight     : %f [Kg]\n", netWeight.load);
 
         if (grossWeight.valid)
-            TRACE("Gross Weight   : %f [Kg]\n", grossWeight.data);
+            TRACE("Gross Weight   : %f [Kg]\n", grossWeight.load);
         */
         if (peakWeight.valid)
-            TRACE("Peak Weight    : %f [Kg]\n", peakWeight.weight);
+            TRACE("Peak Weight    : %f [Kg]\n", peakWeight.load);
 
         if (setpoint1.valid)
-            TRACE("Setpoint 1     : %f [Kg]\n", setpoint1.weight);
+            TRACE("Setpoint 1     : %f [Kg]\n", setpoint1.load);
 
         if (setpoint2.valid)
-            TRACE("Setpoint 2     : %f [Kg]\n", setpoint2.weight);
+            TRACE("Setpoint 2     : %f [Kg]\n", setpoint2.load);
 
         if (setpoint3.valid)
-            TRACE("Setpoint 3     : %f [Kg]\n", setpoint3.weight);
+            TRACE("Setpoint 3     : %f [Kg]\n", setpoint3.load);
     }
 };
 
@@ -223,7 +224,7 @@ struct DataAsciiRequest
             checksum ^= str[i];
         }
 
-        itoa(checksum, ck, 16);
+        sprintf(ck, "%x", checksum);
     }
 
     /**
diff --git a/src/shared/sensors/SensorData.h b/src/shared/sensors/SensorData.h
index f4aeb4e64..b945640e9 100644
--- a/src/shared/sensors/SensorData.h
+++ b/src/shared/sensors/SensorData.h
@@ -56,8 +56,16 @@ struct TimestampData
 
 struct LoadCellData
 {
-    uint64_t weightTimestamp;
-    float weight;
+    uint64_t loadTimestamp;
+    float voltage;
+    float load;
+
+    static std::string header() { return "loadTimestamp,voltage,load\n"; }
+
+    void print(std::ostream& os) const
+    {
+        os << loadTimestamp << "," << voltage << "," << load << "\n";
+    }
 };
 
 struct TemperatureData
diff --git a/src/shared/sensors/analog/loadcell/LoadCell.h b/src/shared/sensors/analog/loadcell/LoadCell.h
index 76d678ce2..ac36f900f 100644
--- a/src/shared/sensors/analog/loadcell/LoadCell.h
+++ b/src/shared/sensors/analog/loadcell/LoadCell.h
@@ -26,8 +26,6 @@
 
 #include <functional>
 
-#include "LoadCellData.h"
-
 namespace Boardcore
 {
 
@@ -50,7 +48,7 @@ public:
     {
         LoadCellData data;
 
-        std::tie(data.timestamp, data.voltage) = getVoltage();
+        std::tie(data.loadTimestamp, data.voltage) = getVoltage();
 
         data.load = data.voltage / conversionCoeff;
 
diff --git a/src/shared/sensors/analog/loadcell/LoadCellData.h b/src/shared/sensors/analog/loadcell/LoadCellData.h
deleted file mode 100644
index 665ae9311..000000000
--- a/src/shared/sensors/analog/loadcell/LoadCellData.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/* Copyright (c) 2022 Skyward Experimental Rocketry
- * Author: 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
- * 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 <ostream>
-
-namespace Boardcore
-{
-
-struct LoadCellData
-{
-    uint64_t timestamp;
-    float voltage;
-    float load;
-
-    static std::string header() { return "timestamp,voltage,load\n"; }
-
-    void print(std::ostream& os) const
-    {
-        os << timestamp << "," << voltage << "," << load << "\n";
-    }
-};
-
-}  // namespace Boardcore
diff --git a/src/shared/utils/CSVReader/CSVReader.h b/src/shared/utils/CSVReader/CSVReader.h
index 32388292c..a8f59a5ef 100644
--- a/src/shared/utils/CSVReader/CSVReader.h
+++ b/src/shared/utils/CSVReader/CSVReader.h
@@ -123,6 +123,9 @@ private:
 /**
  * @brief Iterable parser of CSV files.
  *
+ * If the CSV file has an header row, you must specify true as the second
+ * parameter in the constructor.
+ *
  * Given the file name, reads the contents as elements of type Data. Can be used
  * with CSVIterator to iterate through all the CSV rows.
  * You can retrieve all data inside the file as a vector with collect().
@@ -134,7 +137,14 @@ template <typename Data>
 class CSVParser
 {
 public:
-    CSVParser(const char* fileName) : fileStream(fileName) {}
+    CSVParser(const char* fileName, bool hasHeader = false)
+        : fileStream(fileName)
+    {
+        // If the file has the header, ignore everithing in the first line
+        if (hasHeader)
+            fileStream.ignore(std::numeric_limits<std::streamsize>::max(),
+                              '\n');
+    }
 
     ~CSVParser() { fileStream.close(); }
 
-- 
GitLab