diff --git a/.gitignore b/.gitignore
index 9b89790f971bdc8817c9e536f0eccafcf4009da4..a9f1775b4bc49623280a7697bbb213db7e2b4b91 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 83c45bdd3c1959aa6fb9ff9bdc05e26e3bb9dac1..78209a5f4446e7dc5eaef63de2a9bf1202863192 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 4c48cde6bb08d87f0ba9e4ae3a02cc2dba7fe1df..eff44bf316fabcf0e68b244c992a0807d248dc96 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 c8674a48e794c246f79c56b163ebab72d3654846..935bf1944e1ddeaf51fd22cdce04a2a97762890f 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 0a30ee85eaf9786bc68f52dcd335486e4766392e..2523965cd9ce3b7e20457d7d5c1f047d90386c7c 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 96b81e338727137ff3d25d077d1c56891226fd15..670873a182784e3a882b1649fb48e69502e3b164 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
Binary files a/scripts/logdecoder/sample_no_cereal.dat.dat and /dev/null differ
diff --git a/scripts/logdecoder/xbee/.gitignore b/scripts/logdecoder/xbee/.gitignore
deleted file mode 100644
index 3e6fd163051d66dceb9c808d07e314ae4d022ee5..0000000000000000000000000000000000000000
--- 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 cb82189b489a302f28b3f62dfd61fec88c1326b7..0000000000000000000000000000000000000000
--- 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 47258b629723d159885432ac1e485023f5d40002..0000000000000000000000000000000000000000
--- 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 40577eef2088983028f356bb13b341f97641ed3d..0000000000000000000000000000000000000000
--- 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 63bdfbe53bec423e99ff24544062da452b0adba7..e0382dffcaec69b821faa0b7f28b81f0095c0a4a 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 0000000000000000000000000000000000000000..3863ea5d5c79f735c181c347a3a6ab8ab9e1dcbc
--- /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 6d4f4940229b86fd157f6b4b133ee6b7ec8c9d14..49e25db1942c56331a90e9bbe6cd29f21741607d 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 1874fff78cb19a8b22ff69cefb07e4c1462c9bb2..4e2a6fa7cf780bcdf8aa4e193700578bc6120595 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 aefe3c6808653ca2ca93abd0742feae5d8f23273..d8e57f5f65bdded510a9ad6830bed13d1c053106 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 c576fa20e15f691d11f8a060e6545f449c786310..3c9c12495040743ac5dc2bfd0a7647f62115ee94 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 f4aeb4e642155d38e0054796e840b77bd30d0d36..b945640e9cb8a5f31a888361469c8db7b9a11801 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 76d678ce2304542247fb0fa57b33aed73972ff4d..ac36f900faf2f98ce613bf3ff3cd94924745f0d4 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 665ae93111656de0f1c756d2a4003d27093fd1fc..0000000000000000000000000000000000000000
--- 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 32388292c5890d88e3fa43182e049ac89ddaa477..a8f59a5efae736e8de7fb31193163d7fb4964f16 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(); }