106 lines
3.5 KiB
Python
Executable File

import os
import sys
import time
import tkinter as tk
from tkinter import ttk
from tkinter import messagebox
import RPi.GPIO as GPIO
# Add the parent directory to the module search path
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))
from interface_board_libs.adc_mcp3208 import MCP3208
from interface_board_libs.shift_register import ShiftRegister
from interface_board_pins import * # Import pin assignments
from gui_helpers import create_adc_plot
# Initialize ADC & Shift Register
adc = MCP3208()
shift_reg = ShiftRegister(GPIO_SHIFT_REG_DATA, GPIO_SHIFT_REG_LATCH, GPIO_SHIFT_REG_CLOCK)
# GPIO Setup
GPIO.setmode(GPIO.BCM)
for pin in GPIO_DIGITAL_INPUTS.values():
GPIO.setup(pin, GPIO.IN)
GPIO.setup(GPIO_PWM1, GPIO.OUT)
GPIO.setup(GPIO_PWM2, GPIO.OUT)
pwm1 = GPIO.PWM(GPIO_PWM1, 1000)
pwm2 = GPIO.PWM(GPIO_PWM2, 1000)
pwm1.start(0)
pwm2.start(0)
# Tkinter GUI
root = tk.Tk()
root.title("Raspberry Pi Interface Board")
root.attributes('-fullscreen', True)
root.configure(bg="black")
# Tabbed Interface
notebook = ttk.Notebook(root)
main_frame = ttk.Frame(notebook)
plot_frame = ttk.Frame(notebook)
notebook.add(main_frame, text="Controls")
notebook.add(plot_frame, text="ADC Plot")
notebook.pack(expand=True, fill="both")
# Layout Variables
digital_input_states = [tk.StringVar(value="LOW") for _ in range(8)]
digital_output_states = [tk.BooleanVar(value=False) for _ in range(8)]
adc_values = [tk.StringVar(value="0.00V") for _ in range(8)]
pwm_values = [tk.IntVar(value=0), tk.IntVar(value=0)]
def update_inputs():
for i, pin in enumerate(GPIO_DIGITAL_INPUTS.values()):
digital_input_states[i].set("HIGH" if GPIO.input(pin) else "LOW")
root.after(500, update_inputs)
def update_adc():
for i, adc_channel in enumerate(ADC_CHANNELS.values()):
value = adc.read(adc_channel)
adc_values[i].set(f"{round(value * 12 / 4095, 2)}V")
root.after(1000, update_adc)
def toggle_output(index):
shift_reg.set_pin(index, digital_output_states[index].get())
def update_pwm(channel, value):
duty_cycle = int(float(value))
if channel == 0:
pwm1.ChangeDutyCycle(duty_cycle)
else:
pwm2.ChangeDutyCycle(duty_cycle)
def exit_program():
pwm1.stop()
pwm2.stop()
GPIO.cleanup()
root.quit()
# Create UI Elements in Main Frame
frame = ttk.Frame(main_frame, padding=20)
frame.pack(expand=True, fill="both")
for i in range(8):
ttk.Label(frame, text=f"ADC {i+1}:").grid(row=i, column=0, sticky="e")
ttk.Label(frame, textvariable=adc_values[i], width=10).grid(row=i, column=1, sticky="w")
ttk.Label(frame, text=f"IN {i+1}:").grid(row=i, column=2, sticky="e")
ttk.Label(frame, textvariable=digital_input_states[i], width=6).grid(row=i, column=3, sticky="w")
btn = ttk.Checkbutton(frame, text=f"OUT {i+1}", variable=digital_output_states[i], command=lambda i=i: toggle_output(i))
btn.grid(row=i, column=4, sticky="w")
for i in range(2):
ttk.Label(frame, text=f"PWM{i+1}").grid(row=i, column=5, sticky="e")
slider = ttk.Scale(frame, from_=0, to=100, orient="horizontal", length=300, variable=pwm_values[i], command=lambda val, i=i: update_pwm(i, val))
slider.grid(row=i, column=6, sticky="w")
exit_button = ttk.Button(root, text="Exit", command=exit_program)
exit_button.place(relx=0.9, rely=0.9, anchor="center")
# Create ADC Plot in Second Tab
create_adc_plot(plot_frame, adc)
# Start Updates
update_inputs()
update_adc()
# Run GUI
root.mainloop()