def pressed_mode(self, value): self.input_mode = self.input_modes[value] self.board.a_in_mode_write(self.input_mode) if self.input_mode == AnalogInputMode.DIFF: state = tkinter.DISABLED else: state = tkinter.NORMAL for index in range(mcc128.info().NUM_AI_CHANNELS[AnalogInputMode.DIFF], mcc128.info().NUM_AI_CHANNELS[AnalogInputMode.SE]): if state == tkinter.NORMAL and self.check_values[index].get() == 0: pass else: self.checkboxes[index].config(state=state) self.channel_labels[index].config(state=state) self.voltages[index].config(state=state)
def update_inputs(self): """ Periodically read inputs and display the values """ if self.device_open: for channel in range( mcc128.info().NUM_AI_CHANNELS[self.input_mode]): if self.check_values[channel].get() == 1: value = self.board.a_in_read(channel) self.voltages[channel].config(text="{:.5f}".format(value)) # schedule another update in 200 ms self.master.after(200, self.update_inputs)
def enable_controls(self): """ Enable controls when board opened """ # Disable the address selector self.device_lister.config(state=tkinter.DISABLED) # Enable the board controls for child in self.mid_frame.winfo_children(): child.config(state=tkinter.NORMAL) for child in self.bottom_frame.winfo_children(): child.config(state=tkinter.NORMAL) # Reset the channels to enabled for index in range(mcc128.info().NUM_AI_CHANNELS[AnalogInputMode.SE]): self.check_values[index].set(1)
class DaqStreamSettings: # General settings guid = uuid.uuid4() sleep_between_reads = -1 # -1 = don't give away the time slice sleep_between_channels = 0.25 number_of_channels = 4 low_chan = 0 high_chan = 3 channels = [True, True, True, True] sensor_type = 'mcc_single_value_read' reader_type_a = 'mcc_single_value_read' # 'grove_gsr' # 'dummy_read' #'single_ended' #'differential_i2c' #'single_ended' #'differential' reader_type_b = 'mcc_single_value_read' # 'grove_gsr' # 'dummy_read' #'single_ended' #'differential_i2c' #'single_ended' #'differential' # DaqStreamSettings are the most important settings for DaqStreamInfo # MCC128-specific settings analog_input_range = AnalogInputRange.BIP_10V reader_type = 'differential' # or 'single-ended' options = OptionFlags.DEFAULT input_mode = AnalogInputMode.DIFF # or SE input_range = AnalogInputRange.BIP_10V # BIP_1V mcc_128_num_channels = mcc128.info().NUM_AI_CHANNELS[input_mode] sample_interval = 0.1 # 0.5 # Seconds
def main(): """ This function is executed automatically when the module is run directly. """ options = OptionFlags.DEFAULT low_chan = 0 high_chan = 3 input_mode = AnalogInputMode.SE input_range = AnalogInputRange.BIP_10V mcc_128_num_channels = mcc128.info().NUM_AI_CHANNELS[input_mode] sample_interval = 0.5 # Seconds try: # Ensure low_chan and high_chan are valid. if low_chan < 0 or low_chan >= mcc_128_num_channels: error_message = ('Error: Invalid low_chan selection - must be ' '0 - {0:d}'.format(mcc_128_num_channels - 1)) raise Exception(error_message) if high_chan < 0 or high_chan >= mcc_128_num_channels: error_message = ('Error: Invalid high_chan selection - must be ' '0 - {0:d}'.format(mcc_128_num_channels - 1)) raise Exception(error_message) if low_chan > high_chan: error_message = ('Error: Invalid channels - high_chan must be ' 'greater than or equal to low_chan') raise Exception(error_message) # Get an instance of the selected hat device object. address = select_hat_device(HatIDs.MCC_128) hat = mcc128(address) hat.a_in_mode_write(input_mode) hat.a_in_range_write(input_range) print('\nMCC 128 single data value read example') print(' Functions demonstrated:') print(' mcc128.a_in_read') print(' mcc128.a_in_mode_write') print(' mcc128.a_in_range_write') print(' Input mode: ', input_mode_to_string(input_mode)) print(' Input range: ', input_range_to_string(input_range)) print(' Channels: {0:d} - {1:d}'.format(low_chan, high_chan)) print(' Options:', enum_mask_to_string(OptionFlags, options)) try: input("\nPress 'Enter' to continue") except (NameError, SyntaxError): pass print('\nAcquiring data ... Press Ctrl-C to abort') # Display the header row for the data table. print('\n Samples/Channel', end='') for chan in range(low_chan, high_chan + 1): print(' Channel', chan, end='') print('') try: samples_per_channel = 0 while True: # Display the updated samples per channel count samples_per_channel += 1 print('\r{:17}'.format(samples_per_channel), end='') # Read a single value from each selected channel. for chan in range(low_chan, high_chan + 1): value = hat.a_in_read(chan, options) print('{:12.5} V'.format(value), end='') stdout.flush() # Wait the specified interval between reads. sleep(sample_interval) except KeyboardInterrupt: # Clear the '^C' from the display. print(CURSOR_BACK_2, ERASE_TO_END_OF_LINE, '\n') except (HatError, ValueError) as error: print('\n', error)
sys.path.insert(1, '/home/pi/Documents/Code/PlantPlayground') from pi.ADS1115Runner import * # Constants #CURSOR_BACK_2 = '\x1b[2D' #ERASE_TO_END_OF_LINE = '\x1b[0K' #MCC DAQ START options = OptionFlags.DEFAULT low_chan = 0 high_chan = 3 input_mode = AnalogInputMode.DIFF #or SE input_range = AnalogInputRange.BIP_10V #BIP_1V mcc_128_num_channels = mcc128.info().NUM_AI_CHANNELS[input_mode] sample_interval = 0.1 #0.5 # Seconds try: # Ensure low_chan and high_chan are valid. if low_chan < 0 or low_chan >= mcc_128_num_channels: error_message = ('Error: Invalid low_chan selection - must be ' '0 - {0:d}'.format(mcc_128_num_channels - 1)) raise Exception(error_message) if high_chan < 0 or high_chan >= mcc_128_num_channels: error_message = ('Error: Invalid high_chan selection - must be ' '0 - {0:d}'.format(mcc_128_num_channels - 1)) raise Exception(error_message) if low_chan > high_chan: error_message = ('Error: Invalid channels - high_chan must be ' 'greater than or equal to low_chan')
def __init__(self, master): self.master = master master.title("MCC 128 CE Test") # Initialize variables self.device_open = False self.board = None self.voltage_limit = DEFAULT_V_LIMIT self.max_channels = mcc128.info().NUM_AI_CHANNELS[TEST_MODE] self.voltages = [0.0] * self.max_channels self.failures = [0] * self.max_channels self.current_failures = 0 self.test_count = 0 self.trigger_errors = 0 self.last_trigger_error = False self.software_errors = 0 self.baseline_set = False self.watchdog_count = 0 self.csvfile = None self.id = None self.activity_id = None self.num_channels = self.max_channels self.scan_rate = SCAN_RATE self.scan_count = SCAN_SAMPLE_COUNT # 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="NEW") # 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, anchor=E) 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 setup") self.test_frame.grid(row=0, column=1, rowspan=2, sticky="NEW", padx=3, pady=3) # Test widgets self.test_frame = LabelFrame(master, text="Test setup") self.test_frame.grid(row=0, column=1, rowspan=2, sticky="NEW", padx=3, pady=3) # Test widgets label = Label(self.test_frame, text="# Channels:") label.grid(row=0, column=0, padx=3, pady=3, sticky="E") chan_values = list(range(1, self.max_channels + 1)) self.chan_combo = Combobox(self.test_frame, values=chan_values, width=8, justify="right") self.chan_combo.set(self.max_channels) self.chan_combo.bind("<<ComboboxSelected>>", self.channelsChanged) self.chan_combo.grid(row=0, column=1, padx=3, pady=3, sticky="NSEW") self.start_button = Button(self.test_frame, text="Start", command=self.startTest) self.start_button.grid(row=0, column=2, padx=3, pady=3) label = Label(self.test_frame, text="Sample rate:") label.grid(row=1, column=0, padx=3, pady=3, sticky="E") self.sample_rate = IntVar(value=12500) self.sample_rate_widget = Spinbox(self.test_frame, from_=1, to=12500, width=8, textvariable=self.sample_rate, justify="right") self.sample_rate_widget.grid(row=1, column=1, padx=3, pady=3, sticky="NSEW") style = Style() style.configure("C.TButton", foreground='red') self.stop_button = Button( self.test_frame, text="Stop", style="C.TButton", #foreground="red", command=self.stopTest, state=DISABLED) self.stop_button.grid(row=1, column=2, 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=2, column=0, columnspan=2, padx=3, pady=3, sticky="E") self.reset_button = Button(self.test_frame, text="Reset", command=self.resetTest) self.reset_button.grid(row=2, column=2, padx=3, pady=3, sticky="NSEW") label = Label(self.test_frame, text="Pass/fail (latch):") label.grid(row=3, column=0, padx=3, pady=3, sticky="E") self.pass_led = LED(self.test_frame, size=20) self.pass_led.grid(row=3, column=1, padx=3, pady=3) label = Label(self.test_frame, text="Pass/fail (inst):") label.grid(row=4, column=0, padx=3, pady=3, sticky="E") self.inst_pass_led = LED(self.test_frame, size=20) self.inst_pass_led.grid(row=4, column=1, padx=3, pady=3) label = Label(self.test_frame, text="Test count:") label.grid(row=5, column=0, padx=3, pady=3, sticky="E") self.test_count_label = Label(self.test_frame, width=8, text="0", relief=SUNKEN, anchor=E) self.test_count_label.grid(row=5, column=1, padx=3, pady=3) # Voltage Frame self.volt_frame = LabelFrame(master, text="Voltage Inputs, mV") #self.tc_frame.pack(side=BOTTOM, expand=True, fill=BOTH) self.volt_frame.grid(row=1, column=0, rowspan=2, sticky="NSEW", padx=3, pady=3) # Voltage widgets label = Label(self.volt_frame, text="Limit: ±") label.grid(row=0, column=0, padx=3, pady=3, sticky="E") label = Label(self.volt_frame, text="{:.3f}".format(self.voltage_limit), relief=SUNKEN, anchor=E, width=8) label.grid(row=0, column=1, padx=3, pady=3, ipadx=2, ipady=2) label = Label(self.volt_frame, text="Channel") label.grid(row=1, column=0, padx=3, pady=3) label = Label(self.volt_frame, text="Current") label.grid(row=1, column=1, padx=3, pady=3) label = Label(self.volt_frame, text="Failures") label.grid(row=1, column=2, padx=3, pady=3) self.voltage_labels = [] self.failure_labels = [] for index in range(self.max_channels): # Labels label = Label(self.volt_frame, text="{}".format(index)) label.grid(row=index + 2, column=0, padx=3, pady=3) #label.grid_configure(sticky="W") # Voltages self.voltage_labels.append( Label(self.volt_frame, width=8, anchor=E, text="0.0", relief=SUNKEN)) self.voltage_labels[index].grid(row=index + 2, column=1, padx=3, pady=3, ipadx=2, ipady=2) self.voltage_labels[index].grid_configure(sticky="E") self.failure_labels.append( Label(self.volt_frame, width=8, anchor=E, relief=SUNKEN, text="0")) self.failure_labels[index].grid(row=index + 2, column=2, padx=3, pady=3, ipadx=2, ipady=2) # Trigger Frame self.trigger_frame = LabelFrame(master, text="Trigger Input") self.trigger_frame.grid(row=2, column=1, sticky="NEW", padx=3, pady=3) label = Label(self.trigger_frame, text="Failures:") label.grid(row=0, column=0, padx=3, pady=3, sticky="E") self.trigger_error_label = Label(self.trigger_frame, width=8, text="0", relief=SUNKEN, anchor=E) self.trigger_error_label.grid(row=0, column=1, padx=3, pady=3, ipadx=2, ipady=2) 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)
def __init__(self, master): self.master = master master.title("MCC 128 Control Panel") # Initialize variables self.device_open = False self.open_address = 0 self.board = None # 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="Configuration") self.mid_frame.pack(expand=False, fill=tkinter.X) self.bottom_frame = tkinter.LabelFrame(master, text="Analog Inputs") self.bottom_frame.pack(expand=True, fill=tkinter.BOTH) # Create widgets self.dev_label = tkinter.Label(self.top_frame, text="MCC 128 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 128 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) label = tkinter.Label(self.mid_frame, text="Input mode") label.grid(row=0, column=0) label.grid_configure(sticky="E") label = tkinter.Label(self.mid_frame, text="Input range") label.grid(row=0, column=2) label.grid_configure(sticky="E") modes = ["Single Ended", "Differential"] self.input_modes = { "Single Ended": AnalogInputMode.SE, "Differential": AnalogInputMode.DIFF } self.input_modes_reversed = dict( map(reversed, self.input_modes.items())) self.input_mode = AnalogInputMode.SE self.input_mode_var = tkinter.StringVar(self.mid_frame) self.input_mode_var.set(modes[0]) self.mode_option = tkinter.OptionMenu(self.mid_frame, self.input_mode_var, *modes, command=self.pressed_mode) self.mode_option.config(width=12) self.mode_option.grid(row=0, column=1) self.mode_option.grid_configure(sticky="EW") ranges = ["10V", "5V", "2V", "1V"] self.input_ranges = { "10V": AnalogInputRange.BIP_10V, "5V": AnalogInputRange.BIP_5V, "2V": AnalogInputRange.BIP_2V, "1V": AnalogInputRange.BIP_1V } self.input_range = AnalogInputRange.BIP_10V self.input_ranges_reversed = dict( map(reversed, self.input_ranges.items())) self.input_range_var = tkinter.StringVar(self.mid_frame) self.input_range_var.set(ranges[0]) self.range_option = tkinter.OptionMenu(self.mid_frame, self.input_range_var, *ranges, command=self.pressed_range) self.range_option.config(width=3) self.range_option.grid(row=0, column=3) self.range_option.grid_configure(sticky="EW") self.checkboxes = [] self.check_values = [] self.channel_labels = [] self.voltages = [] for index in range(mcc128.info().NUM_AI_CHANNELS[AnalogInputMode.SE]): # Checkboxes self.check_values.append(tkinter.IntVar()) self.checkboxes.append( tkinter.Checkbutton( self.bottom_frame, variable=self.check_values[index], command=lambda index=index: self.pressed_check(index))) self.checkboxes[index].grid(row=index, column=0) self.checkboxes[index].select() # 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") # Voltages self.voltages.append( tkinter.Label(self.bottom_frame, text="0.00000", font=self.bold_font)) self.voltages[index].grid(row=index, column=2) self.voltages[index].grid_configure(sticky="E") self.bottom_frame.grid_rowconfigure(index, weight=1) self.mid_frame.grid_columnconfigure(0, weight=1) self.mid_frame.grid_columnconfigure(2, 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)