def openCsvFile(self): if not os.path.isdir('./data'): # create the data directory os.mkdir('./data') filename = "./data/mcc134_test_" + datetime.datetime.now().strftime( "%d-%m-%Y_%H-%M-%S") + ".csv" self.csvfile = open(filename, 'w') mystr = ("Time," + ",".join("TC {}".format(channel) for channel in range(mcc134.info().NUM_AI_CHANNELS)) + "," + ",".join("CJC {}".format(channel) for channel in range(mcc134.info().NUM_AI_CHANNELS)) + ",Status\n") self.csvfile.write(mystr)
def pressedOpenButton(self): if self.open_button.cget('text') == "Open": # Open the selected device address = int(self.device_variable.get()) if self.openDevice(address): self.device_open = True self.open_address = address self.enableControls() # read the TC types for index in range(mcc134.info().NUM_AI_CHANNELS): tc_type = self.board.tc_type_read(index) self.tc_type_vars[index].set( self.tc_types_reversed[tc_type]) if tc_type == TcTypes.DISABLED: self.channel_labels[index].config(state=DISABLED) self.temperatures[index].config(state=DISABLED) else: self.channel_labels[index].config(state=NORMAL) self.temperatures[index].config(state=NORMAL) # Periodically read the inputs and update controls self.updateInputs() self.open_button.config(text="Close") else: messagebox.showerror("Error", "Could not open device.") else: if self.device_open: self.closeDevice() self.device_open = False self.open_button.config(text="Open") self.disableControls()
def updateDisplay(self): for channel in range(mcc134.info().NUM_AI_CHANNELS): self.tc_voltage_labels[channel].config( text="{:.1f}".format(self.tc_voltages[channel])) self.tc_failure_labels[channel].config( text="{}".format(self.tc_failures[channel])) self.cjc_temp_labels[channel].config( text="{:.1f}".format(self.cjc_temps[channel])) self.cjc_failure_labels[channel].config( text="{}".format(self.cjc_failures[channel])) self.cjc_error_labels[channel].config( text="{:.1f}".format(self.cjc_errors[channel])) self.baseline_temp_labels[channel].config( text="{:.1f}".format(self.baseline_temps[channel])) if self.current_failures > 0: self.inst_pass_led.set(2) self.pass_led.set(2) else: self.inst_pass_led.set(1) #self.pass_id = self.master.after(500, self.passBlink) self.software_error_label.config( text="{}".format(self.software_errors)) self.test_count_label.config(text="{}".format(self.test_count))
def resetTest(self): # Reset the error counters and restart if self.id: self.master.after_cancel(self.id) if self.activity_id: self.master.after_cancel(self.activity_id) #if self.pass_id: # self.master.after_cancel(self.pass_id) if self.csvfile: self.csvfile.close() self.csfvile = None self.board = None self.device_open = False self.tc_voltages = [0.0]*mcc134.info().NUM_AI_CHANNELS self.tc_failures = [0]*mcc134.info().NUM_AI_CHANNELS self.cjc_temps = [0.0]*mcc134.info().NUM_AI_CHANNELS self.cjc_errors = [0.0]*mcc134.info().NUM_AI_CHANNELS self.baseline_temps = [0.0]*mcc134.info().NUM_AI_CHANNELS self.cjc_failures = [0]*mcc134.info().NUM_AI_CHANNELS self.test_count = 0 self.software_errors = 0 self.baseline_set = False self.watchdog_count = 0 self.pass_led.set(1) self.inst_pass_led.set(0) self.ready_led.set(0) self.master.after(500, self.establishBaseline)
def initBoard(self): # Try to initialize the device try: self.board = mcc134(0) serial = self.board.serial() self.serial_number.set(serial) for channel in range(mcc134.info().NUM_AI_CHANNELS): self.board.tc_type_write(channel, TcTypes.TYPE_T) self.ready_led.set(1) self.device_open = True except: self.software_errors += 1 self.current_failures += 1
def updateInputs(self): if self.device_open: # Read the enabled channels for channel in range(mcc134.info().NUM_AI_CHANNELS): if self.tc_type_vars[channel].get() != 'Disabled': value = self.board.t_in_read(channel) if value == mcc134.OPEN_TC_VALUE: text = "Open" elif value == mcc134.OVERRANGE_TC_VALUE: text = "Overrange" elif value == mcc134.COMMON_MODE_TC_VALUE: text = "Common mode error" else: text = "{:.2f}".format(value) self.temperatures[channel].config(text=text) # call this every second self.job = self.master.after(1000, self.updateInputs)
def establishBaseline(self): self.id = None self.current_failures = 0 if self.device_open: self.activity_led.set(1) self.activity_id = self.master.after(100, self.activityBlink) self.current_failures = 0 try: for channel in range(mcc134.info().NUM_AI_CHANNELS): # read the cjc value self.cjc_temps[channel] = self.board.cjc_read(channel) self.baseline_temps[channel] = self.cjc_temps[channel] self.baseline_set = True self.watchdog_count = 0 # Create csv file with current date/time in file name self.openCsvFile() # go to the test loop self.id = self.master.after(1000, self.updateInputs) except FileNotFoundError: messagebox.showerror("Error", "Cannot create CSV file") except: self.software_errors += 1 self.current_failures += 1 self.watchdog_count += 1 # try again self.id = self.master.after(1000, self.establishBaseline) self.updateDisplay() else: # Open the device self.initBoard() # schedule another attempt self.id = self.master.after(500, self.establishBaseline)
def __init__(self, master): self.master = master master.title("MCC 134 Control Panel") # Initialize variables self.device_open = False self.open_address = 0 self.board = None self.job = None self.tc_types = { "J": TcTypes.TYPE_J, "K": TcTypes.TYPE_K, "T": TcTypes.TYPE_T, "E": TcTypes.TYPE_E, "R": TcTypes.TYPE_R, "S": TcTypes.TYPE_S, "B": TcTypes.TYPE_B, "N": TcTypes.TYPE_N, "Disabled": TcTypes.DISABLED } self.tc_types_reversed = dict(map(reversed, self.tc_types.items())) # GUI Setup self.bold_font = tkinter.font.Font( family=tkinter.font.nametofont("TkDefaultFont")["family"], size=tkinter.font.nametofont("TkDefaultFont")["size"], weight="bold") # Create and organize frames self.top_frame = tkinter.LabelFrame(master, text="Select Device") self.top_frame.pack(expand=False, fill=tkinter.X) self.mid_frame = tkinter.LabelFrame(master, text="TC Types") self.mid_frame.pack(expand=False, fill=tkinter.X) self.bottom_frame = tkinter.LabelFrame(master, text="Temperature Inputs") self.bottom_frame.pack(expand=True, fill=tkinter.BOTH) # Create widgets self.dev_label = tkinter.Label(self.top_frame, text="MCC 134 address:") self.dev_label.grid(row=0, column=0) self.open_button = tkinter.Button(self.top_frame, text="Open", width=6, command=self.pressed_open_button) # Get list of MCC 134 devices for the device list widget self.addr_list = self.list_devices() if not self.addr_list: self.device_lister = tkinter.Label(self.top_frame, text="None found") self.open_button.config(state=tkinter.DISABLED) else: self.device_variable = tkinter.StringVar(self.top_frame) self.device_variable.set(self.addr_list[0]) self.device_lister = tkinter.OptionMenu(self.top_frame, self.device_variable, *self.addr_list) self.device_lister.grid(row=0, column=1) self.open_button.grid(row=0, column=2) self.channel_labels = [] self.tc_type_options = [] self.temperatures = [] self.tc_type_vars = [] tc_choices = ("J", "K", "T", "E", "R", "S", "B", "N", "Disabled") for index in range(mcc134.info().NUM_AI_CHANNELS): # TC types and labels label = tkinter.Label(self.mid_frame, text="Ch {}".format(index)) label.grid(row=index, column=0) self.tc_type_vars.append(tkinter.StringVar(self.mid_frame)) self.tc_type_vars[index].set(tc_choices[0]) self.tc_type_options.append( tkinter.OptionMenu(self.mid_frame, self.tc_type_vars[index], *tc_choices, command=lambda value, index=index: self. pressed_tc(value, index))) self.tc_type_options[index].grid(row=index, column=1) self.tc_type_options[index].grid_configure(sticky="E") # Labels self.channel_labels.append( tkinter.Label(self.bottom_frame, text="Ch {}".format(index), font=self.bold_font)) self.channel_labels[index].grid(row=index, column=1) self.channel_labels[index].grid_configure(sticky="W") # Temperatures self.temperatures.append( tkinter.Label(self.bottom_frame, text="0.00", font=self.bold_font)) self.temperatures[index].grid(row=index, column=3) self.temperatures[index].grid_configure(sticky="E") self.bottom_frame.grid_rowconfigure(index, weight=1) self.mid_frame.grid_columnconfigure(1, weight=1) self.bottom_frame.grid_columnconfigure(1, weight=1) self.bottom_frame.grid_columnconfigure(2, weight=1) self.bottom_frame.bind("<Configure>", self.resize_text) # Disable widgets until a device is opened self.disable_controls() master.protocol('WM_DELETE_WINDOW', self.close) # exit cleanup icon = tkinter.PhotoImage(file='/usr/share/mcc/daqhats/icon.png') # pylint: disable=protected-access master.tk.call('wm', 'iconphoto', master._w, icon)
def __init__(self, master): self.master = master master.title("MCC 134 CE Test") # Initialize variables self.device_open = False self.board = None self.tc_limit = DEFAULT_TC_LIMIT self.cjc_limit = DEFAULT_CJC_LIMIT self.tc_voltages = [0.0]*mcc134.info().NUM_AI_CHANNELS self.tc_failures = [0]*mcc134.info().NUM_AI_CHANNELS self.cjc_temps = [0.0]*mcc134.info().NUM_AI_CHANNELS self.cjc_errors = [0.0]*mcc134.info().NUM_AI_CHANNELS self.baseline_temps = [0.0]*mcc134.info().NUM_AI_CHANNELS self.cjc_failures = [0]*mcc134.info().NUM_AI_CHANNELS self.test_count = 0 self.software_errors = 0 self.baseline_set = False self.watchdog_count = 0 self.csvfile = None # GUI Setup # Device Frame self.device_frame = LabelFrame(master, text="Device status") #self.device_frame.pack(side=TOP, expand=False, fill=X) self.device_frame.grid(row=0, column=0, padx=3, pady=3, sticky="NSEW") # Device widgets label = Label(self.device_frame, text="Serial number:") label.grid(row=0, column=0, padx=3, pady=3, sticky="E") self.serial_number = StringVar(self.device_frame, "00000000") label = Label(self.device_frame, width=8, textvariable=self.serial_number, relief=SUNKEN) label.grid(row=0, column=1, padx=3, pady=3, ipadx=2, ipady=2) label = Label(self.device_frame, text="Software errors:") label.grid(row=1, column=0, padx=3, pady=3, sticky="E") self.software_error_label = Label( self.device_frame, width=8, text="0", relief=SUNKEN) self.software_error_label.grid(row=1, column=1, padx=3, pady=3, ipadx=2, ipady=2) label = Label(self.device_frame, text="Ready:") label.grid(row=0, column=3, padx=3, pady=3, sticky="E") self.ready_led = LED(self.device_frame, size=20) self.ready_led.grid(row=0, column=4, padx=3, pady=3) label = Label(self.device_frame, text="Activity:") label.grid(row=1, column=3, padx=3, pady=3, sticky="E") self.activity_led = LED(self.device_frame, size=20) self.activity_led.grid(row=1, column=4, padx=3, pady=3) # empty column for stretching self.device_frame.grid_columnconfigure(2, weight=1) # Test Frame self.test_frame = LabelFrame(master, text="Test status") self.test_frame.grid(row=0, column=1, columnspan=2, sticky="NSEW", padx=3, pady=3) # Test widgets label = Label(self.test_frame, text="Pass/fail (latch):") label.grid(row=0, column=0, padx=3, pady=3, sticky="E") self.pass_led = LED(self.test_frame, size=20) self.pass_led.grid(row=0, column=1, padx=3, pady=3) label = Label(self.test_frame, text="Pass/fail (inst):") label.grid(row=1, column=0, padx=3, pady=3, sticky="E") self.inst_pass_led = LED(self.test_frame, size=20) self.inst_pass_led.grid(row=1, column=1, padx=3, pady=3) label = Label(self.test_frame, text="Test count:") label.grid(row=0, column=2, padx=3, pady=3, sticky="E") self.test_count_label = Label(self.test_frame, width=8, text="0", relief=SUNKEN) self.test_count_label.grid(row=0, column=3, padx=3, pady=3) self.stop_button = Button(self.test_frame, text="Stop", fg="red", command=self.stopTest) self.stop_button.grid(row=0, column=4, padx=3, pady=3, sticky="NSEW") self.reset_button = Button(self.test_frame, text="Reset", command=self.resetTest) self.reset_button.grid(row=1, column=4, padx=3, pady=3, sticky="NSEW") v = IntVar() self.watchdog_check = Checkbutton( self.test_frame, text="Use watchdog", variable=v) self.watchdog_check.var = v self.watchdog_check.grid(row=1, column=2, columnspan=2, padx=3, pady=3, sticky="W") # TC Frame self.tc_frame = LabelFrame(master, text="Thermocouple Inputs") #self.tc_frame.pack(side=BOTTOM, expand=True, fill=BOTH) self.tc_frame.grid(row=1, column=0, sticky="NSEW", padx=3, pady=3) # TC widgets label = Label(self.tc_frame, text="Limit: ±") label.grid(row=0, column=0, padx=3, pady=3, sticky="E") label = Label(self.tc_frame, text="{:.1f}".format(self.tc_limit), relief=SUNKEN, anchor=E, width=8) label.grid(row=0, column=1, padx=3, pady=3, ipadx=2, ipady=2) label = Label(self.tc_frame, text="Channel") label.grid(row=1, column=0, padx=3, pady=3) label = Label(self.tc_frame, text="Current") label.grid(row=1, column=1, padx=3, pady=3) label = Label(self.tc_frame, text="Failures") label.grid(row=1, column=2, padx=3, pady=3) self.tc_voltage_labels = [] self.tc_failure_labels = [] for index in range(mcc134.info().NUM_AI_CHANNELS): # Labels label = Label(self.tc_frame, text="{}".format(index)) label.grid(row=index+2, column=0, padx=3, pady=3) #label.grid_configure(sticky="W") # TC Voltages self.tc_voltage_labels.append(Label(self.tc_frame, width=8, anchor=E, text="0.0", relief=SUNKEN)) self.tc_voltage_labels[index].grid(row=index+2, column=1, padx=3, pady=3, ipadx=2, ipady=2) self.tc_voltage_labels[index].grid_configure(sticky="E") self.tc_failure_labels.append(Label(self.tc_frame, width=8, anchor=E, relief=SUNKEN, text="0")) self.tc_failure_labels[index].grid(row=index+2, column=2, padx=3, pady=3, ipadx=2, ipady=2) #self.tc_frame.grid_rowconfigure(index, weight=1) #self.tc_frame.grid_columnconfigure(1, weight=1) #self.tc_frame.grid_columnconfigure(2, weight=1) # CJC Frame self.cjc_frame = LabelFrame(master, text="CJC Sensors") #self.cjc_frame.pack(side=BOTTOM, expand=True, fill=BOTH) self.cjc_frame.grid(row=1, column=1, sticky="NSEW", padx=3, pady=3) # CJC widgets label = Label(self.cjc_frame, text="Limit: ±") label.grid(row=0, column=2, padx=3, pady=3, sticky="E") label = Label(self.cjc_frame, relief=SUNKEN, anchor=E, width=6, text="{:.1f}".format(self.cjc_limit)) label.grid(row=0, column=3, padx=3, pady=3, ipadx=2, ipady=2, sticky="NSEW") label = Label(self.cjc_frame, text="Channel") label.grid(row=1, column=0, padx=3, pady=3) label = Label(self.cjc_frame, text="Baseline") label.grid(row=1, column=1, padx=3, pady=3) label = Label(self.cjc_frame, text="Current") label.grid(row=1, column=2, padx=3, pady=3) label = Label(self.cjc_frame, text="Difference") label.grid(row=1, column=3, padx=3, pady=3) label = Label(self.cjc_frame, text="Failures") label.grid(row=1, column=4, padx=3, pady=3) self.baseline_temp_labels = [] self.cjc_temp_labels = [] self.cjc_error_labels = [] self.cjc_failure_labels = [] for index in range(mcc134.info().NUM_AI_CHANNELS): label = Label(self.cjc_frame, text="{}".format(index)) label.grid(row=index+2, column=0, padx=3, pady=3) #label.grid_configure(sticky="W") self.baseline_temp_labels.append(Label(self.cjc_frame, width=6, anchor=E, text="0.0", relief=SUNKEN)) self.baseline_temp_labels[index].grid(row=index+2, column=1, padx=3, pady=3, ipadx=2, ipady=2, sticky="NSEW") #self.baseline_temp_labels[index].grid_configure(sticky="E") self.cjc_temp_labels.append(Label(self.cjc_frame, width=6, anchor=E, text="0.0", relief=SUNKEN)) self.cjc_temp_labels[index].grid(row=index+2, column=2, padx=3, pady=3, ipadx=2, ipady=2, sticky="NSEW") #self.cjc_temp_labels[index].grid_configure(sticky="E") self.cjc_error_labels.append(Label(self.cjc_frame, width=6, anchor=E, text="0.0", relief=SUNKEN)) self.cjc_error_labels[index].grid(row=index+2, column=3, padx=3, pady=3, ipadx=2, ipady=2, sticky="NSEW") #self.cjc_error_labels[index].grid_configure(sticky="E") self.cjc_failure_labels.append(Label(self.cjc_frame, width=8, anchor=E, relief=SUNKEN, text="0")) self.cjc_failure_labels[index].grid(row=index+2, column=4, padx=3, pady=3, ipadx=2, ipady=2, sticky="NSEW") master.protocol('WM_DELETE_WINDOW', self.close) # exit cleanup icon = PhotoImage(file='/usr/share/mcc/daqhats/icon.png') master.tk.call('wm', 'iconphoto', master._w, icon) self.pass_led.set(1) self.master.after(500, self.establishBaseline)
def updateInputs(self): self.id = None if self.device_open: self.activity_led.set(1) self.activity_id = self.master.after(100, self.activityBlink) self.current_failures = 0 logstr = datetime.datetime.now().strftime("%H:%M:%S") + "," try: for channel in range(mcc134.info().NUM_AI_CHANNELS): # read the tc value self.tc_voltages[channel] = self.board.a_in_read(channel) * 1e6 # read the cjc value self.cjc_temps[channel] = self.board.cjc_read(channel) self.watchdog_count = 0 if self.baseline_set == True: # compare to limits tc_voltage = self.tc_voltages[channel] if (tc_voltage > self.tc_limit) or (tc_voltage < -self.tc_limit): self.current_failures += 1 self.tc_failures[channel] += 1 self.cjc_errors[channel] = (self.cjc_temps[channel] - self.baseline_temps[channel]) cjc_error = self.cjc_errors[channel] if (cjc_error > self.cjc_limit) or (cjc_error < -self.cjc_limit): self.current_failures += 1 self.cjc_failures[channel] += 1 logstr += (",".join( "{:.1f}".format(value) for value in self.tc_voltages) + "," + ",".join( "{:.1f}".format(value) for value in self.cjc_temps) + ",\n") except: self.software_errors += 1 self.current_failures += 1 self.watchdog_count += 1 logstr += ",,,,,,,,Software error\n" self.csvfile.write(logstr) self.test_count += 1 self.updateDisplay() if (self.watchdog_check.var.get() == 1 and self.watchdog_count >= 5): self.board = None self.device_open = False self.watchdog_count = 0 self.ready_led.set(0) self.master.after(500, self.updateInputs) else: # schedule another update in 1 s self.id = self.master.after(1000, self.updateInputs) else: # Open the device self.initBoard() # schedule another attempt self.id = self.master.after(500, self.updateInputs)