#!/usr/bin/env python # -*- coding: utf-8 -*- # ***************************************************************************** # This program is free software; you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software # Foundation; either version 2 of the License, or (at your option) any later # version. # # This program is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more # details. # # You should have received a copy of the GNU General Public License along with # this program; if not, write to the Free Software Foundation, Inc., # 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Module authors: # Daniel Margineda # ***************************************************************************** """SIGNAL RECOVERY SR7270: lOCKIN AMPLIFIER FOR AC SUSCEPTIBILITY""" from secop.core import Readable, Parameter, Override, FloatRange, TupleOf, HasIodev, StringIO, \ Done, Attached, IntRange, BoolType class SR7270(StringIO): end_of_line = b'\x00' def do_communicate(self, command): #remove dash from terminator reply = StringIO.do_communicate(self, command) status = self._conn.readbytes(2, 0.1) # get the 2 status bytes # print('comm=',command,'reply=',reply,'status=',status) return reply + ';%d;%d' % tuple(status) class XY(HasIodev, Readable): properties = { 'x': Attached(), 'y': Attached(), 'freq_arg': Attached(), 'amp_arg': Attached(), 'tc_arg': Attached(), } parameters = { 'value': Override('X, Y', datatype=TupleOf(FloatRange(unit='V'), FloatRange(unit='V'))), 'freq': Parameter('exc_freq_int', FloatRange(0.001,250e3,unit='Hz'), poll=True, readonly=False, default=100), 'amp': Parameter('exc_volt_int', FloatRange(0.00,5,unit='Vrms'), poll=True, readonly=False, default=5), 'range': Parameter('sensitivity value', FloatRange(0.00,1,unit='V'), poll=True, default=1), 'irange': Parameter('sensitivity index', IntRange(0,27), poll=True, readonly=False, default=25), 'autorange': Parameter('autorange_on', BoolType(), readonly=False, default=True), 'tc': Parameter('time constant value', FloatRange(10e-6,1,unit='s'), poll=True, default=0.1), 'itc': Parameter('time constant index', IntRange(0,30), poll=True, readonly=False, default=12), 'nm': Parameter ('noise mode',BoolType(), readonly=False, default=0), 'aphase': Parameter('autophase',BoolType(), readonly=False, default=0), # FloatRange(0.00,5e6,unit='uVrms'), # poll=True, readonly=False, default=100), } iodevClass = SR7270 def comm(self, command): reply, status, overload = self.sendRecv(command).split(';') if overload != '0': self.status = self.Status.WARN, 'overload %s' % overload else: self.status = self.Status.IDLE, '' return reply def read_value(self): reply = self.comm('XY.').split(',') x = float(reply[0]) y = float(reply[1]) if self.autorange: if max(abs(x), abs(y)) >= 0.9*self.range and self.irange < 27: self.write_irange(self.irange+1) elif max(abs(x), abs(y)) <= 0.3*self.range and self.irange > 1: self.write_irange(self.irange-1) self._x.value = x # to update X,Y classes which will be the collected data. self._y.value = y self._freq_arg.value = self.freq self._amp_arg.value = self.amp self._tc_arg.value =self.tc return x,y def read_freq(self): reply = self.comm('OF.') return reply def write_freq(self,value): self.comm('OF. %g' % value) return value #oscillator amplitude module def read_amp(self): reply = self.comm('OA.') return reply def write_amp(self,value): self.comm('OA. %g' % value) return value #sensitivity module def read_range(self): reply = self.comm('SEN.') return reply def write_irange(self,value): self.comm('SEN %g' % value) self.read_range() return value def read_irange(self): reply = self.comm('SEN') return reply #time constant module/ noisemode off or 0 allows to use all the time constant range def read_nm(self): reply = self.comm('NOISEMODE') return reply def write_nm(self,value): self.comm('NOISEMODE %d' % int(value)) self.read_nm() return value def read_tc(self): reply = self.comm('TC.') return reply def write_itc(self,value): self.comm('TC %g' % value) self.read_tc() return value def read_itc(self): reply = self.comm('TC') return reply #autophase def read_aphase(self): reply = self.comm('AQN') return reply def write_aphase(self,value): self.comm('AQN') self.read_aphase() return value class Comp(Readable): pollerClass = None parameters = { 'value': Override(datatype=FloatRange(unit='V')), } class arg(Readable): pollerClass = None parameters = { 'value': Override(datatype=FloatRange(unit='')), } # parameters = { # 'valueX': Override('X, Y', datatype=TupleOf(FloatRange(unit='V'), FloatRange(unit='V'))), #} #iodevClass = SR7270 # def read_valueX(self): # reply = self.sendRecv('XY.') # return reply.split(',')[0] # def read_valueY(self): # reply = self.sendRecv('XY.') # return reply.split(',')[1] #class aphase(self): # reply = self.sendRecv('ASM') # return reply # def asens(self): # reply = self.sendRecv('AS') # return reply # def write_Fstart(self,value): # self.sendRecv('FSTART. %g' % value) # return value # def write_Fstop(self,value): # self.sendRecv('FSTOP. %g' % value) # return value # def write_Fstep(self,value): # self.sendRecv('FSTEP. %g' % value) # return value # def write_Astart(self,value): # self.sendRecv('ASTART. %g' % value') # return value # def write_Astop(self,value): # self.sendRecv('ASTOP. %g' % value) # return value # def write_Astep(self,value): # self.sendRecv('ASTEP. %g' % value) # return value