コード例 #1
0
    def __init__(self, name, pumpname, max, isSerial, **kwargs):
        super(Worker, self).__init__()

        # Store constructor arguments (re-used for processing)
        self.name = name
        self.max = max
        self.isPaused = False
        self.pumpname = pumpname

        self.resultsvector = []
        self.changevector = []
        self.isSerial = isSerial
        self.kwargs = kwargs
        self.signals = WorkerSignals()
        self.running = True
        if (self.isSerial == True):
            try:
                self.pumpPort = serial.Serial(port=self.pumpname,
                                              baudrate=4800,
                                              bytesize=serial.SEVENBITS,
                                              parity=serial.PARITY_ODD,
                                              timeout=1)
            except:
                self.pumpPort.close()
                self.pumpPort = serial.Serial(port=self.pumpname,
                                              baudrate=4800,
                                              bytesize=serial.SEVENBITS,
                                              parity=serial.PARITY_ODD,
                                              timeout=1)

        self.scalePort = MettlerToledoDevice(port=self.name)
コード例 #2
0
class ScaleThread(QThread):
    def __init__(self, portName):
        QThread.__init__(self)
        self.portName = portName
        self.txq = queue.queue()
        self.running = True

    def ser_out(self, s):
        self.txq.put(s)

    def ser_in(self, s):
        display(s)

    def run(self):
        try:
            self.scalePort = MettlerToledoDevice(port=self.portName)
        except:
            self.scalePort = None
        if not self.scalePort:
            print("Serial Port troubs")
            self.running = False
        while (self.running):
            s = self.scalePort.get_weight()
            if s:
                num = s[0]
                numstr = int.Parse(num)
                self.ser_in(numstr)
            if not self.txq.empty():
                txd = str(self.txq.get())
                self.ser_out(txd)
            if self.scalePort:
                self.scalePort.close()
                self.scalePort = None
コード例 #3
0
    def __init__(self, name, max, **kwargs):
        super(Worker, self).__init__()

        # Store constructor arguments (re-used for processing)
        self.name = name
        self.max = max
        self.kwargs = kwargs
        self.signals = WorkerSignals()
        self.running = True
        self.isPaused = False

        self.scalePort = MettlerToledoDevice(port=self.name)
コード例 #4
0
 def run(self):
     try:
         self.scalePort = MettlerToledoDevice(port=self.portName)
     except:
         self.scalePort = None
     if not self.scalePort:
         print("Serial Port troubs")
         self.running = False
     while (self.running):
         s = self.scalePort.get_weight()
         if s:
             num = s[0]
             numstr = int.Parse(num)
             self.ser_in(numstr)
         if not self.txq.empty():
             txd = str(self.txq.get())
             self.ser_out(txd)
         if self.scalePort:
             self.scalePort.close()
             self.scalePort = None
コード例 #5
0
    def __init__(self, name, pumpname, max, isSerial, **kwargs):
        super(Worker, self).__init__()

        # Store constructor arguments (re-used for processing)
        self.name = name
        self.max = max
        self.pumpname = pumpname
        self.isSerial = isSerial
        self.kwargs = kwargs
        self.signals = WorkerSignals()
        self.running = True

        self.txq = queue.Queue()

        self.scalePort = MettlerToledoDevice(port=self.name)
        if (self.isSerial == True):
            try:
                self.pumpPort = MasterflexSerial(self.pumpname, self.pumpPort)
            except:
                self.pumpPort.close()
コード例 #6
0
ファイル: dispense_volumes.py プロジェクト: janelia-idf/elf
    def __init__(self,
                 config_file_path,
                 calibration_file_path,
                 *args,**kwargs):
        if 'debug' in kwargs:
            self._debug = kwargs['debug']
        else:
            kwargs.update({'debug': DEBUG})
            self._debug = DEBUG
        with open(config_file_path,'r') as config_stream:
            self._config = yaml.load(config_stream)
        with open(calibration_file_path,'r') as calibration_stream:
            self._calibration = yaml.load(calibration_stream)
        self._valves = self._config['head']
        self._valves.update(self._config['manifold'])
        ports = find_serial_device_ports(debug=self._debug)
        self._debug_print('Found serial devices on ports ' + str(ports))
        self._debug_print('Identifying connected devices (may take some time)...')
        self._balance = MettlerToledoDevice()
        ports.remove(self._balance.get_port())
        # try:
        #     self._bsc = BioshakeDevice()
        # except RuntimeError:
        #     # try one more time
        #     self._bsc = BioshakeDevice()
        # self._debug_print('Found bioshake device on port ' + str(self._bsc.get_port()))
        # ports.remove(self._bsc.get_port())
        # self._SHAKE_SPEED_MIN = self._bsc.get_shake_speed_min()
        # self._SHAKE_SPEED_MAX = self._bsc.get_shake_speed_max()
        # self._SHAKE_DURATION_MIN = 10
        # self._SHAKE_ATTEMPTS = 2
        # self._POST_SHAKE_OFF_DURATION = 5
        modular_devices = ModularDevices(try_ports=ports)

        try:
            msc_dict = modular_devices['mixed_signal_controller']
        except KeyError:
            raise HybridizerError('Could not find mixed_signal_controller. Check connections and permissions.')
        if len(msc_dict) > 1:
            raise HybridizerError('More than one mixed_signal_controller found. Only one should be connected.')
        self._msc = msc_dict[msc_dict.keys()[0]]
        self._debug_print('Found mixed_signal_controller on port ' + str(self._msc.get_port()))

        # self._adc_values_min = None
        # self._adc_values_max = None
        self._adc_sample_count = 21
        self._fill_duration_all_cylinders = 250
        self._fill_duration_one_cylinder = 100
        self._volume_crossover = 6
        self._volume_threshold_initial = 1.0
コード例 #7
0
ファイル: Connection.py プロジェクト: MValle21/DeviceControl
class Connection:
    def __init__(self, address, device_id):
        self.address = address
        self.device_id = device_id
        self.dev = MettlerToledoDevice(port=self.address)

    def get_weight(self):
        weight = self.dev.get_weight()
        return {
            'value': weight[0],
            'unit': weight[1],
            'stable': True if weight[2] is 'S' else False
        }

    def get_info(self):
        data = self.dev.get_balance_data()
        sn = self.dev.get_serial_number()
        sw = self.dev.get_software_version()
        if len(data) > 3:
            info = {
                'model': data[0],
                'model-type': data[1],
                'sn': sn,
                'sw-version': sw[0],
                'sw-type': sw[1],
                'capacity': data[1],
                'unit': data[2]
            }
        else:
            info = {
                'model': data[0],
                'sn': sn,
                'sw-version': sw[0],
                'sw-type': sw[1],
                'capacity': data[1],
                'unit': data[2]
            }
        return info

    def get_address(self):
        return self.dev.get_port()

    def close(self):
        self.dev.close()
コード例 #8
0
class Worker(QObject):
    '''
    Worker thread

    Inherits from QRunnable to handler worker thread setup, signals and wrap-up.

    :param callback: The function callback to run on this worker thread. Supplied args and 
                     kwargs will be passed through to the runner.
    :type callback: function
    :param args: Arguments to pass to the callback function
    :param kwargs: Keywords to pass to the callback function

    '''
    def __init__(self, name, max, **kwargs):
        super(Worker, self).__init__()

        # Store constructor arguments (re-used for processing)
        self.name = name
        self.max = max
        self.kwargs = kwargs
        self.signals = WorkerSignals()
        self.running = True
        self.isPaused = False

        self.scalePort = MettlerToledoDevice(port=self.name)

        # Add the callback to our kwargs
    def stop(self):
        self.event

    @Slot()
    def pause(self):
        self.isPaused = True

    @Slot()
    def resume(self):
        self.isPaused = False

    def cancel(self):
        self.scalePort.close()
        self.running = False

    def factor_conversion(self):
        if 0 < self.maxed < 5001:
            factor = 0.9
        elif 5001 <= self.max < 20001:
            factor = 0.99
        elif 20001 <= self.max:
            factor = 0.999
        return factor

    @Slot()
    def run(self):
        resultcounter = 0
        resultarray = npy.array([])
        deltaarray = npy.array([])
        changecounter = 0
        while (self.running):
            while self.isPaused() == True:
                time.wait(0)
            try:

                s = self.scalePort.get_weight()
                if s:
                    resultcounter += 1

                    num = s[0]
                    inum = int(num)
                    result = str(num)
                    if resultcounter >= 5:
                        resultarray.append(result)
                        resultcounter = 0
                        changecounter += 1
                        p
                        if changecounter >= 5:
                            deltaarray.append(resultarray[len(resultarray) -
                                                          1] - resultarray[-1])
                            changecounter = 0
                            if deltaarray[len(deltaarray) -
                                          1] - deltaarray[-1] <= 50:
                                self.cancel()

                    if len(resultarray) > 10:
                        if len(resultarray) < 25:
                            if sum(resultarray) / len(resultarray) <= 100:
                                self.cancel()

                    self.signals.result.emit(result)
                    self.signals.progress.emit(
                        100 * inum / int(0.9 * self.factor_conversion()))
                    if (inum > int(self.factor_conversion())):
                        self.cancel()
                        break

                if self.scalePort is None:
                    self.cancel()
                    break
            except:
                self.cancel()
                break
        # Return the result of the processin
        # Done
        if (self.running == False):
            self.signals.finished.emit()
コード例 #9
0
              end='')
        sys.stdout.flush()
        time.sleep(drop_wait_s)
        print('done')

        robot.moveXY(pump_xy_approach[-1])
        #zvial_travel = robot.z2_to_worksurface - 2 * vial_grip_height - 3
        # (to simplify things for now)
        zvial_travel = 0
        robot.moveZ2(zvial_travel)
        for xy in pump_xy_approach[:-1][::-1]:
            robot.moveXY(xy)

    if weigh_aliquots:
        from mettler_toledo_device import MettlerToledoDevice
        scale = MettlerToledoDevice(port='/dev/ttyUSB2')

        # TODO some scale command to automate this? setting to make it not
        # sleep?
        print('Tap the scale to wake it up, if it is not already.')
        #
        zeroed = False
        # TODO this doesn't seem to work if we can't wake the scale...
        print('Waiting for stable weight to zero... ', end='')
        sys.stdout.flush()
        while not zeroed:
            zeroed = scale.zero_stable()
        print('done')

        scale_xy = (632, 2)
        # 23 would stick sometimes
コード例 #10
0
class Worker(QRunnable):
    '''
    Worker thread
    Inherits from QRunnable to handler worker thread setup, signals and wrap-up.
    :param callback: The function callback to run on this worker thread. Supplied args and 
                     kwargs will be passed through to the runner.
    :type callback: function
    :param args: Arguments to pass to the callback function
    :param kwargs: Keywords to pass to the callback function
    '''
    def __init__(self, name, pumpname, max, isSerial, **kwargs):
        super(Worker, self).__init__()

        # Store constructor arguments (re-used for processing)
        self.name = name
        self.max = max
        self.isPaused = False
        self.pumpname = pumpname

        self.resultsvector = []
        self.changevector = []
        self.isSerial = isSerial
        self.kwargs = kwargs
        self.signals = WorkerSignals()
        self.running = True
        if (self.isSerial == True):
            try:
                self.pumpPort = serial.Serial(port=self.pumpname,
                                              baudrate=4800,
                                              bytesize=serial.SEVENBITS,
                                              parity=serial.PARITY_ODD,
                                              timeout=1)
            except:
                self.pumpPort.close()
                self.pumpPort = serial.Serial(port=self.pumpname,
                                              baudrate=4800,
                                              bytesize=serial.SEVENBITS,
                                              parity=serial.PARITY_ODD,
                                              timeout=1)

        self.scalePort = MettlerToledoDevice(port=self.name)

        # Add the callback to our kwargs
    def stop(self):
        self.event

    def pause(self):
        self.isPaused = True

    def resume(self):
        self.isPaused = False

    def cancel(self):
        if (self.isSerial == True):
            try:
                self.scalePort.close()
                self.running = False
                self.resultsvector = []
                self.changevector = []
                self.pumpPort.close()
            except:
                self.scalePort = None
                self.pumpPort = None
        else:

            #self.signals.pumpStop.emit()
            self.scalePort.close()
            self.running = False

    def factor_conversion(self):
        if 0 < self.max < 5001:
            factor = 0.9
        elif 5001 <= self.max < 20001:
            factor = 0.99
        elif 20001 <= self.max:
            factor = 0.999
        return factor

    def convertToVoltage(self, rpm):
        volt = self.rpm * 0.016

    @Slot()
    def run(self):
        if (self.isSerial == True):
            if (self.pumpPort):
                self.pumpPort.close()

        while (self.running):
            while self.isPaused:
                time.sleep(0)

            try:

                s = self.scalePort.get_weight()
                if s:
                    num = s[0]
                    inum = int(num)
                    result = str(num)
                    changes = []
                    self.resultsvector.append(int(inum))
                    self.signals.result.emit(result)
                    self.signals.progress.emit(100 * inum /
                                               int(0.97 * self.max))

                    if (len(self.resultsvector) > 5):
                        if (self.resultsvector[-1] != self.resultsvector[-2]):

                            change = float(self.resultsvector[-1]) - float(
                                self.resultsvector[-2])
                            self.changevector.append(float(change))

                        if (len(self.changevector) > 5):
                            avg = sum(self.changevector) / len(
                                self.changevector)
                            if ((self.changevector[-1]) / avg < 0.1):
                                self.signals.result.emit(
                                    "Air in the line or still clamped")
                                self.signals.error.emit((str(
                                    self.changevector[-1]
                                ), "Rate of change has fallen to low, check line"
                                                         ))
                                self.cancel()
                                break

                    if (inum > int(0.999 * self.max)):
                        self.cancel()
                        break

                if self.scalePort is None:
                    self.cancel()
                    break
            except:

                self.cancel()
                break

        # Return the result of the processin
        # Done
        if (self.running == False):
            self.signals.finished.emit()
コード例 #11
0
ファイル: Connection.py プロジェクト: MValle21/DeviceControl
 def __init__(self, address, device_id):
     self.address = address
     self.device_id = device_id
     self.dev = MettlerToledoDevice(port=self.address)
コード例 #12
0
import io
import random
import picamera
import datetime as dt
from time import gmtime, strftime
import csv
from mettler_toledo_device import MettlerToledoDevice
dev = MettlerToledoDevice() # Might automatically find device if one available
# if it is not found automatically, specify port directly
dev = MettlerToledoDevice(port='/dev/ttyACM0') # Linux specific port


filename = dt.datetime.now().strftime('%Y-%m-%d hr%H_min%M_s%S')
filename += '.csv'
saveFile = open(filename, 'w')
#saveFile = open('timedata.csv', 'aw')
writer = csv.writer(saveFile)

# Main #
# get current weight
print('program started')
weight, units, stability = dev.get_weight()
currWeight = weight
# start picamera
camera = picamera.PiCamera()
stream = picamera.PiCameraCircularIO(camera, seconds=10)
camera.start_recording(stream, format='h264')
try:
    while True:
        print('waiting')
        # # Annotate camera
コード例 #13
0
class Worker(QRunnable):
    '''
    Worker thread

    Inherits from QRunnable to handler worker thread setup, signals and wrap-up.

    :param callback: The function callback to run on this worker thread. Supplied args and 
                     kwargs will be passed through to the runner.
    :type callback: function
    :param args: Arguments to pass to the callback function
    :param kwargs: Keywords to pass to the callback function

    '''
    def __init__(self, name, pumpname, max, **kwargs):
        super(Worker, self).__init__()

        # Store constructor arguments (re-used for processing)
        self.name = name
        self.max = max
        self.pumpname = pumpname
        self.kwargs = kwargs
        self.signals = WorkerSignals()
        self.running = True
        self.resultsvector = []
        self.changevector = []
        self.txq = queue.Queue()
        self.scalePort = MettlerToledoDevice(port=self.name)

        try:
            self.pumpPort = serial.Serial(port=self.pumpname,
                                          baudrate=4800,
                                          bytesize=serial.SEVENBITS,
                                          parity=serial.PARITY_ODD,
                                          timeout=1)
        except:
            self.pumpPort.close()
            self.pumpPort = serial.Serial(port=self.pumpname,
                                          baudrate=4800,
                                          bytesize=serial.SEVENBITS,
                                          parity=serial.PARITY_ODD,
                                          timeout=1)

        # Add the callba   ck to our kwargs
    def stop(self):
        self.event

    def cancel(self):
        try:

            self.scalePort.close()
            self.running = False
            self.pumpPort.close()
            self.resultsvector = []
            self.changevector = []
        except:
            self.scalePort = None
            self.pumpPort = None

    @Slot()
    def run(self):

        if (self.pumpPort):
            self.pumpPort.close()
        while (self.running):
            try:

                s = self.scalePort.get_weight()
                if s:
                    num = s[0]
                    inum = int(num)
                    result = str(num)
                    changes = []
                    self.resultsvector.append(int(inum))
                    self.signals.result.emit(result)
                    self.signals.progress.emit(100 * inum /
                                               int(0.97 * self.max))
                    if (len(self.resultsvector) > 2):
                        if (self.resultsvector[-1] != self.resultsvector[-2]):

                            change = float(self.resultsvector[-1]) - float(
                                self.resultsvector[-2])
                            self.changevector.append(float(change))
                    if (len(self.changevector) > 5):
                        avg = sum(self.changevector) / len(self.changevector)
                        if (avg > 0 and (self.changevector[-1]) / avg < 0.1):
                            self.signals.result.emit(
                                "Air in the line or still clamped")
                            self.signals.error.emit(
                                (str(self.changevector[-1]),
                                 "Rate of change has fallen to low, check line"
                                 ))
                            self.cancel()
                            break
                        elif (avg == 0 and len(self.changevector) < 2):
                            self.signals.result.emit(
                                "Air in the line or still clamped")
                            self.signals.error.emit(
                                (str(self.changevector[-1]),
                                 "Rate of change has fallen to low, check line"
                                 ))
                            self.cancel()
                            break

                    if (inum > int(0.99 * self.max)):
                        self.cancel()
                        break

                if self.scalePort is None:
                    self.cancel()
                    break
            except:
                traceback.print_exc()
                exctype, value = sys.exc_info()[:2]
                self.signals.error.emit(
                    (exctype, value, traceback.format_exc()))
                self.cancel()
                break

        # Return the result of the processin
        # Done
        if (self.running == False):
            self.signals.finished.emit()
コード例 #14
0
from mettler_toledo_device import MettlerToledoDevice
dev = MettlerToledoDevice()  # Might automatically find device if one available
# if it is not found automatically, specify port directly
dev = MettlerToledoDevice(port='/dev/ttyACM0')  # Linux specific port
#dev = MettlerToledoDevice(port='/dev/tty.usbmodem262471') # Mac OS X specific port
#dev = MettlerToledoDevice(port='COM3') # Windows specific port
dev.get_serial_number()
#1126493049
dev.get_balance_data()
#['XS204', 'Excellence', '220.0090', 'g']
dev.get_weight_stable()
#[-0.0082, 'g'] #if weight is stable
#None  #if weight is dynamic
dev.get_weight()
#[-0.6800, 'g', 'S'] #if weight is stable
#[-0.6800, 'g', 'D'] #if weight is dynamic
dev.zero_stable()
#True  #zeros if weight is stable
#False  #does not zero if weight is not stable
dev.zero()
#'S'   #zeros if weight is stable
#'D'   #zeros if weight is dynamic
コード例 #15
0
ファイル: dispense_volumes.py プロジェクト: janelia-idf/elf
class Hybridizer(object):
    '''
    This Python package (hybridizer) creates a class named Hybridizer to
    communcate with and control the Janelia Hybridizer. The hybridizer
    uses two hardware control devices, the mixed_signal_controller
    modular_device, and the bioshake_device. The
    mixed_signal_controller both switches the valves and reads the
    analog signals from the cylinder hall effect sensors. The
    bioshake_device controls the heater/shaker.
    Example Usage:

    hyb = Hybridizer('example_config.yaml')
    hyb.run_protocol()
    '''

    # def __init__(self,
    #              config_file_path,
    #              *args,**kwargs):
    def __init__(self,
                 config_file_path,
                 calibration_file_path,
                 *args,**kwargs):
        if 'debug' in kwargs:
            self._debug = kwargs['debug']
        else:
            kwargs.update({'debug': DEBUG})
            self._debug = DEBUG
        with open(config_file_path,'r') as config_stream:
            self._config = yaml.load(config_stream)
        with open(calibration_file_path,'r') as calibration_stream:
            self._calibration = yaml.load(calibration_stream)
        self._valves = self._config['head']
        self._valves.update(self._config['manifold'])
        ports = find_serial_device_ports(debug=self._debug)
        self._debug_print('Found serial devices on ports ' + str(ports))
        self._debug_print('Identifying connected devices (may take some time)...')
        self._balance = MettlerToledoDevice()
        ports.remove(self._balance.get_port())
        # try:
        #     self._bsc = BioshakeDevice()
        # except RuntimeError:
        #     # try one more time
        #     self._bsc = BioshakeDevice()
        # self._debug_print('Found bioshake device on port ' + str(self._bsc.get_port()))
        # ports.remove(self._bsc.get_port())
        # self._SHAKE_SPEED_MIN = self._bsc.get_shake_speed_min()
        # self._SHAKE_SPEED_MAX = self._bsc.get_shake_speed_max()
        # self._SHAKE_DURATION_MIN = 10
        # self._SHAKE_ATTEMPTS = 2
        # self._POST_SHAKE_OFF_DURATION = 5
        modular_devices = ModularDevices(try_ports=ports)

        try:
            msc_dict = modular_devices['mixed_signal_controller']
        except KeyError:
            raise HybridizerError('Could not find mixed_signal_controller. Check connections and permissions.')
        if len(msc_dict) > 1:
            raise HybridizerError('More than one mixed_signal_controller found. Only one should be connected.')
        self._msc = msc_dict[msc_dict.keys()[0]]
        self._debug_print('Found mixed_signal_controller on port ' + str(self._msc.get_port()))

        # self._adc_values_min = None
        # self._adc_values_max = None
        self._adc_sample_count = 21
        self._fill_duration_all_cylinders = 250
        self._fill_duration_one_cylinder = 100
        self._volume_crossover = 6
        self._volume_threshold_initial = 1.0

    def prime_system(self):
        self._setup()
        self._debug_print('priming system...')
        manifold = self._config['manifold']
        chemicals = manifold.keys()
        try:
            chemicals.remove('aspirate')
        except ValueError:
            pass
        try:
            chemicals.remove('separate')
        except ValueError:
            pass
        self._set_valves_on(['separate','aspirate'])
        for chemical in chemicals:
            self._prime_chemical(chemical,self._config['system_prime_count'])
        self._set_all_valves_off()
        self._debug_print('priming finished!')

    def run_protocol(self):
        self._setup()
        self.protocol_start_time = time.time()
        self._debug_print('running protocol...')
        self._set_valves_on(['separate','aspirate'])
        for chemical_info in self._config['protocol']:
            chemical = chemical_info['chemical']
            try:
                prime_count = chemical_info['prime_count']
            except KeyError:
                prime_count = 1
            try:
                dispense_count = chemical_info['dispense_count']
            except KeyError:
                dispense_count = 1
            try:
                shake_speed = chemical_info['shake_speed']
            except KeyError:
                shake_speed = None
            try:
                shake_duration = chemical_info['shake_duration']
            except KeyError:
                shake_duration = None
            try:
                post_shake_duration = chemical_info['post_shake_duration']
            except KeyError:
                post_shake_duration = 0
            try:
                separate = chemical_info['separate']
            except KeyError:
                separate = False
            try:
                aspirate = chemical_info['aspirate']
            except KeyError:
                aspirate = True
            try:
                temperature = chemical_info['temperature']
            except KeyError:
                temperature = None
            try:
                repeat = chemical_info['repeat']
            except KeyError:
                repeat = 0
            self._run_chemical(chemical,
                               prime_count,
                               dispense_count,
                               shake_speed,
                               shake_duration,
                               post_shake_duration,
                               separate,
                               aspirate,
                               temperature,
                               repeat)
        self._set_all_valves_off()
        self.protocol_end_time = time.time()
        protocol_run_time = self.protocol_end_time - self.protocol_start_time
        self._debug_print('protocol finished! it took ' + str(round(protocol_run_time/60)) + ' mins to run.')

    def _setup(self):
        # self._bsc.reset_device()
        self._msc.remove_all_set_fors()
        self._set_all_valves_off()
        self._set_valves_on(['primer','quad1','quad2','quad3','quad4','quad5','quad6'])
        self._debug_print('setting up for ' + str(self._config['setup_duration']) + 's...')
        time.sleep(self._config['setup_duration'])
        self._set_all_valves_off()
        self._debug_print('setup finished!')

    def _prime_chemical(self,chemical,prime_count):
        if prime_count > 0:
            self._set_valve_on(chemical)
        for i in range(prime_count):
            self._set_valves_on(['primer','system'])
            self._debug_print('priming ' + chemical + ' for ' + str(self._config['prime_duration']) + 's ' + str(i+1) + '/' + str(prime_count) + '...')
            time.sleep(self._config['prime_duration'])
            self._set_valves_off(['system'])
            self._debug_print('emptying ' + chemical + ' for ' + str(self._config['prime_aspirate_duration']) + 's ' + str(i+1) + '/' + str(prime_count) + '...')
            time.sleep(self._config['prime_aspirate_duration'])
            self._set_valve_off('primer')
        if prime_count > 0:
            self._set_valve_off(chemical)

    def _run_chemical(self,
                      chemical,
                      prime_count=1,
                      dispense_count=1,
                      shake_speed=None,
                      shake_duration=None,
                      post_shake_duration=0,
                      separate=False,
                      aspirate=True,
                      temp_target=None,
                      repeat=0):
        if (chemical not in self._valves):
            raise HybridizerError(chemical + ' is not listed as part of the manifold in the config file!')
        if repeat < 0:
            repeat = 0
        run_count = repeat + 1
        if temp_target is not None:
            self._debug_print('turning on temperature control for ' + chemical + '...')
            self._bsc.temp_on(temp_target)
            temp_actual = self._bsc.get_temp_actual()
            self._debug_print('actual temperature: ' + str(temp_actual) + ',target temperature: ' + str(temp_target))
            while abs(temp_target - temp_actual) > 0.5:
                time.sleep(1)
                temp_actual = self._bsc.get_temp_actual()
                self._debug_print('actual temperature: ' + str(temp_actual) + ',target temperature: ' + str(temp_target))
            self._debug_print()
        self._prime_chemical(chemical,prime_count)
        for run in range(run_count):
            self._debug_print('running ' + chemical + ' ' + str(run+1) + '/' + str(run_count) + '...')
            self._set_valve_on(chemical)
            self._set_valves_on(['quad1','quad2','quad3','quad4','quad5','quad6','aspirate'])
            for i in range(dispense_count):
                if i > 0:
                    dispense_shake_duration = self._config['inter_dispense_shake_duration']
                    if dispense_shake_duration < self._SHAKE_DURATION_MIN:
                        dispense_shake_duration = self._SHAKE_DURATION_MIN
                    dispense_shake_speed = self._shake_on(self._config['inter_dispense_shake_speed'])
                    self._debug_print('shaking at ' + str(dispense_shake_speed) + 'rpm for ' + str(dispense_shake_duration) + 's...')
                    time.sleep(dispense_shake_duration)
                    self._shake_off(dispense_shake_speed)
                self._set_valve_on('system')
                self._debug_print('loading ' + chemical + ' into syringes for ' + str(self._config['load_duration']) + 's ' + str(i+1) + '/' + str(dispense_count) + '...')
                time.sleep(self._config['load_duration'])
                self._set_valve_off('system')
                self._debug_print('dispensing ' + chemical + ' into microplate for ' + str(self._config['dispense_duration']) + 's ' + str(i+1) + '/' + str(dispense_count) + '...')
                time.sleep(self._config['dispense_duration'])
            self._set_valves_off(['quad1','quad2','quad3','quad4','quad5','quad6'])
            if not ((shake_duration is None) or (shake_duration <= 0)):
                actual_shake_duration = shake_duration
                if shake_duration < self._SHAKE_DURATION_MIN:
                    actual_shake_duration = self._SHAKE_DURATION_MIN
                actual_shake_speed = self._shake_on(shake_speed)
                self._debug_print('shaking at ' + str(actual_shake_speed) + 'rpm for ' + str(actual_shake_duration) + 's...')
                time.sleep(actual_shake_duration)
                self._shake_off(actual_shake_speed)
            if (post_shake_duration > 0):
                self._debug_print('waiting post shake for ' + str(post_shake_duration) + 's...')
                time.sleep(post_shake_duration)
            if separate:
                separate_shake_speed = self._shake_on(self._config['separate_shake_speed'])
                self._set_valve_off('separate')
                self._debug_print('separating ' + chemical + ' for ' + str(self._config['chemical_separate_duration']) + 's...')
                time.sleep(self._config['chemical_separate_duration'])
                self._set_valve_on('separate')
                self._shake_off(separate_shake_speed)
            if aspirate:
                aspirate_shake_speed = self._shake_on(self._config['aspirate_shake_speed'])
                self._set_valve_off('aspirate')
                self._debug_print('aspirating ' + chemical + ' from microplate for ' + str(self._config['chemical_aspirate_duration']) + 's...')
                time.sleep(self._config['chemical_aspirate_duration'])
                self._set_valve_on('aspirate')
                self._shake_off(aspirate_shake_speed)
            self._set_valve_off(chemical)
            self._debug_print(chemical + ' finished!')
            self._debug_print()
        if temp_target is not None:
            self._debug_print('turning off temperature control for ' + chemical + '...')
            try:
                self._bsc.temp_off()
            except BioshakeError:
                pass
            self._debug_print()

    def _shake_on(self,shake_speed):
        if (shake_speed is None) or (shake_speed < self._SHAKE_SPEED_MIN):
            shake_speed = 0
        elif shake_speed > self._SHAKE_SPEED_MAX:
            shake_speed = self._SHAKE_SPEED_MAX
        if shake_speed != 0:
            shook = False
            shake_try = 0
            while (not shook) and (shake_try < self._SHAKE_ATTEMPTS):
                shake_try += 1
                try:
                    self._bsc.shake_on(shake_speed)
                    shook = True
                except BioshakeError:
                    self._debug_print('bioshake_device.get_error_list(): ' + str(self._bsc.get_error_list()))
                    self._debug_print('BioshakeError! Resetting for ' + str(self._config['setup_duration']) + 's and trying again...')
                    self._bsc.reset_device()
                    time.sleep(self._config['setup_duration'])
        return shake_speed

    def _shake_off(self,shake_speed):
        if shake_speed != 0:
            shook = False
            shake_try = 0
            while (not shook) and (shake_try < self._SHAKE_ATTEMPTS):
                shake_try += 1
                try:
                    self._bsc.shake_off()
                    shook = True
                except BioshakeError:
                    self._debug_print('bioshake_device.get_error_list(): ' + str(self._bsc.get_error_list()))
                    self._debug_print('BioshakeError! Resetting for ' + str(self._config['setup_duration']) + 's and trying again...')
                    self._bsc.reset_device()
                    time.sleep(self._config['setup_duration'])
            time.sleep(self._POST_SHAKE_OFF_DURATION)

    def _debug_print(self,*args):
        if self._debug:
            print(*args)

    def _set_valve_on(self,valve_key):
        try:
            valve = self._valves[valve_key]
            channels = [valve['channel']]
            self._msc.set_channels_on(channels)
        except KeyError:
            raise HybridizerError('Unknown valve: ' + str(valve_key) + '. Check yaml config file for errors.')

    def _set_valves_on(self,valve_keys):
        try:
            channels = [self._valves[valve_key]['channel'] for valve_key in valve_keys]
            self._msc.set_channels_on(channels)
        except KeyError:
            raise HybridizerError('Unknown valve: ' + str(valve_key) + '. Check yaml config file for errors.')

    def _set_valve_off(self,valve_key):
        try:
            valve = self._valves[valve_key]
            channels = [valve['channel']]
            self._msc.set_channels_off(channels)
        except KeyError:
            raise HybridizerError('Unknown valve: ' + str(valve_key) + '. Check yaml config file for errors.')

    def _set_valves_off(self,valve_keys):
        try:
            channels = [self._valves[valve_key]['channel'] for valve_key in valve_keys]
            self._msc.set_channels_off(channels)
        except KeyError:
            raise HybridizerError('Unknown valve: ' + str(valve_key) + '. Check yaml config file for errors.')

    def _set_all_valves_off(self):
        valve_keys = self._get_valves()
        self._set_valves_off(valve_keys)

    def _get_valves(self):
        valve_keys = self._valves.keys()
        valve_keys.sort()
        return valve_keys

    def _get_adc_values_filtered(self):
        adc_values = None
        for sample_n in range(self._adc_sample_count):
            sample_values = self._msc.get_analog_inputs_filtered()
            if adc_values is None:
                adc_values = numpy.array([sample_values],int)
            else:
                adc_values = numpy.append(adc_values,[sample_values],axis=0)
            time.sleep(0.1)
        adc_values_filtered = numpy.median(adc_values,axis=0)
        adc_values_filtered = adc_values_filtered.astype(int)
        return adc_values_filtered

    # def _store_adc_values_min(self):
    #     self._adc_values_min = {}
    #     adc_values_filtered = self._get_adc_values_filtered()
    #     head_valves = self._config['head']
    #     for head_valve in head_valves:
    #         try:
    #             ain = self._config['head'][head_valve]['analog_inputs']['low']
    #             adc_value = adc_values_filtered[ain]
    #             self._adc_values_min[head_valve] = adc_value
    #         except KeyError:
    #             continue
    #     self._debug_print(self._adc_values_min)

    # def _set_valves_on_until(self,valve_keys,volume):
    #     for valve_key in valve_keys:
    #         valve = self._valves[valve_key]
    #         channels = [valve['channel']]
    #         adc_value_goal,ain = self._volume_to_adc_and_ain(valve_key,volume)
    #         set_until_index = self._msc.set_channels_on_until(channels,ain,adc_value_goal)
    #     while not self._msc.are_all_set_untils_complete():
    #         self._debug_print('Waiting...')
    #         time.sleep(1)
    #     self._msc.remove_all_set_untils()
    #     for valve_key in valve_keys:
    #         valve = self._valves[valve_key]
    #         adc_value_goal,ain = self._volume_to_adc_and_ain(valve_key,volume)
    #         adc_value = self._msc.get_analog_input(ain)
    #         volume = self._adc_to_volume_low(valve_key,adc_value)

    def _set_valves_on_until(self,valve_keys,volume):
        channels = []
        adc_value_goals = []
        ains = []
        jumps = {}
        valve_keys_copy = copy.copy(valve_keys)
        for valve_key in valve_keys:
            valve = self._valves[valve_key]
            channels.append(valve['channel'])
            adc_value_goal,ain = self._volume_to_adc_and_ain(valve_key,volume)
            adc_value_goals.append(adc_value_goal)
            ains.append(ain)
            jumps[valve_key] = 0

        volume_goal_initial = volume - self._volume_threshold_initial
        fill_duration_initial_max = 0
        fill_durations_initial = []
        if volume_goal_initial >= self._volume_threshold_initial/2:
            for valve_key in valve_keys:
                fill_duration_initial = self._volume_to_fill_duration(valve_key,volume_goal_initial)
                fill_durations_initial.append(fill_duration_initial)
            fill_duration_initial_min = min(fill_durations_initial)
            self._msc.set_channels_on_for(channels,fill_duration_initial_min)
            while not self._msc.are_all_set_fors_complete():
                self._debug_print('Waiting...')
                time.sleep(0.5 + fill_duration_initial_min/1000)
            self._msc.remove_all_set_fors()

        fill_duration_base = self._fill_duration_one_cylinder
        fill_duration_per_cylinder = (self._fill_duration_all_cylinders - self._fill_duration_one_cylinder)//(len(channels)-1)
        while len(channels) > 0:
            fill_duration = fill_duration_base + fill_duration_per_cylinder*(len(channels)-1)
            self._debug_print("Setting {0} valves on for {1}ms".format(valve_keys_copy,fill_duration))
            self._msc.set_channels_on_for(channels,fill_duration)
            while not self._msc.are_all_set_fors_complete():
                self._debug_print('Waiting...')
                time.sleep(fill_duration/1000)
            self._msc.remove_all_set_fors()
            adc_values_filtered = self._get_adc_values_filtered()
            ains_copy = copy.copy(ains)
            for ain in ains_copy:
                index = ains.index(ain)
                valve_key_copy = valve_keys_copy[index]
                jumps[valve_key_copy] += 1
                if adc_values_filtered[ain] >= adc_value_goals[index]:
                    channels.pop(index)
                    adc_value_goals.pop(index)
                    ains.pop(index)
                    valve_keys_copy.pop(index)
        adc_values_filtered = self._get_adc_values_filtered()
        final_adc_values = []
        jumps_list = []
        for valve_key in valve_keys:
            adc_value_goal,ain = self._volume_to_adc_and_ain(valve_key,volume)
            adc_value = adc_values_filtered[ain]
            final_adc_values.append(adc_value)
            jumps_list.append(jumps[valve_key])
            # volume = self._adc_to_volume_low(valve_key,adc_value)
        return final_adc_values,jumps_list

    # def _volume_to_adc_and_ain(self,valve_key,volume):
    #     valve = self._valves[valve_key]
    #     if volume <= self._config['volume_crossover']:
    #         ain = valve['analog_inputs']['low']
    #     else:
    #         ain = valve['analog_inputs']['low']
    #     if volume > self._config['volume_max']:
    #         raise HybridizerError('Asking for volume greater than the max volume of {0}!'.format(self._config['volume_max']))
    #     if volume <= self._config['volume_crossover']:
    #         poly = Polynomial(self._config['poly_coefficients']['volume_to_adc_low'])
    #         adc_value = int(round(poly(volume)))
    #         adc_value += self._adc_values_min[valve_key]
    #         self._debug_print("valve: {0}, adc_value: {1}, ain: {2}".format(valve_key,adc_value,ain))
    #         return adc_value,ain
    #     else:
    #         return 400,ain

    def _volume_to_adc_and_ain(self,valve_key,volume):
        valve = self._valves[valve_key]
        if volume <= self._volume_crossover:
            ain = valve['analog_inputs']['low']
        else:
            ain = valve['analog_inputs']['high']
        if volume > self._config['volume_max']:
            raise HybridizerError('Asking for volume greater than the max volume of {0}!'.format(self._config['volume_max']))
        if volume <= self._volume_crossover:
            poly = Polynomial(self._calibration[valve_key]['volume_to_adc_low'])
            adc_value = int(round(poly(volume)))
            self._debug_print("valve: {0}, adc_value: {1}, ain: {2}".format(valve_key,adc_value,ain))
            return adc_value,ain
        else:
            poly = Polynomial(self._calibration[valve_key]['volume_to_adc_high'])
            adc_value = int(round(poly(volume)))
            self._debug_print("valve: {0}, adc_value: {1}, ain: {2}".format(valve_key,adc_value,ain))
            return adc_value,ain

    def _volume_to_fill_duration(self,valve_key,volume):
        poly = Polynomial(self._calibration[valve_key]['volume_to_fill_duration'])
        fill_duration = int(round(poly(volume)))
        return fill_duration

    # def _adc_to_volume_low(self,valve_key,adc_value):
    #     valve = self._valves[valve_key]
    #     adc_value -= self._adc_values_min[valve_key]
    #     poly = Polynomial(self._config['poly_coefficients']['adc_to_volume_low'])
    #     volume = poly(adc_value)
    #     self._debug_print("valve: {0}, adc_value: {1}, volume: {2}".format(valve_key,adc_value,volume))
    #     return volume

    def run_dispense_tests(self):
        self._debug_print('pre setup sequence...')
        valves = ['quad1','quad2','quad3','quad4','quad5','quad6']
        self._set_valve_on('aspirate')
        self._set_valve_on('system')
        self._set_valves_on(valves)
        time.sleep(10)
        self._set_valve_off('system')
        time.sleep(10)
        self._set_valve_off('aspirate')
        time.sleep(20)
        self._setup()
        self._set_valve_on('aspirate')
        time.sleep(10)
        # self._debug_print('zeroing hall effect sensors...')
        # self._store_adc_values_min()
        self._debug_print('zeroing balance...')
        self._balance.zero()
        self._debug_print('running dispense tests...')
        timestr = time.strftime("%Y%m%d-%H%M%S")
        data_file = open(timestr+'.csv','w')
        data_writer = csv.writer(data_file)
        header = ['dispense_goal','initial_weight']
        valve_adc = [valve+'_adc' for valve in valves]
        header.extend(valve_adc)
        valve_jumps = [valve+'_jumps' for valve in valves]
        header.extend(valve_jumps)
        header.extend(valves)
        data_writer.writerow(header)
        # dispense_goals = [5,4,3,2,1]
        # dispense_goals = [1,0.75,0.5,0.25]
        dispense_goals = [5,1,0.5]
        # dispense_goals = [2,1]
        # run_count = 10
        run_count = 1
        # dispense_goals = [1]
        # run_count = 2
        for dispense_goal in dispense_goals:
            for run in range(run_count):
                self._set_valve_on('aspirate')
                time.sleep(2)
                self._debug_print('dispense_goal: {0}, run: {1} out of {2}'.format(dispense_goal,run+1,run_count))
                row_data = []
                row_data.append(dispense_goal)
                initial_weight = self._balance.get_weight()[0]
                self._debug_print('initial_weight: {0}'.format(initial_weight))
                row_data.append(initial_weight)
                self._set_valve_on('system')
                time.sleep(2)
                final_adc_values,jumps = self._set_valves_on_until(valves,dispense_goal)
                row_data.extend(final_adc_values)
                row_data.extend(jumps)
                self._set_valve_off('system')
                time.sleep(4)
                weight_prev = initial_weight
                for valve in valves:
                    self._debug_print('Dispensing {0}'.format(valve))
                    self._set_valve_on(valve)
                    time.sleep(4)
                    self._set_valve_off(valve)
                    time.sleep(2)
                    weight_total = self._balance.get_weight()[0]
                    weight = weight_total - weight_prev
                    self._debug_print('{0} measured {1}'.format(valve,weight))
                    row_data.append(weight)
                    weight_prev = weight_total
                self._set_valve_off('aspirate')
                self._debug_print('aspirating...')
                time.sleep(20)
                self._set_all_valves_off()
                data_writer.writerow(row_data)
        data_file.close()

    def run_calibration(self):
        self._debug_print('pre setup sequence...')
        valves = ['quad1','quad2','quad3','quad4','quad5','quad6']
        self._set_valve_on('aspirate')
        self._set_valve_on('system')
        self._set_valves_on(valves)
        time.sleep(10)
        self._set_valve_off('system')
        time.sleep(10)
        self._set_valve_off('aspirate')
        time.sleep(20)
        self._setup()
        self._set_valve_on('aspirate')
        time.sleep(10)
        # self._debug_print('zeroing hall effect sensors...')
        # self._store_adc_values_min()
        self._debug_print('zeroing balance...')
        self._balance.zero()
        self._debug_print('running calibration...')
        timestr = time.strftime("%Y%m%d-%H%M%S")
        data_file = open(timestr+'.csv','w')
        data_writer = csv.writer(data_file)
        header = ['fill_duration','initial_weight']
        valve_adc_low = [valve+'_adc_low' for valve in valves]
        header.extend(valve_adc_low)
        valve_adc_high = [valve+'_adc_high' for valve in valves]
        header.extend(valve_adc_high)
        header.extend(valves)
        data_writer.writerow(header)
        duration_inc = 250
        duration_max = 10000
        fill_durations = range(duration_inc,duration_max+duration_inc,duration_inc)
        run_count = 3
        for run in range(run_count):
            for fill_duration in fill_durations:
                self._set_valve_on('aspirate')
                time.sleep(2)
                self._debug_print('fill_duration: {0}, run: {1} out of {2}'.format(fill_duration,run+1,run_count))
                row_data = []
                row_data.append(fill_duration)
                initial_weight = self._balance.get_weight()[0]
                self._debug_print('initial_weight: {0}'.format(initial_weight))
                row_data.append(initial_weight)
                self._set_valve_on('system')
                time.sleep(2)
                channels = []
                adc_low_ain = []
                adc_high_ain = []
                for valve_key in valves:
                    valve = self._valves[valve_key]
                    channels.append(valve['channel'])
                    adc_low_ain.append(valve['analog_inputs']['low'])
                    adc_high_ain.append(valve['analog_inputs']['high'])
                self._msc.set_channels_on_for(channels,fill_duration)
                while not self._msc.are_all_set_fors_complete():
                    self._debug_print('Waiting...')
                    time.sleep(fill_duration/1000)
                self._msc.remove_all_set_fors()
                adc_values_filtered = self._get_adc_values_filtered()
                adc_low_values = [adc_values_filtered[ain] for ain in adc_low_ain]
                adc_high_values = [adc_values_filtered[ain] for ain in adc_high_ain]
                row_data.extend(adc_low_values)
                row_data.extend(adc_high_values)
                self._set_valve_off('system')
                time.sleep(4)
                weight_prev = initial_weight
                for valve in valves:
                    self._debug_print('Dispensing {0}'.format(valve))
                    self._set_valve_on(valve)
                    time.sleep(4)
                    self._set_valve_off(valve)
                    time.sleep(2)
                    weight_total = self._balance.get_weight()[0]
                    weight = weight_total - weight_prev
                    self._debug_print('{0} measured {1}'.format(valve,weight))
                    row_data.append(weight)
                    weight_prev = weight_total
                self._set_valve_off('aspirate')
                self._debug_print('aspirating...')
                time.sleep(20)
                self._set_all_valves_off()
                data_writer.writerow(row_data)
        data_file.close()
コード例 #16
0
from mettler_toledo_device import MettlerToledoDevice
dev = MettlerToledoDevice()  # Might automatically find device if one available
# if it is not found automatically, specify port directly
#dev = MettlerToledoDevice(port='/dev/ttyUSB0') # Linux specific port
dev = MettlerToledoDevice(
    port='/dev/ttyACM0')  # Linux specific port for abstract control model
dev = MettlerToledoDevice(
    port='/dev/tty.usbmodem262471')  # Mac OS X specific port
#dev = MettlerToledoDevice(port='COM3') # Windows specific port
dev.get_serial_number()
#1126493049
dev.get_balance_data()
#['XS204', 'Excellence', '220.0090', 'g']
dev.get_weight_stable()
#[-0.0082, 'g'] #if weight is stable
#None  #if weight is dynamic
dev.get_weight()
#[-0.6800, 'g', 'S'] #if weight is stable
#[-0.6800, 'g', 'D'] #if weight is dynamic
dev.zero_stable()
#True  #zeros if weight is stable
#False  #does not zero if weight is not stable
dev.zero()
#'S'   #zeros if weight is stable
#'D'   #zeros if weight is dynamic
コード例 #17
0
ファイル: Test.py プロジェクト: emmanuel-contreras/rpi_usb
import serial
from time import gmtime, strftime
import picamera
import datetime as dt
import csv
from mettler_toledo_device import MettlerToledoDevice
dev = MettlerToledoDevice() # Might automatically find device if one available
# if it is not found automatically, specify port directly
dev = MettlerToledoDevice(port='/dev/ttyACM0') # Linux specific port


#ser = serial.Serial('/dev/ttyACM0',9600)
#weightdata = ser.readline()
weightdata = dev.get_weight()
timedata = strftime("%Y-%m-%d %H:%M:%S", gmtime())

file = open('timedata.csv','aw')
writer = csv.writer(file)


# with picamera.PiCamera() as camera:
#   camera.resolution = (640, 480)

#weightdata = ser.readline()
weightdata = dev.get_weight()
timedata = strftime("%Y-%m-%d %H:%M:%S", gmtime())
print(weightdata,timedata)

camera = picamera.PiCamera(resolution=(1280, 720), framerate=24)
camera.start_preview()
camera.annotate_background = picamera.Color('black')
コード例 #18
0
from mettler_toledo_device import MettlerToledoDevice
dev = MettlerToledoDevice() # Might automatically find device if one available
# if it is not found automatically, specify port directly
#dev = MettlerToledoDevice(port='/dev/ttyUSB0') # Linux specific port
dev = MettlerToledoDevice(port='/dev/ttyACM0') # Linux specific port for abstract control model
dev = MettlerToledoDevice(port='/dev/tty.usbmodem262471') # Mac OS X specific port
#dev = MettlerToledoDevice(port='COM3') # Windows specific port
dev.get_serial_number()
#1126493049
dev.get_balance_data()
#['XS204', 'Excellence', '220.0090', 'g']
dev.get_weight_stable()
#[-0.0082, 'g'] #if weight is stable
#None  #if weight is dynamic
dev.get_weight()
#[-0.6800, 'g', 'S'] #if weight is stable
#[-0.6800, 'g', 'D'] #if weight is dynamic
dev.zero_stable()
#True  #zeros if weight is stable
#False  #does not zero if weight is not stable
dev.zero()
#'S'   #zeros if weight is stable
#'D'   #zeros if weight is dynamic
コード例 #19
0
import io
import random
import picamera
import datetime as dt
from time import gmtime, strftime
import csv
from mettler_toledo_device import MettlerToledoDevice
dev = MettlerToledoDevice()  # Might automatically find device if one available
# if it is not found automatically, specify port directly
dev = MettlerToledoDevice(port='/dev/ttyACM0')  # Linux specific port

filename = dt.datetime.now().strftime('%Y-%m-%d hr%H_min%M_s%S')
filename += '.csv'
saveFile = open(filename, 'w')
#saveFile = open('timedata.csv', 'aw')
writer = csv.writer(saveFile)

# Main #
# get current weight
print('program started')
weight, units, stability = dev.get_weight()
currWeight = weight
# start picamera
camera = picamera.PiCamera()
stream = picamera.PiCameraCircularIO(camera, seconds=10)
camera.start_recording(stream, format='h264')
try:
    while True:
        print('waiting')
        # # Annotate camera
        timestamp = dt.datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')