import PySimpleGUI as sg # on linux: # sudo pip3 install pyserial # /home/bruce/.local/lib/python3.5 # sudo python3.5 pic_target_3.py # # you can find out more about PySimleGUI at # https://pysimplegui.readthedocs.io/en/latest/ # # --event format to PIC-- # Four sharacters for each non-string event: # pushbutton event 'b' + 2 digit button number + value (1,0) # toggle sw event 't' + 2 digit button number + value (1,0) # slider event 's' + 1-digit slider number + n digit value # listbox event 'l' + + 1-digit listbox number + 1 digit selection number # radio button 'r' + 1 digit group number + 1 digit selection numbr # -- string -- # strings typed in the input line are sent in their entirety. # -- reset -- # RESET has NO code on PIC! # serial reset event sends a rs-232 BREAK which is connected # through a filter to MCLR pin # # Python_TX_pin--(100ohm)--(+Schottky Diode-)------>(target MCLR pin) # | # (10uf)------(1kohm) # | | # ------------- # | # (PIC gnd) # import time import serial # open microcontroller serial port # For windows the device will be 'COMx' ser = serial.Serial('/dev/ttyUSB0', 115200, timeout=0.001) # open serial port 38400 #sg.theme('DarkAmber') # Add a touch of color # All the stuff inside your window. # This a heirachical list of items to be displayd in the window # First list is first row controls, etc # Buttons: # Realtime buttons respond to push-events # After the window is defined below, release events may be bound to each realtime button # The 'key' for each button must be of the form 'pushbutNN', # where 'NN' are digits 0-9 defining the button number # Toggles: # Toggle switches are actually checkboxes # The 'key' for each checkbox must be of the form 'toggleNN', # where 'NN' are digits 0-9 defining the checkbox number # Sliders # The 'key' for each slider must be of the form 'sliderN', # where 'N' is a digit 0-9 defining the slider number # Sliders can have any integer range which is handy for the application # Text # The text input field acts like the one-line Arduino serial send box. # The multiline output box receives serial from the PIC. text typed here is ignored. # Listbox # The 'key' for each listbox must be of the form 'listN', # where 'N' is a digit 0-9 defining the listbox number # Listbox as implemented can have only one selected value font_spec = 'Courier 24 bold' heading_color = '#2FB8AD' layout = [ [sg.Text('LED Control', background_color=heading_color)], [sg.RealtimeButton('LED', key='pushbut01', font='Helvetica 12')], # [sg.Text('TFT LCD', background_color=heading_color)], [sg.RealtimeButton('CLR LCD', key='pushbut02', font='Helvetica 12'), sg.Checkbox('Dot Color', key='toggle01', font='Helvetica 12',enable_events=True)], [sg.Text('Line Position'), sg.Slider(range=(0,200), default_value=0, size=(22,15), key='slider1', orientation='horizontal', font=('Helvetica', 12),enable_events=True)], # [sg.Text('Direct Digital Synthesis', background_color=heading_color)], [sg.Radio('DDS', "radio1", default=True, key='radio1_1', enable_events=True), sg.Radio('Vout', "radio1", key='radio1_2', enable_events=True), sg.Listbox(values=['Sine', 'Square', 'Triangle'], key='list1', size=(10, 1), select_mode='LISTBOX_SELECT_MODE_SINGLE', enable_events=True)], # [sg.Text('DDS Freq'), sg.Slider(range=(20,1000), default_value=400, size=(22,15), key='slider2', orientation='horizontal', font=('Helvetica', 12),enable_events=True)], # [sg.Text(' Vout '), sg.Slider(range=(0,2.00), default_value=0, size=(22,15), key='slider3', resolution=0.01, orientation='horizontal', font=('Helvetica', 12),enable_events=True)], # [sg.Text('Serial data to PIC', background_color=heading_color)], [sg.InputText('', size=(40,10), key='pic_input', do_not_clear=False, enable_events=False, focus=True), sg.Button('Send', key='pic_send', font='Helvetica 12')], # [sg.Text('Serial data from PIC', background_color=heading_color)], [sg.Multiline('', size=(50,10), key='console', autoscroll=True, enable_events=False)], # [sg.Text('System Controls', background_color=heading_color)], [sg.Button('Exit', font='Helvetica 12')], [ sg.Checkbox('reset_enable', key='r_en', font='Helvetica 8', enable_events=True), sg.Button('RESET PIC', key='rtg', font='Helvetica 8') ] ] # change the colors in any way you like. sg.SetOptions(background_color='#9FB8AD', text_element_background_color='#9FB8AD', element_background_color='#475841',#'#9FB8AD', scrollbar_color=None, input_elements_background_color='#9FB8AD',#'#F7F3EC', progress_meter_color = ('green', 'blue'), button_color=('white','#475841'), ) # Create the Window window = sg.Window('ECE4760 Interface', layout, location=(0,0), return_keyboard_events=True, use_default_focus=True, element_justification='c', finalize=True) # Bind the realtime button release events # https://github.com/PySimpleGUI/PySimpleGUI/issues/2020 window['pushbut01'].bind('', 'r') window['pushbut02'].bind('', 'r') # Event Loop to process "events" # event is set by window.read event = 0 # # button state machine variables button_on = 0 button_which = '0' # # while True: # time out paramenter makes the system non-blocking # If there is no event the call returns event '__TIMEOUT__' event, values = window.read(timeout=20) # timeout=10 # #print(event) # for debugging # if user closes window using windows 'x' or clicks 'Exit' button if event == sg.WIN_CLOSED or event == 'Exit': # break # # pushbutton events state machine if event[0:3] == 'pus' and button_on == 0 : # 'b' for button, two numeral characters, a '1' for pushed, and a terminator ser.write(('b' + event[7:9] + '1' + '\r').encode()) button_on = 1 button_which = event[7:9] # releaase event signalled by the 'r' elif (button_on == 1 and event[7:10] == button_which +'r') : ser.write(('b' + button_which + '0' + '\r').encode()) button_on = 0 button_which = ' ' # # listbox if event[0:3] == 'lis' : # get the list box index# listbox_value = window.Element(event).GetIndexes() ser.write(('l0' + event[4] + str(listbox_value[0]) + '\r').encode()) # # radio button if event[0:3] == 'rad' : #print(event) # get the radio group ID and group-member ID radio1_2 ser.write(('r0' + event[5] + event[7] + '\r').encode()) # toggle switches if event[0:3] == 'tog' : # read out the toggle switches switch_state = window.Element(event).get() ser.write(('t' + event[6:8] + str(switch_state) + '\r').encode()) # # silder events if event[0:3] == 'sli' : ser.write(('s ' + event[6] + " {:f}".format((values[event])) + '\r').encode()) # # reset events switch_state = window.Element('r_en').get() if event[0:3] == 'rtg' and switch_state == 1 : # drops the data line for 100 mSec ser.send_break() #optional duration; duration=0.01 # # The one-line text input button event if event == 'pic_send': # The text from the one-line input field input_state = window.Element('pic_input').get() # add for PIC input_state = '$' + input_state + '\r' # zero the input field window['pic_input'].update('') # send to PIC protothreads ser.write((input_state).encode()) # # character loopback from PIC while ser.in_waiting > 0: #serial_chars = (ser.read().decode('utf-8')); #window['console'].update(serial_chars+'\n', append=True) pic_char = chr(ser.read(size=1)[0]) if (pic_char) == '\r' : window['console'].update('\n', append=True) else : window['console'].update((pic_char), append=True) # close port and Bail out ser.close() window.close()