diff --git a/Python_script/prototype.py b/Python_script/prototype.py index b5fcfbba3ecef6f3aef91265bd21a75635139b68..b50d5c28ddddc4ad8753c610bdc4e3cf05b7cfbd 100755 --- a/Python_script/prototype.py +++ b/Python_script/prototype.py @@ -7,7 +7,6 @@ import numpy from argparse import ArgumentParser import pandas as pd import matplotlib.pyplot as plt -import numpy as np import climate_chamber import VNA import virtual_time @@ -22,6 +21,10 @@ PHASE_STABLE = 0x8 class Measurements: def __init__(self, chamber_address, vna_address, sweep_file, output_file, standby, target_accuracy): self.target_accuracy = target_accuracy + self.max_delta_temp = target_accuracy[0] + self.max_delta_hum = target_accuracy[1] + self.max_delta_mag = data['delta_mag'] + self.max_delta_phase = data['delta_phase'] self.chamber = climate_chamber.create_chamber(chamber_address, self.target_accuracy) self.vna = VNA.create_vna(vna_address, target_accuracy) self.sweep_file = sweep_file @@ -29,6 +32,10 @@ class Measurements: self.output = output_file self.clock = virtual_time.get_clock(chamber_address, target_accuracy) self.soaking_time_past = False + self.temperature_stable = False + self.humidity_stable = False + self.magnitude_stable = False + self.phase_stable = False self.vna.create_new_trace("Trace1", "S11") self.vna.create_new_trace("Trace2", "S11") @@ -62,35 +69,73 @@ class Measurements: set_mode_response = self.chamber.set_mode('CONSTANT') print(set_mode_response) - start_time = self.current_milli_time() - self.soaking_time_past = False # wait until set point is reached (+soaking time) + magnitudes_queue = [] + phase_queue = [] + + number_of_soaking_reads = next_soaking / data["sleep_time"] + 1 + while True: - # FIXME: Reading is done in read_data_and_write again. Remove this duplication + # FIXME: put this to a "read data" function which returns a tuple? [temp, hum, mode, alarms] = self.chamber.read_monitor().split(',') + s11 = self.get_trace_data("Trace1") + s21 = self.get_trace_data("Trace2") + s12 = self.get_trace_data("Trace3") + s22 = self.get_trace_data("Trace4") # if it is not within the target range reset start time - if not(next_temp-self.target_accuracy[0] <= float(temp) <= next_temp+self.target_accuracy[0]): - start_time = self.current_milli_time() - - if not (next_hum-self.target_accuracy[1] <= float(hum) <= next_hum+self.target_accuracy[1]): - start_time = self.current_milli_time() - - # if the value is stable long enough - if (self.current_milli_time() - start_time) / 1000 > next_soaking: - print('SOAKING FINISHED!') - self.soaking_time_past = True - break - + self.temperature_stable = False + self.humidity_stable = False + + self.temperature_stable = (next_temp-self.target_accuracy[0] <= float(temp)) and (float(temp) <= next_temp+self.target_accuracy[0]) + print (temp + " temp has stability :" + str(self.temperature_stable)) + self.humidity_stable = (next_hum-self.target_accuracy[1] <= float(hum)) and (float(hum) <= next_hum+self.target_accuracy[1]) + print (hum + " hum has stability :" + str(self.humidity_stable)) + + # The queue must no be longer than the max number of soaking reads. + # If the queue is already full, we have to pop the first element before we can add the + # current measurement. + if len(magnitudes_queue) == number_of_soaking_reads: + magnitudes_queue.pop(0) + if self.temperature_stable and self.humidity_stable: + magnitudes_queue.append(self.calculate_mean_magnitude(s21)) + else: + magnitudes_queue.clear() + + # check cable stability parameters + self.magnitude_stable = False + if len(magnitudes_queue) == number_of_soaking_reads: + spread = max(magnitudes_queue) - min(magnitudes_queue) + if spread < 2*self.max_delta_mag: + self.magnitude_stable = True + + if len(phase_queue) == number_of_soaking_reads: + phase_queue.pop(0) + if self.temperature_stable and self.humidity_stable: + phase_queue.append(self.calculate_mean_magnitude(s21)) + else: + phase_queue.clear() + + self.phase_stable = False + if len(phase_queue) == number_of_soaking_reads: + spread = max(phase_queue) - min(phase_queue) + if spread < 2*self.max_delta_phase: + self.phase_stable = True + + # fixme: get rid of the read part, just write print('Setpoint: ' + str(next_temp) + ' ' + str(next_hum) + ' | Temp: ' + temp + ' °C' + ' | Humid: ' + hum + '%' - + ' | time soaking: ' + str((self.current_milli_time() - start_time) / 1000) + 's') + + ' | soaking read nr' + str(len(magnitudes_queue))) + self.data_write(writer, next_temp, next_hum) - self.read_data_and_write(writer, next_temp, next_hum) - self.clock.sleep(data["sleep_time"]) + if self.temperature_stable and self.humidity_stable and self.magnitude_stable and self.phase_stable: + print('SOAKING FINISHED!') + break + else: + self.clock.sleep(data["sleep_time"]) for i in range(0, next_reads): - self.read_data_and_write(writer, next_temp, next_hum) + self.data_write(writer, next_temp, next_hum) print('Read no.', str(i)) self.clock.sleep(data["sleep_time"]) @@ -101,7 +146,7 @@ class Measurements: standby_response = self.chamber.set_mode('STANDBY') print(standby_response) - def read_data_and_write(self, writer, target_temp, target_hum): + def data_write(self, writer, target_temp, target_hum): # get the actual temperature & humidity [temp, hum, mode, alarms] = self.chamber.read_monitor().split(',') s11 = self.get_trace_data("Trace1") @@ -116,7 +161,7 @@ class Measurements: 'READBACK_HUMIDITY': hum, 'RF_POWER': self.vna.get_current_power(), 'RF_FREQUENCY': self.vna.get_current_cw_frequency(), - 'EQUILIBRIUM_INDICATOR': self.equi_indicator(), + 'EQUILIBRIUM_INDICATOR': self.cook_up_equi_indicator(), 'S11_PHASE': self.calculate_mean_phase(s11), 'S11_MAGNITUDE': self.calculate_mean_magnitude(s11), 'S21_PHASE': self.calculate_mean_phase(s21), @@ -159,19 +204,19 @@ class Measurements: phases = self.calculate_phases(values_list) return numpy.mean(phases) - def equi_indicator(self): + def cook_up_equi_indicator(self): equilibrium_indicator = 0 - if self.chamber.is_temperature_reached(): + if self.temperature_stable: equilibrium_indicator = equilibrium_indicator | TEMPERATURE_STABLE - if self.chamber.is_humidity_reached(): + if self.humidity_stable: equilibrium_indicator = equilibrium_indicator | HUMIDITY_STABLE - # FIXME - if self.soaking_time_past == True: + + if self.magnitude_stable: equilibrium_indicator = equilibrium_indicator | MAGNITUDE_STABLE - if self.soaking_time_past == True: + if self.phase_stable: equilibrium_indicator = equilibrium_indicator | PHASE_STABLE return equilibrium_indicator @@ -180,37 +225,39 @@ class Measurements: data = pd.read_csv(output_file) fig, ax1 = plt.subplots(2, figsize=(8, 8)) + twin2_0 = ax1[0].twinx() + twin3_0 = ax1[0].twinx() + twin2_1 = ax1[1].twinx() + twin3_1 = ax1[1].twinx() fig.suptitle("Graphical representation of chamber output", color="red") - ax1[0].scatter(data.TIMESTAMP, data.S11_PHASE, c='red', marker='<') - ax2_0 = ax1[0].twinx() - ax1[0].scatter(data.TIMESTAMP, data.S11_MAGNITUDE, c='#3120E0', marker='4') - ax3_0 = ax1[0].twinx() - ax3_0.spines['right'].set_position(('outward', 40)) - ax1[0].scatter(data.TIMESTAMP, data.EQUILIBRIUM_INDICATOR, c='black', marker=".") - - ax1[0].set_xlabel("TIMESTAMP") - ax1[0].set_ylabel("PHASE", color='red') - ax2_0.set_ylabel("MAGNITUDE", color='#3120E0') - ax3_0.set_ylabel("EQUILIBRIUM_INDICATOR", color='black') - ax1[0].grid(True, linestyle=":") - ax1[0].legend(["Phase", "Magnitude", 'Equilibrium_indicator'], loc=6, fontsize=10) - ax1[1].scatter(data.TIMESTAMP, data.READBACK_TEMPERATURE, c='blue', marker='p') - ax2_1 = ax1[1].twinx() - ax1[1].scatter(data.TIMESTAMP, data.READBACK_HUMIDITY, c='green', marker="*") - ax3_1 = ax1[1].twinx() - ax3_1.spines['right'].set_position(('outward', 40)) - ax1[1].scatter(data.TIMESTAMP, data.EQUILIBRIUM_INDICATOR, c='black', marker=".") + twin2_1.scatter(data.TIMESTAMP, data.READBACK_HUMIDITY, c='green', marker="*") + twin3_1.spines['right'].set_position(('outward', 40)) + twin3_1.scatter(data.TIMESTAMP, data.EQUILIBRIUM_INDICATOR, c='black', marker=".") ax1[1].set_xlabel("TIMESTAMP") ax1[1].set_ylabel("TEMPERATURE ", color='blue') - ax2_1.set_ylabel("HUMIDITY", color='green') - ax3_1.set_ylabel("EQUILIBRIUM_INDICATOR", color='black') + twin2_1.set_ylabel("HUMIDITY", color='green') + twin3_1.set_ylabel("EQUILIBRIUM_INDICATOR", color='black') + ax1[1].grid(True, linestyle=":") ax1[1].legend(["Temperature", "Humidity", 'Equilibrium_indicator'], loc=6, fontsize=10) + ax1[0].scatter(data.TIMESTAMP, data.S11_PHASE, c='red', marker='<') + twin2_0.scatter(data.TIMESTAMP, data.S11_MAGNITUDE, c='#3120E0', marker='4') + twin3_0.spines['right'].set_position(('outward', 40)) + twin3_0.scatter(data.TIMESTAMP, data.EQUILIBRIUM_INDICATOR, c='black', marker=".") + + ax1[0].set_xlabel("TIMESTAMP") + ax1[0].set_ylabel("PHASE", color='red') + twin2_0.set_ylabel("MAGNITUDE", color='#3120E0') + twin3_0.set_ylabel("EQUILIBRIUM_INDICATOR", color='black') + + ax1[0].grid(True, linestyle=":") + ax1[0].legend(["Phase", "Magnitude", 'Equilibrium_indicator'], loc=6, fontsize=10) + plt.show() if __name__ == '__main__':