Skip to content
Snippets Groups Projects
Commit a62ee801 authored by Michael DM Dryden's avatar Michael DM Dryden
Browse files

Microdrop interface using zmq. Currently defaults to listening on all interfaces for TCP port 6789.

parent c60cf353
Branches
Tags
No related merge requests found
......@@ -8,6 +8,7 @@
/* Begin PBXFileReference section */
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>"; };
......@@ -23,6 +24,7 @@
5FF00FDC1942BD16004D38A8 /* setup.py */,
5F87883C19072E86007B53E0 /* mpltest.py */,
5FCB541D1905923800CEB148 /* interface_test.py */,
5FB0B8E1198ACD4B00FA6CB7 /* microdrop.py */,
5FCB54231905B6EE00CEB148 /* dstat_comm.py */,
5FCB541B190591CD00CEB148 /* interface */,
5FDC0DFD18FDAD79003F857A /* mpl.py */,
......
......@@ -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>
......
#!/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,6 +78,7 @@ 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')
......@@ -143,6 +146,11 @@ class main:
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()
......@@ -196,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 = {}
......@@ -247,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())
......@@ -292,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())
......@@ -343,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())
......@@ -401,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())
......@@ -457,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:
......@@ -534,7 +550,6 @@ class main:
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:
......@@ -546,6 +561,13 @@ class main:
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)
self.stopbutton.set_sensitive(False)
......@@ -560,7 +582,46 @@ class main:
save_inst = save.manSave(self.current_exp)
def on_file_save_plot_activate(self, menuitem, data=None):
save_inst = save.plotSave(self.plot)
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):
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__":
......
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
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment