diff --git a/dstatInterface/dstatInterface.xcodeproj/project.pbxproj b/dstatInterface/dstatInterface.xcodeproj/project.pbxproj
index 6371382929b9f627d60a7074a43dc02e99d5e76e..9fedcac4413bba0fbe1c6486ab4392a7aae472e0 100644
--- a/dstatInterface/dstatInterface.xcodeproj/project.pbxproj
+++ b/dstatInterface/dstatInterface.xcodeproj/project.pbxproj
@@ -7,7 +7,9 @@
 	objects = {
 
 /* Begin PBXFileReference section */
+		5F05410F1994220800185C41 /* build_windows.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = build_windows.py; sourceTree = "<group>"; };
 		5F87883C19072E86007B53E0 /* mpltest.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = mpltest.py; sourceTree = "<group>"; };
+		5FB0B8E1198ACD4B00FA6CB7 /* microdrop.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = microdrop.py; sourceTree = "<group>"; };
 		5FCB541B190591CD00CEB148 /* interface */ = {isa = PBXFileReference; lastKnownFileType = folder; path = interface; sourceTree = "<group>"; };
 		5FCB541D1905923800CEB148 /* interface_test.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = interface_test.py; sourceTree = "<group>"; };
 		5FCB54231905B6EE00CEB148 /* dstat_comm.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = dstat_comm.py; sourceTree = "<group>"; };
@@ -22,7 +24,9 @@
 			children = (
 				5FF00FDC1942BD16004D38A8 /* setup.py */,
 				5F87883C19072E86007B53E0 /* mpltest.py */,
+				5F05410F1994220800185C41 /* build_windows.py */,
 				5FCB541D1905923800CEB148 /* interface_test.py */,
+				5FB0B8E1198ACD4B00FA6CB7 /* microdrop.py */,
 				5FCB54231905B6EE00CEB148 /* dstat_comm.py */,
 				5FCB541B190591CD00CEB148 /* interface */,
 				5FDC0DFD18FDAD79003F857A /* mpl.py */,
diff --git a/dstatInterface/interface/dstatInterface.glade b/dstatInterface/interface/dstatInterface.glade
deleted file mode 100644
index ba074302e10d9eefd38816f915f25d55a3aa2287..0000000000000000000000000000000000000000
--- a/dstatInterface/interface/dstatInterface.glade
+++ /dev/null
@@ -1,651 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<interface>
-  <requires lib="gtk+" version="2.24"/>
-  <!-- interface-naming-policy project-wide -->
-  <object class="GtkListStore" id="ExpComboListStore">
-    <columns>
-      <!-- column-name index -->
-      <column type="guint"/>
-      <!-- column-name name -->
-      <column type="gchararray"/>
-    </columns>
-    <data>
-      <row>
-        <col id="0">0</col>
-        <col id="1" translatable="yes">Chronoamperometry</col>
-      </row>
-      <row>
-        <col id="0">1</col>
-        <col id="1" translatable="yes">Linear Sweep Voltammetry</col>
-      </row>
-      <row>
-        <col id="0">2</col>
-        <col id="1" translatable="yes">Cyclic Voltammetry</col>
-      </row>
-      <row>
-        <col id="0">3</col>
-        <col id="1" translatable="yes">Square Wave Voltammetry</col>
-      </row>
-      <row>
-        <col id="0">4</col>
-        <col id="1" translatable="yes">Differential Pulse Voltammetry</col>
-      </row>
-      <row>
-        <col id="0">5</col>
-        <col id="1" translatable="yes">AC Voltammetry</col>
-      </row>
-      <row>
-        <col id="0">6</col>
-        <col id="1" translatable="yes">Photodiode</col>
-      </row>
-    </data>
-  </object>
-  <object class="GtkAboutDialog" id="aboutdialog1">
-    <property name="can_focus">False</property>
-    <property name="border_width">5</property>
-    <property name="type_hint">dialog</property>
-    <property name="program_name">Dstat Interface</property>
-    <property name="version">0.1</property>
-    <property name="copyright" translatable="yes">© Michael Dryden 2014</property>
-    <property name="license" translatable="yes">GNU</property>
-    <property name="authors">Michael Dryden</property>
-    <child internal-child="vbox">
-      <object class="GtkVBox" id="dialog-vbox1">
-        <property name="visible">True</property>
-        <property name="can_focus">False</property>
-        <property name="spacing">2</property>
-        <child internal-child="action_area">
-          <object class="GtkHButtonBox" id="dialog-action_area1">
-            <property name="visible">True</property>
-            <property name="can_focus">False</property>
-            <property name="layout_style">end</property>
-          </object>
-          <packing>
-            <property name="expand">True</property>
-            <property name="fill">True</property>
-            <property name="position">0</property>
-          </packing>
-        </child>
-        <child>
-          <placeholder/>
-        </child>
-      </object>
-    </child>
-  </object>
-  <object class="GtkTextBuffer" id="databuffer1"/>
-  <object class="GtkTextBuffer" id="databuffer2"/>
-  <object class="GtkImage" id="image1">
-    <property name="visible">True</property>
-    <property name="can_focus">False</property>
-    <property name="yalign">0.47999998927116394</property>
-    <property name="stock">gtk-missing-image</property>
-  </object>
-  <object class="GtkImage" id="image2">
-    <property name="visible">True</property>
-    <property name="can_focus">False</property>
-    <property name="stock">gtk-save-as</property>
-  </object>
-  <object class="GtkListStore" id="serial_liststore">
-    <columns>
-      <!-- column-name serial -->
-      <column type="gchararray"/>
-    </columns>
-  </object>
-  <object class="GtkAdjustment" id="updatesamples_adj">
-    <property name="upper">100</property>
-    <property name="value">5</property>
-    <property name="step_increment">1</property>
-    <property name="page_increment">10</property>
-  </object>
-  <object class="GtkWindow" id="window1">
-    <property name="can_focus">False</property>
-    <property name="border_width">6</property>
-    <property name="title" translatable="yes">Main</property>
-    <property name="default_width">1200</property>
-    <property name="default_height">800</property>
-    <signal name="destroy" handler="on_window1_destroy" swapped="no"/>
-    <child>
-      <object class="GtkVBox" id="vbox1">
-        <property name="visible">True</property>
-        <property name="can_focus">False</property>
-        <child>
-          <object class="GtkMenuBar" id="menubar1">
-            <property name="visible">True</property>
-            <property name="can_focus">False</property>
-            <child>
-              <object class="GtkMenuItem" id="menuitem1">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
-                <property name="label" translatable="yes">_File</property>
-                <property name="use_underline">True</property>
-                <child type="submenu">
-                  <object class="GtkMenu" id="menu1">
-                    <property name="visible">True</property>
-                    <property name="can_focus">False</property>
-                    <child>
-                      <object class="GtkImageMenuItem" id="gtk_new">
-                        <property name="label">gtk-new</property>
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="use_underline">True</property>
-                        <property name="use_stock">True</property>
-                      </object>
-                    </child>
-                    <child>
-                      <object class="GtkImageMenuItem" id="gtk-open">
-                        <property name="label">gtk-open</property>
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="use_underline">True</property>
-                        <property name="use_stock">True</property>
-                      </object>
-                    </child>
-                    <child>
-                      <object class="GtkImageMenuItem" id="file_save_exp">
-                        <property name="label">Save current data...</property>
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="image">image2</property>
-                        <property name="use_stock">False</property>
-                        <signal name="activate" handler="on_file_save_exp_activate" swapped="no"/>
-                      </object>
-                    </child>
-                    <child>
-                      <object class="GtkImageMenuItem" id="gtk-save-as">
-                        <property name="label">gtk-save-as</property>
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="use_underline">True</property>
-                        <property name="use_stock">True</property>
-                      </object>
-                    </child>
-                    <child>
-                      <object class="GtkImageMenuItem" id="gtk_quit">
-                        <property name="label">gtk-quit</property>
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="use_underline">True</property>
-                        <property name="use_stock">True</property>
-                        <signal name="activate" handler="on_gtk_quit_activate" swapped="no"/>
-                      </object>
-                    </child>
-                  </object>
-                </child>
-              </object>
-            </child>
-            <child>
-              <object class="GtkMenuItem" id="menuitem2">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
-                <property name="label" translatable="yes">_Edit</property>
-                <property name="use_underline">True</property>
-                <child type="submenu">
-                  <object class="GtkMenu" id="menu2">
-                    <property name="visible">True</property>
-                    <property name="can_focus">False</property>
-                    <child>
-                      <object class="GtkImageMenuItem" id="imagemenuitem7">
-                        <property name="label">gtk-copy</property>
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="use_underline">True</property>
-                        <property name="use_stock">True</property>
-                      </object>
-                    </child>
-                    <child>
-                      <object class="GtkImageMenuItem" id="imagemenuitem8">
-                        <property name="label">gtk-paste</property>
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="use_underline">True</property>
-                        <property name="use_stock">True</property>
-                      </object>
-                    </child>
-                  </object>
-                </child>
-              </object>
-            </child>
-            <child>
-              <object class="GtkMenuItem" id="gtk_view">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
-                <property name="label" translatable="yes">_View</property>
-                <property name="use_underline">True</property>
-                <child type="submenu">
-                  <object class="GtkMenu" id="menu5">
-                    <property name="visible">True</property>
-                    <property name="can_focus">False</property>
-                    <child>
-                      <object class="GtkImageMenuItem" id="push_status">
-                        <property name="label">Push Status</property>
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="use_stock">False</property>
-                      </object>
-                    </child>
-                    <child>
-                      <object class="GtkImageMenuItem" id="pop_status">
-                        <property name="label">Pop Status</property>
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="use_stock">False</property>
-                      </object>
-                    </child>
-                    <child>
-                      <object class="GtkImageMenuItem" id="clear_status">
-                        <property name="label">Clear Status</property>
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="use_stock">False</property>
-                      </object>
-                    </child>
-                  </object>
-                </child>
-              </object>
-            </child>
-            <child>
-              <object class="GtkMenuItem" id="menuitem4">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
-                <property name="label" translatable="yes">_Help</property>
-                <property name="use_underline">True</property>
-                <child type="submenu">
-                  <object class="GtkMenu" id="menu3">
-                    <property name="visible">True</property>
-                    <property name="can_focus">False</property>
-                    <child>
-                      <object class="GtkImageMenuItem" id="gtk_about">
-                        <property name="label">gtk-about</property>
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="use_underline">True</property>
-                        <property name="use_stock">True</property>
-                        <signal name="activate" handler="on_gtk_about_activate" swapped="no"/>
-                      </object>
-                    </child>
-                  </object>
-                </child>
-              </object>
-            </child>
-          </object>
-          <packing>
-            <property name="expand">False</property>
-            <property name="fill">True</property>
-            <property name="position">0</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkHPaned" id="hpaned1">
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="position">300</property>
-            <property name="position_set">True</property>
-            <child>
-              <object class="GtkVBox" id="vbox2">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
-                <child>
-                  <object class="GtkVBox" id="vbox3">
-                    <property name="visible">True</property>
-                    <property name="can_focus">False</property>
-                    <child>
-                      <object class="GtkHBox" id="gain_adc_box">
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="spacing">2</property>
-                        <child>
-                          <placeholder/>
-                        </child>
-                      </object>
-                      <packing>
-                        <property name="expand">True</property>
-                        <property name="fill">True</property>
-                        <property name="position">0</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkLabel" id="label7">
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="label" translatable="yes">Experiment:</property>
-                        <attributes>
-                          <attribute name="weight" value="semibold"/>
-                        </attributes>
-                      </object>
-                      <packing>
-                        <property name="expand">True</property>
-                        <property name="fill">True</property>
-                        <property name="padding">10</property>
-                        <property name="position">1</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkComboBox" id="expcombobox">
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="model">ExpComboListStore</property>
-                        <signal name="changed" handler="on_expcombobox_changed" swapped="no"/>
-                      </object>
-                      <packing>
-                        <property name="expand">True</property>
-                        <property name="fill">True</property>
-                        <property name="position">2</property>
-                      </packing>
-                    </child>
-                  </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">True</property>
-                    <property name="position">0</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkHBox" id="exp_section_box">
-                    <property name="visible">True</property>
-                    <property name="can_focus">False</property>
-                    <child>
-                      <placeholder/>
-                    </child>
-                  </object>
-                  <packing>
-                    <property name="expand">True</property>
-                    <property name="fill">True</property>
-                    <property name="position">1</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkHBox" id="hbox1">
-                    <property name="visible">True</property>
-                    <property name="can_focus">False</property>
-                    <child>
-                      <object class="GtkButton" id="pot_start">
-                        <property name="label">gtk-execute</property>
-                        <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="receives_default">True</property>
-                        <property name="use_stock">True</property>
-                        <signal name="clicked" handler="on_pot_start_clicked" swapped="no"/>
-                      </object>
-                      <packing>
-                        <property name="expand">True</property>
-                        <property name="fill">True</property>
-                        <property name="position">0</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkButton" id="pot_stop">
-                        <property name="label">gtk-stop</property>
-                        <property name="visible">True</property>
-                        <property name="sensitive">False</property>
-                        <property name="can_focus">True</property>
-                        <property name="receives_default">True</property>
-                        <property name="use_stock">True</property>
-                        <signal name="clicked" handler="on_pot_stop_clicked" swapped="no"/>
-                      </object>
-                      <packing>
-                        <property name="expand">True</property>
-                        <property name="fill">True</property>
-                        <property name="position">1</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkSpinner" id="spinner">
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                      </object>
-                      <packing>
-                        <property name="expand">True</property>
-                        <property name="fill">True</property>
-                        <property name="position">2</property>
-                      </packing>
-                    </child>
-                  </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">False</property>
-                    <property name="padding">5</property>
-                    <property name="position">2</property>
-                  </packing>
-                </child>
-              </object>
-              <packing>
-                <property name="resize">False</property>
-                <property name="shrink">True</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkNotebook" id="notebook1">
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <child>
-                  <object class="GtkVBox" id="vbox4">
-                    <property name="visible">True</property>
-                    <property name="can_focus">False</property>
-                    <child>
-                      <object class="GtkHBox" id="hbox3">
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <child>
-                          <object class="GtkCheckButton" id="plotinteractive_checkbutton">
-                            <property name="label" translatable="yes">Plot updates during measurement</property>
-                            <property name="visible">True</property>
-                            <property name="can_focus">True</property>
-                            <property name="receives_default">False</property>
-                            <property name="draw_indicator">True</property>
-                          </object>
-                          <packing>
-                            <property name="expand">False</property>
-                            <property name="fill">True</property>
-                            <property name="position">0</property>
-                          </packing>
-                        </child>
-                        <child>
-                          <object class="GtkSpinButton" id="samples_spinbutton">
-                            <property name="visible">True</property>
-                            <property name="can_focus">True</property>
-                            <property name="invisible_char">●</property>
-                            <property name="truncate_multiline">True</property>
-                            <property name="primary_icon_activatable">False</property>
-                            <property name="secondary_icon_activatable">False</property>
-                            <property name="primary_icon_sensitive">True</property>
-                            <property name="secondary_icon_sensitive">True</property>
-                            <property name="adjustment">updatesamples_adj</property>
-                            <property name="snap_to_ticks">True</property>
-                            <property name="numeric">True</property>
-                            <property name="update_policy">if-valid</property>
-                          </object>
-                          <packing>
-                            <property name="expand">False</property>
-                            <property name="fill">True</property>
-                            <property name="padding">5</property>
-                            <property name="position">1</property>
-                          </packing>
-                        </child>
-                        <child>
-                          <object class="GtkLabel" id="label1">
-                            <property name="visible">True</property>
-                            <property name="can_focus">False</property>
-                            <property name="label" translatable="yes">samples per update</property>
-                          </object>
-                          <packing>
-                            <property name="expand">False</property>
-                            <property name="fill">True</property>
-                            <property name="padding">5</property>
-                            <property name="position">2</property>
-                          </packing>
-                        </child>
-                        <child>
-                          <object class="GtkLabel" id="label4">
-                            <property name="visible">True</property>
-                            <property name="can_focus">False</property>
-                          </object>
-                          <packing>
-                            <property name="expand">True</property>
-                            <property name="fill">True</property>
-                            <property name="position">3</property>
-                          </packing>
-                        </child>
-                      </object>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">True</property>
-                        <property name="position">0</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkHBox" id="plotbox">
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <child>
-                          <placeholder/>
-                        </child>
-                      </object>
-                      <packing>
-                        <property name="expand">True</property>
-                        <property name="fill">True</property>
-                        <property name="position">1</property>
-                      </packing>
-                    </child>
-                  </object>
-                </child>
-                <child type="tab">
-                  <object class="GtkLabel" id="label2">
-                    <property name="visible">True</property>
-                    <property name="can_focus">False</property>
-                    <property name="label" translatable="yes">Plot</property>
-                  </object>
-                  <packing>
-                    <property name="tab_fill">False</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkScrolledWindow" id="scrolledwindow1">
-                    <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="hscrollbar_policy">automatic</property>
-                    <property name="vscrollbar_policy">automatic</property>
-                    <child>
-                      <object class="GtkTextView" id="datatextview1">
-                        <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="editable">False</property>
-                        <property name="left_margin">10</property>
-                        <property name="right_margin">10</property>
-                        <property name="buffer">databuffer1</property>
-                      </object>
-                    </child>
-                  </object>
-                  <packing>
-                    <property name="position">1</property>
-                  </packing>
-                </child>
-                <child type="tab">
-                  <object class="GtkLabel" id="label3">
-                    <property name="visible">True</property>
-                    <property name="can_focus">False</property>
-                    <property name="label" translatable="yes">Raw Data</property>
-                  </object>
-                  <packing>
-                    <property name="position">1</property>
-                    <property name="tab_fill">False</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkScrolledWindow" id="scrolledwindow2">
-                    <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="hscrollbar_policy">automatic</property>
-                    <property name="vscrollbar_policy">automatic</property>
-                    <child>
-                      <object class="GtkTextView" id="datatextview2">
-                        <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="editable">False</property>
-                        <property name="left_margin">10</property>
-                        <property name="right_margin">10</property>
-                        <property name="buffer">databuffer2</property>
-                      </object>
-                    </child>
-                  </object>
-                  <packing>
-                    <property name="position">2</property>
-                  </packing>
-                </child>
-                <child type="tab">
-                  <object class="GtkLabel" id="label5">
-                    <property name="visible">True</property>
-                    <property name="can_focus">False</property>
-                    <property name="label" translatable="yes">Extra Data</property>
-                  </object>
-                  <packing>
-                    <property name="position">2</property>
-                    <property name="tab_fill">False</property>
-                  </packing>
-                </child>
-              </object>
-              <packing>
-                <property name="resize">True</property>
-                <property name="shrink">True</property>
-              </packing>
-            </child>
-          </object>
-          <packing>
-            <property name="expand">True</property>
-            <property name="fill">True</property>
-            <property name="position">1</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkHBox" id="hbox2">
-            <property name="visible">True</property>
-            <property name="can_focus">False</property>
-            <child>
-              <object class="GtkComboBox" id="serial_combobox">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
-                <property name="model">serial_liststore</property>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">False</property>
-                <property name="position">0</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkButton" id="serial_refresh">
-                <property name="label">gtk-refresh</property>
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="receives_default">True</property>
-                <property name="use_stock">True</property>
-                <signal name="clicked" handler="on_serial_refresh_clicked" swapped="no"/>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">False</property>
-                <property name="position">1</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkStatusbar" id="statusbar">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
-                <property name="spacing">2</property>
-              </object>
-              <packing>
-                <property name="expand">True</property>
-                <property name="fill">True</property>
-                <property name="position">2</property>
-              </packing>
-            </child>
-          </object>
-          <packing>
-            <property name="expand">False</property>
-            <property name="fill">False</property>
-            <property name="position">2</property>
-          </packing>
-        </child>
-      </object>
-    </child>
-  </object>
-</interface>
diff --git a/dstatInterface/interface/dstatinterface.glade b/dstatInterface/interface/dstatinterface.glade
index ba074302e10d9eefd38816f915f25d55a3aa2287..6b1062a172816a5543303c918182dd7edbdf0d5a 100644
--- a/dstatInterface/interface/dstatinterface.glade
+++ b/dstatInterface/interface/dstatinterface.glade
@@ -85,18 +85,17 @@
     <property name="can_focus">False</property>
     <property name="stock">gtk-save-as</property>
   </object>
+  <object class="GtkImage" id="image3">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <property name="stock">gtk-save</property>
+  </object>
   <object class="GtkListStore" id="serial_liststore">
     <columns>
       <!-- column-name serial -->
       <column type="gchararray"/>
     </columns>
   </object>
-  <object class="GtkAdjustment" id="updatesamples_adj">
-    <property name="upper">100</property>
-    <property name="value">5</property>
-    <property name="step_increment">1</property>
-    <property name="page_increment">10</property>
-  </object>
   <object class="GtkWindow" id="window1">
     <property name="can_focus">False</property>
     <property name="border_width">6</property>
@@ -151,12 +150,13 @@
                       </object>
                     </child>
                     <child>
-                      <object class="GtkImageMenuItem" id="gtk-save-as">
-                        <property name="label">gtk-save-as</property>
+                      <object class="GtkImageMenuItem" id="file_save_plot">
+                        <property name="label">Save Plot…</property>
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
-                        <property name="use_underline">True</property>
-                        <property name="use_stock">True</property>
+                        <property name="image">image3</property>
+                        <property name="use_stock">False</property>
+                        <signal name="activate" handler="on_file_save_plot_activate" swapped="no"/>
                       </object>
                     </child>
                     <child>
@@ -174,31 +174,32 @@
               </object>
             </child>
             <child>
-              <object class="GtkMenuItem" id="menuitem2">
+              <object class="GtkMenuItem" id="menu_dropbot">
                 <property name="visible">True</property>
                 <property name="can_focus">False</property>
-                <property name="label" translatable="yes">_Edit</property>
+                <property name="label" translatable="yes">Dropbot</property>
                 <property name="use_underline">True</property>
                 <child type="submenu">
                   <object class="GtkMenu" id="menu2">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
                     <child>
-                      <object class="GtkImageMenuItem" id="imagemenuitem7">
-                        <property name="label">gtk-copy</property>
+                      <object class="GtkImageMenuItem" id="menu_dropbot_connect">
+                        <property name="label">gtk-connect</property>
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
-                        <property name="use_underline">True</property>
                         <property name="use_stock">True</property>
+                        <signal name="activate" handler="on_menu_dropbot_connect_activate" swapped="no"/>
                       </object>
                     </child>
                     <child>
-                      <object class="GtkImageMenuItem" id="imagemenuitem8">
-                        <property name="label">gtk-paste</property>
+                      <object class="GtkImageMenuItem" id="menu_dropbot_disconnect">
+                        <property name="label">gtk-disconnect</property>
                         <property name="visible">True</property>
+                        <property name="sensitive">False</property>
                         <property name="can_focus">False</property>
-                        <property name="use_underline">True</property>
                         <property name="use_stock">True</property>
+                        <signal name="activate" handler="on_menu_dropbot_disconnect_activate" swapped="no"/>
                       </object>
                     </child>
                   </object>
@@ -426,8 +427,8 @@
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
                         <child>
-                          <object class="GtkCheckButton" id="plotinteractive_checkbutton">
-                            <property name="label" translatable="yes">Plot updates during measurement</property>
+                          <object class="GtkCheckButton" id="autosave_checkbutton">
+                            <property name="label" translatable="yes">Autosave</property>
                             <property name="visible">True</property>
                             <property name="can_focus">True</property>
                             <property name="receives_default">False</property>
@@ -440,51 +441,41 @@
                           </packing>
                         </child>
                         <child>
-                          <object class="GtkSpinButton" id="samples_spinbutton">
+                          <object class="GtkFileChooserButton" id="autosavedir_button">
                             <property name="visible">True</property>
-                            <property name="can_focus">True</property>
-                            <property name="invisible_char">●</property>
-                            <property name="truncate_multiline">True</property>
-                            <property name="primary_icon_activatable">False</property>
-                            <property name="secondary_icon_activatable">False</property>
-                            <property name="primary_icon_sensitive">True</property>
-                            <property name="secondary_icon_sensitive">True</property>
-                            <property name="adjustment">updatesamples_adj</property>
-                            <property name="snap_to_ticks">True</property>
-                            <property name="numeric">True</property>
-                            <property name="update_policy">if-valid</property>
+                            <property name="can_focus">False</property>
+                            <property name="action">select-folder</property>
+                            <property name="preview_widget_active">False</property>
+                            <property name="title" translatable="yes">Select a Save Folder</property>
                           </object>
                           <packing>
-                            <property name="expand">False</property>
+                            <property name="expand">True</property>
                             <property name="fill">True</property>
-                            <property name="padding">5</property>
                             <property name="position">1</property>
                           </packing>
                         </child>
                         <child>
-                          <object class="GtkLabel" id="label1">
+                          <object class="GtkEntry" id="autosavename">
                             <property name="visible">True</property>
-                            <property name="can_focus">False</property>
-                            <property name="label" translatable="yes">samples per update</property>
+                            <property name="can_focus">True</property>
+                            <property name="has_tooltip">True</property>
+                            <property name="max_length">32</property>
+                            <property name="invisible_char">●</property>
+                            <property name="text" translatable="yes">file</property>
+                            <property name="caps_lock_warning">False</property>
+                            <property name="primary_icon_stock">gtk-file</property>
+                            <property name="primary_icon_activatable">False</property>
+                            <property name="secondary_icon_activatable">False</property>
+                            <property name="primary_icon_sensitive">True</property>
+                            <property name="secondary_icon_sensitive">True</property>
+                            <property name="primary_icon_tooltip_text" translatable="yes">File name</property>
                           </object>
                           <packing>
                             <property name="expand">False</property>
                             <property name="fill">True</property>
-                            <property name="padding">5</property>
                             <property name="position">2</property>
                           </packing>
                         </child>
-                        <child>
-                          <object class="GtkLabel" id="label4">
-                            <property name="visible">True</property>
-                            <property name="can_focus">False</property>
-                          </object>
-                          <packing>
-                            <property name="expand">True</property>
-                            <property name="fill">True</property>
-                            <property name="position">3</property>
-                          </packing>
-                        </child>
                       </object>
                       <packing>
                         <property name="expand">False</property>
@@ -648,4 +639,10 @@
       </object>
     </child>
   </object>
+  <object class="GtkAdjustment" id="updatesamples_adj">
+    <property name="upper">100</property>
+    <property name="value">5</property>
+    <property name="step_increment">1</property>
+    <property name="page_increment">10</property>
+  </object>
 </interface>
diff --git a/dstatInterface/interface/save.py b/dstatInterface/interface/save.py
index 4789d408d2ab596dca851e6edbacf560a9c5722a..4456d08f27347a589ab654ea16eac6603d02f031 100644
--- a/dstatInterface/interface/save.py
+++ b/dstatInterface/interface/save.py
@@ -1,49 +1,154 @@
 #!/usr/bin/env python
+# -*- coding: utf-8 -*-
 
-import gtk, io
+import gtk, io, os
 import numpy as np
+from datetime import datetime
 
-class npSave:
-    def __init__(self, current_exp):
-        self.exp = current_exp
-        self.fcd = gtk.FileChooserDialog("Save...", None, gtk.FILE_CHOOSER_ACTION_SAVE, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_SAVE, gtk.RESPONSE_OK))
+def manSave(current_exp):
+    exp = current_exp
+    fcd = gtk.FileChooserDialog("Save...", None, gtk.FILE_CHOOSER_ACTION_SAVE, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_SAVE, gtk.RESPONSE_OK))
+    
+    filters = [gtk.FileFilter()]
+    filters[0].set_name("NumPy binary (.npy)")
+    filters[0].add_pattern("*.npy")
+    filters.append(gtk.FileFilter())
+    filters[1].set_name("Space separated text (.txt)")
+    filters[1].add_pattern("*.txt")
+    
+    fcd.set_do_overwrite_confirmation(True)
+    for i in filters:
+        fcd.add_filter(i)
+                 
+    response = fcd.run()
+    
+    if response == gtk.RESPONSE_OK:
+        path = fcd.get_filename()
+        print "Selected filepath: %s" % path
+        filter_selection = fcd.get_filter().get_name()
         
-        self.filters = [gtk.FileFilter()]
-        self.filters[0].set_name("NumPy binary (.npy)")
-        self.filters[0].add_pattern("*.npy")
-        self.filters.append(gtk.FileFilter())
-        self.filters[1].set_name("Space separated text (.txt)")
-        self.filters[1].add_pattern("*.txt")
+        if filter_selection.endswith("(.npy)"):
+            npy(exp, path)
+        elif filter_selection.endswith("(.txt)"):
+            text(exp, path)
+        fcd.destroy()
         
-        self.fcd.set_do_overwrite_confirmation(True)
-        for i in self.filters:
-            self.fcd.add_filter(i)
-                     
-        self.response = self.fcd.run()
+    elif response == gtk.RESPONSE_CANCEL:
+        fcd.destroy()
+
+def plotSave(plot):
+    fcd = gtk.FileChooserDialog("Save Plot…", None, gtk.FILE_CHOOSER_ACTION_SAVE, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_SAVE, gtk.RESPONSE_OK))
+
+    filters = [gtk.FileFilter()]
+    filters[0].set_name("Portable Document Format (.pdf)")
+    filters[0].add_pattern("*.pdf")
+    filters.append(gtk.FileFilter())
+    filters[1].set_name("Portable Network Graphics (.png)")
+    filters[1].add_pattern("*.png")
+    
+    fcd.set_do_overwrite_confirmation(True)
+    for i in filters:
+        fcd.add_filter(i)
+    
+    response = fcd.run()
+    
+    if response == gtk.RESPONSE_OK:
+        path = fcd.get_filename()
+        print "Selected filepath: %s" % path
+        filter_selection = fcd.get_filter().get_name()
         
-        if self.response == gtk.RESPONSE_OK:
-            self.path = self.fcd.get_filename()
-            print "Selected filepath: %s" % self.path
-            filter_selection = self.fcd.get_filter().get_name()
-            
-            if filter_selection.endswith("(.npy)"):
-                self.npy()
-            elif filter_selection.endswith("(.txt)"):
-                self.text()
-            self.fcd.destroy()
-    
-    def npy(self):
-        self.data = np.array(self.exp.data)
-        np.save(self.path, self.data())
-
-    def text(self):
-        if not self.path.endswith(".txt"):
-            self.path += ".txt"
+        if filter_selection.endswith("(.pdf)"):
+            if not path.endswith(".pdf"):
+                path += ".pdf"
+        
+        elif filter_selection.endswith("(.png)"):
+            if not path.endswith(".png"):
+                path += ".png"
+
+        plot.figure.savefig(path) #savefig determines format from file extension
+        fcd.destroy()
+    
+    elif response == gtk.RESPONSE_CANCEL:
+        fcd.destroy()
+
+def autoSave(current_exp, dir_button, name, expnumber):
+    if name == "":
+        name = "file"
+    path = dir_button.get_filename()
+    path += '/'
+    path += name
+    path += str(expnumber)
+
+    text(current_exp, path, auto=True)
+
+def autoPlot(plot, dir_button, name, expnumber):
+    if name == "":
+        name = "file"
+    
+    path = dir_button.get_filename()
+    path += '/'
+    path += name
+    path += str(expnumber)
+    
+    if path.endswith(".pdf"):
+        path = path.rstrip(".pdf")
+
+    j = 1
+    while os.path.exists("".join([path, ".pdf"])):
+        if j > 1:
+            path = path[:-len(str(j))]
+        path += str(j)
+        j += 1
+
+    path += ".pdf"
+    plot.figure.savefig(path)
+
+
+def npy(exp, path, auto=False):
+    if path.endswith(".npy"):
+        path = path.rstrip(".npy")
+
+    data = np.array(exp.data)
+
+    if auto == True:
+        j = 1
+        while os.path.exists("".join([path, ".npy"])):
+            if j > 1:
+                path = path[:-len(str(j))]
+            path += str(j)
+            j += 1
+
+    np.save(path, data)
+
+def text(exp, path, auto=False):
+    if path.endswith(".txt"):
+        path = path.rstrip(".txt")
+    
+    if auto == True:
+        j = 1
         
-        self.data = np.array(self.exp.data)
-        header = ""
-        for i in self.exp.commands:
-            header += i
-        np.savetxt(self.path, self.data.transpose(), header=header, newline='\n')
+        while os.path.exists("".join([path, ".txt"])):
+            if j > 1:
+                path = path[:-len(str(j))]
+            path += str(j)
+            j += 1
+    
+    path += ".txt"
+    file = open(path, 'w')
+    
+    time = datetime.now()
+
+    data = np.array(exp.data)
+    header = "".join(['#', time.isoformat(), "\n#"])
+    for i in exp.commands:
+        header += i
+
+    file.write("".join([header, '\n']))
+    for col in zip(*exp.data):
+        for row in col:
+            file.write(str(row)+ "    ")
+        file.write('\n')
+    
+    file.close()
 
 
diff --git a/dstatInterface/interface_test.py b/dstatInterface/interface_test.py
index 49076362e437d45413fdcb753d9a5df97e33657e..abca328e397154c6b03f2ba4c5b572e8f2e954ec 100644
--- a/dstatInterface/interface_test.py
+++ b/dstatInterface/interface_test.py
@@ -1,4 +1,5 @@
 #!/usr/bin/env python
+# -*- coding: utf-8 -*-
 
 import sys
 try:
@@ -34,6 +35,7 @@ import multiprocessing
 import time
 
 import mpltest
+import microdrop
 
 class Error(Exception):
     pass
@@ -76,10 +78,15 @@ class main:
         self.pd = pd.pd()
         
         self.error_context_id = self.statusbar.get_context_id("error")
+        self.message_context_id = self.statusbar.get_context_id("message")
         
         self.plotwindow = self.builder.get_object('plotbox')
-        self.plotint_checkbox = self.builder.get_object('plotinteractive_checkbutton')
-        self.updatelimit_adj = self.builder.get_object('updatesamples_adj')
+        
+        #setup autosave
+        self.autosave_checkbox = self.builder.get_object('autosave_checkbutton')
+        self.autosavedir_button = self.builder.get_object('autosavedir_button')
+        self.autosavename = self.builder.get_object('autosavename')
+        
         self.plot = mpltest.plotbox(self.plotwindow)
         
         #fill exp_section
@@ -138,6 +145,13 @@ class main:
         self.acv_container.hide()
         self.pd_container.hide()
 
+        self.expnumber = 0
+        
+        self.menu_dropbot_connect = self.builder.get_object('menu_dropbot_connect')
+        self.menu_dropbot_disconnect = self.builder.get_object('menu_dropbot_disconnect')
+        self.dropbot_enabled = False
+        self.dropbot_triggered = False
+
     def exp_param_show(self, selection):
         self.chronoamp_container.hide()
         self.lsv_container.hide()
@@ -190,6 +204,18 @@ class main:
             self.serial_liststore.append([i])
 
     def on_pot_start_clicked(self, data=None):
+    
+        def exceptions(): #cleans up after errors
+            if self.dropbot_enabled == True:
+                if self.dropbot_triggered == True:
+                    self.dropbot_triggered = False
+                    print "finallydone"
+                    self.microdrop.reply(microdrop.EXPFINISHED)
+                    self.microdrop_proc = gobject.timeout_add(500, self.microdrop_listen)
+            self.spinner.stop()
+            self.startbutton.set_sensitive(True)
+            self.stopbutton.set_sensitive(False)
+            
         selection = self.expcombobox.get_active()
         parameters = {}
         view_parameters = {}
@@ -207,9 +233,6 @@ class main:
         parameters['adc_pga'] = pga_model.get_value(self.adc_pot.pga_combobox.get_active_iter(), 2)
         parameters['gain'] = gain_model.get_value(self.adc_pot.gain_combobox.get_active_iter(), 2)
         
-        view_parameters['update'] = self.plotint_checkbox.get_active()
-        view_parameters['updatelimit'] = int(self.updatelimit_adj.get_value())
-        
         self.line = 0
         self.lastline = 0
         self.lastdataline = 0
@@ -244,6 +267,7 @@ class main:
                 
                 self.plot_proc = gobject.timeout_add(200, self.experiment_running_plot)
                 gobject.idle_add(self.experiment_running)
+                return
         
             elif selection == 1: #LSV
                 parameters['clean_mV'] = int(self.lsv.clean_mV.get_text())
@@ -289,6 +313,7 @@ class main:
 
                 self.plot_proc = gobject.timeout_add(200, self.experiment_running_plot)
                 gobject.idle_add(self.experiment_running)
+                return
             
             elif selection == 2: #CV
                 parameters['clean_mV'] = int(self.cv.clean_mV.get_text())
@@ -340,6 +365,7 @@ class main:
                 
                 self.plot_proc = gobject.timeout_add(200, self.experiment_running_plot)
                 gobject.idle_add(self.experiment_running)
+                return
                 
             elif selection == 3: #SWV
                 parameters['clean_mV'] = int(self.swv.clean_mV.get_text())
@@ -398,6 +424,7 @@ class main:
                 
                 self.plot_proc = gobject.timeout_add(200, self.experiment_running_plot)
                 gobject.idle_add(self.experiment_running)
+                return
         
             elif selection == 4: #DPV
                 parameters['clean_mV'] = int(self.dpv.clean_mV.get_text())
@@ -454,35 +481,27 @@ class main:
 
                 self.plot_proc = gobject.timeout_add(200, self.experiment_running_plot)
                 gobject.idle_add(self.experiment_running)
+                return
 
             else:
                 self.statusbar.push(self.error_context_id, "Experiment not yet implemented.")
-                self.startbutton.set_sensitive(True)
-                self.stopbutton.set_sensitive(False)
+                exceptions()
                 
         except ValueError:
-            self.spinner.stop()
             self.statusbar.push(self.error_context_id, "Experiment parameters must be integers.")
-            self.startbutton.set_sensitive(True)
-            self.stopbutton.set_sensitive(False)
+            exceptions()
         
         except InputError as e:
-            self.spinner.stop()
             self.statusbar.push(self.error_context_id, e.msg)
-            self.startbutton.set_sensitive(True)
-            self.stopbutton.set_sensitive(False)
+            exceptions()
         
         except SerialException:
-            self.spinner.stop()
             self.statusbar.push(self.error_context_id, "Could not establish serial connection.")
-            self.startbutton.set_sensitive(True)
-            self.stopbutton.set_sensitive(False)
+            exceptions()
 
         except AssertionError as e:
-            self.spinner.stop()
             self.statusbar.push(self.error_context_id, str(e))
-            self.startbutton.set_sensitive(True)
-            self.stopbutton.set_sensitive(False)
+            exceptions()
 
     def experiment_running(self):
         try:
@@ -519,7 +538,7 @@ class main:
     def experiment_done(self):
         gobject.source_remove(self.plot_proc) #stop automatic plot update
         self.experiment_running_plot() #make sure all data updated on plot
-        
+
         self.databuffer.set_text("")
         self.databuffer.place_cursor(self.databuffer.get_start_iter())
         self.rawbuffer.insert_at_cursor("\n")
@@ -528,16 +547,26 @@ class main:
 
         for col in zip(*self.current_exp.data):
             for row in col:
-                self.rawbuffer.insert_at_cursor(str(row)+ "\t")
+                self.rawbuffer.insert_at_cursor(str(row)+ "    ")
             self.rawbuffer.insert_at_cursor("\n")
         
-        
         if self.current_exp.data_extra:
             for col in zip(*self.current_exp.data_extra):
                 for row in col:
-                    self.databuffer.insert_at_cursor(str(row)+ "\t")
+                    self.databuffer.insert_at_cursor(str(row)+ "    ")
                 self.databuffer.insert_at_cursor("\n")
+    
+        if self.autosave_checkbox.get_active():
+            save.autoSave(self.current_exp, self.autosavedir_button, self.autosavename.get_text(), self.expnumber)
+            save.autoPlot(self.plot, self.autosavedir_button, self.autosavename.get_text(), self.expnumber)
+            self.expnumber += 1
         
+        if self.dropbot_enabled == True:
+            if self.dropbot_triggered == True:
+                self.dropbot_triggered = False
+                print "expdone"
+                self.microdrop.reply(microdrop.EXPFINISHED)
+            self.microdrop_proc = gobject.timeout_add(500, self.microdrop_listen)
         
         self.spinner.stop()
         self.startbutton.set_sensitive(True)
@@ -550,7 +579,50 @@ class main:
     
     def on_file_save_exp_activate(self, menuitem, data=None):
         if self.current_exp:
-            self.save = save.npSave(self.current_exp)
+            save_inst = save.manSave(self.current_exp)
+    
+    def on_file_save_plot_activate(self, menuitem, data=None):
+        save_inst = save.plotSave(self.plot)
+    
+    def on_menu_dropbot_connect_activate(self, menuitem, data=None):
+        self.microdrop = microdrop.microdropConnection()
+        self.dropbot_enabled = True
+        self.menu_dropbot_connect.set_sensitive(False)
+        self.menu_dropbot_disconnect.set_sensitive(True)
+        self.statusbar.push(self.message_context_id, "Waiting for µDrop to connect…")
+        self.microdrop_proc = gobject.timeout_add(500, self.microdrop_listen)
+    
+    def on_menu_dropbot_disconnect_activate(self, menuitem, data= None):
+        gobject.source_remove(self.microdrop_proc)
+        self.microdrop.reset()
+        del self.microdrop
+        self.dropbot_enabled = False
+        self.menu_dropbot_connect.set_sensitive(True)
+        self.menu_dropbot_disconnect.set_sensitive(False)
+
+    def microdrop_listen(self):
+        drdy, data = self.microdrop.listen()
+        if drdy == False:
+            return True
+        if self.microdrop.connected == False:
+            if data == microdrop.CONREQ:
+                print "INFO: µDrop connected"
+                self.statusbar.push(self.message_context_id, "µDrop connected.")
+                self.microdrop.reply(microdrop.CONREP)
+                self.microdrop.connected = True
+            else:
+                print "WAR: Invalid µDrop connection request."
+                self.microdrop.reply(microdrop.INVAL_CMD)
+        elif data == microdrop.STARTEXP:
+            self.dropbot_triggered = True
+            self.on_pot_start_clicked()
+            return False
+        else:
+            print "WAR: Received invalid command from µDrop"
+            self.microdrop.reply(microdrop.INVAL_CMD)
+        return True
+
+
 
 
 if __name__ == "__main__":
diff --git a/dstatInterface/microdrop.py b/dstatInterface/microdrop.py
new file mode 100644
index 0000000000000000000000000000000000000000..95ea34cbe86d9998730c12a9eb91151e23782028
--- /dev/null
+++ b/dstatInterface/microdrop.py
@@ -0,0 +1,51 @@
+import zmq
+import zmq.error
+
+#signals
+CONREQ = "0"
+CONREP = "1"
+STARTEXP = "10"
+EXPFINISHED = "11"
+INVAL_CMD = "99"
+
+#States
+RECV = 0
+SEND = 1
+
+class microdropConnection:
+
+    def __init__(self, port=6789):
+        self.port = port
+        self.connected = False
+        self.state = RECV
+    
+        self.ctx = zmq.Context()
+        self.soc = zmq.Socket(self.ctx, zmq.REP)
+        self.soc.bind("".join(['tcp://*:',str(self.port)]))
+    
+    def listen(self):
+        if self.state == SEND:
+            print "WAR: Microdrop Connection state invalid, resetting..."
+            self.reset()
+            self.__init__(self.port)
+        try:
+            message = self.soc.recv(flags=zmq.NOBLOCK, copy=True)
+            self.state = SEND
+            return (True, message)
+        except zmq.Again:
+            return (False, "")
+
+    def reply(self, data):
+        if self.state == RECV:
+            print "WAR: Microdrop Connection state invalid, resetting..."
+            self.reset()
+            self.__init__(self.port)
+            return False
+        self.state = RECV
+        self.soc.send(data)
+        return True
+        
+    def reset(self):
+        self.soc.unbind("".join(['tcp://*:',str(self.port)]))
+        del self.soc
+        del self.ctx