diff --git a/groundStation/src/backend/common/controller.h b/groundStation/src/backend/common/controller.h
new file mode 100644
index 0000000000000000000000000000000000000000..8c88147c29fe01613b65bd053a5ae351e2cd7301
--- /dev/null
+++ b/groundStation/src/backend/common/controller.h
@@ -0,0 +1,29 @@
+#ifndef _controller_h
+#define _controller_h
+
+enum ControllerID {
+	ROLL_ID,              // 00 - Roll PID
+	PITCH_ID,             // 01 - Pitch PID
+	YAW_ID,               // 02 - Yaw PID
+	ROLL_RATE_ID,         // 03 - Roll rate PID
+	PITCH_RATE_ID,        // 04 - Pitch rate PID
+	YAW_RATE_ID,          // 05 - Yaw rate PID
+	LOCAL_X_ID,           // 06 - Local X PID
+	LOCAL_Y_ID,           // 07 - Local Y PID
+	ALT_ID,               // 08 - Altitude PID
+};
+
+enum ControllerValueID{
+    KP_ID,                 // 00 - P constant
+    KI_ID,                 // 01 - I constant
+    KD_ID,                 // 02 - D constant
+    SP_ID,                 // 03 - Setpoint value
+};
+
+struct controller_message {
+	enum ControllerID id;
+	enum ControllerValueID value_id;
+	float value;
+};
+
+#endif
diff --git a/groundStation/src/backend/common/examples.c b/groundStation/src/backend/common/examples.c
new file mode 100644
index 0000000000000000000000000000000000000000..7d0ee50aef6df1b4c7ef349fd707521ee68213eb
--- /dev/null
+++ b/groundStation/src/backend/common/examples.c
@@ -0,0 +1,72 @@
+#include "packet.h"
+#include "setcontrol.h"
+#include "commands.h"
+
+#include <sys/types.h>
+
+static int next_msg_id = 0;
+
+int SendSetControl()
+{
+	struct metadata m;
+	struct controller_message cm;
+
+	cm.id = ROLL_ID;        /* Roll controller */
+	cm.value_id = KI_ID;    /* I coefficient */
+	cm.value = 42.00f;      /* An appropriate value */
+
+	uint8_t data[64];
+	m.msg_id = next_msg_id++;
+	/* Fills in the rest of the metadata automatically */
+	if (EncodeSetcontrol(&m, data, 64, &cm) < 0) {
+		return -1;
+	}
+
+	uint8_t packet[128];
+	ssize_t length;
+	if ((length = EncodePacket(packet, 128, &m, data)) < 0) {
+		return -1;
+	}
+
+	/* Now you can send the packet
+	 * sendThePacket(packet, length);
+	 */
+
+	return 0;
+}
+
+
+/* Process incoming packets */
+int receive_packet(uint8_t * packet, size_t length)
+{
+	struct metadata m;
+	uint8_t data[128];
+
+	/* Will fail if checksum is bad, etc */
+	if (DecodePacket(&m, data, 128, packet, length) < 0) {
+		return -1;
+	}
+
+	/* Let's pretend that the callbacks have signature
+	 * void cb(
+	 *     const struct metadata * m,
+	 *     const uint8_t * data);
+	 *
+	 * Call the callback.
+	 */
+	(*MessageTypes[m.msg_type].functionPtr)(&m, data);
+
+	return 0;
+}
+
+/* An example of a setcontrol callback. Arguments
+ * aren't important, as long as we have access
+ * to the packet bytes and the length
+ */
+void cb_setcontrol(const struct metadata *m, const uint8_t *data)
+{
+	struct controller_message cm;
+	DecodeSetcontrol(&cm, m, data);
+
+	/* cm now has populated controller ID, value ID, and value */
+}
diff --git a/groundStation/src/backend/common/packet.h b/groundStation/src/backend/common/packet.h
new file mode 100644
index 0000000000000000000000000000000000000000..2763a8036d93cc6b867fb12386ef783b0475f649
--- /dev/null
+++ b/groundStation/src/backend/common/packet.h
@@ -0,0 +1,33 @@
+#ifndef _packet_h
+#define _packet_h
+
+#include <stdint.h>
+#include <sys/types.h>
+
+struct metadata {
+	int msg_type;
+	int msg_id;
+	int data_len;
+};
+
+/* Combine metadata and data to form a wire-sendable packet.
+ * Returns the size of the encoded packet 
+ */
+ssize_t EncodePacket(
+		uint8_t * packet,           /* Buffer to encode into */
+		size_t packet_size,         /* Max buffer size */
+		const struct metadata * m,  /* Metadata to encode */
+		const uint8_t * data);      /* Data to encode */
+
+/* Break apart packet, populating metadata. Data is copied
+ * into the space pointed to by data.
+ * Returns the size of the data.
+ */
+ssize_t DecodePacket(
+		struct metadata * m,        /* Decoded metadata (includes data_len)*/
+		uint8_t * data,             /* Data is copied into this buffer */
+		size_t data_size,           /* Max buffer size */
+		const uint8_t * packet,     /* Packet to decode */
+		size_t packet_size);        /* Size of packet to decode */
+
+#endif
diff --git a/groundStation/src/backend/common/setcontrol.h b/groundStation/src/backend/common/setcontrol.h
new file mode 100644
index 0000000000000000000000000000000000000000..b7f880bce7e9f1f458752973142e42b39b6878b6
--- /dev/null
+++ b/groundStation/src/backend/common/setcontrol.h
@@ -0,0 +1,27 @@
+#ifndef _setcontrol_h
+#define _setcontrol_h
+
+#include "packet.h"
+#include "controller.h"
+
+#include <sys/types.h>
+
+/* Creates data and metadata for a setcontrol packet
+ * Returns data size.
+ */
+ssize_t EncodeSetcontrol(
+		struct metadata * m,        /* data_len and msg_type will be populated*/
+		uint8_t * data,             /* Output buffer */
+		size_t data_size,           /* Max buffer size */
+		const struct controller_message * cm);      /* Message to encode */
+
+/* Decode a metadata and data to populate a controller.
+ * Returns 0 on success, -1 on failure.
+ */
+int DecodeSetcontrol(
+		struct controller_message * cm,     /* Decoded controller message */
+		const struct metadata * m,          /* Metadata to aid in decoding */
+		const uint8_t * data);              /* Data to decode */
+
+
+#endif