Index: elec/CrO2/software/Makefile
===================================================================
--- elec/CrO2/software/Makefile	(revision f9263dd2949eb63851e44991b4ffe2eddd0c432e)
+++ elec/CrO2/software/Makefile	(revision 192e29968ecf06910106597b9e82d2572120ed48)
@@ -14,6 +14,6 @@
 
 CC		= g++
-CPPFLAGS	= $(USBFLAGS) -O -Wall -I/usr/include/IUP/ -g -std=c++0x
-LIBS	= $(USBLIBS) -L/usr/lib/ -mwindows -liup -lcomctl32 -lole32
+CPPFLAGS	= $(USBFLAGS) -O -Wall -I/usr/include/IUP/ -I/local/include -g -std=c++0x -mthreads
+LIBS	= $(USBLIBS) -L/usr/lib/ -mwindows -liup -lcomctl32 -lole32 -mthreads
 
 PROJECT = CrO2
Index: elec/CrO2/software/cro2.cpp
===================================================================
--- elec/CrO2/software/cro2.cpp	(revision f9263dd2949eb63851e44991b4ffe2eddd0c432e)
+++ elec/CrO2/software/cro2.cpp	(revision 192e29968ecf06910106597b9e82d2572120ed48)
@@ -19,6 +19,4 @@
 int main(int argc, char **argv)
 {
-	int                 nBytes = 0;
-
     if(argc < 2){
 		Gui gui(&argc, &argv);
@@ -30,7 +28,9 @@
 
 		if(strcmp(argv[1], "get") == 0){
+			int                 nBytes = 0;
 			unsigned char       buffer[275];
 			memset(buffer, 0, 275);
 			nBytes = dev.read(buffer, sizeof(buffer));
+			if (nBytes < 0) fprintf(stderr, "USB error %s\n", usb_strerror());
 		}else if(strcmp(argv[1], "put") == 0){
 
@@ -38,17 +38,5 @@
 			K5 file(argv[2]);
 
-			for (int k = 0; k < file.getBlockCount(); k++)
-			{
-				// wait for motor on
-				while (dev.getStatus() & 8)
-					Sleep(1000);
-
-				K5::Block block = file.getBlock(k);
-
-				nBytes = dev.write(block.data, block.length - 1, block.type);
-
-				// TODO wait for correct time (read status from usb OR compute from size+type)
-				Sleep(1400);
-			}
+			dev.write(file);
 		}else{
 			// TODO print usage
@@ -56,5 +44,4 @@
 		}
 
-		if (nBytes < 0) fprintf(stderr, "USB error %s\n", usb_strerror());
 		return 0;
 	}
Index: elec/CrO2/software/device.cpp
===================================================================
--- elec/CrO2/software/device.cpp	(revision f9263dd2949eb63851e44991b4ffe2eddd0c432e)
+++ elec/CrO2/software/device.cpp	(revision 192e29968ecf06910106597b9e82d2572120ed48)
@@ -8,4 +8,5 @@
 
 #include "device.h"
+#include "k5.h"
 
 bool Device::initOnce = false;
@@ -141,9 +142,28 @@
 }
 
+
+void Device::write(K5& file)
+{
+	for (int k = 0; k < file.getBlockCount(); k++)
+	{
+		// wait for motor on
+		while (getStatus() & 8)
+			Sleep(1000);
+
+		K5::Block block = file.getBlock(k);
+
+		int nBytes = write(block.data, block.length - 1, block.type);
+			// TODO error handling
+
+		// TODO wait for correct time (read status from usb OR compute from size+type)
+		Sleep(1400);
+	}
+}
+
 uint8_t Device::getStatus()
 {
 	uint8_t status;
 	usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN,
-		PSCMD_STATUS, 0,0, (char*)&status, 1, 5000);
+			PSCMD_STATUS, 0,0, (char*)&status, 1, 5000);
 		// TODO handle errors (return value)
 	return status;
Index: elec/CrO2/software/device.h
===================================================================
--- elec/CrO2/software/device.h	(revision f9263dd2949eb63851e44991b4ffe2eddd0c432e)
+++ elec/CrO2/software/device.h	(revision 192e29968ecf06910106597b9e82d2572120ed48)
@@ -8,6 +8,7 @@
 
 #include <stdint.h>
+#include <lusb0_usb.h>
 
-#include <lusb0_usb.h>    /* this is libusb, see http://libusb.sourceforge.net/ */
+class K5;
 
 class Device
@@ -20,4 +21,5 @@
 		int read(uint8_t* buffer, size_t max); // Fill the buffer with data from device
 		int write(uint8_t* buffer, size_t size, int blktype);
+		void write(K5& file);
 		uint8_t getStatus();
 
Index: elec/CrO2/software/gui.cpp
===================================================================
--- elec/CrO2/software/gui.cpp	(revision f9263dd2949eb63851e44991b4ffe2eddd0c432e)
+++ elec/CrO2/software/gui.cpp	(revision 192e29968ecf06910106597b9e82d2572120ed48)
@@ -14,6 +14,7 @@
 
 	// Start status poller "thread"
-	int pollStatus(Ihandle* ih)
-	{
+int pollStatus(Ihandle* ih)
+{
+	try {
 		Ihandle* motoron = (Ihandle*)IupGetAttribute(ih, "target");
 
@@ -23,6 +24,12 @@
 		else
 			IupSetAttribute(motoron, "VALUE", "1"); // motor ON
-		return IUP_DEFAULT;
+	} catch(const char*) {
+		// Silently ignore exception if device is not available - not a good
+		// idea to handle it from a timer...
+		// Keep the timer running so it starts working when the device is
+		// plugged
 	}
+	return IUP_DEFAULT;
+}
 
 void startPolling(Ihandle* target) {
@@ -37,9 +44,4 @@
 
 /* UI */
-
-int Gui::menu_exit()
-{
-	return IUP_CLOSE;
-}
 
 Gui::Gui(int* argc, char*** argv)
@@ -66,5 +68,4 @@
 	);
 
-
 	// CONTROL
 	Ihandle* motoron = IupProgressBar();
@@ -81,4 +82,7 @@
 	IupSetAttribute(blocklist, "EXPAND", "VERTICAL");
 
+	Ihandle* playToggle = IupToggle("play", NULL);
+	Callback<Gui, int>::create(playToggle, "ACTION", this, &Gui::setPlaying);
+
 	Ihandle* tabs = IupTabs(
 		IupVbox(
@@ -89,5 +93,5 @@
 			),
 			IupHbox(
-				IupToggle("play",NULL),
+				playToggle,
 				IupToggle("REC",NULL),
 				NULL
@@ -136,4 +140,5 @@
 }
 
+
 int Gui::menu_open()
 {
@@ -147,2 +152,20 @@
 	return IUP_DEFAULT;
 }
+
+int Gui::menu_exit()
+{
+	return IUP_CLOSE;
+}
+
+int Gui::setPlaying(int state)
+{
+	if (state == 0)
+	{
+		// pause
+	} else {
+		// play
+		Device::getDevice().write(*file);
+	}
+
+	return IUP_DEFAULT;
+}
Index: elec/CrO2/software/gui.h
===================================================================
--- elec/CrO2/software/gui.h	(revision f9263dd2949eb63851e44991b4ffe2eddd0c432e)
+++ elec/CrO2/software/gui.h	(revision 192e29968ecf06910106597b9e82d2572120ed48)
@@ -20,4 +20,6 @@
 		int menu_exit();
 
+		int setPlaying(int state);
+
 		K5* file;
 };
Index: elec/CrO2/software/k5.cpp
===================================================================
--- elec/CrO2/software/k5.cpp	(revision f9263dd2949eb63851e44991b4ffe2eddd0c432e)
+++ elec/CrO2/software/k5.cpp	(revision 192e29968ecf06910106597b9e82d2572120ed48)
@@ -23,4 +23,17 @@
 	data = new uint8_t[length];
 	memcpy(data, other.data, length);
+}
+
+const K5::Block& K5::Block::operator=(const Block& other)
+{
+	delete[] data;
+		// May not be null ?
+
+	length = other.length;
+	type = other.type;
+	data = new uint8_t[length];
+	memcpy(data, other.data, length);
+
+	return *this;
 }
 
Index: elec/CrO2/software/k5.h
===================================================================
--- elec/CrO2/software/k5.h	(revision f9263dd2949eb63851e44991b4ffe2eddd0c432e)
+++ elec/CrO2/software/k5.h	(revision 192e29968ecf06910106597b9e82d2572120ed48)
@@ -17,8 +17,11 @@
 				Block(const Block& other);
 				~Block();
+				const Block& operator=(const Block& other);
 
 				int length;
 				uint8_t* data;
 				uint8_t type;
+			private:
+				Block();
 		};
 
@@ -27,4 +30,5 @@
 
 	private:
+		K5();
 		std::vector<Block> blocks;
 };
