Skip to content

Commit

Permalink
Initial version with a generic instr, OSA, Osc
Browse files Browse the repository at this point in the history
ToDo:
Readme/more Documentation
  • Loading branch information
timhellwig authored May 26, 2017
1 parent 38883d0 commit be5e3e9
Show file tree
Hide file tree
Showing 7 changed files with 323 additions and 0 deletions.
10 changes: 10 additions & 0 deletions config/Misc/Katana.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
spec: "1.0"

readOnlyProps:

readWriteProps:
pumpCurrent : ldc
frequency : f
laser : ld

readBinaryTraces:
17 changes: 17 additions & 0 deletions config/OSA/Yokogawa_AQ6370C.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
spec: "1.0"

readOnlyProps:
name : '*IDN'

readWriteProps:
startwl : :SENS:WAV:STAR
stopwl : :SENS:WAV:STOP
span : :SENS:WAV:SPAN
centerwl : :SENS:WAV:CENT
bandwidth : :SENS:BAND:RES
points : :SENS:SWE:POIN
sweepmode : :INIT:SMOD

readBinaryTraces:
wavelength : :TRAC:X
data : :TRAC:Y
42 changes: 42 additions & 0 deletions config/Oscilloscopes/RS_RTO1044.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
spec: "1.0"

readOnlyProps:
name : '*IDN'

readWriteProps:
points : ':ACQuire:POINts:AUTO RECLength;:ACQuire:POINts'
resolution : ':ACQuire:POINts:AUTO RESolution;:ACQuire:RESolution'
time_range : :TIMebase:RANGe
time_scale : :TIMebase:SCALe
time_ref : :TIMebase:REFerence
time_pos : :TIMebase:POS

ch1_position: :CHAN1:POS
ch1_offset : :CHAN1:OFFS
ch1_range : :CHAN1:RANG
ch1_triglvl : :TRIG:LEV1


ch2_position: :CHAN2:POS
ch2_offset : :CHAN2:OFFS
ch2_range : :CHAN2:RANG
ch2_triglvl : :TRIG:LEV2


ch3_position: :CHAN3:POS
ch3_offset : :CHAN3:OFFS
ch3_range : :CHAN3:RANG
ch3_triglvl : :TRIG:LEV3


ch4_position: :CHAN4:POS
ch4_offset : :CHAN4:OFFS
ch4_range : :CHAN4:RANG
ch4_triglvl : :TRIG:LEV4


readBinaryTraces:
ch1_data : :CHAN1:WAV1:DATA
ch2_data : :CHAN2:WAV1:DATA
ch3_data : :CHAN3:WAV1:DATA
ch4_data : :CHAN4:WAV1:DATA
118 changes: 118 additions & 0 deletions generic.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
""" Scientific - Instrumentation module based on pyvisa
"""

__author__ = 'Tim Hellwig'

import visa
import numpy as np
import os
import yaml



class Instrument:
"""This class should allow easy setting and getting values and
measurement data of common Visa Instruments like Oscilloscopes,
Optical Spectrum Analyzer or Radio Frequency Spectrum Analyzer
This class is intended to inherit from and implement specific
_readOnlyProps etc lists. Furthermore implement own is_ready
function """

_readOnlyProps = {'name':'*IDN'}
_readWriteProps={'voltage':':VOLT:IMM:AMPL'}
_readBinaryTraces={'wavelength':'TRACEX'}

_visa = None
_getString = '?'
_setString = ' '
_expctResponse = None
_formatString = '{}'


def __init__(self,visa_rm,address,conffile=None):
"""Connects to the Instrument and prepares properties"""


if conffile is not None:
cfg_path = os.path.join(os.path.dirname(__file__), 'config',conffile)
with open(cfg_path, 'r') as ymlfile:
cfg = yaml.load(ymlfile)

self._readOnlyProps=cfg['readOnlyProps']
self._readWriteProps=cfg['readWriteProps']
self._readBinaryTraces=cfg['readBinaryTraces']

_rm = visa_rm

self._visa = _rm.open_resource(address)
self._visa.values_format.use_binary('f', False, np.array)

def make_instr_prop(prop):
"""Getter and setter dynamically for read write
properties"""

def getter( self ):
return self._process_read_values(self._visa.query(self._readWriteProps[prop]+self._getString))
def setter( self,value ):
self._visa.write(self._readWriteProps[prop]+self._setString+self._formatString.format(value))
if self._expctResponse is not None:
response = self._visa.read()
if not response == self._expctResponse:
msg = 'Response was: {}; expected: {}'.format(response,self._expctResponse)
raise AttributeError(msg)

retvalue = self.__getattribute__(prop)
if not value == retvalue:
msg = 'Set value: {}; returned value: {}'.format(value,retvalue)
raise AttributeError(msg)
return property(getter,setter)

def make_read_only_instr_prop(prop):
""" Getter for read only properties"""

def getter( self ):
return self._visa.query(self._readOnlyProps[prop]+self._getString)
return property(getter)

def make_read_binary_instr_data(prop):
""" Getter for binary arrays"""

def getter( self ):
return self._visa.query_values(self._readBinaryTraces[prop]+self._getString)
return property(getter)



# add all the properties
for i in self._readOnlyProps or {}:
setattr(self.__class__, i, make_read_only_instr_prop(i))
for i in self._readWriteProps or {}:
setattr(self.__class__, i, make_instr_prop(i))
for i in self._readBinaryTraces or {}:
setattr(self.__class__, i, make_read_binary_instr_data(i))



def _process_read_values(self,string):
"""Usually we expect returning a float; inhereted classes can specify"""
return float(string)

def is_ready(self):
""" Query the instrument whether it has succesfully completed
all operations"""

return True


def __del__(self):
if self._visa is not None:
self._visa.close()


if __name__ == "__main__":
b = Instrument(visa.ResourceManager('@sim'),'ASRL2::INSTR')

print(b.name)
print(b.voltage)
66 changes: 66 additions & 0 deletions misc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
""" Scientific - Instrumentation module based on pyvisa
implements misc sort of instruments not fitting other categories
"""

__author__ = 'Tim Hellwig'



import sci_instr.generic
import os
import re



class Katana(sci_instr.generic.Instrument):
"""Allows easy communication with OneFive Katana
uses non standard set command (=) and wants only integer numbers,
as well as answers with "done\r\n" to each setting change!
"""

_getString = '?'
_setString = '='
_expctResponse = 'done\r\n'
_formatString = '{:d}'


def __init__(self,visa_rm,address):


"""Call generic init to connect and prepare instrument"""
super(Katana, self).__init__(visa_rm,address,conffile=os.path.join('Misc','Katana.yaml'))

self._visa.baud_rate = 19200
self._visa.encoding='windows-1252'


def _process_read_values(self,msg):
"""Find the numbers in Katanas long msg and parse on/off as 1/0 for
laser status"""

#print(msg)
out = re.findall(r"[-+]?\d*\.\d+|\d+",msg)
if out:
return float(out[0])
else:
if not msg.find(' on\r\n')==-1:
return 1
elif not msg.find(' off\r\n')==-1:
return 0

def debug(self):
out = ''
self._visa.write('debug?')
for i in range(0,27):
out = out + self._visa.read()
#join them to one byte String
print(out) #decode the byte String into something printable





36 changes: 36 additions & 0 deletions osa.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
""" Scientific - Instrumentation module based on pyvisa
"""

__author__ = 'Tim Hellwig'



import sci_instr.generic
import os



class AQ6370C(sci_instr.generic.Instrument):
"""Allows easy communication with Yokogawa OSA AQ6370C"""

def __init__(self,visa_rm,address):


"""Call generic init to connect and prepare instrument"""
super(AQ6370C, self).__init__(visa_rm,address,conffile=os.path.join('Osa','AQ6370C.yaml'))

self._visa.write(':init:smode 1;*CLS";:init')

def start_sweep():
"""Sends the trigger to start a sweep"""
self._visa.write('*CLS";:init')

def is_ready(self):
""" Query the instrument whether it has succesfully completed
all operations"""
out = self._visa.query(':stat:oper:even?')

return bool(out[0])


34 changes: 34 additions & 0 deletions oscilloscope.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
""" Scientific - Instrumentation module based on pyvisa
implements different Oscilloscopes
"""

__author__ = 'Tim Hellwig'



import sci_instr.generic
import os


class RS_RTO1044(sci_instr.generic.Instrument):
"""Allows easy communication with R&S Oscilloscope RTO1044"""

def __init__(self,visa_rm,address):


"""Call generic init to connect and prepare instrument"""
super(RS_RTO1044, self).__init__(visa_rm,address,conffile=os.path.join('Oscilloscopes','RS_RTO1044.yaml'))

self._visa.write('FORM REAL,32;')



def is_ready(self):
""" Query the instrument whether it has succesfully completed
all operations"""
out = self._visa.query(':stat:oper:even?')

return bool(out[0])


0 comments on commit be5e3e9

Please sign in to comment.