commit 30107682d94f522c4d667e9ed7d6fd5dc95c5509 Author: Adema Date: Thu Apr 3 13:11:20 2025 +0200 Upload files to "python" diff --git a/python/ble_gui5.py b/python/ble_gui5.py new file mode 100644 index 0000000..5f4073b --- /dev/null +++ b/python/ble_gui5.py @@ -0,0 +1,142 @@ +import tkinter as tk +import serial +import threading +import csv +import serial.tools.list_ports +from datetime import datetime +import pytz +import os + +# Set timezone for Amsterdam +AMSTERDAM_TZ = pytz.timezone("Europe/Amsterdam") + +# Global variables +recording = False +csv_file = None +csv_writer = None +ser = None + +def get_amsterdam_time(): + """Returns the current time in Amsterdam with microseconds.""" + return datetime.now(AMSTERDAM_TZ).strftime("%Y-%m-%d %H:%M:%S.%f") + +def get_timestamped_filename(): + """Generates a timestamped filename in Amsterdam time.""" + timestamp = datetime.now(AMSTERDAM_TZ).strftime("%Y-%m-%d_%H-%M-%S") + return f"sensor_data_{timestamp}.csv" + +def list_serial_ports(): + """Returns a list of available serial ports.""" + return [port.device for port in serial.tools.list_ports.comports()] + +def connect_serial(): + """Connects to the selected serial port.""" + global ser + selected_port = port_var.get() + if selected_port: + try: + ser = serial.Serial(selected_port, 115200, timeout=1) + lbl_status.config(text=f"Connected to {selected_port}", fg="green") + threading.Thread(target=read_serial, daemon=True).start() + except Exception as e: + lbl_status.config(text=f"Error: {e}", fg="red") + +def read_serial(): + """Reads serial data and updates the GUI while optionally saving to CSV.""" + global csv_writer, csv_file + while ser and ser.is_open: + try: + line = ser.readline().decode('utf-8').strip() + values = line.split(",") + if len(values) == 4: + timestamp = get_amsterdam_time() + + # Format numbers to keep width fixed + formatted_values = [f"{int(v):>6}" for v in values] + + # Update GUI labels + lbl_value1.config(text=formatted_values[0]) + lbl_value2.config(text=formatted_values[1]) + lbl_value3.config(text=formatted_values[2]) + lbl_value4.config(text=formatted_values[3]) + + # Save to CSV if recording + if recording and csv_writer: + csv_writer.writerow([timestamp] + values) + csv_file.flush() # Ensure data is written immediately + except: + pass + +def toggle_recording(): + """Starts or stops data recording with a timestamped filename.""" + global recording, csv_file, csv_writer + if not recording: + btn_record.config(text="Stop Recording", fg="red") + + # Create a timestamped filename + filename = get_timestamped_filename() + csv_file = open(filename, "w", newline="") + csv_writer = csv.writer(csv_file) + csv_writer.writerow(["Timestamp", "Value 1", "Value 2", "Value 3", "Value 4"]) + + lbl_status.config(text=f"Recording to {filename}", fg="blue") + recording = True + else: + btn_record.config(text="Start Recording", fg="black") + recording = False + if csv_file: + csv_file.close() + csv_file = None + lbl_status.config(text="Recording Stopped", fg="black") + +# Create main GUI window +root = tk.Tk() +root.title("BLE Sensor Data Logger") +root.geometry("400x300") # Set window size +root.resizable(False, False) + +# Create a frame for better layout +frame = tk.Frame(root, padx=20, pady=10) +frame.pack(pady=5) + +# Dropdown for selecting serial port +tk.Label(frame, text="Select Serial Port:", font=("Arial", 12)).grid(row=0, column=0, sticky="w", padx=5) +port_var = tk.StringVar(root) +ports = list_serial_ports() +port_dropdown = tk.OptionMenu(frame, port_var, *ports) +port_dropdown.grid(row=0, column=1, padx=5) +port_var.set(ports[0] if ports else "No ports found") + +# Connect button +btn_connect = tk.Button(frame, text="Connect", font=("Arial", 12), command=connect_serial) +btn_connect.grid(row=0, column=2, padx=5) + +# Connection status label +lbl_status = tk.Label(root, text="Not connected", font=("Arial", 10), fg="red") +lbl_status.pack(pady=5) + +# Sensor values section +monospace_font = ("Courier", 14, "bold") + +tk.Label(frame, text="Value 1:", font=("Arial", 12)).grid(row=1, column=0, sticky="w", padx=10) +lbl_value1 = tk.Label(frame, text="------", font=monospace_font, fg="blue", width=6, anchor="e") +lbl_value1.grid(row=1, column=1, sticky="w") + +tk.Label(frame, text="Value 2:", font=("Arial", 12)).grid(row=2, column=0, sticky="w", padx=10) +lbl_value2 = tk.Label(frame, text="------", font=monospace_font, fg="blue", width=6, anchor="e") +lbl_value2.grid(row=2, column=1, sticky="w") + +tk.Label(frame, text="Value 3:", font=("Arial", 12)).grid(row=3, column=0, sticky="w", padx=10) +lbl_value3 = tk.Label(frame, text="------", font=monospace_font, fg="blue", width=6, anchor="e") +lbl_value3.grid(row=3, column=1, sticky="w") + +tk.Label(frame, text="Value 4:", font=("Arial", 12)).grid(row=4, column=0, sticky="w", padx=10) +lbl_value4 = tk.Label(frame, text="------", font=monospace_font, fg="blue", width=6, anchor="e") +lbl_value4.grid(row=4, column=1, sticky="w") + +# Start/Stop Recording Button +btn_record = tk.Button(root, text="Start Recording", font=("Arial", 12), command=toggle_recording) +btn_record.pack(pady=10) + +# Run the GUI +root.mainloop()