Cyber_301/python/sliders.py

149 lines
4.2 KiB
Python

import serial
import time
import tkinter as tk
import json
import threading
test_mode = False
# Read the joint configuration from the config.json file
with open('python/config.json', 'r') as f:
config = json.load(f)
# Configure the serial port
try:
ser = serial.Serial(config["COM_PORT"], 9600) # Replace 'COM9' with your Arduino's serial port
time.sleep(2) # Wait for the serial connection to initialize
except serial.SerialException as e:
print(f"Error opening serial port: {e}")
print("Starting Test Mode")
test_mode = True
def send_potentiometer_values(values):
if len(values) != 6:
raise ValueError("Exactly 6 values are required")
# Convert the values to a comma-separated string
values_str = ','.join(map(str, values))
if not test_mode:
try:
# Send the values to the Arduino
ser.write((values_str + '\n').encode())
log_serial(f"-> {values_str}")
except serial.SerialException as e:
print(f"Error writing to serial port: {e}")
else:
log_serial(f"-> {values_str} (test)")
def log_serial(message):
serial_text.config(state=tk.NORMAL)
serial_text.insert(tk.END, message + '\n')
serial_text.config(state=tk.DISABLED)
serial_text.see(tk.END)
def read_serial():
while True:
if ser.in_waiting > 0:
try:
line = ser.readline().decode('utf-8').strip()
log_serial(f"<- {line}")
except serial.SerialException as e:
print(f"Error reading from serial port: {e}")
time.sleep(0.1)
# Create the main window
root = tk.Tk()
root.title("Potentiometer Sliders" + (f" ({config["COM_PORT"]} Not Found)" if test_mode else f"({config["COM_PORT"]})"))
# Create a frame for the sliders
slider_frame = tk.Frame(root)
slider_frame.pack(side=tk.LEFT, padx=10, pady=10)
# Create a list to store the slider values
slider_values = [tk.IntVar() for _ in range(6)]
# Create and pack the sliders using the configuration from config.json
sliders = []
for joint in config['joints']:
slider = tk.Scale(
slider_frame,
from_=joint['step_range'][0],
to=joint['step_range'][1],
orient=tk.HORIZONTAL,
variable=slider_values[joint['id'] - 1],
label=f"Joint {joint['id']}: {joint['name']}",
length=400
)
slider.pack()
sliders.append(slider)
def update_values():
values = [var.get() for var in slider_values]
send_potentiometer_values(values)
# Create a frame for the serial communication
serial_frame = tk.Frame(root)
serial_frame.pack(side=tk.RIGHT, padx=10, pady=10)
# Create a text widget for serial communication
serial_text = tk.Text(serial_frame, state=tk.DISABLED, width=50, height=20)
serial_text.pack()
def home_position():
# Set all sliders to 0
for slider in sliders:
slider.set(0)
# Send the home position values
update_values()
# Create a frame for the buttons
button_frame = tk.Frame(serial_frame)
button_frame.pack(side=tk.BOTTOM, pady=10)
# Create and pack the send button
send_button = tk.Button(button_frame, text="Send", command=update_values)
send_button.pack(side=tk.LEFT, padx=5)
# Create and pack the home button
home_button = tk.Button(button_frame, text="Home", command=home_position)
home_button.pack(side=tk.LEFT, padx=5)
# Loop functionality
looping = False
def toggle_loop():
global looping
looping = not looping
if looping:
loop_button.config(text="Loop: ON")
start_loop()
else:
loop_button.config(text="Loop: OFF")
def start_loop():
if looping:
update_values()
root.after(1000, start_loop) # Adjust the interval as needed
# Create and pack the loop button
loop_button = tk.Button(button_frame, text="Loop: OFF", command=toggle_loop)
loop_button.pack(side=tk.LEFT, padx=5)
# Start a thread to read from the serial port
if not test_mode:
threading.Thread(target=read_serial, daemon=True).start()
# Run the Tkinter event loop
try:
root.mainloop()
except Exception as e:
print(f"Error in Tkinter event loop: {e}")
# Close the serial port when the program is terminated
try:
ser.close()
except serial.SerialException as e:
print(f"Error closing serial port: {e}")