diff --git a/dstat-interface/dstat-interface/dstat_comm.py b/dstat-interface/dstat-interface/dstat_comm.py index 0a17f894bd82acd72d83b743622b943a3e397e4a..32f3e8d3aa177eb907793783949ded58275b59b1 100644 --- a/dstat-interface/dstat-interface/dstat_comm.py +++ b/dstat-interface/dstat-interface/dstat_comm.py @@ -22,6 +22,7 @@ from serial.tools import list_ports import time import struct import multiprocessing as mp +from errors import VarError def call_it(instance, name, args=(), kwargs=None): """Indirect caller for instance methods and multiprocessing. @@ -36,6 +37,40 @@ def call_it(instance, name, args=(), kwargs=None): kwargs = {} return getattr(instance, name)(*args, **kwargs) +def version_check(ser_port): + """Tries to contact DStat and get version. Returns a tuple of + (major, minor). If no response, returns empty tuple. + + Arguments: + ser_port -- address of serial port to use + """ + ser = delayedSerial(ser_port, 1024000, timeout=1) + ser.write("ck") + + ser.flushInput() + ser.write('!') + + while not ser.read().startswith("C"): + ser.write('!') + ser.write('V') + for line in ser: + if line.startswith('V'): + input = line.lstrip('V') + elif line.startswith("#"): + print line + elif line.lstrip().startswith("no"): + print line + ser.flushInput() + break + + parted = input.rstrip().split('.') + print parted + + ser.close() + + return (int(parted[0]), int(parted[1])) + + class delayedSerial(serial.Serial): """Extends Serial.write so that characters are output individually @@ -77,7 +112,17 @@ class Experiment(object): self.databytes = 8 self.data_extra = [] # must be defined even when not needed - self.__gaintable = [1e2, 3e2, 3e3, 3e4, 3e5, 3e6, 3e7, 5e8] + + major, minor = self.parameters['version'] + + if major >= 1: + if minor == 1: + self.__gaintable = [1e2, 3e2, 3e3, 3e4, 3e5, 3e6, 3e7, 5e8] + elif minor >= 2: + self.__gaintable = [1, 1e2, 3e3, 3e4, 3e5, 3e6, 3e7, 1e8] + else: + raise VarError(parameters['version'], "Invalid version parameter.") + self.gain = self.__gaintable[int(self.parameters['gain'])] self.commands = ["A", "G"] diff --git a/dstat-interface/dstat-interface/errors.py b/dstat-interface/dstat-interface/errors.py new file mode 100644 index 0000000000000000000000000000000000000000..9661262b9a4836198e9f8bcb2781dfee167e3f53 --- /dev/null +++ b/dstat-interface/dstat-interface/errors.py @@ -0,0 +1,47 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# DStat Interface - An interface for the open hardware DStat potentiostat +# Copyright (C) 2014 Michael D. M. Dryden - +# Wheeler Microfluidics Laboratory <http://microfluidics.utoronto.ca> +# +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +class Error(Exception): + """Copies Exception class""" + pass + +class InputError(Error): + """Exception raised for errors in the input. Extends Error class. + + Attributes: + expr -- input expression in which the error occurred + msg -- error message + """ + + def __init__(self, expr, msg): + self.expr = expr + self.msg = msg + +class VarError(Error): + """Exception raised for internal variable errors. Extends Error class. + + Attributes: + var -- var in which the error occurred + msg -- error message + """ + + def __init__(self, var, msg): + self.var = var + self.msg = msg \ No newline at end of file diff --git a/dstat-interface/dstat-interface/interface/adc_pot.py b/dstat-interface/dstat-interface/interface/adc_pot.py index 715b07a641a359af9924ce9d2bccacf40ca44921..e3888986f6c94e04ccd5b83282e1b26897102070 100644 --- a/dstat-interface/dstat-interface/interface/adc_pot.py +++ b/dstat-interface/dstat-interface/interface/adc_pot.py @@ -1,4 +1,5 @@ #!/usr/bin/env python +# -*- coding: utf-8 -*- # DStat Interface - An interface for the open hardware DStat potentiostat # Copyright (C) 2014 Michael D. M. Dryden - # Wheeler Microfluidics Laboratory <http://microfluidics.utoronto.ca> @@ -19,6 +20,24 @@ import gtk +v1_1_gain = [(0, "100 Ω (15 mA FS)", 0), + (1, "300 Ω (5 mA FS)", 1), + (2, "3 kΩ (500 µA FS)", 2), + (3, "30 kΩ (50 µA FS)", 3), + (4, "300 kΩ (5 µA FS)", 4), + (5, "3 MΩ (500 nA FS)", 5), + (6, "30 MΩ (50 nA FS)", 6), + (7, "500 MΩ (3 nA FS)", 7)] + +v1_2_gain = [(0, "Bypass", 0), + (1, "100 Ω (15 mA FS)", 1), + (2, "3 kΩ (500 µA FS)", 2), + (3, "30 kΩ (50 µA FS)", 3), + (4, "300 kΩ (5 µA FS)", 4), + (5, "3 MΩ (500 nA FS)", 5), + (6, "30 MΩ (50 nA FS)", 6), + (7, "100 MΩ (15 nA FS)", 7)] + class adc_pot: def __init__(self): self.builder = gtk.Builder() @@ -40,6 +59,19 @@ class adc_pot: self.srate_combobox.set_active(7) self.gain_combobox = self.builder.get_object('gain_combobox') + self.gain_liststore = self.builder.get_object('gain_liststore') self.gain_combobox.pack_start(self.cell, True) self.gain_combobox.add_attribute(self.cell, 'text', 1) - self.gain_combobox.set_active(2) \ No newline at end of file + self.gain_combobox.set_active(2) + + def set_version(self, version): + """ Sets menus for DStat version. """ + self.gain_liststore.clear() + if version[0] == 1: + if version[1] == 1: + for i in v1_1_gain: + self.gain_liststore.append(i) + elif version[1] >= 2: + for i in v1_2_gain: + self.gain_liststore.append(i) + \ No newline at end of file diff --git a/dstat-interface/dstat-interface/interface/dstatinterface.glade b/dstat-interface/dstat-interface/interface/dstatinterface.glade index ee27bdf75c9a2817aecf517df73e972da20b33b9..644e4307c141a6ef7ca7953a3fbfd5d18456f328 100644 --- a/dstat-interface/dstat-interface/interface/dstatinterface.glade +++ b/dstat-interface/dstat-interface/interface/dstatinterface.glade @@ -1210,6 +1210,21 @@ Thanks to Christian Fobel for help with Dropbot Plugin</property> <property name="position">2</property> </packing> </child> + <child> + <object class="GtkButton" id="serial_version"> + <property name="label">gtk-connect</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_version_clicked" swapped="no"/> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">3</property> + </packing> + </child> <child> <object class="GtkStatusbar" id="statusbar"> <property name="visible">True</property> @@ -1219,7 +1234,7 @@ Thanks to Christian Fobel for help with Dropbot Plugin</property> <packing> <property name="expand">True</property> <property name="fill">True</property> - <property name="position">3</property> + <property name="position">4</property> </packing> </child> </object> diff --git a/dstat-interface/dstat-interface/main.py b/dstat-interface/dstat-interface/main.py index 434316977b4509d0f735cb27c0fc750fe2075fa8..9425a42a727abbd3c40ea99a070f581719f802bb 100644 --- a/dstat-interface/dstat-interface/main.py +++ b/dstat-interface/dstat-interface/main.py @@ -44,27 +44,12 @@ import interface.exp_window as exp_window import interface.adc_pot as adc_pot import plot import microdrop +from errors import InputError, VarError from serial import SerialException import multiprocessing import time -class Error(Exception): - """Copies Exception class""" - pass - -class InputError(Error): - """Exception raised for errors in the input. Extends Error class. - - Attributes: - expr -- input expression in which the error occurred - msg -- error message - """ - - def __init__(self, expr, msg): - self.expr = expr - self.msg = msg - class Main(object): """Main program """ def __init__(self): @@ -167,6 +152,24 @@ class Main(object): for i in self.serial_devices.ports: self.serial_liststore.append([i]) + + def on_serial_version_clicked(self, data=None): + """Retrieve DStat version.""" + self.version = comm.version_check(self.serial_liststore.get_value( + self.serial_combobox.get_active_iter(), 0)) + + self.statusbar.remove_all(self.error_context_id) + + if not len(self.version) == 2: + self.statusbar.push(self.error_context_id, "Communication Error") + return + + else: + self.adc_pot.set_version(self.version) + self.statusbar.push(self.error_context_id, + "".join(["DStat version: ", str(self.version[0]), + ".", str(self.version[1])]) + ) def on_pot_start_clicked(self, data=None): """Run currently visible experiment.""" @@ -185,6 +188,7 @@ class Main(object): selection = self.expcombobox.get_active() parameters = {} + parameters['version'] = self.version if self.adc_pot.buffer_toggle.get_active(): #True if box checked parameters['adc_buffer'] = "2"