diff --git a/scripts/logdecoder/logdecoder.cpp b/scripts/logdecoder/logdecoder.cpp
index 670873a182784e3a882b1649fb48e69502e3b164..59b7e03aad83b09bb6baea4d986f205a4d3d41d1 100644
--- a/scripts/logdecoder/logdecoder.cpp
+++ b/scripts/logdecoder/logdecoder.cpp
@@ -42,25 +42,43 @@
 using namespace tscpp;
 using namespace Boardcore;
 
-void showUsage(string commandName);
+void showUsage(const string& cmdName)
+{
+    std::cerr << "Usage: " << cmdName << " {-a | <log_file_name> | -h}"
+              << "Options:\n"
+              << "\t-h,--help\t\tShow help message\n"
+              << "\t-a,--all Deserialize all logs in the current directory\n"
+              << std::endl;
+}
 
-/**
- * @brief Deserialize a file.
- *
- * @param fileName File name complete with extension.
- * @return Whether the deserialization was successful.
- */
-bool deserialize(string fileName);
+bool deserialize(string logName)
+{
+    std::cout << "Deserializing " << logName << "...\n";
+    Deserializer d(logName);
+    LogTypes::registerTypes(d);
 
-/**
- * @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();
+    return d.deserialize();
+}
+
+bool deserializeAll()
+{
+    for (int i = 0; i < 100; i++)
+    {
+        char fn[10];
+        char fnext[11];
+        sprintf(fn, "log%02d", i);
+        sprintf(fnext, "log%02d.dat", i);
+        struct stat st;
+        if (stat(fnext, &st) != 0)
+            continue;  // File not found
+        // File found
+        if (!deserialize(string(fn)))
+        {
+            return false;
+        }
+    }
+    return true;
+}
 
 int main(int argc, char* argv[])
 {
@@ -93,47 +111,3 @@ int main(int argc, char* argv[])
         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/src/shared/logger/Deserializer.h b/src/shared/logger/Deserializer.h
index e0382dffcaec69b821faa0b7f28b81f0095c0a4a..f724e7342fcd46b5b7c014c67f7260eef2124fec 100644
--- a/src/shared/logger/Deserializer.h
+++ b/src/shared/logger/Deserializer.h
@@ -1,5 +1,5 @@
-/* Copyright (c) 2015-2018 Skyward Experimental Rocketry
- * Author: Luca Erbetta
+/* Copyright (c) 2015-2022 Skyward Experimental Rocketry
+ * Authors: 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
@@ -47,26 +47,31 @@ typedef std::numeric_limits<float> flt;
 // linter off
 
 /**
- * Class used to deserialize log files created using fedetft's logger.
+ * @brief Class used to deserialize the binary logs created using fedetft's
+ * logger into csv files.
  */
 class Deserializer
 {
 public:
+    /**
+     * @brief Initializes the deserializer with the filename provided.
+     */
     Deserializer(std::string fileName);
 
     ~Deserializer();
 
     /**
-     * Register a type to be deserialized, and the associated print function.
+     * @brief Register a type to be deserialized.
+     *
+     * Node: The object type must provide a static header function and a print
+     * function with the following prototypes:
+     * static std::string header()
+     * void print(std::ostream& os) const
      *
-     * @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.
+     * @tparam T The object type to be deserialized.
      */
     template <typename T>
-    bool registerType(std::function<void(T& t, std::ostream& os)> fncPrint,
-                      std::string header = "");
+    void registerType();
 
     /**
      * @brief Deserializes the provided file.
@@ -75,72 +80,84 @@ public:
      */
     bool deserialize();
 
+    /**
+     * @brief Closes all the openend files.
+     */
     void close();
 
 private:
+    /**
+     * @brief Function to print a data element into its csv file.
+     *
+     * @tparam T Type of the object.
+     * @param t Object to be printed in the file.
+     * @param path Path where to save the file.
+     * @param prefix Prefix added to the file.
+     */
+    template <typename T>
+    void printType(T& t, std::string path = "", std::string prefix = "");
+
     bool closed = false;
 
     std::vector<std::ofstream*> fileStreams;
     tscpp::TypePoolStream tps;
 
-    std::string fileName;
+    std::string logFilename;
+    std::string logFilenameWithoutExtension;
+    std::string logFolderPath;
 };
 
-Deserializer::Deserializer(std::string fileName) : fileName(fileName) {}
-
-Deserializer::~Deserializer()
+Deserializer::Deserializer(std::string logFilename) : logFilename(logFilename)
 {
-    if (!closed)
-        for (auto it = fileStreams.begin(); it != fileStreams.end(); it++)
-        {
-            (*it)->close();
-            delete *it;
-        }
+    // Prepare the folder path
+    logFilenameWithoutExtension =
+        logFilename.substr(0, logFilename.find_last_of("."));
+    logFolderPath = logFilenameWithoutExtension + "/";
 }
 
+Deserializer::~Deserializer() { close(); }
+
 template <typename T>
-bool Deserializer::registerType(
-    std::function<void(T& t, std::ostream& os)> fncPrint, std::string header)
+void Deserializer::registerType()
 {
-    if (closed)
-    {
-        printf("Error: Deserializer is closed.\n");
-        return false;
-    }
-
-    char cFilename[128];
-    sprintf(cFilename, "%s_%s.csv", fileName.c_str(), typeid(T).name());
-
-    std::string filename(cFilename);
+    std::function<void(T & t)> callback =
+        std::bind(&Deserializer::printType<T>, this, std::placeholders::_1,
+                  logFolderPath, logFilenameWithoutExtension);
 
-    std::ofstream* stream = new std::ofstream();
-    stream->open(filename);
+    tps.registerType<T>(callback);
+}
 
-    if (!stream->is_open())
-    {
-        printf("Error opening file %s.\n", filename.c_str());
-        perror("Error is:");
-        delete stream;
-        return false;
-    }
+template <typename T>
+void Deserializer::printType(T& t, std::string path, std::string prefix)
+{
+    static std::ofstream* stream = nullptr;
 
-    fileStreams.push_back(stream);
-    stream->precision(flt::max_digits10);  // Set stream precision to
-                                           // maximum float precision
-    // Print the header
-    if (header.length() > 0)
+    // If not already initialize, open the file and write the header
+    if (stream == nullptr)
     {
-        *stream << header;
-    }
+        stream = new std::ofstream();
+        std::string filename =
+            path + prefix + "_" + tscpp::demangle(typeid(T).name()) + ".csv";
+        std::cout << "Creating file " + filename << std::endl;
+        stream->open(filename);
 
-    using namespace std::placeholders;  // for _1
+        if (!stream->is_open())
+        {
+            printf("Error opening file %s.\n", filename.c_str());
+            perror("Error is:");
+            return;
+        }
 
-    std::function<void(T & t)> callback =
-        std::bind(fncPrint, _1, std::ref(*stream));
+        // Print the header in the file
+        *stream << T::header();
 
-    tps.registerType<T>(callback);
+        // Add the file to the vector such that it will be closed
+        fileStreams.push_back(stream);
+    }
 
-    return true;
+    // Print data into the file if it is open
+    if (stream->is_open())
+        t.print(std::ref(*stream));
 }
 
 bool Deserializer::deserialize()
@@ -148,46 +165,54 @@ bool Deserializer::deserialize()
     if (closed)
         return false;
 
-    bool success = true;
-    std::string unknownTypeName;
+    // Create the folder
+    mkdir(logFolderPath.c_str(), 0777);
 
-    std::ifstream file(fileName);
+    // Move the log file into the folder
+    if (rename(logFilename.c_str(), (logFolderPath + logFilename).c_str()))
+    {
+        std::cout << logFilename + " does not exists." << std::endl;
+        return false;
+    }
+
+    // Open the log file
+    std::ifstream file(logFolderPath + logFilename);
 
     // Check if the file exists
     if (!file)
     {
-        std::cout << fileName << " does not exists." << std::endl;
+        std::cout << logFolderPath + logFilename + " does not exists."
+                  << std::endl;
         return false;
     }
 
-    tscpp::UnknownInputArchive ia(file, tps);
-    int i = 0;
-    while (success)
+    tscpp::UnknownInputArchive inputArchive(file, tps);
+    while (true)
     {
         try
         {
-            ia.unserialize();
+            inputArchive.unserialize();
         }
         catch (tscpp::TscppException& ex)
         {
             // Reached end of file
             if (strcmp(ex.what(), "eof") == 0)
             {
-                break;
+                return true;
             }
+            // Unknown type found
             else if (strcmp(ex.what(), "unknown type") == 0)
             {
-                unknownTypeName = ex.name();
-                success         = false;
+                std::string unknownTypeName = ex.name();
                 std::cout << "Unknown type found: " << unknownTypeName
                           << std::endl;
-                break;
+                return false;
             }
         }
     }
 
     file.close();
-    return success;
+    return true;
 }
 
 void Deserializer::close()
diff --git a/src/shared/logger/LogTypes.h b/src/shared/logger/LogTypes.h
index bb2a1c06dfee3da621fe2676f56cdce841af3904..b0c45d193df4c9aac7924a41dd4a7e82aef716cf 100644
--- a/src/shared/logger/LogTypes.h
+++ b/src/shared/logger/LogTypes.h
@@ -22,6 +22,7 @@
 
 #pragma once
 
+#include <actuators/Servo/ServoData.h>
 #include <algorithms/NAS/NASState.h>
 #include <diagnostic/PrintLoggerData.h>
 #include <drivers/adc/InternalADCData.h>
@@ -71,53 +72,42 @@ 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<NASState>(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);
+    ds.registerType<ServoData>();
+    ds.registerType<NASState>();
+    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>();
 }
 
 }  // namespace LogTypes