def control_stim_signal(event):
    click_location = 4
    click_value = event.x
    if event.x > 0 and event.x < 250:
        click_location = int(event.y / 60)

        #0 = pwm, 1 = freq, 2 = ch1, 3 = ch2
        if click_location == 0:
            global EMG_pwm
            EMG_pwm = int(click_value)
            set_controller_freq_pwm(EMG_pwm, EMG_freq)
        elif click_location == 1:
            global EMG_freq
            EMG_freq = int(click_value)
            set_controller_freq_pwm(EMG_pwm, EMG_freq)
        elif click_location == 2:
            global EMG_ch1, EMG_ch2, stim_Ratio, calibrated_pose
            EMG_ch1 = int(click_value)
            load_balancing(0, True, False)
            set_controller_amplitude(EMG_ch1, EMG_ch2)
        elif click_location == 3:
            global EMG_ch2, EMG_ch1, stim_Ratio, calibrated_pose
            EMG_ch2 = int(click_value)
            load_balancing(0, True, True)
            set_controller_amplitude(EMG_ch1, EMG_ch2)

        time.sleep(0.1)
        send_sock_command(participant_ID_, 1, curr_gesture)
        global participant_ID_, pose_number
        write_sleeve_status_to_file(participant_ID_, pose_number, True,
                                    "machine", electrodes, data, curr_gesture,
                                    EMG_ch1, EMG_ch2, EMG_pwm, EMG_freq)

    update_controls_drawing()
def run_EMS_to_amp(frequency, pulse_width, amp, channel):
    global EMG_pwm, EMG_freq, EMG_ch2, stop_EMS_ramp
    stop_EMS_ramp = False
    EMG_pwm = pulse_width
    EMG_freq = frequency
    set_controller_freq_pwm()

    if channel == 2:
        EMG_ch2 = 0
        set_controller_amplitude()

        for i in range(EMG_ch2, int(amp)):
            EMG_ch2 += 1
            set_controller_amplitude()

            time.sleep(1.2 / float(amp))

            if stop_EMS_ramp:
                EMG_ch2 = 0
                set_controller_amplitude()

            # update_controls_drawing()
    elif channel == 1:
        EMG_ch1 = 0
        set_controller_amplitude()

        for i in range(EMG_ch1, int(amp)):
            EMG_ch1 += 1
            set_controller_amplitude()

            time.sleep(1.2 / float(amp))

            if stop_EMS_ramp:
                EMG_ch1 = 0
                set_controller_amplitude()
def keyboard_control_stim(event):
    print "Keypress ", event.char
    chan2_change = False

    global EMG_ch1, EMG_ch2, stim_Ratio, calibrated_pose, EMG_freq, EMG_pwm, stop_EMS_ramp, playLoop, curr_gesture
    if event.char == 'm':
        EMG_ch2 += 1
        chan2_change = True
    elif event.char == 'n':
        EMG_ch2 -= 1
        chan2_change = True
        if EMG_ch2 <= 0:
            EMG_ch2 = 0
    elif event.char == 'c':
        EMG_ch1 -= 1
        if EMG_ch1 <= 0:
            EMG_ch1 = 0
    elif event.char == 'v':
        EMG_ch1 += 1
    elif event.char == ' ':
        EMG_ch2 = 0
        EMG_ch1 = 0
        stop_EMS_ramp = True
        playLoop = False
    elif event.char == 'g':
        EMG_freq += 1
    elif event.char == 'f':
        EMG_freq -= 1
    elif event.char == 'h':
        EMG_pwm -= 1
    elif event.char == 'j':
        EMG_pwm += 1
    else:
        global data, key_poses
        for targets in key_poses:
            if event.char == targets[0]:
                data = np.copy(targets[1])
                EMG_ch1 = targets[2]
                EMG_ch2 = targets[3]
                EMG_freq = targets[4]
                EMG_pwm = targets[5]

                #Update drawings based on input
                update_sleeve_drawing()
                set_all_sleeve_electrodes()
                update_sleeve_drawing()

    #Ensure safe load balance
    #If multiple electrodes are removed, make sure amplitude is decreased
    load_balancing(0, True, chan2_change)

    #Trigger optitrack if either channel % 5 equals 0
    #Random(ish) step, change to increase/decrease
    if EMG_ch2 % 5 == 0 or EMG_ch1 % 5 == 0:
        send_sock_command(participant_ID_, 1, curr_gesture)

    #set amplitudes and frequences, update graphics
    set_controller_amplitude(EMG_ch1, EMG_ch2)
    set_controller_freq_pwm(EMG_pwm, EMG_freq)
    update_controls_drawing()
def reset_connection():
    command = "3c"
    send_command(True, command)

    time.sleep(1)
    command = "5c"
    send_command(True, command)
    EMS_active = True

    global data
    set_all_sleeve_electrodes(data)
    set_controller_amplitude(EMG_ch1, EMG_ch2)
    set_controller_freq_pwm(EMG_pwm, EMG_freq)
def run_pose_tkinter(participant_ID,
                     gesture_no,
                     new_win,
                     stim_points,
                     stim_proportions,
                     stim_proportions_norm,
                     num_electrode_rows_,
                     num_electrode_cols_,
                     raw=False,
                     authoring=False,
                     sequencer=False):
    global stim_window
    stim_window = tkinter.Toplevel(new_win)
    stim_window.title("EMS Controls")
    stim_window.geometry('+600+500')
    stim_window.lift()

    set_color_map()

    global electrodes, controls
    left_frame = tkinter.Frame(stim_window)
    left_frame.pack(side="left")
    top_label = tkinter.Label(left_frame, text="TOP SLEEVE")
    top_label.pack()
    electrodes = tkinter.Canvas(left_frame, width=240, height=300)
    electrodes.bind('<Button>', control_stim_electrode)

    #Create Sleeve
    for i in range(0, 6):
        for j in range(0, 10):
            electrodes.create_rectangle(40 * i,
                                        30 * j,
                                        40 * (i + 1),
                                        30 * (j + 1),
                                        tags="rec" + str(i) + "_" + str(j))
    electrodes.pack()

    #Create signal controllers
    right_frame = tkinter.Frame(stim_window)
    right_frame.pack(side="left", padx=(20, 10))
    controls_label = tkinter.Label(right_frame, text="SIGNAL CONTROLS")
    controls_label.pack()
    controls = tkinter.Canvas(right_frame, width=280, height=300)
    controls.bind('<Button>', control_stim_signal)

    controls_text = ["PWM", "FREQ", "AMP1", "AMP2"]
    start_y = 50
    for i in range(0, 4):
        controls.create_text(30, (60 * i) + 20,
                             font="Helvetica",
                             text=controls_text[i])
        controls.create_rectangle(1, (60 * i),
                                  250,
                                  60 * (i + 1),
                                  tags="sig" + str(i))
        controls.create_line(41, (60 * i),
                             41,
                             60 * (i + 1),
                             tags="line" + str(i))
    controls.pack(padx=(20, 10))

    bottom_label = tkinter.Label(left_frame, text="BOTTOM SLEEVE")
    bottom_label.pack()

    global calibrated_pose
    calibrated_pose = not raw

    #Make electrode sleeve size global
    global num_electrode_rows, num_electrode_cols, curr_gesture, participant_ID_
    num_electrode_rows = num_electrode_rows_
    num_electrode_cols = num_electrode_cols_
    curr_gesture = gesture_no
    participant_ID_ = participant_ID

    #Tell Arduino we are doing EMS
    global EMS_active
    command = "5c"
    send_command(True, command)
    EMS_active = True

    #set freq/pwm data from...
    global EMG_pwm, EMG_freq
    EMG_pwm = 200
    EMG_freq = 170
    set_controller_freq_pwm(EMG_pwm, EMG_freq)

    global EMG_ch1, EMG_ch2
    EMG_ch1 = 5
    EMG_ch2 = 5
    set_controller_amplitude(EMG_ch1, EMG_ch2)

    #Initialise ELectrode Data Store
    global data
    data = np.zeros(shape=(num_electrode_rows, num_electrode_cols))

    #Map stim values to channel selections
    stim_vals_chans = [0, 0, 1, 2, 3, 4]

    if not raw:
        #set amplitude data from stim_proportions
        global stim_Ratio
        stim_Ratio = stim_proportions[1]
        max_stim = 15

        #Loop through stimulation arrays and set coordinates
        for stim_coords_groups, stim_vals in zip(stim_points,
                                                 stim_proportions_norm):
            if stim_vals > 0:
                for stim_coords in stim_coords_groups:
                    data[int(stim_coords[0])][int(
                        stim_coords[1])] = stim_vals_chans[stim_vals * 2]
                    data[int(stim_coords[2])][int(
                        stim_coords[3])] = stim_vals_chans[(stim_vals * 2) + 1]

        check_valid_layout()

        #Send sleeve commands for data parameters
        for locs in np.argwhere(data > 0.):
            set_sleeve_electrodes(locs[1], locs[0], data[locs[0]][locs[1]])
    else:
        EMG_ch1 = 1
        EMG_ch2 = 1

    set_controller_freq_pwm(EMG_pwm, EMG_freq)
    set_controller_amplitude(EMG_ch1, EMG_ch2)

    update_sleeve_drawing()
    update_controls_drawing()

    bottom_frame = tkinter.Frame(stim_window)
    bottom_frame.pack()

    stim_window.bind("<KeyPress>", keyboard_control_stim)

    if not authoring and not sequencer:
        global save_machine_button, save_button
        bottom_frame = tkinter.Frame(stim_window)
        bottom_frame.pack()
        save_machine_button = tkinter.Button(
            master=bottom_frame,
            text="Continue",
            command=lambda: continue_button_controls(
                participant_ID, gesture_no, True, "machine"))
        save_machine_button.pack()
        save_button = tkinter.Button(
            master=bottom_frame,
            text="Done",
            command=lambda: continue_button_controls(
                participant_ID, gesture_no, True, "human"))
        save_button.pack()
        button = tkinter.Button(master=bottom_frame,
                                text='Quit',
                                command=lambda: _quit(stim_window, raw))
        button.pack()

        reset_connection_button = tkinter.Button(
            master=bottom_frame,
            text="Reset",
            command=lambda: reset_connection())
        reset_connection_button.pack(pady=(10, 0))
    elif authoring:

        initialise_file(participant_ID, gesture_no, True)

        author_tools_window = tkinter.Toplevel(stim_window)
        author_tools_window.title("Gesture Author")
        author_tools_window.geometry('+1230+520')
        move_patterns = tkinter.Frame(author_tools_window)
        move_patterns.pack()
        map_keys_frame = tkinter.Frame(author_tools_window)
        map_keys_frame.pack()
        save_load_frame = tkinter.Frame(author_tools_window)
        save_load_frame.pack()

        global pose_no, key_poses
        move_pattern_labels = ["left", "up", "down", "right"]
        move_pattern_buttons = []
        for move_ in move_pattern_labels:
            move_pattern_buttons.append(
                tkinter.Button(
                    master=move_patterns,
                    text=move_,
                    command=lambda motion=move_: translate_electrodes(motion)))
            move_pattern_buttons[-1].pack(side="left", pady=(10, 10))
        map_pose_label = tkinter.Label(master=map_keys_frame,
                                       text="Map pose to Number key:")
        map_pose_label.pack()
        global map_pose_key_entry
        map_pose_key_entry = tkinter.Entry(master=map_keys_frame)
        map_pose_key_entry.pack()
        map_pose_key = tkinter.Button(
            master=map_keys_frame,
            text="Map",
            command=lambda: bind_pose_to_key(author_tools_window))
        map_pose_key.pack(pady=(5, 10))

        author_tools_window.bind("<KeyPress>", keyboard_control_stim)

    if sequencer:

        #Create sequencer variables
        global ch1_sequence, ch2_sequence
        for i in range(0, 20):
            ch1_sequence.append(sequence_event(np.zeros(data.shape), 0))
            ch2_sequence.append(sequence_event(np.zeros(data.shape), 0))
            emg_sequence.append(0)

        #Create new window for sequencer
        timeline_window = tkinter.Toplevel(stim_window)
        timeline_window.title("Gesture Sequencer")
        timeline_window.geometry('+1500+510')
        timeline_frame = tkinter.Frame(timeline_window)
        timeline_frame.pack()

        timeline_window.bind("<KeyPress>", keyboard_control_stim)

        #Add timeline
        global timeStart, timeEnd, timelineCanvas
        timelineCanvas = tkinter.Canvas(timeline_frame, width=300, height=200)
        timelineCanvas.create_rectangle(20, 70, 280, 120, tags="timeline")
        timelineCanvas.create_line(20, 60, 21, 160, tags="time", fill="red")

        #Add locations for item placement
        start_loc_x = 20
        for i in range(0, 20):
            timelineCanvas.create_rectangle(20 + (i * 13),
                                            70,
                                            20 + (i + 1) * 13,
                                            90,
                                            tags="ch1_" + str(i))
            timelineCanvas.create_rectangle(20 + (i * 13),
                                            100,
                                            20 + (i + 1) * 13,
                                            120,
                                            tags="ch2_" + str(i))
            timelineCanvas.create_rectangle(20 + (i * 13),
                                            130,
                                            20 + (i + 1) * 13,
                                            150,
                                            tags="emg_" + str(i))
        timelineCanvas.pack()

        #Add control buttons
        global EMG_labels
        EMG_labels = tkinter.Label(timeline_frame,
                                   text="EMG: 'wrist up', 'wrist down")
        EMG_labels.pack()
        timeEnd = tkinter.Entry(timeline_frame)
        timeEnd.pack()
        startTimeBar = tkinter.Button(
            timeline_frame,
            text="Play",
            command=lambda: timeBarButtonpress(stim_window))
        startTimeBar.pack()
        global playLoop, pauseLoop
        stopTimeBar = tkinter.Button(
            timeline_frame,
            text="Stop",
            command=lambda: stop_sequence_play(timeline_window))
        stopTimeBar.pack()

        #Bind mouse controls
        timelineCanvas.bind("<Button-1>",
                            lambda e: sequencer_controls(e, "down"))
        timelineCanvas.bind("<B1-Motion>",
                            lambda e: sequencer_controls(e, "drag"))
        timelineCanvas.bind("<ButtonRelease-1>",
                            lambda e: sequencer_controls(e, "up"))
        timelineCanvas.bind("<Button-2>",
                            lambda e: sequencer_controls(e, "right"))

    stim_window.protocol("WM_DELETE_WINDOW", lambda: _quit(stim_window, raw))
    stim_window.mainloop()