aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--eitControl.py422
-rw-r--r--example_config.ini40
-rw-r--r--funcGenerator.py274
-rw-r--r--labjackStreamTest.py167
-rw-r--r--rfGen.py50
-rw-r--r--test_rfGenLMX2487.py20
-rwxr-xr-xtest_serial.py47
-rwxr-xr-xtest_ue9.py10
-rw-r--r--ue9qol.py76
9 files changed, 0 insertions, 1106 deletions
diff --git a/eitControl.py b/eitControl.py
deleted file mode 100644
index 10832fc..0000000
--- a/eitControl.py
+++ /dev/null
@@ -1,422 +0,0 @@
-from pyqtgraph.Qt import QtGui, QtCore
-import pyqtgraph as pg
-from pyqtgraph.dockarea import *
-import pyqtgraph.exporters
-
-import platform
-import os
-import argparse
-import ast
-
-from threading import Thread
-
-import time # For sleep, clock, time and perf_counter
-from datetime import datetime, timedelta, date
-
-import numpy as np
-import csv
-
-import ue9qol
-from funcGenerator import Sweeper, SinGen, TriangleGen, RampGen, PulseGen, SawGen
-import rfGen
-
-from configparser import ConfigParser, ExtendedInterpolation
-config = ConfigParser(interpolation=ExtendedInterpolation(),
- converters = {'list': lambda x: [i.strip() for i in x.strip().split('\n')]})
-default_config = """
-[RF]
-central_frequency = 6.83468e9
-frequency_span = 100e3
-initial_frequency = 6.834e9
-frequency_export_name = rfFreq
-
-[DAQ]
-# channels to grab and their meaning
-ain0 = transmission
-ain1 = lockin
-ain2 = davll
-ain3 = ain3_undefined
-# commented out channels will not be processed or stored
-# dac0 = dac0_undefined
-# dac1 = dac1_undefined2
-
-[Plot]
-x_axis_data = rfFreq
-
-[Plot_channels_visibility]
-transmission = yes
-lockin = yes
-davll = yes
-
-[Plot_channels_colors]
-# color specification will be evaluated and should match PyQtGraph.mkColor(args)
-# for example
-# (R,G,B,Alpha) tuple: example_trace = (255,0,255,100)
-# or color name: example_trace = 'g'
-transmission = (20,20,20,100)
-lockin = (85,170,255,100)
-davll = (255,0,255,100)
-ain3_undefined = (0,85,255,100)
-
-
-[Save]
-save_prefix = eit
-data_dir = z:\data.VAMPIRE
-
-"""
-
-config.read_string(default_config)
-# additional config
-config.read("config.ini")
-
-
-class Experiment:
-
- def __init__(self, root, config, args):
- self.root = root
- self.config = config
- self.save_cnt = 0
- self.tic = 0
- self.newDataIsReady = False
- self.xlabel=''
- self.channelGraph={}
- self.clearData()
- self.hardware = {}
- self.hardwareSetup(args)
-
- # now we ready to do gui
- self.buttons = {}
- self.guiSweeper = Sweeper(self.root, Npoints=10, SweepTime=1, onTicCallbacks=[self.updatePlot])
- self.guiSetup(root)
- self.guiSweeper.cmdStart()
-
-
- def hardwareSetup(self,args):
- if args.test:
- print("Test mode, run with fake hardware")
- self.sweeper = Sweeper(self.root, Npoints=100, SweepTime=1, onTicCallbacks=[self.onTic])
- self.hardware['LabJack'] = ue9qol.UE9qolDummy(sweeper=self.sweeper)
- self.hardware['rfGen'] = rfGen.rfGenLMX2487Dummy(port='/dev/ttyUSB0', speed=115200, timeout=1)
- else:
- self.sweeper = Sweeper(self.root, Npoints=500, SweepTime=10, onTicCallbacks=[self.onTic])
- self.hardware['LabJack'] = ue9qol.UE9qol()
- if platform.system() == 'Linux':
- rf=rfGen.rfGenLMX2487(port='/dev/ttyUSB0', speed=115200, timeout=1)
- else:
- rf=rfGen.rfGenLMX2487(port='COM5', speed=115200, timeout=1)
- self.hardware['rfGen'] = rf
-
- fCent = self.config['RF'].getfloat('central_frequency', fallback=6.83468e9)
- fSpan = self.config['RF'].getfloat('frequency_span', fallback=100e3)
- rf_f_init = self.config['RF'].getfloat('initial_frequency', fallback=6.834e9)
- self.hardware['rfGen'].setFreq(rf_f_init)
- self.rfGenFunc = SawGen(start=0, stop=0, sweeper = self.sweeper, duty_cycle=0.9)
- self.rfGenFunc.setCenter(fCent)
- self.rfGenFunc.setSpan(fSpan)
-
- self.funcGen = TriangleGen(start=0, stop=5, sweeper = self.sweeper)
-
-
- def centralFreqValueChanged(self, sb):
- v=sb.value()
- self.config['RF']['central_frequency'] = str(v)
- self.rfGenFunc.setCenter(v)
- pass
-
- def freqSpanValueChanged(self, sb):
- v=sb.value()
- self.config['RF']['frequency_span'] = str(v)
- self.rfGenFunc.setSpan(v)
- pass
-
- def guiSetup(self, root):
- self.dockArea = area = DockArea()
- d1 = Dock("Global", size=(5,1))
- d2 = Dock("Data", size=(100,100))
- d3 = Dock("RF Gen", size=(1,2))
- dS = Dock("Status", size=(1,2), autoOrientation=False)
- dS.setOrientation(o='horizontal')
- area.addDock(d1, 'top')
- area.addDock(dS, 'bottom', d1)
- area.addDock(d2, 'bottom', dS)
- area.addDock(d3, 'bottom', d2)
- self.root.addWidget(area)
-
- self.dataPlot = pg.PlotWidget(name='Plot1')
- d2.addWidget(self.dataPlot)
- self.dataPlot.showGrid(x=True, y=True)
- self.dataPlot.addLegend()
- self.vLineSweepPosition = vLine = pg.InfiniteLine(angle=90, movable=False, pen='r')
- self.dataPlot.addItem(vLine, ignoreBounds=True)
-
- # global buttons
- w1 = pg.LayoutWidget()
- bAutoZoom = QtGui.QPushButton('&AutoZoom')
- bAutoZoom.clicked.connect(self.autoZoom)
- self.buttons["AutoZoom"] = bAutoZoom
- bRestart = QtGui.QPushButton('&Restart')
- bRestart.clicked.connect(self.restart)
- self.buttons["Restart"] = bRestart
- bStartStopToggle = QtGui.QPushButton('&Start')
- bStartStopToggle.clicked.connect(self.start)
- self.buttons["StartStopToggle"] = bStartStopToggle
- bSave = QtGui.QPushButton('Sa&ve data')
- bSave.clicked.connect(self.saveCmd)
- self.buttons["Save"] = bSave
- bExit = QtGui.QPushButton('&Exit')
- bExit.clicked.connect(exit)
- self.buttons["Exit"] = bExit
- bSaveConfig = QtGui.QPushButton('Save Con&fig')
- bSaveConfig.clicked.connect(self.saveConfigCmd)
- self.buttons["SaveConfig"] = bSaveConfig
- w1.addWidget(bAutoZoom, row=0, col=0)
- w1.addWidget(bRestart, row=0, col=1)
- w1.addWidget(bStartStopToggle, row=0, col=2)
- w1.addWidget(bSave, row=0, col=3)
- w1.addWidget(bSaveConfig, row=0, col=4)
- w1.addWidget(bExit, row=0, col=5)
- d1.addWidget(w1)
-
- ## status line
- self.statusline = l = QtGui.QLabel("All ok")
- dS.addWidget(l, row=1, col=0)
-
- # RF gen gui
- fCent=self.rfGenFunc.getCenter()
- fSpan=self.rfGenFunc.getSpan()
- spins = [
- ("Central Frequency",
- pg.SpinBox(value=fCent, bounds=[6.83e9, 6.84e9], suffix='Hz', siPrefix=True, step=1e3, decimals=10),
- self.centralFreqValueChanged),
- ("Frequency Span",
- pg.SpinBox(value=fSpan, bounds=[1, 10e6], dec=True, step=0.5, suffix='Hz', siPrefix=True, minStep=1),
- self.freqSpanValueChanged)
- ]
- w3 = pg.LayoutWidget()
- d3.addWidget(w3)
- for text, spin, cb in spins:
- l=QtGui.QLabel(text)
- w3.addWidget(l)
- w3.addWidget(spin)
- spin.sigValueChanged.connect(cb)
-
- def clearData(self):
- self.data = {}
- # RF generator channels
- rf_freq_Name = self.config['RF'].get('frequency_export_name')
- self.data[rf_freq_Name] = []
- # DAQ channels
- for ch in self.config['DAQ']:
- ch_meaning = self.config['DAQ'][ch]
- self.data[ch_meaning] = []
- # special channels
- self.data['tic'] = []
- self.data['x'] = []
-
-
- def stop(self):
- self.sweeper.cmdStop()
- self.buttons["StartStopToggle"].setText("&Continue")
- self.buttons["StartStopToggle"].clicked.disconnect()
- self.buttons["StartStopToggle"].clicked.connect(self.start)
-
- def start(self):
- self.sweeper.cmdStart()
- self.buttons["StartStopToggle"].setText("&Pause")
- self.buttons["StartStopToggle"].clicked.disconnect()
- self.buttons["StartStopToggle"].clicked.connect(self.stop)
-
- def restart(self):
- self.clearData()
- self.sweeper.cmdRestart()
- self.buttons["StartStopToggle"].setText("&Pause")
- self.buttons["StartStopToggle"].clicked.disconnect()
- self.buttons["StartStopToggle"].clicked.connect(self.stop)
-
- def getNewDataFileName(self, ext="csv"):
- data_dir = self.config['Save'].get('data_dir', fallback='unset_data_dir')
- if not os.path.exists(data_dir):
- os.mkdir(data_dir)
- if not os.path.isdir(data_dir):
- print(f"ERROR: cannot create directory for data: {data_dir}")
- print(f"Will use current dir for storage")
- data_dir = "."
-
- prefix = self.config['Save'].get('save_prefix', fallback='unset_experiment_prefix')
- today = date.today()
- datestr = today.strftime("%Y%m%d")
- self.save_cnt += 1
-
- base_name = f"{prefix}_{datestr}_{self.save_cnt:#04}"
- file_name = f"{base_name}.{ext}"
- data_file = os.path.join(data_dir, file_name)
- if os.path.exists(data_file):
- data_file = self.getNewDataFileName(ext=ext)
- return data_file
-
- def saveCmd(self):
- csv_file = self.getNewDataFileName(ext='csv')
- data = self.data
- try:
- with open(csv_file, 'w') as csvfile:
- writer = csv.writer(csvfile)
- writer.writerow(data.keys())
- writer.writerows(zip(*data.values()))
- except IOError:
- print('I/O error')
- msg = f"data saved to {csv_file}"
- print(msg)
- self.statusline.setText(msg)
-
- png_file=csv_file.replace(".csv", ".png")
- print(f"Picture saved to {png_file}")
- plt = self.dataPlot.getPlotItem()
- ex = pg.exporters.ImageExporter(plt)
- if pg.__version__ == '0.10.0':
- # Workaround for PyQtGraph version <= 0.10.0
- # see https://github.com/pyqtgraph/pyqtgraph/issues/538#issuecomment-361405356
- w= int(plt.width())
- h= int(plt.height())
- # the value in setValue need to be different from default
- # otherwise it will not be taken
- ex.parameters().param('width').setValue(w+1, blockSignal=ex.widthChanged)
- ex.parameters().param('height').setValue(h+1, blockSignal=ex.heightChanged)
- # now we set actual value
- # ex.parameters()['width'] = w
- ex.parameters().param('width').setValue(w, blockSignal=ex.widthChanged)
- ex.parameters().param('height').setValue(h, blockSignal=ex.heightChanged)
- # beware this is bad workaround!!! plot data is misplaced
- ex.export(png_file)
-
- def saveConfigCmd(self):
- with open('config.ini', 'w') as configfile:
- self.config.write(configfile)
-
- def onTic(self,swp=None):
- start = datetime.now()
- if swp is None:
- swp = self.sweeper
-
- # RF generator
- rfFreq = self.rfGenFunc.getValue(swp)
- self.hardware['rfGen'].setFreq(rfFreq)
- # skip data update based on independent variable (rfGen) sweep direction
- sweep_direction = self.rfGenFunc.getSweepDirection(swp)
- if sweep_direction < .5:
- # sweep_direction is either 0 or 1
- # we do no data collection on the backward stroke
- return
- rf_freq_Name = self.config['RF'].get('frequency_export_name')
- self.data[rf_freq_Name].append(rfFreq)
-
- # global tic counter
- tic = self.sweeper.getCnt()
- self.data['tic'].append(tic)
-
- # DAQ
- daq0 = self.hardware['LabJack']
-
- # dac0
- # dac0 = self.funcGen.getValue(swp)
- # dac0 = 0
- # dac0 = self.funcGen.getValue(swp)
- # daq0.setOutputCh(0, dac0)
- # self.data['dac0'].append(dac0)
-
- # dac1
- # dac1 = PulseGen(ampl=5, sweeper=swp).getValue()
- # dac1 = 0
- # daq0.setOutputCh(1, dac1)
- # self.data['dac1'].append(dac1)
-
- for ch in self.config['DAQ']:
- if ch[0:3] == 'ain':
- n=int(ch[3:])
- vIn = daq0.getInputCh(n)
- ch_meaning = self.config['DAQ'][ch]
- self.data[ch_meaning].append( vIn )
-
- # X-axis (i.e. independent variable)
- x=self.data[self.config['Plot']['x_axis_data']]
- x=np.array(x)
- fCent = self.rfGenFunc.getCenter()
- x=(x-fCent)
- self.data['x'] = x
- self.dataPlot.setLabel('bottom', 'Frequency offset', units='Hz')
- self.dataPlot.setLabel('left', 'Signal', units='V')
-
- self.newDataIsReady = True
- stop = datetime.now()
- runTime = (stop-start).seconds + float((stop-start).microseconds)/1000000
- # print("onTic DAQ took %s seconds." % (runTime) )
-
- def autoZoom(self):
- self.dataPlot.autoRange()
-
- def updatePlot(self,swp=None):
- if self.newDataIsReady:
- self.newDataIsReady = False
- else:
- return
-
- start = datetime.now()
- x = self.data['x']
- for name in self.config['Plot_channels_visibility']:
- if not self.config['Plot_channels_visibility'].getboolean(name):
- continue
- if name not in self.data:
- continue
- y = self.data[name]
- if name not in self.channelGraph:
- if name in self.config['Plot_channels_colors']:
- color_str = self.config['Plot_channels_colors'][name]
- color = ast.literal_eval(color_str)
- else:
- color = (255,0,0)
- self.channelGraph[name]=self.dataPlot.plot(x,y, pen=None, symbol='o', symbolPen=None, symbolBrush=color, symbolSize=5, name=name)
- else:
- self.channelGraph[name].setData(x,y)
- if len(x)>0:
- self.vLineSweepPosition.setValue(x[-1])
- # centralFreqFormatted = pg.siFormat(self.fCent, suffix='Hz', precision=4)
- # showing trailing zeros is tricky
- fCent = self.rfGenFunc.getCenter()
- centralFreqFormatted = f"{fCent/1e9:.9f}"
- centralFreqFormatted = str.ljust(centralFreqFormatted, 11, '0') + " GHz"
- self.dataPlot.setTitle(f"Signals around center frequency {centralFreqFormatted}")
-
- stop = datetime.now()
- runTime = (stop-start).seconds + float((stop-start).microseconds)/1000000
- print("Replot took %s seconds to plot %s points per channel." % (runTime, len(self.data['x'])) )
-
-
-if __name__ == '__main__':
- parser = argparse.ArgumentParser(description='Perform EIT based experiment.')
- parser.add_argument('--test', '-t', action='store_true',
- help='test mode, use fake/dummy hardware')
- parser.add_argument('--config-file', '-c', action='append',
- help='additional config files, could be used multiple time')
- args = parser.parse_args()
-
- if args.config_file:
- for cf in args.config_file:
- print("Reading config file: " + cf)
- config.read(cf)
-
- app = QtGui.QApplication([])
- pg.setConfigOption('background', 'w')
- pg.setConfigOption('foreground', 'k')
- mw = QtGui.QMainWindow()
- mw.setWindowTitle('pyqtgraph example: PlotWidget')
- mw.resize(800,800)
- cw = QtGui.QWidget()
- mw.setCentralWidget(cw)
- l = QtGui.QVBoxLayout()
- cw.setLayout(l)
-
- mw.show()
-
- experiment=Experiment(l, config, args)
- app.exec()
-
-
diff --git a/example_config.ini b/example_config.ini
deleted file mode 100644
index c0fc146..0000000
--- a/example_config.ini
+++ /dev/null
@@ -1,40 +0,0 @@
-[RF]
-central_frequency = 6.83468e9
-frequency_span = 100e3
-initial_frequency = 6.834e9
-frequency_export_name = rfFreq
-
-[DAQ]
-# channels to grab and their meaning
-ain0 = transmission
-ain1 = lockin
-ain2 = davll
-ain3 = ain3_undefined
-# commented out channels will not be processed or stored
-# dac0 = dac0_undefined
-# dac1 = dac1_undefined2
-
-[Plot]
-x_axis_data = rfFreq
-
-[Plot_channels_visibility]
-transmission = yes
-lockin = yes
-davll = yes
-
-[Plot_channels_colors]
-# color specification will be evaluated and should match PyQtGraph.mkColor(args)
-# for example
-# (R,G,B,Alpha) tuple: example_trace = (255,0,255,100)
-# or color name: example_trace = 'g'
-transmission = (20,20,20,100)
-lockin = (85,170,255,100)
-davll = (255,0,255,100)
-ain3_undefined = (0,85,255,100)
-
-
-[Save]
-save_prefix = eit
-data_dir = z:\data.VAMPIRE
-
-
diff --git a/funcGenerator.py b/funcGenerator.py
deleted file mode 100644
index cd33f0b..0000000
--- a/funcGenerator.py
+++ /dev/null
@@ -1,274 +0,0 @@
-import time # For sleep, clock, time and perf_counter
-from datetime import datetime, timedelta
-import numpy as np
-
-try:
- from pyqtgraph.Qt import QtCore
-except:
- pass
-
-class SinGen:
- def __init__(self, ampl=1, offset=0, phase=0, sweeper=None):
- self.ampl = ampl
- self.phase = phase
- self.sweeper = sweeper
- self.offset = offset
-
- def getValue(self, sweeper=None):
- if sweeper is None and self.sweeper is None:
- print("Error: generator needs sweeper")
- return 0
- if sweeper is None:
- sweeper = self.sweeper
- return self.ampl * np.sin( 2*np.pi*sweeper.getRelPos()) + self.offset
-
-class RampGen:
- # monotonically goes from start to stop, at final point move to start
- def __init__(self, start=0, stop=0, sweeper=None):
- self.start = start
- self.stop = stop
- self.sweeper = sweeper
-
- def setCenterAndSpan(self, center, span):
- self.start = center-span/2
- self.stop = center+span/2
-
- def setCenter(self, center):
- span = self.stop - self.start;
- self.setCenterAndSpan(center, span)
-
- def getCenter(self):
- return (self.stop + self.start)/2
-
- def setSpan(self, span):
- center = (self.stop + self.start)/2
- self.setCenterAndSpan(center, span)
-
- def getSpan(self):
- return self.stop - self.start;
-
- def getValue(self, sweeper=None):
- if sweeper is None and self.sweeper is None:
- print("Error: generator needs sweeper")
- return 0
- if sweeper is None:
- sweeper = self.sweeper
- return self.start + sweeper.getRelPos()*(self.stop - self.start)
-
-class SawGen(RampGen):
- # monotonically goes from start to stop, once reaches stop goes back to start
- # does it with duty_cycle,
- # i.e duty_cycle*period we go up, the other time we go down
- def __init__(self, duty_cycle=0.5, **kwds):
- self.duty_cycle = duty_cycle;
- super().__init__(**kwds)
-
- def getValue(self, sweeper=None):
- if sweeper is None and self.sweeper is None:
- print("Error: generator needs sweeper")
- return 0
- if sweeper is None:
- sweeper = self.sweeper
- if sweeper.getRelPos() < self.duty_cycle:
- return self.start + sweeper.getRelPos()/self.duty_cycle*(self.stop - self.start)
- return self.start + (1-sweeper.getRelPos())/(1-self.duty_cycle)*(self.stop - self.start)
- def getSweepDirection(self, sweeper = None):
- if sweeper is None and self.sweeper is None:
- print("Error: generator needs sweeper")
- return 0
- if sweeper is None:
- sweeper = self.sweeper
- if sweeper.getRelPos() < self.duty_cycle:
- return 1; # increasing value direction
- return 0; # decreasing value direction
-
-class TriangleGen(SawGen):
- # monotonically goes from start to stop, once reaches stop goes back to start
- # does it with 50% duty cycle, i.e half of period we go up, the other half down
- def __init__(self, **kwds):
- super().__init__(duty_cycle=0.5, **kwds)
-
-class PulseGen:
- # produce ampl for the first half a period and 0 for the other half
- def __init__(self, ampl=1, sweeper=None):
- self.ampl = ampl
- self.sweeper = sweeper
-
- def getValue(self, sweeper=None):
- if sweeper is None and self.sweeper is None:
- print("Error: generator needs sweeper")
- return 0
- if sweeper is None:
- sweeper = self.sweeper
- if sweeper.getRelPos() < 0.5:
- return self.ampl
- return 0
-
-class Sweeper:
- # main clock sweeper for any function generator
- def __init__(self, widget, Npoints, SweepTime, onTicCallbacks=[]):
- # walk from start to stop with Npoints
- # cnt = 1 corresponds to start
- # cnt = Npoints corresponds to stop
- # variables like relVar are relative to the start of the period
- self.cnt = 0 # onTic will increase it right away
- self.widget = widget
- self.Npoints = Npoints
- self.start = 1
- self.stop = self.Npoints
- self.SweepTime = SweepTime
- self.onTicCallbacks = onTicCallbacks
- self.isOn = False
- self.isRestart = True
- self.isTicRunning = False
-
- self.span = self.stop - self.start
- self.center = (self.stop + self.start)/2
- self.dPos = self.span/(self.Npoints-1)
- self.dT = self.SweepTime/(self.Npoints-1)
- self.dTmS = round(self.dT*1000) # dT in milliseconds
-
- def reset(self):
- self.cnt = 0 # onTic will increase it right away
- self.isRestart = False
- self.startTime = datetime.now()
-
- def onTic(self):
- start = datetime.now()
- deadline = start + timedelta(milliseconds=self.dTmS)
-
- if not self.isOn:
- self.isTicRunning = False
- return
- self.isTicRunning = True
- if self.isRestart:
- self.reset()
- self.isRestart = False
- self.incr()
- for cb in self.onTicCallbacks:
- cb(self)
- stop = datetime.now()
- self.isTicRunning = False
- if stop > deadline:
- runTime = (stop-start).seconds + float((stop-start).microseconds)/1000000
- print("Overrun: Callbacks took %s seconds instead of %s" % (runTime, self.dTmS/1000) )
- self.after(0, self.onTic)
-
- idleTime_mS = round((deadline-stop).seconds * 1000 + (deadline-stop).microseconds/1000)
- # print("Will idle for %s" % (idleTime_mS) )
- self.after(idleTime_mS, self.onTic)
-
- def after(self, idleTime_mS, cmnd):
- # this function modelled after Tk.after
- # it is execute 'cmnd' after idle time given in mS
- # idleTime_mS = 0 means execute immediately
- try:
- # Tk style
- self.widget.after(idleTime_mS, cmnd)
- return
- except AttributeError:
- pass
-
- try:
- # PyQt style
- t = QtCore.QTimer()
- t.singleShot( idleTime_mS, cmnd )
- return
- except NameError:
- pass
-
- raise Exception("Something went horribly wrong: we have no mechanism for Sweeper.after()")
-
-
- def cmdRestart(self):
- self.cnt = 0
- if self.isOn:
- self.isRestart = True
- return
- self.reset()
- self.isOn = True
- self.onTic()
-
- def cmdStart(self):
- self.isOn = True
- self.onTic()
-
- def cmdStop(self):
- self.isOn = False
-
- def incr(self):
- self.cnt += 1
- self.updPos()
-
- def updPos(self):
- self.relCnt = 1 + ((self.cnt-1) % self.Npoints)
- self.pos = self.start + self.dPos * (self.relCnt - 1)
- self.relPos = (self.pos-self.start)/self.span
-
- def getCnt(self):
- return self.cnt
-
- def getRelCnt(self):
- return self.relCnt
-
- def getPos(self):
- return self.pos
-
- def getRelPos(self):
- return self.relPos
-
-def testOnTicTk(sweeper):
- print( sweeper.getPos() )
- if sweeper.getPos() == sweeper.Npoints:
- print("Tk sweeper is done")
- sweeper.cmdStop()
- sweeper.widget.destroy()
- sweeper.widget.quit()
-
-def testSweeperTk():
- print("test Sweeper with Tk")
- root=Tk()
- root.geometry("800x600")
- root.withdraw(); # do not show window
-
- Np = 10
- SweepTime = Np
- print(f'Test sweeper: you should see a sequence of {Np} numbers updating about every {SweepTime/Np} seconds')
- sweeper = Sweeper(root, Npoints=Np, SweepTime=SweepTime, onTicCallbacks=[testOnTicTk])
- sweeper.cmdStart()
-
- root.mainloop()
-
-def testOnTicPyQtGraph(sweeper):
- print( sweeper.getPos() )
- if sweeper.getPos() == sweeper.Npoints:
- print("PyQtGraph sweeper is done")
- sweeper.cmdStop()
- sweeper.widget.exit()
-
-def testSweeperPyQtGraph():
- print("test Sweeper with PyQtGraph")
- app = QtGui.QApplication([])
-
- Np = 10
- SweepTime = Np
- print(f'Test sweeper: you should see a sequence of {Np} numbers updating about every {SweepTime/Np} seconds')
- sweeper = Sweeper(app, Npoints=Np, SweepTime=SweepTime, onTicCallbacks=[testOnTicPyQtGraph])
- sweeper.cmdStart()
-
- app.exec()
-
-if __name__ == '__main__':
- try:
- from tkinter import Tk
- testSweeperTk()
- except ModuleNotFoundError:
- print("Tk module not found, skipping testSweeperTk")
-
- try:
- from pyqtgraph.Qt import QtGui, QtCore
- testSweeperPyQtGraph()
- except ModuleNotFoundError:
- print("pyqtgraph.Qt module not found, skipping testSweeperPyQtGraph")
- print("Done with tests")
-
diff --git a/labjackStreamTest.py b/labjackStreamTest.py
deleted file mode 100644
index c5368ea..0000000
--- a/labjackStreamTest.py
+++ /dev/null
@@ -1,167 +0,0 @@
-import sys
-import traceback
-import time # For sleep, clock, time and perf_counter
-from datetime import datetime
-
-import u3
-import u6
-import ue9
-
-dacAddress = 5000 # DAC Modbus address
-
-# MAX_REQUESTS is the number of packets to be read.
-MAX_REQUESTS = 75
-# SCAN_FREQUENCY is the scan frequency of stream mode in Hz
-SCAN_FREQUENCY = 1000
-
-d = None
-
-###############################################################################
-# U3
-# Uncomment these lines to stream from a U3
-###############################################################################
-'''
-# At high frequencies ( >5 kHz), the number of samples will be MAX_REQUESTS
-# times 48 (packets per request) times 25 (samples per packet).
-d = u3.U3()
-
-# To learn the if the U3 is an HV
-d.configU3()
-
-# For applying the proper calibration to readings.
-d.getCalibrationData()
-
-# Set the FIO0 and FIO1 to Analog (d3 = b00000011)
-d.configIO(FIOAnalog=3)
-
-print("Configuring U3 stream")
-d.streamConfig(NumChannels=2, PChannels=[0, 1], NChannels=[31, 31], Resolution=3, ScanFrequency=SCAN_FREQUENCY)
-'''
-
-###############################################################################
-# U6
-# Uncomment these lines to stream from a U6
-###############################################################################
-'''
-# At high frequencies ( >5 kHz), the number of samples will be MAX_REQUESTS
-# times 48 (packets per request) times 25 (samples per packet).
-d = u6.U6()
-
-# For applying the proper calibration to readings.
-d.getCalibrationData()
-
-print("Configuring U6 stream")
-
-d.streamConfig(NumChannels=2, ChannelNumbers=[0, 1], ChannelOptions=[0, 0], SettlingFactor=1, ResolutionIndex=1, ScanFrequency=SCAN_FREQUENCY)
-'''
-
-###############################################################################
-# UE9
-# Uncomment these lines to stream from a UE9
-###############################################################################
-# At 96 Hz or higher frequencies, the number of samples will be MAX_REQUESTS
-# times 8 (packets per request) times 16 (samples per packet).
-# Currently over ethernet packets per request is 1.
-d = ue9.UE9()
-#d = ue9.UE9(ethernet=True, ipAddress="192.168.1.209") # Over TCP/ethernet connect to UE9 with IP address 192.168.1.209
-
-# For applying the proper calibration to readings.
-c=d.getCalibrationData()
-
-# by evmik
-# fixing missing slope for gain '0'
-c['AINSlopes']['0']= 0.0000775030
-
-
-print("Configuring UE9 stream")
-
-d.streamConfig(NumChannels=4, ChannelNumbers=[0, 1, 2, 3], ChannelOptions=[0, 0, 0, 0], SettlingTime=0, Resolution=12, ScanFrequency=SCAN_FREQUENCY)
-'''
-'''
-
-if d is None:
- print("""Configure a device first.
-Please open streamTest.py in a text editor and uncomment the lines for your device.
-
-Exiting...""")
- sys.exit(0)
-
-try:
- print("Start stream")
- d.writeRegister(dacAddress, 2.05)
- # d.singleIO(IOType=5, Channel=0, DAC=0)
- dacNumber=0
- bits = d.voltageToDACBits(1.4, dacNumber = dacNumber)
- out=d.singleIO(IOType=5, Channel=dacNumber, DAC=bits)
- print(out)
-
- d.streamStart()
- start = datetime.now()
- print("Start time is %s" % start)
-
- missed = 0
- dataCount = 0
- packetCount = 0
- v=0.1
-
- for r in d.streamData():
- # d.writeRegister(dacAddress, 0.05*dataCount)
- v=v+0.1
- print(v)
- bits = d.voltageToDACBits(v, dacNumber = dacNumber)
- out=d.singleIO(IOType=5, Channel=dacNumber, DAC=bits)
- if r is not None:
- # Our stop condition
- if dataCount >= MAX_REQUESTS:
- break
-
- if r["errors"] != 0:
- print("Errors counted: %s ; %s" % (r["errors"], datetime.now()))
-
- if r["numPackets"] != d.packetsPerRequest:
- print("----- UNDERFLOW : %s ; %s" %
- (r["numPackets"], datetime.now()))
-
- if r["missed"] != 0:
- missed += r['missed']
- print("+++ Missed %s" % r["missed"])
-
- if r["firstPacket"] != packetCount % 256:
- print("----- Overflow skipping packets : expected %s got %s ; %s" %
- (packetCount, r["firstPacket"], datetime.now()))
-
- # Comment out these prints and do something with r
- print("Average of %s AIN0, %s AIN1 readings: %s, %s" %
- (len(r["AIN0"]), len(r["AIN1"]), sum(r["AIN0"])/len(r["AIN0"]), sum(r["AIN1"])/len(r["AIN1"])))
-
- dataCount += 1
- packetCount += r['numPackets']
- else:
- # Got no data back from our read.
- # This only happens if your stream isn't faster than the USB read
- # timeout, ~1 sec.
- print("No data ; %s" % datetime.now())
-except:
- print("".join(i for i in traceback.format_exc()))
-finally:
- stop = datetime.now()
- d.streamStop()
- print("Stream stopped.\n")
- d.close()
-
- sampleTotal = packetCount * d.streamSamplesPerPacket
-
- scanTotal = sampleTotal / 2 # sampleTotal / NumChannels
- print("%s requests with %s packets per request with %s samples per packet = %s samples total." %
- (dataCount, (float(packetCount)/dataCount), d.streamSamplesPerPacket, sampleTotal))
- print("%s samples were lost due to errors." % missed)
- sampleTotal -= missed
- print("Adjusted number of samples = %s" % sampleTotal)
-
- runTime = (stop-start).seconds + float((stop-start).microseconds)/1000000
- print("The experiment took %s seconds." % runTime)
- print("Actual Scan Rate = %s Hz" % SCAN_FREQUENCY)
- print("Timed Scan Rate = %s scans / %s seconds = %s Hz" %
- (scanTotal, runTime, float(scanTotal)/runTime))
- print("Timed Sample Rate = %s samples / %s seconds = %s Hz" %
- (sampleTotal, runTime, float(sampleTotal)/runTime))
diff --git a/rfGen.py b/rfGen.py
deleted file mode 100644
index 3084664..0000000
--- a/rfGen.py
+++ /dev/null
@@ -1,50 +0,0 @@
-import serial
-import io
-
-import time # For sleep, clock, time and perf_counter
-from datetime import datetime, timedelta
-
-class rfGenLMX2487:
- def __init__(self, port='/dev/ttyUSB0', speed=115200, timeout=1, setToDefaults=True):
- self.port = port
- self.speed = speed
- self.timeout = timeout
- self.connection = serial.Serial( self.port, self.speed, timeout=self.timeout)
- self.log = []
- self.logCapacity = 10
- if setToDefaults:
- self.sendSerialCmd("set_lmx2487_board_to_default_state()")
-
- def add2log(self, text):
- self.log.append(text)
- while len(self.log) > self.logCapacity:
- self.log.pop(0)
-
- def log2str(self, interval=None):
- strOut = ""
- for e in self.log:
- strOut += e
- return strOut
-
- def sendSerialCmd(self, cmd):
- self.connection.write(bytes(cmd+'\r','ascii'))
- if "3.4" == serial.__version__:
- # older version style
- resp = self.connection.read_until(terminator=b'> ')
- else:
- # new style after 20180616
- resp = self.connection.read_until(expected=b'> ')
- resp = resp.decode('utf-8')
- self.add2log(resp)
- return resp
-
- def setFreq(self,freq):
- cmd_str=f'setFreq({freq:.2f})'
- self.sendSerialCmd(cmd_str)
-
-class rfGenLMX2487Dummy:
- def __init__(self, port='/dev/ttyUSB0', speed=115200, timeout=1):
- return
-
- def setFreq(self,freq):
- return
diff --git a/test_rfGenLMX2487.py b/test_rfGenLMX2487.py
deleted file mode 100644
index e87ad79..0000000
--- a/test_rfGenLMX2487.py
+++ /dev/null
@@ -1,20 +0,0 @@
-from rfGen import rfGenLMX2487
-import numpy as np
-import platform
-
-if platform.system() == 'Linux':
- rf=rfGenLMX2487(port='/dev/ttyUSB0', speed=115200, timeout=1)
-else:
- rf=rfGenLMX2487(port='COM5', speed=115200, timeout=1)
-
-freqStart = 6.830e9
-freqStop = 6.840e9
-Np = 21
-print(f'We will sweep frequency from {freqStart} to {freqStop} in {Np} points')
-for freq in np.linspace(freqStart,freqStop, num=Np, endpoint=True):
- print(f'Frequency set to {freq:.2f}')
- rf.setFreq(freq)
-
-print("Printing log")
-print(rf.log2str())
-
diff --git a/test_serial.py b/test_serial.py
deleted file mode 100755
index f88302b..0000000
--- a/test_serial.py
+++ /dev/null
@@ -1,47 +0,0 @@
-import serial
-import io
-
-import time # For sleep, clock, time and perf_counter
-from datetime import datetime, timedelta
-
-# ser = serial.Serial('COM4', 115200, timeout=1)
-ser = serial.Serial('/dev/ttyUSB0', 115200, timeout=1)
-# ser = serial.Serial('/dev/ttyUSB0', 9600, timeout=1)
-
-# ser.write(b'dofile("bits_converging.lua")\r')
-# ser.write(b'dofile("microwire.lua")\r')
-# ser.write(b'dofile("lmx2487lib.lua")\r')
-# ser.write(b'dofile("Frequency_Settings.lua")\r')
-
-# ser.write(b'settings = initSettings()\r')
-# ser.write(b'settings = set_lmx2487_to_Frequency (startfreq, settings)\r')
-
-
-
-def sendSerialCmd(cmd):
- # start = datetime.now()
- ser.write(bytes(cmd+'\r','ascii'))
- resp = ser.read_until(terminator=b'> ')
- resp = resp.decode('utf-8')
- # print(resp)
- # stop = datetime.now()
- # runTime = (stop-start).seconds + float((stop-start).microseconds)/1000000
- # print("Command: " + cmd + " runtime %s seconds." % (runTime) )
- return resp
-
-sendSerialCmd("print(2+3)")
-
-line = ser.readline()
-print(line)
-
-start = datetime.now()
-# resp = sendSerialCmd("print(node.heap())")
-# resp = sendSerialCmd(""); # empty command
-resp = sendSerialCmd("muSb= tmr.now(); setFreq(6.834e9); muSe =tmr.now(); print(\"execution time: \" .. muSe-muSb .. \" muS\")")
-print(resp)
-stop = datetime.now()
-runTime = (stop-start).seconds + float((stop-start).microseconds)/1000000
-print("runtime %s seconds." % (runTime) )
-
-
-ser.close()
diff --git a/test_ue9.py b/test_ue9.py
deleted file mode 100755
index d8a0dff..0000000
--- a/test_ue9.py
+++ /dev/null
@@ -1,10 +0,0 @@
-
-import ue9qol
-
-daq = ue9qol.UE9qol()
-
-daq.setOutputCh(0, 0.5)
-
-v1 = daq.getInputCh(1)
-print(f'ch1 = {v1}')
-
diff --git a/ue9qol.py b/ue9qol.py
deleted file mode 100644
index e95fe6b..0000000
--- a/ue9qol.py
+++ /dev/null
@@ -1,76 +0,0 @@
-import sys
-import traceback
-import time # For sleep, clock, time and perf_counter
-from datetime import datetime
-import random
-
-import u3
-import u6
-import ue9
-
-class UE9qol:
-
- def __init__(self, debug = False, autoOpen = True, **kargs):
- #d = ue9.UE9(ethernet=True, ipAddress="192.168.1.209") # Over TCP/ethernet connect to UE9 with IP address 192.168.1.209
- self.daq = ue9.UE9(debug=debug, autoOpen=autoOpen)
-
- # For applying the proper calibration to readings.
- c=self.daq.getCalibrationData()
-
- # by evmik
- # fixing missing slope for gain '0'
- c['AINSlopes']['0']= 0.0000775030
-
- def getInputCh(self, chNum, BipGain = 8):
- # BipGain = 8 -> bipolar range (-5V, +5V) gain 1
- # UE9 default BipGain = 0 -> signal range (0V, +5V) gain 1
- # other BipGain could be:
- # 0 = Unipolar Gain 1, 1 = Unipolar Gain 2,
- # 2 = Unipolar Gain 4, 3 = Unipolar Gain 8,
- # 8 = Bipolar Gain 1
- return self.daq.getAIN(chNum, BipGain = BipGain)
-
- def setOutputCh(self, chNum=None, volts=None):
- if chNum == None or volts == None:
- print("setOutputCh needs chNum and volts to be set")
- return 0
- bits = self.daq.voltageToDACBits(volts, dacNumber = chNum)
- # out is completely bogus for DAC settings in UE9
- out=self.daq.singleIO(IOType=5, Channel=chNum, DAC=bits)
- return volts
-
- def close(self):
- self.daq.close()
-
-class UE9qolDummy:
- from funcGenerator import Sweeper, SinGen, TriangleGen, RampGen, PulseGen
- # to be used for graphics debugging
- def __init__(self, debug = False, autoOpen = True, sweeper=None, **kargs):
- self.sweeper = sweeper
- # do nothing
- return
-
- def getInputCh(self, chNum):
- a =.3
- if chNum == 0:
- val = self.SinGen(ampl=a, offset=chNum, sweeper=self.sweeper).getValue()
- elif chNum == 1:
- val = self.PulseGen(ampl=a, sweeper=self.sweeper).getValue()
- val += chNum
- elif chNum == 2:
- val = self.TriangleGen(start=chNum-a/2, stop=chNum+a/2, sweeper=self.sweeper).getValue()
- elif chNum == 3:
- val = self.RampGen(start=chNum-a/2, stop=chNum+a/2, sweeper=self.sweeper).getValue()
- else:
- val = self.SinGen(ampl=.2, offset=chNum, sweeper=self.sweeper).getValue()
- val += random.normalvariate(0, 0.01)
- return val
-
- def setOutputCh(self, chNum=None, volts=None):
- # do nothing
- return
-
- def close(self):
- # do nothing
- return
-