Updates to OTF, and added RP100 strain cell power supply, as well as a couple network analysers. Results from the mRS network analyser are questionable at best, and nonsense at worst. Beware.

This commit is contained in:
2025-07-09 13:02:24 +02:00
parent 10acd4a188
commit 5dfe929da5
15 changed files with 2494 additions and 8 deletions

View File

@@ -0,0 +1,183 @@
'''
Force reader class (specially for FC100)
Based on the psiSerial class
(c) 2023 Jonas Philipe
'''
import os
import time
import numpy as np
import traceback
import threading
from frappy_psi.uniaxial_cell.psi_serial import *
class psu_RP100_serialwrapper():
_instance = None
_lock = threading.Lock()
port = None
def __new__(cls, *args, **kwargs):
with cls._lock:
if cls._instance is None:
print('New RP100 object opened')
cls._instance = super().__new__(cls)
cls.port = psu_RP100(*args, **kwargs)
return cls._instance
class psu_RP100(psiSerial):
def __init__(self,**kwargs):
print('INIT')
super(psu_RP100,self).__init__(**kwargs)
self.customConnectionError = b'DEVICE CONNECTION ERROR\r\n'
self.endOfLine='\n' # different end of line than the standard Arduino
'''
-----------------------------------------
RP100 power supply class.
Serial interaction with power supply.
Inherits from class psiSerial.
-----------------------------------------
Commands:
self.enable(channel):
IN: string "channel", values contain "CH1" or "CH2".
e.g.: self.enable('CH1') enables channel 1.
OUT:
'''
self.channel1=False
self.channel2=False
self.statusChannel1 = None
self.statusChannel2 = None
self._port_opened = True
def __del__(self):
self.reset()
def to_bool(self, line):
return line[0] == b'0'
def reset(self):
self.psi_write('*RST')
time.sleep(1)
def enable(self,channel):
'''
self.enable(channel):
IN: string "channel", values contain "CH1" or "CH2".
e.g.: self.enable('CH1') enables channel 1.
OUT:
'''
try:
# Read status first:
self.statusChannel1=self.to_bool(self.psi_write_readline('OUTP1?',response_code=False))
self.statusChannel2=self.to_bool(self.psi_write_readline('OUTP2?',response_code=False))
except:
print('Cannot read source status.')
try:
if channel.find('CH1')>-1 and not self.statusChannel1:
self.psi_write_readline('OUTP1 1',response_code=False)
self.statusChannel1=self.to_bool(self.psi_write_readline('OUTP1?',response_code=False))
if channel.find('CH2')>-1 and not self.statusChannel2:
self.psi_write_readline('OUTP2 1',response_code=False)
self.statusChannel2=self.to_bool(self.psi_write_readline('OUTP2?',response_code=False))
except:
print('Could not enable the selected channel. Make sure the arguments are correct: "CH1" and / or "CH2". Full TB below')
traceback.print_exc()
def disable(self,channel):
'''
self.enable(channel):
IN: string "channel", values contain "CH1" or "CH2".
e.g.: self.enable('CH1') enables channel 1.
OUT:
'''
try:
# Read status first:
self.statusChannel1=self.to_bool(self.psi_write_readline('OUTP1?',response_code=False))
self.statusChannel2=self.to_bool(self.psi_write_readline('OUTP2?',response_code=False))
except:
print('Cannot read source status.')
traceback.print_exc()
try:
if channel.find('CH1')>-1 and self.statusChannel1:
self.psi_write_readline('OUTP1 0',response_code=False)
self.statusChannel1=self.to_bool(self.psi_write_readline('OUTP1?',response_code=False))
if channel.find('CH2')>-1 and self.statusChannel2:
self.psi_write_readline('OUTP2 0',response_code=False)
self.statusChannel2=self.to_bool(self.psi_write_readline('OUTP2?',response_code=False))
except:
print('Could not enable the selected channel. Make sure the arguments are correct: "CH1" and / or "CH2".')
def read_source_voltage(self,**kwargs):
s1 = self.psi_write_readline('SOUR1:VOLT:NOW?',response_code=False)
s2 = self.psi_write_readline('SOUR2:VOLT:NOW?',response_code=False)
try:
s1 = float(s1)
except:
print(s1)
s1 = None
try:
s2 = float(s2)
except:
print(s2)
s2 = None
return s1,s2
def set_slew(self,slew_value,**kwargs):
'''
Set ramping voltage to all channels.
Keyword: channel.
Example: channel='CH1,CH2' or channel='CH1'
'''
assert(slew_value >= 0.1e-3 and slew_value <= 100e3)
try:
cc = kwargs['channel']
except:
cc = 'CH1,CH2'
if cc.find('CH1')>-1:
self.psi_write_readline('SOUR1:VOLT:SLEW '+str(slew_value),response_code=False)
if cc.find('CH2')>-1:
self.psi_write_readline('SOUR2:VOLT:SLEW '+str(slew_value),response_code=False)
def read_slew(self,**kwargs):
s1 = self.psi_write_readline('SOUR1:VOLT:SLEW?',response_code=False)
s2 = self.psi_write_readline('SOUR2:VOLT:SLEW?',response_code=False)
return s1.decode(),s2.decode()
def measure_voltage(self,**kwargs):
s1 = self.psi_write_readline('MEAS1:VOLT?',response_code=False)
s2 = self.psi_write_readline('MEAS2:VOLT?',response_code=False)
try:
s1 = float(s1)
except:
print(s1)
s1 = None
try:
s2 = float(s2)
except:
print(s2)
s2 = None
return s1,s2
def set_voltage(self,source,voltage,**kwargs):
'''
Need to implement security limits on the voltage at some point!
'''
assert(voltage <= 230 and voltage >= -230)
if source == 'SOUR1' or source == 'SOUR2':
a = self.psi_write_readline(source+':VOLT '+str(voltage),response_code=False)
return a
def clear(self):
'''
Clears status code
'''
a=self.psi_write_readline('*CLS')
return a