diff --git a/Makefile b/Makefile
index e934c54a86ad6ca80c8c82d1e1070183b42a3c31..d7c9a688fbf260b2629200d9a081227f6a1ff0c7 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 LIBRARIES=libmoberg.so
 MOBERG_VERSION=$(shell git describe --tags | sed -e 's/^v//;s/-/_/g' )
-CCFLAGS+=-Wall -Werror -I$(shell pwd) -g
+CCFLAGS+=-Wall -Werror -I$(shell pwd) -O3 -g
 LDFLAGS+=-L$(shell pwd)/build/ -lmoberg
 PLUGINS:=$(wildcard plugins/*)
 ADAPTORS:=$(wildcard adaptors/*)
@@ -8,7 +8,7 @@ export CCFLAGS LDFLAGS
 LDFLAGS_parse_config=-ldl
 #-export-dynamic
 
-all: $(LIBRARIES:%=build/%) $(PLUGINS) $(ADAPTORS)
+all: $(LIBRARIES:%=build/%) build/moberg $(PLUGINS) $(ADAPTORS)
 	echo $(PLUGINS)
 	echo $(CCFLAGS)
 
@@ -16,6 +16,9 @@ build/libmoberg.so: Makefile | build
 	$(CC) -o $@ $(CCFLAGS) -shared -fPIC -I. \
 		$(filter %.o,$^) -lxdg-basedir -ldl
 
+build/moberg: moberg_tool.c Makefile | build
+	$(CC) -o $@ $(CCFLAGS) $< -L../build -lmoberg
+
 build/lib build:
 	mkdir -p $@
 
diff --git a/adaptors/matlab/.gitignore b/adaptors/matlab/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..71e1b42b14886cf32163712d501bbf20116ee8ad
--- /dev/null
+++ b/adaptors/matlab/.gitignore
@@ -0,0 +1 @@
+*.mex*
\ No newline at end of file
diff --git a/adaptors/matlab/Makefile.mex b/adaptors/matlab/Makefile.mex
index 322bed350e3c0a2a193c886f1085559d82a4a03e..9a0767a0ede486e3d5724fe523de03ed6ea927a8 100644
--- a/adaptors/matlab/Makefile.mex
+++ b/adaptors/matlab/Makefile.mex
@@ -8,11 +8,11 @@ TARGETS=realtimer \
 	encoderin 
 
 EXTRAFLAGS_realtimer=
-EXTRAFLAGS_analogin=-lmoberg4simulink
-EXTRAFLAGS_analogout=-lmoberg4simulink
-EXTRAFLAGS_digitalin=-lmoberg4simulink
-EXTRAFLAGS_digitalout=-lmoberg4simulink
-EXTRAFLAGS_encoderin=-lmoberg4simulink
+EXTRAFLAGS_analogin=-lmoberg4simulink -lmoberg
+EXTRAFLAGS_analogout=-lmoberg4simulink -lmoberg
+EXTRAFLAGS_digitalin=-lmoberg4simulink -lmoberg
+EXTRAFLAGS_digitalout=-lmoberg4simulink -lmoberg
+EXTRAFLAGS_encoderin=-lmoberg4simulink -lmoberg
 
 all:	$(TARGETS:%=%.$(SUFFIX))
 
diff --git a/adaptors/matlab/analogin.c b/adaptors/matlab/analogin.c
index 32ae34209a0270cf1e314fdefbb0214cf4147c81..6d267263fb1e55ba4a510bf3e8628a3622cf4285 100644
--- a/adaptors/matlab/analogin.c
+++ b/adaptors/matlab/analogin.c
@@ -132,11 +132,12 @@ static void mdlOutputs(SimStruct *S, int_T tid)
   {
     int i;
     real_T *y = ssGetOutputPortRealSignal(S, 1);
-      
+
     for (i = 0 ; i < ssGetNumPWork(S) ; i++) {
       struct moberg_analog_in *ain = (struct moberg_analog_in*)pwork[i];
-      if (! ain->read(ain->context, &y[i])) {
+      if (! moberg_OK(ain->read(ain->context, &y[i]))) {
         static char error[256];
+        double *channel = mxGetPr(ssGetSFcnParam(S,1));
         sprintf(error, "Failed to read analogin #%d", (int)channel[i]);
         ssSetErrorStatus(S, error);
       }
diff --git a/adaptors/matlab/analogout.c b/adaptors/matlab/analogout.c
index ba1b0918f1a1c076142774593ae761072934938c..a1d5909669a7af86b7cf6d25fdfdb400ea448672 100644
--- a/adaptors/matlab/analogout.c
+++ b/adaptors/matlab/analogout.c
@@ -131,12 +131,17 @@ static void mdlOutputs(SimStruct *S, int_T tid)
     y[0] = *up[0]+1;
   }
   {
-    InputRealPtrsType up = ssGetInputPortRealSignalPtrs(S,1);
     int i;
+    InputRealPtrsType up = ssGetInputPortRealSignalPtrs(S,1);
 
     for (i = 0 ; i < ssGetNumPWork(S) ; i++) {
       struct moberg_analog_out *aout = (struct moberg_analog_out*)pwork[i];
-      aout->write(aout->context, *up[i]);
+      if (! moberg_OK(aout->write(aout->context, *up[i]))) {
+        static char error[256];
+        double *channel = mxGetPr(ssGetSFcnParam(S,1));
+        sprintf(error, "Failed to write analogout #%d", (int)channel[i]);
+        ssSetErrorStatus(S, error);
+      }
     }
   }
 }
diff --git a/adaptors/matlab/digitalin.c b/adaptors/matlab/digitalin.c
index 55674db261ded49d9ae3ee7190139a071209b4ee..e8c2b6df77344a8e13b15ed016ce38aa5f613ff9 100644
--- a/adaptors/matlab/digitalin.c
+++ b/adaptors/matlab/digitalin.c
@@ -137,7 +137,12 @@ static void mdlOutputs(SimStruct *S, int_T tid)
     for (i = 0 ; i < ssGetNumPWork(S) ; i++) {
       struct moberg_digital_in *din = (struct moberg_digital_in*)pwork[i];
       int value;
-      din->read(din->context, &value);
+      if (! moberg_OK(din->read(din->context, &value))) {
+        static char error[256];
+        double *channel = mxGetPr(ssGetSFcnParam(S,1));
+        sprintf(error, "Failed to read digitalin #%d", (int)channel[i]);
+        ssSetErrorStatus(S, error);
+      }
       y[i] = value;
     }
   }
diff --git a/adaptors/matlab/digitalout.c b/adaptors/matlab/digitalout.c
index 801573bdf718413070f795dbaa3fdc4b26f5c666..97d9a8bac7be2be3e1368449161ebdecf9d9df35 100644
--- a/adaptors/matlab/digitalout.c
+++ b/adaptors/matlab/digitalout.c
@@ -131,12 +131,17 @@ static void mdlOutputs(SimStruct *S, int_T tid)
     y[0] = *up[0]+1;
   }
   {
-    InputRealPtrsType up = ssGetInputPortRealSignalPtrs(S,1);
     int i;
+    InputRealPtrsType up = ssGetInputPortRealSignalPtrs(S,1);
 
     for (i = 0 ; i < ssGetNumPWork(S) ; i++) {
       struct moberg_digital_out *dout = (struct moberg_digital_out*)pwork[i];
-      dout->write(dout->context, *up[i]);
+      if (! moberg_OK(dout->write(dout->context, *up[i]))) {
+        static char error[256];
+        double *channel = mxGetPr(ssGetSFcnParam(S,1));
+        sprintf(error, "Failed to write digitalout #%d", (int)channel[i]);
+        ssSetErrorStatus(S, error);
+      }
     }
   }
 }
diff --git a/adaptors/matlab/encoderin.c b/adaptors/matlab/encoderin.c
index 9a7be54b892b5a57559b78c09a7469962bdbc61f..2c4c0ec557c3db629a7c9ca1f45c91fcca4fb7b8 100644
--- a/adaptors/matlab/encoderin.c
+++ b/adaptors/matlab/encoderin.c
@@ -136,7 +136,12 @@ static void mdlOutputs(SimStruct *S, int_T tid)
     for (i = 0 ; i < ssGetNumPWork(S) ; i++) {
       struct moberg_encoder_in *ein = (struct moberg_encoder_in*)pwork[i];
       long value;
-      ein->read(ein->context, &value);
+      if (! moberg_OK(ein->read(ein->context, &value))) {
+        static char error[256];
+        double *channel = mxGetPr(ssGetSFcnParam(S,1));
+        sprintf(error, "Failed to read encoderin #%d", (int)channel[i]);
+        ssSetErrorStatus(S, error);
+      }
       y[i] = value;
     }
   }
diff --git a/moberg.spec.template b/moberg.spec.template
index e4f9f554730652d35569b7df8a7799418a7e42f3..7498e16a06ac60f1ec0599b2599c1e20dddea201 100644
--- a/moberg.spec.template
+++ b/moberg.spec.template
@@ -61,6 +61,8 @@ rm -rf ${RPM_BUILD_ROOT}
 
 mkdir -p ${RPM_BUILD_ROOT}%{_libdir}
 cp build/libmoberg*.so ${RPM_BUILD_ROOT}%{_libdir}
+mkdir -p ${RPM_BUILD_ROOT}%{_sbindir}
+cp build/moberg ${RPM_BUILD_ROOT}%{_sbindir}
 
 mkdir -p ${RPM_BUILD_ROOT}%{_includedir}
 cp moberg.h ${RPM_BUILD_ROOT}%{_includedir}
@@ -89,6 +91,7 @@ cp adaptors/matlab/Makefile.mex ${RPM_BUILD_ROOT}/opt/matlab/src/moberg/Makefile
 %{_includedir}/moberg.h
 %{_libdir}/libmoberg.so
 %{_libdir}/libmoberg_serial2002.so
+%{_sbindir}/moberg
 
 %files comedi
 %defattr(-,root,root,-)
diff --git a/moberg_tool.c b/moberg_tool.c
new file mode 100644
index 0000000000000000000000000000000000000000..11a6b0c8d3d96de02c02f9335e3965a0d1055bed
--- /dev/null
+++ b/moberg_tool.c
@@ -0,0 +1,29 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <moberg.h>
+
+void usage(char *prog) {
+  fprintf(stderr, "%s [ --start | --stop | -h | --help ]\n", prog);
+}
+
+int main(int argc, char *argv[])
+{
+  
+  if (argc == 2 && strcmp(argv[1], "--start") == 0) {
+    struct moberg *moberg = moberg_new(NULL);
+    moberg_start(moberg, stdout);
+    moberg_free(moberg);    
+  } else if (argc == 2 && strcmp(argv[1], "--stop") == 0) {
+    struct moberg *moberg = moberg_new(NULL);
+    moberg_stop(moberg, stdout);
+    moberg_free(moberg);    
+  } else if (argc == 2 && strcmp(argv[1], "-h") == 0) {
+    usage(argv[0]);
+  } else if (argc == 2 && strcmp(argv[1], "--help") == 0) {
+    usage(argv[0]);
+  } else {
+    usage(argv[0]);
+    exit(1);
+  }
+}