diff --git a/inc/Services/Parameter.hpp b/inc/Services/Parameter.hpp
index 54a40bb1e086a73d755f0c954b73979b662ebb1f..5e90a72b6e88997947b773416a57a6fd2d07e369 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,8 +25,8 @@
  * @typedef Flags: container for the binary flags
  */
 typedef uint16_t ParamId;
-typedef uint32_t ValueType;
-typedef void(*UpdatePtr)(ValueType*);
+//typedef uint32_t ValueType;
+//#typedef ;
 typedef etl::bitset<NUM_OF_FLAGS> Flags;
 
 /**
@@ -55,24 +57,31 @@ 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
  */
-class Parameter {
-	uint8_t ptc;
-	uint8_t pfc;
-	UpdatePtr ptr;
-	Flags flags;
-	ValueType currentValue = 0;
 
+class ParameterBase {
+	protected:
+		uint8_t ptc;
+		uint8_t pfc;
+		uint8_t sizeInBytes;
+		void* valuePtr;
+		Flags flags;
 	public:
-		Parameter(uint8_t newPtc, uint8_t newPfc, uint32_t initialValue = 0, UpdatePtr newPtr = nullptr);
-
-		void setCurrentValue(ValueType newVal);
-		void setFlags(const char* flags);
-
-		ValueType getCurrentValue();
 		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);
+};
 
+template <typename ValueType>
+class Parameter : public ParameterBase {
+	void(*ptr)(ValueType*);
+	ValueType currentValue;
+
+	public:
+		Parameter(uint8_t newPtc, uint8_t newPfc, ValueType initialValue = 0,  void(*newPtr)
+		(ValueType*) = nullptr);
+		String<MAX_STRING_LENGTH> getValueAsString() override;
 };
 
 
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 2ab9227164583af68f9a4ead572dd6f7e06cc429..8bf1603f3b7654e19d4475fe68810bb4d331b697 100644
--- a/src/Services/Parameter.cpp
+++ b/src/Services/Parameter.cpp
@@ -1,10 +1,13 @@
 #include "Services/Parameter.hpp"
 
-Parameter::Parameter(uint8_t newPtc, uint8_t newPfc, ValueType initialValue, UpdatePtr newPtr) {
+template <typename ValueType>
+Parameter<ValueType>::Parameter(uint8_t newPtc, uint8_t newPfc, ValueType initialValue, void (*
+newPtr)(ValueType*)) {
 	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
 
@@ -15,25 +18,28 @@ Parameter::Parameter(uint8_t newPtc, uint8_t newPfc, ValueType initialValue, Upd
 	}
 }
 
-void Parameter::setCurrentValue(ValueType newVal) {
+template <typename ValueType>
+void ParameterBase::setCurrentValue(ValueType newVal) {
 	// set the value only if the parameter can be updated manually
 	if (flags[1]) {
-		currentValue = newVal;
+		*reinterpret_cast<ValueType>(valuePtr) = newVal;
 	}
 }
 
-ValueType Parameter::getCurrentValue() {
-	return currentValue;
+template <typename ValueType>
+String<MAX_STRING_LENGTH> Parameter<ValueType>::getValueAsString() {
+	String<MAX_STRING_LENGTH> contents(reinterpret_cast<uint8_t*>(&currentValue), sizeInBytes);
+	return contents;
 }
 
-uint8_t Parameter::getPTC() {
+uint8_t ParameterBase::getPTC() {
 	return ptc;
 }
 
-uint8_t Parameter::getPFC() {
+uint8_t ParameterBase::getPFC() {
 	return pfc;
 }
 
-void Parameter::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);