Skip to content
Snippets Groups Projects
Commit 910136a8 authored by Sreedevi Potluri's avatar Sreedevi Potluri
Browse files

Added Climat chamber and VNA python scripts

parent edc5e813
No related branches found
No related tags found
No related merge requests found
Necessary libraries to install-
$ pip install -U pyvisa
Recommended software version-
python3.7
import pyvisa
import time
class Vna:
def __init__(self):
"""
Implements the basic operation of the VNA
"""
# open connection here
# store the credentials so that methods can access them
#self.__ip_address = ip_address
# we try to connect to the climate chamber just to see if there is an error
self.rm = pyvisa.ResourceManager()
self.vna = self.rm.open_resource("TCPIP0::192.168.115.39 ::57732::SOCKET")
# self.vna.write_termination = '\r\n'
# self.vna.read_termination = '\r\n'
self.vna.timeout = 5000
# Preset the VNA and wait for preset completion via use of *OPC?
self.vna.write("SYST:PRES; *OPC?")
self.vna.read()
# Clear the event status registers and empty the error queue
self.vna.write("*CLS")
# Query identification string *IDN?
self.vna.write("*IDN?")
print(self.vna.read())
# check the error queue
self.vna.write("SYST:ERR?")
print(self.vna.read())
# the communication section
# Select the default measurement name as assigned on preset. To catalog the measurement names,
# by channel number, use the 'CALCulate[n]:PARameter:CATalog?' command where [n] is the channel
# number.
self.vna.write("CALC:PAR:SEL 'CH1_S11_1'")
# Set data transfer format to ASCII
self.vna.write("FORM:DATA ASCII")
# Alter measure from S11 to S21
self.vna.write("CALC:PAR:MOD S21")
# Loop to control the number of trace points, provide single sweep synchronization, query the data,
# indicate number of points and indicate number of characters in the trace read.
self.traceData = []
i = 0
self.numPointsList = [201, 401, 801, 1601, 3201, 6401, 12801, 20001, 32001, 100001]
while i < len(self.numPointsList):
# Set number of points by list value
self.numPoints = self.numPointsList[i]
self.vna.write("SENS:SWE:POIN " + str(self.numPoints) + ";*OPC?")
self.vna.read()
self.startTime = self.time.clock()
# Trigger assertion with hold-off for trigger complete via *OPC?
self.vna.write("SENS:SWE:MODE SING;*OPC?")
self.vna.read()
self.stopTime = self.time.clock() - self.startTime
# The SDATA assertion queries underlying real and imaginary pair data
self.vna.write("CALC:DATA? SDATA")
self.traceData = self.vna.read()
print("Time to sweep = " + str(self.stopTime))
print("Number of trace points set = " + str(self.numPoints))
print("Number of characters in returned data " + str(len(self.traceData)))
print(self.traceData)
i = i + 1
# Check the error queue. Initially *CLS asserted in beginning of program.
# The application should run from stem to stern error free. The final error
# queue query should return '+0, No Error', else the application has potentially
# caused a correctable error!.
self.vna.write("SYST:ERR?")
print(self.vna.read())
# Close the VISA connection
self.vna.close()
#!/usr/bin/python3
import pyvisa
import time
class ClimateChamber:
def __init__(self, ip_address):
"""
Implements the basic operation of the climate chamber
"""
# open connection here
# store the credentials so that methods can access them
self.__ip_address = ip_address
# we try to connect to the climate chamber just to see if there is an error
self.rm = pyvisa.ResourceManager()
self.chamber = self.rm.open_resource("TCPIP0::" + str(self.__ip_address) + "::57732::SOCKET")
self.chamber.write_termination = '\r\n'
self.chamber.read_termination = '\r\n'
self.chamber.timeout = 5000
# the communication section
def read_temperature(self):
# data format: [current temp, set temp, upper limit, lower limit]
# send the request to the chamber
response = self.chamber.query("TEMP?", delay=2)
# self.my_socket.send(b'TEMP?\r\n')
# temperature = self.my_socket.recv((1024).decode('utf-8'))
# convert into float numbers
temperature = [float(i) for i in response.split(sep=',')]
return temperature
def read_humidity(self):
# data format: [current hum, set hum, upper limit, lower limit]
# send the request to the chamber
response = self.chamber.query("HUMI?", delay=2)
# convert into float numbers
humidity = [float(i) for i in response.split(sep=',')]
return humidity
def set_temperature(self, temperature):
# sets the temp of the chamber, (float) temperature
response = self.chamber.query("TEMP, S" + str(temperature))
# response = (OK: TEMP, S30\r\n)
return response
def set_humidity(self, humidity):
# sets the humidity of the chamber, (float) humidity
response = self.chamber.query("HUMI, S" + str(humidity))
# response = (OK: HUMI, S30\r\n)
return response
def close(self):
self.rm.close()
# additional functionality
def read_monitor(self):
""" gets the chamber test area state
output data format: [temp, humid, op-state, num. of alarms]
"""
response = self.chamber.query("MON?", delay=2)
return response
def set_temperature_limit(self, upper_limit, lower_limit):
"""
Sets the upper and lower temperature limits for the chamber
Parameters
----------
upper_limit : int
Temperature upper limit.
lower_limit : int
Temperature lower limit.
Returns
-------
None.
"""
response = self.chamber.query("TEMP, H" + str(upper_limit))
response = self.chamber.query("TEMP, L" + str(lower_limit))
def set_humidity_limit(self, upper_limit, lower_limit):
"""
Sets the upper and lower humidity limits for the chamber
Parameters
----------
upper_limit : int
humidity upper limit.
lower_limit : int
humidity lower limit.
Returns
-------
None.
"""
response = self.chamber.query("HUMI, H" + str(upper_limit))
response = self.chamber.query("HUMI, L" + str(lower_limit))
def read_mode(self):
""" read the mode of the chamber:
Panel power off "OFF"
All operation stop "STANDBY"
Constant operation "CONSTANT"
Program/remote operation "RUN"
"""
response = self.chamber.query("MODE?", delay=2)
return response
def set_mode(self, mode):
# sets the mode of the chamber:
response = self.chamber.query("MODE, " + mode, delay=2)
return response
def _get_const(self, mode):
response = self.chamber.query("CONSTANT SET?" + mode)
return response
def get_const(self):
"""
combination of read_temperature() and read_humidity()
"""
temp = self.read_temperature()
hum = self.read_humidity()
return [temp, hum]
def set_const(self, setPoint):
"""
Parameters
----------
setPoint : tuple(float,float)
A tuple of temperature and humidity as setpoint
Returns
-------
None.
"""
# setPoint = (temp,hum)
self.set_temprature(setPoint[0])
self.set_humidity(setPoint[1])
def goto_const(self, setPoint, target_accuracy=(0.2, 1), soaking_time=60):
"""
Parameters
----------
setPoint : tuple(float,float)
A tuple of temperature and humidity as setpoint.
target_accuracy : tuple(float,float), optional
A tuple of temperature and humidity as accuracy. The default is (0.2, 1).
soaking_time : int, optional
Soaking time. The default is 60.
Returns
-------
None.
"""
current_milli_time = lambda: int(round(time.time() * 1000))
# set temperature and humidity
self.set_const(setPoint)
# set mode to Const
self.set_mode('CONSTANT')
start_time = current_milli_time()
# wait until setpoint is reached (+soaking time)
while True:
# get the actual temperature & humidity
[temp, hum, mode, alarms] = self.read_monitor().split(',')
# if it is not within the target range reset start time
if not (setPoint[0] - target_accuracy[0] <= float(temp) <= setPoint[0] + target_accuracy[0]):
start_time = current_milli_time()
if not (setPoint[1] - target_accuracy[1] <= float(hum) <= setPoint[1] + target_accuracy[1]):
start_time = current_milli_time()
# if the value is stable long enough
if ((current_milli_time() - start_time) / 1000 > soaking_time):
print('SOAKING FINISHED!')
break
print('Temp: ' + temp + ' °C'
+ '| Humid: ' + hum + '%'
+ '|| time soaking:' + str((current_milli_time() - start_time) / 1000) + 's')
sleep(1)
# The climate chamber will instantly begin with the heat-up.
# The Python process will instantly continue (so it will not wait until the target temperature is reached).
# This function is blocking until the temperature and humidity setpoint have been reached
def is_temperature_reached(self):
current_temp = self.read_temperature()
set_temp = self.set_temperature()
while (not current_temp == set_temp):
print('Target temperature reached =' + str(set_temp))
break
def is_humidity_reached(self):
current_hum = self.read_humidity()
set_hum = self.set_humidity()
while (not current_hum == set_hum):
print('Target humidity reached =' + str(set_hum))
break
def wait_for_setpoints_reached(self):
while (not self.is_humiditiy_reached()) or (not self.is_temperature_reached()):
time.sleep(10)
break
from climate_chamber import ClimateChamber
ip_address = '192.168.115.129'
#initiate and connect to humidity chamber
chamber = ClimateChamber(ip_address)
print('connected')
#Read and print temperature
#temp = [current temp, set temp, upper limit, lower limit]
temp = chamber.read_temperature()
print('Current temperature (°C): ' + str(temp[0]))
#Read and print humidity
#humi = [current humi, set humi, upper limit, lower limit]
humi = chamber.read_humidity()
print('Current humidity (%): ' + str(humi[0]))
#to get the mode of the chamber(OFF, STANDBY or CONSTANT)
status = chamber.read_mode()
print('The chamber status is: ' + str(status))
#to enable or disable the climate chamber we can use command chamber.set_mode()
#let's heat the chamber to 35 °C and 35% relative humidity
#And after connecting, need to set the setpoint and enable the climate chamber
chamber.set_const((35,35))
chamber.set_mode('CONSTANT')
#chamber.goto_const() will block further Python program execution until the target temperature is reached and stable
chamber.goto_const((25,30), (0.2,1), 60)
print('The temperature is stable.')
import sys
from PyQt5.QtGui import QWindow
from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget
from PyQt5 import uic
class MainWindow(QMainWindow):
def __init__(self, *args, **kwargs):
super(MainWindow, self).__init__(*args, **kwargs)
uic.loadUi("main.ui", self)
self.show()
if __name__ == "__main__":
app = QApplication(sys.argv)
main_window = QMainWindow()
app.exec_()
import sys
from PyQt5.QtGui import QWindow
from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget
from ui_startpage import Ui_StartPage
from ui_temperaturesweep import Ui_TemperatureSweep
class TempSweepWindow(QWidget, Ui_TemperatureSweep):
def __init__(self, *args, **kwargs):
super(TempSweepWindow, self).__init__(*args, **kwargs)
self.setupUi(self)
class MainWindow(QMainWindow, Ui_StartPage):
def __init__(self, *args, **kwargs):
super(MainWindow, self).__init__(*args, **kwargs)
self.setupUi(self)
self.pushButton.pressed.connect(self.__create_temprature_sweep_window)
def __create_temprature_sweep_window(self):
self.temp_sweep = TempSweepWindow(self)
self.temp_sweep.show()
# you could add a signal here that links to another window instead
self.temp_sweep.pushButton.pressed.connect(self.temp_sweep.hide)
if __name__ == "__main__":
app = QApplication(sys.argv)
main_window = MainWindow()
main_window.show()
app.exec_()
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment