diff --git a/Makefile b/Makefile
index caf100bec0045c1b9cedbb32707e67f21986be62..c2bb1a0df035ab17f3c55da7bf72eedff68209f3 100644
--- a/Makefile
+++ b/Makefile
@@ -2,16 +2,13 @@ BASE_URL := http://git.ok1kvk.cz/apps/
 QMAKE := qmake-qt5
 CMAKE := cmake
 
-build: build-dserial-cli/Makefile dserial-protocol/Readme.md build-dserial-server/Makefile
+build: dserial-protocol/Readme.md build-dserial-server/Makefile
 	cd build-dserial-server && make qmake && make
-	cd build-dserial-cli && make
+	rm -rf build-dserial-cli && mkdir -p build-dserial-cli && cd build-dserial-cli && $(CMAKE) ../dserial-cli/ && make
 
 build-dserial-server/Makefile: dserial-server/Readme.md
 	mkdir -p build-dserial-server && cd build-dserial-server &&	$(QMAKE) ../dserial-server/dserial-server.pro
 
-build-dserial-cli/Makefile: dserial-cli/Readme.md
-	mkdir -p build-dserial-cli && cd build-dserial-cli && $(CMAKE) ../dserial-cli/
-
 install: dserial-cli/Readme.md dserial-protocol/Readme.md dserial-server/Readme.md
 	cd build-dserial-cli && make install
 	cd build-dserial-server && make install
@@ -22,5 +19,8 @@ push:
 	git subtree push --prefix=dserial-protocol/ protocol master
 	git subtree push --prefix=dserial-server/ server master
 
+run: build
+	build-dserial-cli/dserial interactive
+
 %/Readme.md:
 	git clone $(BASE_URL)%.git
diff --git a/dserial-cli/src/commands/HelpCommand.vala b/dserial-cli/src/commands/HelpCommand.vala
index 02b3410375a7f8d1a6a68f39a8109161992a430b..98bd8bec60e09b345a8e5e9dd33180cc1ab0647c 100644
--- a/dserial-cli/src/commands/HelpCommand.vala
+++ b/dserial-cli/src/commands/HelpCommand.vala
@@ -46,6 +46,7 @@ public class HelpCommand : Object, Command
 			stdout.printf("unbind\t\t\t\tRemoves binding (interactive only)\n");
             stdout.printf("autowrite on|off\t\tSet whether every line should start with write\n");
 			stdout.printf("exit\t\t\t\tExits interactive session (interactive only)\n");
+            stdout.printf("monitor\t\t\t\tShows data written and red simultaneously\n");
 		}else if(args[0] == "commands") {
             for( int i = 0; i < state.command_list.length; i++) {
                 stdout.printf("%s\n", state.command_list.index(i).name());
diff --git a/dserial-cli/src/commands/InteractiveCommand.vala b/dserial-cli/src/commands/InteractiveCommand.vala
index 74a4e02a0e2c22ee537eb79beffdc9dba2fef15a..b3d1ef396516ed32a7e9538c383649317232c4c3 100644
--- a/dserial-cli/src/commands/InteractiveCommand.vala
+++ b/dserial-cli/src/commands/InteractiveCommand.vala
@@ -75,7 +75,7 @@ public class InteractiveCommand : Object, Command
 		state.interactive = true;
 		stdout.printf("dserial: Serial communication program\n");
 		stdout.printf("License: GPL3+\n");
-		stdout.printf("Version: 0.4b\n");
+		stdout.printf("Version: 0.5\n");
 		stdout.printf("Write help for help\n");
 		Readline.History.read(Environment.get_variable("HOME")+"/.dserial-history");
 		Readline.attempted_completion_function = readline_completion;
diff --git a/dserial-cli/src/commands/ReadCommand.vala b/dserial-cli/src/commands/ReadCommand.vala
index 8e5b16ab37029e45d194a3b05eb0ca85733a3019..5316c55ae0a53f77e4621f831b76543a0caf0a14 100644
--- a/dserial-cli/src/commands/ReadCommand.vala
+++ b/dserial-cli/src/commands/ReadCommand.vala
@@ -22,7 +22,12 @@
 public class ReadCommand : Object, Command
 {
 	private static MainLoop loop;
-	public int execute(string[] other_args, ApplicationState state)
+    public virtual int execute(string[] other_args, ApplicationState state)
+	{
+        return do_read(other_args, state, false);
+    }
+
+	public int do_read(string[] other_args, ApplicationState state, bool monitor)
 	{
 		loop = new MainLoop();
 		Serial.SerialClient p;
@@ -84,6 +89,11 @@ public class ReadCommand : Object, Command
 
 		uint counter = 0;
 		uint8[print_length] tmpbuf = new uint8[print_length];
+        uint pccounter = 0;
+        PosColor[print_length] pcbuf = new PosColor[print_length];
+        for(int i = 0; i < print_length; i++) pcbuf[i] = new PosColor();
+        pcbuf[0].pos = 0;
+        pcbuf[0].color = 0;
         p.open();
 
         p.closing.connect(() => {
@@ -93,26 +103,71 @@ public class ReadCommand : Object, Command
 		ulong connection = p.data_recieved.connect((array) => {
 			for(int i = 0; i < array.length; i++) {
                 // For each char
-				uint8[1] onebuf = new uint8[1];
 
                 // Print it using first printer
-				onebuf[0] = array[i];
-				printers[0].a(onebuf);
+				printers[0].a(array[i]);
                 stdout.flush();
 
                 // Save it
+                if(counter == 0 || pcbuf[pccounter-1].color != 0) {
+                    pcbuf[pccounter].pos = counter;
+                    pcbuf[pccounter++].color = 0; // RESET COLOR
+                }
 				tmpbuf[counter++] = array[i];
 
 				if(counter >= print_length) {
 					for(int x = 1; x < printers.length; x++) {
 						stdout.printf("   ");
-						printers[x].a(tmpbuf);
+                        pccounter = 0;
+						for(int pos = 0; pos < tmpbuf.length; pos++) {
+                            if(pcbuf[pccounter].pos == pos) {
+                                stdout.printf("\x1b[%im", pcbuf[pccounter++].color);
+                            }
+                            printers[x].a(tmpbuf[pos]);
+                        }
 					}
 					if(display_fields != "s") stdout.printf("\n");
 					counter = 0;
+                    pccounter = 0;
 				}
 			}
 		});
+        ulong connection2 = 0;
+        if(monitor) {
+            connection2 = p.data_sent.connect((array) => {
+                stdout.printf("\x1b[32m");
+                for(int i = 0; i < array.length; i++) {
+                    // For each char
+
+                    // Print it using first printer
+                    printers[0].a(array[i]);
+                    stdout.flush();
+
+                    // Save it
+                    if(counter == 0 || pcbuf[pccounter-1].color != 32) {
+                        pcbuf[pccounter].pos = counter;
+                        pcbuf[pccounter++].color = 32; // GREEN COLOR
+                    }
+                    tmpbuf[counter++] = array[i];
+
+                    if(counter >= print_length) {
+                        for(int x = 1; x < printers.length; x++) {
+                            stdout.printf("   ");
+                            pccounter = 0;
+                            for(int pos = 0; pos < tmpbuf.length; pos++) {
+                                if(pcbuf[pccounter].pos == pos) {
+                                    stdout.printf("\x1b[%im", pcbuf[pccounter++].color);
+                                }
+                                printers[x].a(tmpbuf[pos]);
+                            }
+                        }
+                        if(display_fields != "s") stdout.printf("\n");
+                        counter = 0;
+                    }
+                }
+                stdout.printf("\x1b[0m");
+            });
+        }
 		var action = Posix.sigaction_t();
 		action.sa_handler = (a)=> {
 			loop.quit();
@@ -120,6 +175,7 @@ public class ReadCommand : Object, Command
 		Posix.sigaction(Posix.SIGINT,action,null);
 		loop.run();
         p.disconnect(connection);
+        if(monitor) p.disconnect(connection2);
 		stdout.printf("\n");
 		var dflact = Posix.sigaction_t();
 		Posix.sigaction(Posix.SIGINT,dflact,null);
@@ -127,10 +183,15 @@ public class ReadCommand : Object, Command
 		return 0;
 	}
 
-	private delegate void FormatPrintArray(uint8[] array);
+	private delegate void FormatPrintChar(uint8 c);
+
+    private class PosColor {
+        public uint pos;
+        public int color;
+    }
 
 	private class FormatWrapper {
-		public FormatPrintArray a;
+		public FormatPrintChar a;
 		public int width_per_char;
 	}
 
@@ -141,67 +202,55 @@ public class ReadCommand : Object, Command
 		var fw = new FormatWrapper();
 		if(c == "X".get_char(0)) {
 			fw.a = (a) => {
-				for(int x = 0; x < a.length; x++) {
-					if(a[x]<16) stdout.printf("0");
-					stdout.printf("%X ", a[x]);
-				}
+                if(a<16) stdout.printf("0");
+                stdout.printf("%X ", a);
 			};
 			fw.width_per_char = 3;
 		} else if(c == "x".get_char(0)) {
 			fw.a = (a) => {
-				for(int x = 0; x < a.length; x++) {
-					if(a[x]<16) stdout.printf("0");
-					stdout.printf("%x ", a[x]);
-				}
+                if(a<16) stdout.printf("0");
+                stdout.printf("%x ", a);
 			};
 			fw.width_per_char = 3;
 		} else if(c == "d".get_char(0) ||
 				  c == "i".get_char(0) ) {
 			fw.a = (a) => {
-				for(int x = 0; x < a.length; x++) {
-					stdout.printf("%d ", a[x]);
-					if(a[x] < 10) stdout.printf(" ");
-					if(a[x] < 100) stdout.printf(" ");
-				}
+                stdout.printf("%d ", a);
+                if(a < 10) stdout.printf(" ");
+                if(a < 100) stdout.printf(" ");
 			};
 			fw.width_per_char = 4;
 		} else if(c == "c".get_char(0)) {
 			fw.a = (a) => {
-				for(int x = 0; x < a.length; x++) {
-					if(a[x]>=32&&a[x]<127){
-						stdout.printf("%c", a[x]);
-					} else {
-						stdout.printf(".");
-					}
-				}
+                if(a>=32&&a<127){
+                    stdout.printf("%c", a);
+                } else {
+                    stdout.printf(".");
+                }
 			};
 			fw.width_per_char = 1;
         } else if(c == "s".get_char(0)) {
             fw.a = (a) => {
-				for(int x = 0; x < a.length; x++) {
-					if(a[x]>=32&&a[x]<127){
-						stdout.printf("%c", a[x]);
-					} else {
-						if(a[x] == 10) { // \n (LF)
-							stdout.printf("\n");
-						} else if(a[x] == 13) { // \r (CR)
-						} else if(a[x] == 9) { // \t (TAB)
-							stdout.printf("\t");
-						} else {
-							stdout.printf(".");
-						}
-					}
-				}
+                if(a>=32&&a<127){
+                    stdout.printf("%c", a);
+                } else {
+                    if(a == 10) { // \n (LF)
+                        stdout.printf("\n");
+                    } else if(a == 13) { // \r (CR)
+                    } else if(a == 9) { // \t (TAB)
+                        stdout.printf("\t");
+                    } else {
+                        stdout.printf(".");
+                    }
+                }
 			};
 			fw.width_per_char = 1;
 		} else if(c == "b".get_char(0)) {
 			fw.a = (a) => {
-				for(int x = 0; x < a.length; x++) {
-					for(int i = 0; i < 8; i++){
-						stdout.printf("%d",(a[x]&1<<i)!=0?1:0);
-					}
-					stdout.printf(" ");
-				}
+                for(int i = 0; i < 8; i++){
+                    stdout.printf("%d",(a&1<<i)!=0?1:0);
+                }
+                stdout.printf(" ");
 			};
 			fw.width_per_char = 9;
 		} else {
@@ -210,7 +259,7 @@ public class ReadCommand : Object, Command
 		return fw;
 	}
 
-	public string name()
+	public virtual string name()
 	{
 		return "read";
 	}
@@ -223,7 +272,7 @@ public class ReadCommand : Object, Command
 			return {};
 	}
 
-    public void help(string[] args)
+    public virtual void help(string[] args)
     {
         stdout.printf("Synopsis: read <port> [format-string] [format-length]\n");
         stdout.printf("Reads from port\n");
@@ -239,3 +288,23 @@ public class ReadCommand : Object, Command
         stdout.printf("Default is determined automagically from terminal width\n");
     }
 }
+
+public class MonitorCommand : ReadCommand
+{
+    public override int execute(string[] args, ApplicationState state)
+	{
+        return do_read(args, state, true);
+	}
+
+    public override string name()
+    {
+        return "monitor";
+    }
+
+    public override void help(string[] args)
+    {
+        stdout.printf("Synopsis: monitor <port> [format-string] [format-length]\n");
+        stdout.printf("Reads from port AND prints messages you send to it\n");
+        stdout.printf("See help read for formatting options\n");
+    }
+}
diff --git a/dserial-cli/src/serial-communicator-cli.vala b/dserial-cli/src/serial-communicator-cli.vala
index 42b04b8c1c59c088e723bb8a5e0ea5cfe92571c3..b1b01b504f05d237d426e5d401e3cdc2ddea8711 100644
--- a/dserial-cli/src/serial-communicator-cli.vala
+++ b/dserial-cli/src/serial-communicator-cli.vala
@@ -78,6 +78,8 @@ void init_list(ApplicationState state) {
 	state.command_list.append_val(c);
     c = new AutowriteCommand();
     state.command_list.append_val(c);
+    c = new MonitorCommand();
+    state.command_list.append_val(c);
 }
 
 /*=====================================