diff --git a/quad/scripts/__pycache__/uart_stress_tests.cpython-36.pyc b/quad/scripts/__pycache__/uart_stress_tests.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..4b92a40fddc351f17e205b35da850c41744a373c
Binary files /dev/null and b/quad/scripts/__pycache__/uart_stress_tests.cpython-36.pyc differ
diff --git a/quad/src/commands/commands.c b/quad/src/commands/commands.c
index 9111f1050af02e5e26800623266e7e83aaefa9dd..14ae7c58c9e3bac69bfc1d4a04c8239cabc0d908 100644
--- a/quad/src/commands/commands.c
+++ b/quad/src/commands/commands.c
@@ -143,14 +143,14 @@ struct MessageType MessageTypes[MAX_TYPE_ID] =
 		// Function pointer
 		&cb_log
 	},
-	// RESPONSE
+	// LOG_END
 	{
 		// Command text
-		"response",
+		"logend",
 		// Type of the command data
 		stringType,
 		// Function pointer
-		&cb_response
+		&cb_logend
 	},
 	// SETPARAM
 	{
@@ -259,15 +259,6 @@ struct MessageType MessageTypes[MAX_TYPE_ID] =
 		floatType,
 		// Function pointer
 		&cb_respaddnode
-	},
-	// LOG_END
-	{
-		// Command text
-		"logend",
-		// Type of the command data
-		stringType,
-		// Function pointer
-		&cb_logend
 	}
 };
 
diff --git a/quad/src/computation_graph/computation_graph.h b/quad/src/computation_graph/computation_graph.h
index 8449a903d77d1d106893cd49908643995a7c5f7f..e997aa7ab06a79d61aac152699d9a49379403ffc 100644
--- a/quad/src/computation_graph/computation_graph.h
+++ b/quad/src/computation_graph/computation_graph.h
@@ -34,6 +34,7 @@ struct graph_node_type {
     execute_node_t execute; // Function describing how to produce outputs
     reset_node_t reset; // Reset this node. Called upon (re)connection
     size_t state_size; // Size of the state struct for this type
+    int type_id; // A unique ID for this node type
 };
 
 // Holds a tuple for defining the source of a node. Includes the node ID and its output ID
diff --git a/quad/src/graph_blocks/graph_blocks.h b/quad/src/graph_blocks/graph_blocks.h
index 7db4f7f2144ec40cccd311e574f167780e67d47e..cc822b242bbbc2a80a064ce2390a846cef7bc8d5 100644
--- a/quad/src/graph_blocks/graph_blocks.h
+++ b/quad/src/graph_blocks/graph_blocks.h
@@ -1,3 +1,6 @@
+#ifndef __GRAPH_BLOCKS_H__
+#define __GRAPH_BLOCKS_H__
+
 #include "computation_graph.h"
 #include "node_constant.h"
 #include "node_add.h"
@@ -48,4 +51,5 @@ extern const struct graph_node_type* blockDefs[MAX_BLOCK_TYPES];
  * Creates a new node and adds it to the graph with the given type ID and name
  * Returns the id of the new node upon success, -1 upon failure
  */
-int graph_add_defined_block(struct computation_graph* graph, int type_id, const char* name);
\ No newline at end of file
+int graph_add_defined_block(struct computation_graph* graph, int type_id, const char* name);
+#endif // __GRAPH_BLOCKS_H__
diff --git a/quad/src/graph_blocks/node_accumulator.c b/quad/src/graph_blocks/node_accumulator.c
index 4d02ab374c0c6909a8d743106075782b1f7c8d6d..10b96873750e862b9072d0f2738842aa3be69ec7 100644
--- a/quad/src/graph_blocks/node_accumulator.c
+++ b/quad/src/graph_blocks/node_accumulator.c
@@ -28,7 +28,8 @@ const struct graph_node_type node_accum_type = {
         .n_params = 0,
         .execute = accum_nodes,
         .reset = reset,
-        .state_size = sizeof(struct accum_state)
+        .state_size = sizeof(struct accum_state),
+        .type_id = BLOCK_ACCUMULATE
 };
 
 int graph_add_node_accum(struct computation_graph *graph, const char* name) {
diff --git a/quad/src/graph_blocks/node_accumulator.h b/quad/src/graph_blocks/node_accumulator.h
index a392a9db295e5bc7f44d84292e4aa561ee3fba9d..43301d6676aa1289a6523da45546ffc88f7cbfe0 100644
--- a/quad/src/graph_blocks/node_accumulator.h
+++ b/quad/src/graph_blocks/node_accumulator.h
@@ -1,6 +1,7 @@
 #ifndef __NODE_ACCUMULATOR_H__
 #define __NODE_ACCUMULATOR_H__
 #include "computation_graph.h"
+#include "graph_blocks.h"
 
 int graph_add_node_accum(struct computation_graph *graph, const char* name);
 
diff --git a/quad/src/graph_blocks/node_add.c b/quad/src/graph_blocks/node_add.c
index db6692856b4be2781160ec6aaf743cdd6db863ee..25a780a32681df3d56aec758f9f0527115ee00b7 100644
--- a/quad/src/graph_blocks/node_add.c
+++ b/quad/src/graph_blocks/node_add.c
@@ -18,7 +18,8 @@ const struct graph_node_type node_add_type = {
         .n_params = 0,
         .execute = add_nodes,
         .reset = reset,
-        .state_size = 0
+        .state_size = 0,
+        .type_id = BLOCK_ADD
 };
 
 int graph_add_node_add(struct computation_graph *graph, const char* name) {
diff --git a/quad/src/graph_blocks/node_add.h b/quad/src/graph_blocks/node_add.h
index 390e3d229c7a943fdd09c26e18be711672cf000e..34b8123638dc1d954ceb0dcd6ceadb959ae6c5c5 100644
--- a/quad/src/graph_blocks/node_add.h
+++ b/quad/src/graph_blocks/node_add.h
@@ -1,6 +1,7 @@
 #ifndef __NODE_ADD_H__
 #define __NODE_ADD_H__
 #include "computation_graph.h"
+#include "graph_blocks.h"
 
 int graph_add_node_add(struct computation_graph *graph, const char* name);
 
diff --git a/quad/src/graph_blocks/node_bounds.c b/quad/src/graph_blocks/node_bounds.c
index cbcad4a1389be1823e6abdecfc9c94a2a5cef7a6..d1fe264311e1c5223df17f61e7e0330e9466c286 100644
--- a/quad/src/graph_blocks/node_bounds.c
+++ b/quad/src/graph_blocks/node_bounds.c
@@ -26,7 +26,8 @@ const struct graph_node_type node_bounds_type = {
         .n_params = 2,
         .execute = bounds_computation,
         .reset = reset_bounds,
-        .state_size = 0
+        .state_size = 0,
+        .type_id = BLOCK_BOUNDS
 };
 
 int graph_add_node_bounds(struct computation_graph *graph, const char* name) {
diff --git a/quad/src/graph_blocks/node_bounds.h b/quad/src/graph_blocks/node_bounds.h
index 4c3b93256106bce8560daf28c67f19844fb2ea8f..7eea073fa6000457c30588f251565fcdd3db1a5c 100644
--- a/quad/src/graph_blocks/node_bounds.h
+++ b/quad/src/graph_blocks/node_bounds.h
@@ -1,6 +1,7 @@
 #ifndef __NODE_BOUNDS_H__
 #define __NODE_BOUNDS_H__
 #include "computation_graph.h"
+#include "graph_blocks.h"
 
 int graph_add_node_bounds(struct computation_graph *graph, const char* name);
 
diff --git a/quad/src/graph_blocks/node_constant.c b/quad/src/graph_blocks/node_constant.c
index e3ca2188cd6ce2b6e455d0f6bc42bf5c3c2531dc..8bd406ad924f3025631c4d251c5d751eddcce90e 100644
--- a/quad/src/graph_blocks/node_constant.c
+++ b/quad/src/graph_blocks/node_constant.c
@@ -18,7 +18,8 @@ const struct graph_node_type node_const_type = {
         .n_params = 1,
         .execute = output_const,
         .reset = reset,
-        .state_size = 0
+        .state_size = 0,
+        .type_id = BLOCK_CONSTANT
 };
 
 int graph_add_node_const(struct computation_graph *graph, const char* name) {
diff --git a/quad/src/graph_blocks/node_constant.h b/quad/src/graph_blocks/node_constant.h
index c67ac6e0511e971e1f9ca57c853bd9de6fca6238..417e92da19bbe1170cbec09598e4129d3c4400a6 100644
--- a/quad/src/graph_blocks/node_constant.h
+++ b/quad/src/graph_blocks/node_constant.h
@@ -1,6 +1,7 @@
 #ifndef __NODE_CONSTANT_H__
 #define __NODE_CONSTANT_H__
 #include "computation_graph.h"
+#include "graph_blocks.h"
 
 int graph_add_node_const(struct computation_graph *graph, const char* name);
 
diff --git a/quad/src/graph_blocks/node_gain.c b/quad/src/graph_blocks/node_gain.c
index f16eb2b2a32c5341e436ccd04e39b34ba40cdacc..3c0ac77ae8a54b0e99b6b767ec85083f3e047e91 100644
--- a/quad/src/graph_blocks/node_gain.c
+++ b/quad/src/graph_blocks/node_gain.c
@@ -18,7 +18,8 @@ const struct graph_node_type node_gain_type = {
         .n_params = 1,
         .execute = scale_nodes,
         .reset = reset,
-        .state_size = 0
+        .state_size = 0,
+        .type_id = BLOCK_GAIN
 };
 
 int graph_add_node_gain(struct computation_graph *graph, const char* name) {
diff --git a/quad/src/graph_blocks/node_gain.h b/quad/src/graph_blocks/node_gain.h
index 4089244980ad7ee2fc50bc375f6cbb1500196b5e..4a1a3322f65789ffccd6282125181f8deade4200 100644
--- a/quad/src/graph_blocks/node_gain.h
+++ b/quad/src/graph_blocks/node_gain.h
@@ -1,6 +1,7 @@
 #ifndef __NODE_GAIN_H__
 #define __NODE_GAIN_H__
 #include "computation_graph.h"
+#include "graph_blocks.h"
 
 int graph_add_node_gain(struct computation_graph *graph, const char* name);
 
diff --git a/quad/src/graph_blocks/node_mixer.c b/quad/src/graph_blocks/node_mixer.c
index d7df8cd3a69a91a2eae9b66af334891a36758792..fe7d57f276106e7847e5c0b0c0ba0fc92f2ed862 100644
--- a/quad/src/graph_blocks/node_mixer.c
+++ b/quad/src/graph_blocks/node_mixer.c
@@ -35,7 +35,8 @@ const struct graph_node_type node_mixer_type = {
         .n_params = 0,
         .execute = mixer_computation,
         .reset = reset_mixer,
-		.state_size = 0
+		.state_size = 0,
+		.type_id = BLOCK_MIXER
 };
 
 int graph_add_node_mixer(struct computation_graph *graph, const char* name) {
diff --git a/quad/src/graph_blocks/node_mixer.h b/quad/src/graph_blocks/node_mixer.h
index ba1ec1c4901db366610506f18e41f9883a41980b..584538f0242677428632b681b2f0fe064e789abc 100644
--- a/quad/src/graph_blocks/node_mixer.h
+++ b/quad/src/graph_blocks/node_mixer.h
@@ -1,6 +1,7 @@
 #ifndef __NODE_MIXER_H__
 #define __NODE_MIXER_H__
 #include "computation_graph.h"
+#include "graph_blocks.h"
 
 int graph_add_node_mixer(struct computation_graph *graph, const char* name);
 
diff --git a/quad/src/graph_blocks/node_mult.c b/quad/src/graph_blocks/node_mult.c
index ba797a5c3620928ec2a1108d726a194544b793b1..427b9e74d071b45bbd5c7ef2437647f13aeb5b5c 100644
--- a/quad/src/graph_blocks/node_mult.c
+++ b/quad/src/graph_blocks/node_mult.c
@@ -18,7 +18,8 @@ const struct graph_node_type node_mult_type = {
         .n_params = 0,
         .execute = mult_nodes,
         .reset = reset,
-        .state_size = 0
+        .state_size = 0,
+        .type_id = BLOCK_MULT
 };
 
 int graph_add_node_mult(struct computation_graph *graph, const char* name) {
diff --git a/quad/src/graph_blocks/node_mult.h b/quad/src/graph_blocks/node_mult.h
index 9ea2bbb9fabdbc522a02f292f5294b33ad7af44c..f86f7ee0ab88c64dc1f3241615ac06d66fc3d925 100644
--- a/quad/src/graph_blocks/node_mult.h
+++ b/quad/src/graph_blocks/node_mult.h
@@ -1,6 +1,7 @@
 #ifndef __NODE_MULT_H__
 #define __NODE_MULT_H__
 #include "computation_graph.h"
+#include "graph_blocks.h"
 
 int graph_add_node_mult(struct computation_graph *graph, const char* name);
 
diff --git a/quad/src/graph_blocks/node_pid.c b/quad/src/graph_blocks/node_pid.c
index 0dc6eed41f3183ff65615f4994e6da2b117b6320..df6b611100aec808a8728a3fbe435ecbe5078557 100644
--- a/quad/src/graph_blocks/node_pid.c
+++ b/quad/src/graph_blocks/node_pid.c
@@ -91,7 +91,8 @@ const struct graph_node_type node_pid_type = {
         .n_params = 4,
         .execute = pid_computation,
         .reset = reset_pid,
-        .state_size = sizeof(struct pid_node_state)
+        .state_size = sizeof(struct pid_node_state),
+        .type_id = BLOCK_PID
 };
 
 int graph_add_node_pid(struct computation_graph *graph, const char* name) {
diff --git a/quad/src/graph_blocks/node_pid.h b/quad/src/graph_blocks/node_pid.h
index 7b384bb1a233785877fc2cc79d56a8e2dd88aa10..694f7a143d5141d7bbcaf951302fee187f56ab15 100644
--- a/quad/src/graph_blocks/node_pid.h
+++ b/quad/src/graph_blocks/node_pid.h
@@ -1,6 +1,7 @@
 #ifndef __NODE_PID_H__
 #define __NODE_PID_H__
 #include "computation_graph.h"
+#include "graph_blocks.h"
 
 int graph_add_node_pid(struct computation_graph *graph, const char* name);
 
diff --git a/quad/src/graph_blocks/node_pow.c b/quad/src/graph_blocks/node_pow.c
index 65af8e45db4004d4a2bd6b5addcde8a6efbd0ad5..e4fe0f25c2dd323085110869e3f1191217914d40 100644
--- a/quad/src/graph_blocks/node_pow.c
+++ b/quad/src/graph_blocks/node_pow.c
@@ -19,7 +19,7 @@ const struct graph_node_type node_pow_type = {
         .n_params = 1,
         .execute = pow_nodes,
         .reset = reset,
-        .state_size = 0
+        .state_size = 0,
 };
 
 int graph_add_node_pow(struct computation_graph *graph, const char* name) {
diff --git a/quad/src/virt_quad/Makefile b/quad/src/virt_quad/Makefile
index 47cebc494626a024de63f93c15480f5e4c3ff5a4..3626790b07efec7ea75a039491b6078a8c6918df 100644
--- a/quad/src/virt_quad/Makefile
+++ b/quad/src/virt_quad/Makefile
@@ -1,6 +1,6 @@
 TOP=../..
 
 NAME = virt_quad
-REQLIBS = -lquad_app -lcomputation_graph -lm -lcommands
+REQLIBS = -lquad_app -lcomputation_graph -lm -lcommands -lgraph_blocks
 
 include $(TOP)/executable.mk
diff --git a/quad/test_logging/Makefile b/quad/test_logging/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..d30eb0102cea878e910d440437f4c185e2562b30
--- /dev/null
+++ b/quad/test_logging/Makefile
@@ -0,0 +1,3 @@
+CC=gcc
+test: test.c
+	$(CC) -o test_log -I. -I../src/quad_app -I../src/computation_graph test.c ../src/quad_app/*.c ../src/computation_graph/*.c -lm
diff --git a/quad/test_logging/log.txt b/quad/test_logging/log.txt
new file mode 100644
index 0000000000000000000000000000000000000000..c66e5152c66693e82bc287674ba3359ab6710dd4
--- /dev/null
+++ b/quad/test_logging/log.txt
@@ -0,0 +1,7 @@
+# MicroCART On-board Quad Log
+# Sample size: 3
+time	accel_x	accel_y	accel_z	gyro_x	gyro_y	gyro_z	Altitude PID_Correction	X pos PID_Correction	Y pos PID_Correction	Pitch PID_Correction	Roll PID_Correction	Yaw PID_Correction	Pitch Rate PID_Correction	Roll Rate PID_Correction	Yaw Rate PID_Correction	Pitch_Constant	Roll_Constant	Yaw_Constant	VRPN X_Constant	VRPN Y_Constant	VRPN Alt_Constant	VRPN Pitch_Constant	VRPN Roll_Constant	X Setpoint_Constant	Y Setpoint_Constant	Alt Setpoint_Constant	Yaw Setpoint_Constant	Signal Mixer_PWM 0	Signal Mixer_PWM 1	Signal Mixer_PWM 2	Signal Mixer_PWM 3
+s	G	G	G	rad/s	rad/s	rad/s	10ns_dutycycle	rad	rad	rad/s	rad/s	rad/s	10ns_dutycycle	10ns_dutycycle	10ns_dutycycle	rad	rad	rad	m	m	m	rad	rad	m	m	m	rad	10ns_dutycycle	10ns_dutycycle	10ns_dutycycle	10ns_dutycycle
+0.000000	0.000000	0.000000	0.000000	0.000000	4722366482869645213696.000000	-nan	0.000000	0.000000	0.000000	0.000000	0.000000	0.000000	0.000000	0.000000	0.000000	0.000000	0.000000	0.000000	0.000000	0.000000	0.000000	0.000000	0.000000	0.000000	0.000000	0.000000	0.000000	0.000000	0.000000	0.000000	0.000000
+0.000000	0.000000	0.000000	0.000000	0.000000	4722366482869645213696.000000	-nan	0.000000	0.000000	0.000000	0.000000	0.000000	0.000000	0.000000	0.000000	0.000000	0.000000	0.000000	0.000000	0.000000	0.000000	0.000000	0.000000	0.000000	0.000000	0.000000	0.000000	0.000000	0.000000	0.000000	0.000000	0.000000
+0.000000	0.000000	0.000000	0.000000	0.000000	4722366482869645213696.000000	-nan	0.000000	0.000000	0.000000	0.000000	0.000000	0.000000	0.000000	0.000000	0.000000	0.000000	0.000000	0.000000	0.000000	0.000000	0.000000	0.000000	0.000000	0.000000	0.000000	0.000000	0.000000	0.000000	0.000000	0.000000	0.000000
diff --git a/quad/test_logging/test.c b/quad/test_logging/test.c
new file mode 100644
index 0000000000000000000000000000000000000000..7fd26a97d187f96630e209fa04f5364fdbdcef58
--- /dev/null
+++ b/quad/test_logging/test.c
@@ -0,0 +1,22 @@
+#include <stddef.h>
+#include "type_def.h"
+#include "log_data.h"
+#include "control_algorithm.h"
+
+int zybo_uart_write(struct UARTDriver *self, unsigned char c) {
+    printf("%c", c);
+    return 0;
+}
+
+
+int main() {
+    modular_structs_t structs;
+    structs.hardware_struct.uart.write = zybo_uart_write;
+    control_algorithm_init(&(structs.parameter_struct));
+	initialize_logging(&structs.log_struct, &structs.parameter_struct);
+    log_data(&(structs.log_struct), &(structs.parameter_struct));
+    log_data(&(structs.log_struct), &(structs.parameter_struct));
+    log_data(&(structs.log_struct), &(structs.parameter_struct));
+    printLogging(&structs.hardware_struct, &(structs.log_struct), &(structs.parameter_struct));
+    return 0;
+}
diff --git a/quad/test_logging/test_log b/quad/test_logging/test_log
new file mode 100644
index 0000000000000000000000000000000000000000..e9c0b45a27eb1eb96d051a7ec6738d3c8ff5adba
Binary files /dev/null and b/quad/test_logging/test_log differ