diff --git a/inc/Services/Parameter.hpp b/inc/Services/Parameter.hpp
index 12f8f1bb3b134870cb3bf46f16e315067733ec26..9cf9a01583ad83c23816fb5785c7a58eece8dfc6 100644
--- a/inc/Services/Parameter.hpp
+++ b/inc/Services/Parameter.hpp
@@ -2,10 +2,12 @@
 #define ECSS_SERVICES_PARAMETER_HPP
 
 #include "etl/bitset.h"
+#include "etl/String.hpp"
 
 // Number of binary flags in every parameter. Final number TBD.
 #define NUM_OF_FLAGS 3
-
+// Maximum etl::string length in bytes
+#define MAX_STRING_LENGTH 5
 /**
  * Implementation of a Parameter field, as specified in ECSS-E-ST-70-41C.
  * Fully compliant with the standards requirements, while adding some small,
@@ -23,7 +25,8 @@
  * @typedef Flags: container for the binary flags
  */
 typedef uint16_t ParamId;
-//typedef etl::variant<bool, uint8_t, int32_t, float> ValueType;
+//typedef uint32_t ValueType;
+//#typedef ;
 typedef etl::bitset<NUM_OF_FLAGS> Flags;
 
 /**
@@ -54,24 +57,59 @@ typedef etl::bitset<NUM_OF_FLAGS> Flags;
  * @public getCurrentValue(): Gets the current value of the parameter
  * @public getPTC(), getPFC(): Returns the PFC and PTC of the parameter
  */
-template <typename ValueType> class Parameter {
+
+class ParameterBase {
+protected:
 	uint8_t ptc;
 	uint8_t pfc;
-	void(*ptr)(ValueType*);
+	uint8_t sizeInBytes;
+	void* valuePtr;
 	Flags flags;
-	ValueType currentValue = 0;
+public:
+	uint8_t getPTC();
+
+	void setFlags(const char* flags);
+
+	uint8_t getPFC();
+
+	virtual String<MAX_STRING_LENGTH> getValueAsString() = 0;
+
+	template <typename ValueType>
+	void setCurrentValue(ValueType newVal) {
+		// set the value only if the parameter can be updated manually
+		if (flags[1]) {
+			*reinterpret_cast<ValueType*>(valuePtr) = newVal;
+		}
+	}
+};
 
-	public:
-		Parameter<ValueType>(uint8_t newPtc, uint8_t newPfc, const ValueType& initialValue, void(*newPtr)(ValueType*));
+template <typename ValueType>
+class Parameter : public ParameterBase {
+	void (* ptr)(ValueType*);
 
-		void setCurrentValue(const ValueType& newVal);
-		void setFlags(const char* flags);
+	ValueType currentValue;
 
-		ValueType getCurrentValue();
-		uint8_t getPTC();
+public:
+	Parameter(uint8_t newPtc, uint8_t newPfc, ValueType initialValue = 0, void(* newPtr)(ValueType*) = nullptr) {
+		ptc = newPtc;
+		pfc = newPfc;
+		ptr = newPtr;
+		sizeInBytes = sizeof(initialValue);
+		valuePtr = static_cast<void*>(&currentValue);
+		// see Parameter.hpp for explanation on flags
+		// by default: no update priority, manual and automatic update available
 
-		uint8_t getPFC();
+		if (ptr != nullptr) {
+			(*ptr)(&currentValue);  // call the update function for the initial value
+		} else {
+			currentValue = initialValue;
+		}
+	}
 
+	String<MAX_STRING_LENGTH> getValueAsString() override {
+		String<MAX_STRING_LENGTH> contents(reinterpret_cast<uint8_t*>(&currentValue), sizeInBytes);
+		return contents;
+	}
 };
 
 
diff --git a/inc/Services/ParameterService.hpp b/inc/Services/ParameterService.hpp
index 3d473103009f0da4bfd90ceb88121edee80e6226..d7f64751d4abf5f5e18192890c77d679a678fcd4 100644
--- a/inc/Services/ParameterService.hpp
+++ b/inc/Services/ParameterService.hpp
@@ -27,7 +27,7 @@
 
 class ParameterService : public Service {
 private:
-	etl::map<ParamId, Parameter, ECSS_ST_20_MAX_PARAMETERS> paramsList;
+	etl::map<ParamId, ParameterBase*, ECSS_ST_20_MAX_PARAMETERS> paramsList;
 
 public:
 	/**
@@ -43,7 +43,7 @@ public:
 	 * @param param: the parameter field to be included
 	 * @param flags: the flags to be set for this field (see Parameter.hpp)
 	 */
-	void addNewParameter(uint16_t id, Parameter param, const char* flags = "110");
+	void addNewParameter(uint16_t id, ParameterBase* param, const char* flags = "110");
 
 	/**
 	 * This function receives a TC[20, 1] packet and returns a TM[20, 2] packet
diff --git a/src/Services/Parameter.cpp b/src/Services/Parameter.cpp
index 9a96fe4eb18eaf8121ab9deb0165f1c7fa4a8a31..f1410d910314931e536b24b49945d3cf9dc2c9fe 100644
--- a/src/Services/Parameter.cpp
+++ b/src/Services/Parameter.cpp
@@ -1,45 +1,13 @@
 #include "Services/Parameter.hpp"
 
-template <typename ValueType>
-Parameter<ValueType>::Parameter(uint8_t newPtc, uint8_t newPfc, const ValueType& initialValue, void(*newPtr)(ValueType*)) {
-	ptc = newPtc;
-	pfc = newPfc;
-	ptr = newPtr;
-
-	// see Parameter.hpp for explanation on flags
-	// by default: no update priority, manual and automatic update available
-
-	if (ptr != nullptr) {
-		(*ptr)(&currentValue);  // call the update function for the initial value
-	} else {
-		currentValue = initialValue;
-	}
-}
-
-template <typename ValueType>
-void Parameter<ValueType>::setCurrentValue(const ValueType& newVal) {
-	// set the value only if the parameter can be updated manually
-	if (flags[1]) {
-		currentValue = newVal;
-	}
-}
-
-template <typename ValueType>
-ValueType Parameter<ValueType>::getCurrentValue() {
-	return currentValue;
-}
-template <typename ValueType>
-uint8_t Parameter<ValueType>::getPTC() {
+uint8_t ParameterBase::getPTC() {
 	return ptc;
 }
 
-template <typename ValueType>
-uint8_t Parameter<ValueType>::getPFC() {
+uint8_t ParameterBase::getPFC() {
 	return pfc;
 }
 
-template <typename ValueType>
-void Parameter<ValueType>::setFlags(const char* flags) {
+void ParameterBase::setFlags(const char* flags) {
 	this->flags = Flags(flags);
-}
-
+}
\ No newline at end of file
diff --git a/src/Services/ParameterService.cpp b/src/Services/ParameterService.cpp
index 2ac5d101a779f2090490fd78d18141bc5bfb9655..aff371d1580ba53aeea6d15fd17a92f2c7d50042 100644
--- a/src/Services/ParameterService.cpp
+++ b/src/Services/ParameterService.cpp
@@ -7,14 +7,14 @@ ParameterService::ParameterService() {
 //	addNewParameter(3, 14);
 }
 
-void ParameterService::addNewParameter(uint16_t id, Parameter param, const char* flags) {
+void ParameterService::addNewParameter(uint16_t id, ParameterBase* param, const char* flags) {
 	if (paramsList.full()) {
 		ErrorHandler::reportInternalError(ErrorHandler::InternalErrorType::MapFull);
 		return;
 	}
 	else {
 		if (paramsList.find(id) == paramsList.end()) {
-			param.setFlags(flags);
+			param->setFlags(flags);
 			paramsList.insert(std::make_pair(id, param));
 			return;
 		}
@@ -26,7 +26,7 @@ void ParameterService::addNewParameter(uint16_t id, Parameter param, const char*
 }
 
 void ParameterService::reportParameterIds(Message& paramIds) {
-	etl::vector<std::pair<uint16_t, ValueType>, ECSS_ST_20_MAX_PARAMETERS> validParams;
+	etl::vector<std::pair<uint16_t, String<MAX_STRING_LENGTH>>, ECSS_ST_20_MAX_PARAMETERS> validParams;
 	Message reqParam(20, 2, Message::TM, 1);
 	// empty TM[20, 2] parameter report message
 
@@ -50,7 +50,8 @@ void ParameterService::reportParameterIds(Message& paramIds) {
 		uint16_t currId = paramIds.readUint16();
 
 		if (paramsList.find(currId) != paramsList.end()) {
-			std::pair<uint16_t, ValueType> p = std::make_pair(currId, paramsList.at(currId).getCurrentValue());
+			std::pair<uint16_t, String<MAX_STRING_LENGTH>> p = std::make_pair(currId, paramsList.at(currId)
+			->getValueAsString());
 			// pair containing the parameter's ID as first element and its current value as second
 			validParams.push_back(p);
 			validIds++;
@@ -65,7 +66,7 @@ void ParameterService::reportParameterIds(Message& paramIds) {
 
 	for (auto i: validParams) {
 		reqParam.appendUint16(i.first);  // append the parameter ID
-		reqParam.appendUint32(i.second); // and its value
+		reqParam.appendString(i.second); // and its value
 	}
 
 	storeMessage(reqParam);  // then store the message
@@ -88,7 +89,7 @@ void ParameterService::setParameterIds(Message& newParamValues) {
 		uint16_t currId = newParamValues.readUint16();
 		// the parameter is checked for read-only status and manual update availability
 		if (paramsList.find(currId) != paramsList.end()) {
-			paramsList.at(currId).setCurrentValue(newParamValues.readUint32());
+			paramsList.at(currId)->setCurrentValue(newParamValues.readUint32());
 		}
 		else {
 			ErrorHandler::reportError(newParamValues,
diff --git a/test/Services/ParameterService.cpp b/test/Services/ParameterService.cpp
index ee678cd5a5998f3a256e9283fb0f2362a14bbee8..86987f9e08d469473bfd2bb9dae342bd64873aaf 100644
--- a/test/Services/ParameterService.cpp
+++ b/test/Services/ParameterService.cpp
@@ -5,38 +5,34 @@
 
 ParameterService& pserv = Services.parameterManagement;
 
-void foo(ValueType* bar) {  // sample function
-	*bar = 0xDEADBEEF;
-}
-
 TEST_CASE("Parameter Service - General") {
 	SECTION("Addition to full map") {
 
-		Parameter param0 = Parameter(3, 14);
-		Parameter param1 = Parameter(1, 7, 12);
-		Parameter param2 = Parameter(4, 12, 3, nullptr);
-		Parameter param3 = Parameter(12, 3, 6, &foo);
-		Parameter param4 = Parameter(15, 7, 3, &foo);
+		Parameter<int> param0 = Parameter<int>(3, 14);
+		Parameter<int> param1 = Parameter<int>(1, 7, 12);
+		Parameter<int> param2 = Parameter<int>(4, 12, 3, nullptr);
+		Parameter<int> param3 = Parameter<int>(12, 3, 6);
+		Parameter<int> param4 = Parameter<int>(15, 7, 3);
 
-		Parameter param5 = Parameter(15, 5, 4);
+		Parameter<int> param5 = Parameter<int>(15, 5, 4);
 
-		pserv.addNewParameter(0, param0);
-		pserv.addNewParameter(1, param1);
-		pserv.addNewParameter(2, param2);
-		pserv.addNewParameter(3, param3);
-		pserv.addNewParameter(4, param4);
+		pserv.addNewParameter(0, static_cast<ParameterBase*>(&param0));
+		pserv.addNewParameter(1, static_cast<ParameterBase*>(&param1));
+		pserv.addNewParameter(2, static_cast<ParameterBase*>(&param2));
+		pserv.addNewParameter(3, static_cast<ParameterBase*>(&param3));
+		pserv.addNewParameter(4, static_cast<ParameterBase*>(&param4));
 
-		pserv.addNewParameter(5, param5);  // addNewParameter should return false
+		pserv.addNewParameter(5, static_cast<ParameterBase*>(&param5));  // addNewParameter should return false
 		CHECK(ServiceTests::thrownError(ErrorHandler::InternalErrorType::MapFull));
 		ServiceTests::reset();
 		Services.reset();  // reset all services
 	}
 
 	SECTION("Addition of already existing parameter") {
-		Parameter param0 = Parameter(1, 3);
-		pserv.addNewParameter(0, param0);
+		Parameter<int> param0 = Parameter<int>(1, 3);
+		pserv.addNewParameter(0, static_cast<ParameterBase*>(&param0));
 
-		pserv.addNewParameter(0, param0);
+		pserv.addNewParameter(0, static_cast<ParameterBase*>(&param0));
 		CHECK(ServiceTests::thrownError(ErrorHandler::InternalErrorType::ExistingParameterId));
 		ServiceTests::reset();
 		Services.reset();
@@ -69,12 +65,12 @@ TEST_CASE("Parameter Report Subservice") {
 	}
 
 	SECTION("Faulty instruction handling") {
-		Parameter param0 = Parameter(3, 14);
-		Parameter param1 = Parameter(1, 7, 12);
-		Parameter param2 = Parameter(4, 12, 3, nullptr);
-		pserv.addNewParameter(0, param0);
-		pserv.addNewParameter(1, param1);
-		pserv.addNewParameter(2, param2);
+		Parameter<int> param0 = Parameter<int>(3, 14);
+		Parameter<int> param1 = Parameter<int>(1, 7, 12);
+		Parameter<int> param2 = Parameter<int>(4, 12, 3, nullptr);
+		pserv.addNewParameter(0, static_cast<ParameterBase*>(&param0));
+		pserv.addNewParameter(1, static_cast<ParameterBase*>(&param1));
+		pserv.addNewParameter(2, static_cast<ParameterBase*>(&param2));
 
 		Message request(20, 1, Message::TC, 1);
 		request.appendUint16(2); // number of requested IDs
@@ -117,12 +113,12 @@ TEST_CASE("Parameter Report Subservice") {
 TEST_CASE("Parameter Setting Subservice") {
 
 	SECTION("Faulty Instruction Handling Test") {
-		Parameter param0 = Parameter(3, 14);
-		Parameter param1 = Parameter(1, 7, 12);
-		Parameter param2 = Parameter(4, 12, 3, nullptr);
-		pserv.addNewParameter(0, param0);
-		pserv.addNewParameter(1, param1);
-		pserv.addNewParameter(2, param2);
+		Parameter<int> param0 = Parameter<int>(3, 14);
+		Parameter<int> param1 = Parameter<int>(1, 7, 12);
+		Parameter<int> param2 = Parameter<int>(4, 12, 3, nullptr);
+		pserv.addNewParameter(0, static_cast<ParameterBase*>(&param0));
+		pserv.addNewParameter(1, static_cast<ParameterBase*>(&param1));
+		pserv.addNewParameter(2, static_cast<ParameterBase*>(&param2));
 
 		Message setRequest(20, 3, Message::TC, 1);
 		setRequest.appendUint16(2); // total number of IDs
@@ -154,8 +150,8 @@ TEST_CASE("Parameter Setting Subservice") {
 	}
 
 	SECTION("Attempt to set parameter with no manual update availability") {
-		Parameter param1 = Parameter(1, 7, 12);
-		pserv.addNewParameter(1, param1, "100");
+		Parameter<int> param1 = Parameter<int>(1, 7, 12);
+		pserv.addNewParameter(1, static_cast<ParameterBase*>(&param1), "100");
 
 		Message setRequest = Message(20, 3, Message::TC, 1);
 		setRequest.appendUint16(1);