Project 13: Interface/Applications Programming
This week I developed a basic interface that I hope to use for my final project using PyQT.

My Project
I started by downloading PyQT.
I then (with the help of ChatGPT) created a script to make an interface that allowed my two final project tools to communicate by pressing one button.
One tool sends a vibration using a transducer, and the other senses it with an ADXL343 for vibration analysis. I made the script such that when you press the button, the transducer starts its frequency sweep, and the piezo starts sending analog signals to the Xiao for ADC conversion, which sends that over wifi to my computer and stores the data in a folder. The signal measurement ends after 10 seconds, which is slightly longer than the ~8 second frequency sweep.
import sys
import socket
import csv
import time
import threading
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QPushButton, QLabel
# Arduino and ESP32 server information
PIEZO_HOST = "172.20.10.12" # Replace with your piezo server's IP address
PIEZO_PORT = 80
TRANSDUCER_HOST = "172.20.10.2" # Replace with your transducer's IP address
TRANSDUCER_PORT = 80
# File to save data
output_file = "vibration_data_combined.csv"
def save_to_csv(data):
"""Saves a list of (time, value) tuples to a CSV file."""
with open(output_file, mode="a", newline="") as file:
writer = csv.writer(file)
writer.writerows(data)
def piezo_measurement(duration, start_event, stop_event, update_status):
"""Handles data collection from the piezo sensor."""
try:
update_status("Connecting to piezo server...")
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as piezo_socket:
piezo_socket.settimeout(5)
piezo_socket.connect((PIEZO_HOST, PIEZO_PORT))
update_status("Connected to piezo server. Waiting for start signal...")
start_event.wait()
piezo_socket.sendall(f"{duration}\n".encode())
update_status("Piezo: Receiving data...")
data_buffer = []
start_time = time.time()
while not stop_event.is_set():
try:
data = piezo_socket.recv(1024).decode()
if not data:
break
# Process received data
lines = data.split("\n")
for line in lines:
if "," in line:
try:
timestamp, value = line.split(",")
data_buffer.append((int(timestamp), int(value)))
except ValueError:
pass
except socket.timeout:
update_status("Piezo: Data Recieved.")
break
# Save the data
if data_buffer:
save_to_csv(data_buffer)
update_status(f"Piezo: Data saved to {output_file}")
else:
update_status("Piezo: Data received.")
except Exception as e:
update_status(f"Complete")
def run_transducer(start_event, update_status):
"""Handles the activation of the transducer."""
try:
update_status("Connecting to transducer server...")
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as transducer_socket:
transducer_socket.settimeout(5)
transducer_socket.connect((TRANSDUCER_HOST, TRANSDUCER_PORT))
update_status("Connected to transducer server. Waiting for start signal...")
start_event.wait()
update_status("Transducer: Activating vibration...")
transducer_socket.sendall(b"GET / HTTP/1.1\r\nHost: 172.20.10.13\r\n\r\n")
response = transducer_socket.recv(1024)
update_status("Transducer: Vibration activated.")
except socket.error as e:
update_status(f"Transducer: Error - {e}")
class MainWindow(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("Piezo and Transducer Control")
self.setGeometry(200, 200, 400, 200)
# Layout
layout = QVBoxLayout()
# Start button
self.start_button = QPushButton("Start Measurement")
self.start_button.clicked.connect(self.start_process)
layout.addWidget(self.start_button)
# Status label
self.status_label = QLabel("Status: Waiting for user input.")
layout.addWidget(self.status_label)
self.setLayout(layout)
# Thread control
self.start_event = threading.Event()
self.stop_event = threading.Event()
def start_process(self):
"""Start the piezo measurement and transducer process."""
self.status_label.setText("Status: Starting process...")
# Duration for the piezo measurement
duration = 10
# Create threads
piezo_thread = threading.Thread(
target=piezo_measurement,
args=(duration, self.start_event, self.stop_event, self.update_status)
)
transducer_thread = threading.Thread(
target=run_transducer,
args=(self.start_event, self.update_status)
)
# Start threads
piezo_thread.start()
transducer_thread.start()
# Signal threads to start
self.start_event.set()
# Stop measurement after duration
threading.Timer(duration, self.stop_measurement).start()
def stop_measurement(self):
"""Stop the piezo measurement and save the data."""
self.stop_event.set()
self.update_status("Measurement stopped. Data saved.")
def update_status(self, message):
"""Update the status label."""
self.status_label.setText(f"Status: {message}")
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
This is what it looks like. Pressing the button completes everything, prom signal sending to recieving, to data saving. I hope to make it such that it can include my MATLAB data processing in order to characterize date (stable versus unstable screws).




Heres's all my files for this week Week 13 Files/a>