diff --git a/scm_v3c/sensor_adc/adc.py b/scm_v3c/sensor_adc/adc.py index 10702675..2f47ea27 100644 --- a/scm_v3c/sensor_adc/adc.py +++ b/scm_v3c/sensor_adc/adc.py @@ -201,5 +201,80 @@ def test_adc_psu( return adc_outs +def test_temp_sensor(scm_port="COM18", temp_port="COM9", control_mode='uart', read_mode='uart', + iterations=1): + """ + Inputs: + scm_port: String. Name of the COM port that the UART is connected to. + temp_port: String. Name of the COM port that the ground truth temperature sensor + is connected to. + control_mode: String 'uart', 'loopback' 'gpio'. Determines if you'll be triggering + the FSM via UART, GPIO loopback, or externally-controlled (e.g. Teensy) GPI. + read_mode: String 'uart' or 'gpio'. Determines if you're reading via GPIO. + iterations: Integer. Number of times to take a reading for + a single input voltage. + Outputs: + Returns an ordered collection of tuples (gnd_truth, adc_code) + where the ith element corresponds to the ith reading. gnd_truth is the value + read from the device used for ground truth temperature measurements. + adc_code is the output of the ADC for that particular reading. Note that this + assumes that SCM has already been programmed. + Raises: + ValueError if the control mode is not 'uart', 'loopback', or 'gpio'. + ValueError if the read mode is not 'uart' or 'gpio'. + """ + if control_mode not in ['uart', 'loopback', 'gpio']: + raise ValueError("Invalid control mode {}".format(control_mode)) + if read_mode not in ['uart', 'gpio']: + raise ValueError("Invalid read mode {}".format(read_mode)) + + # Opening up the UART connection + scm_ser = serial.Serial( + port=scm_port, + baudrate=19200, + parity=serial.PARITY_NONE, + stopbits=serial.STOPBITS_ONE, + bytesize=serial.EIGHTBITS, + timeout=1) + + # Opening the ground truth temperature sensor connection + temp_ser = serial.Serial( + port=temp_port, + baudrate=19200, + parity=serial.PARITY_NONE, + stopbits=serial.STOPBITS_ONE, + bytesize=serial.EIGHTBITS, + timeout=1) + + results = [] + + for _ in range(iterations): + # Trigger the ground truth temperature reading + temp_ser.write(b"temp\n") + + # Trigger SCM ADC reading + trigger_spot(scm_ser, control_mode) + + if read_mode == 'uart': + read_func = read_uart + elif read_mode == 'gpio': + read_func = read_gpo + + # Read from the ground truth temp sensor + gnd_truth = temp_ser.readline() + + # Read from SCM + adc_out = read_func(scm_ser) + + print((gnd_truth, adc_out)) + # Append the results + results.append((gnd_truth, adc_out)) + + temp_ser.close() + scm_ser.close() + + return results + + if __name__ == "__main__": print("Don't modify this file. Use ../run_me.py ") \ No newline at end of file diff --git a/scm_v3c/sensor_adc/data_handling.py b/scm_v3c/sensor_adc/data_handling.py index 3eaeb184..e533e40c 100644 --- a/scm_v3c/sensor_adc/data_handling.py +++ b/scm_v3c/sensor_adc/data_handling.py @@ -10,6 +10,70 @@ import numpy as np from scipy import stats +def write_temp_data(temp_data, file_out): + """ + Inputs: + temp_data: A collection of tuples (gnd_truth, adc_out) where + gnd_truth is the reading from the ground truth I2C temperature + sensor and adc_out is the ADC reading taken for that temperature. + file_out: String. Path to the file to hold the data. + Outputs: + No return value. The first column is the temperature readings taken + from the I2C temperature sensor. The second column is the ADC codes + associated with the I2C reading of the same row. + """ + with open(file_out, 'w') as f: + fwriter = csv.writer(f) + for tup in temp_data: + fwriter.writerow(list(tup)) + return + +def read_temp_data(file_in): + """ + Inputs: + file_in: String. Path to the file containing the data. The format + should have it that the first column is the ground truth values, + and the second column is the ADC readings. + + e.g. + gnd_truth0, adc0 + gnd_truth1, adc1 + Outputs: + Returns a collection of tuples (gnd_truth, adc_out) where gnd_truth + is the reading from the ground truth I2C temperature sensor and + adc_out is the ADC reading taken for that temperature. + """ + temp_data = [] + with open(file_in, 'r') as f: + freader = csv.reader(f) + for row in freader: + if len(row) == 0: + continue + gnd_truth = row[0] + adc_out = row[1] + temp_data.append((gnd_truth, adc_out)) + return temp_data + +def plot_temp_data(temp_data, pga_gain=1): + """ + Inputs: + temp_data: A collection of tuples (gnd_truth, adc_out) where + gnd_truth is the reading from the ground truth I2C temperature + sensor and adc_out is the ADC reading taken for that temperature. + pga_gain: Integer. The gain setting on the PGA. This is strictly + for record-keeping purposes. + Outputs: + No return value. Provides a scatter plot of ADC code vs. ground + truth temperature. + """ + gnd_truths = [float(datum[0]) for datum in temp_data] + adc_outs = [int(datum[1]) for datum in temp_data] + plt.scatter(gnd_truths, adc_outs) + plt.title("PGA Gain={0}".format(pga_gain)) + plt.xlabel("I2C Temperature Reading") + plt.ylabel("ADC Code") + plt.show() + def write_adc_data(adc_outs, file_out): """ Inputs: @@ -132,8 +196,6 @@ def calc_adc_inl_straightline(adc_outs, vlsb_ideal): return slope, intercept - - def plot_adc_data(adc_outs, plot_inl=False, plot_ideal=False, vdd=1.2, num_bits=10): """ Inputs: