ADD: DEADBEEF packet and vizualize #8
This commit is contained in:
parent
578962d9fe
commit
8abc3b0709
1 changed files with 78 additions and 38 deletions
116
vizualize.py
116
vizualize.py
|
@ -1,48 +1,88 @@
|
|||
import serial
|
||||
import struct
|
||||
import threading
|
||||
import matplotlib.pyplot as plt
|
||||
import matplotlib.animation as animation
|
||||
import numpy as np
|
||||
from matplotlib.animation import FuncAnimation
|
||||
# Configure your serial port settings.
|
||||
SERIAL_PORT = '/dev/ttyUSB0' # Update to match your serial port.
|
||||
BAUD_RATE = 115200 # Update to match your settings.
|
||||
FLOAT_SIZE = 4 # Size of a float in bytes (usually 4 bytes)
|
||||
|
||||
# Open the serial port. Replace 'COM3' with your serial port name.
|
||||
serial_port = '/dev/ttyUSB0'
|
||||
baud_rate = 115200 # Adjust as per your device configuration
|
||||
ser = serial.Serial(serial_port, baud_rate, timeout=1)
|
||||
# Shared state, updated by the reading thread, read by the plotting function.
|
||||
# Initialize values with None.
|
||||
adc_values = [None, None, None]
|
||||
angle = None
|
||||
|
||||
# Setup the matplotlib figure and axes for polar plot.
|
||||
fig, ax = plt.subplots(subplot_kw={'projection': 'polar'})
|
||||
line, = ax.plot([], [], 'b-', lw=2) # Line object to update the angle
|
||||
ax.set_ylim(0, 1) # Set the radius range (fixed in this case)
|
||||
# Define the thread that will read the serial data.
|
||||
def read_serial_data(ser):
|
||||
global adc_values, angle
|
||||
try:
|
||||
while True:
|
||||
byte = ser.read(1)
|
||||
if byte == b'\xDE':
|
||||
next_byte = ser.read(1)
|
||||
if next_byte == b'\xAD':
|
||||
data = ser.read(FLOAT_SIZE * 4)
|
||||
if len(data) == FLOAT_SIZE * 4:
|
||||
floats = struct.unpack('<4f', data)
|
||||
packet_end = ser.read(2)
|
||||
if packet_end == bytes([0xBE, 0xAF]):
|
||||
# Update our shared state.
|
||||
adc_values = list(floats[0:3])
|
||||
angle = floats[3]
|
||||
except serial.SerialException as e:
|
||||
print("Serial exception:", e)
|
||||
except struct.error as e:
|
||||
print("Unpacking error:", e)
|
||||
except:
|
||||
print("Other error or thread exiting.")
|
||||
|
||||
# Adjust the orientation so that 0 is up and the angle proceeds clockwise.
|
||||
ax.set_theta_zero_location('N')
|
||||
ax.set_theta_direction(-1)
|
||||
# Start the serial reader in a separate thread.
|
||||
thread = threading.Thread(target=read_serial_data, args=(serial.Serial(SERIAL_PORT, BAUD_RATE, timeout=1),))
|
||||
thread.daemon = True # Thread will be killed when the main thread exits.
|
||||
thread.start()
|
||||
|
||||
# Initialization function to clear the data.
|
||||
def init():
|
||||
line.set_data([], [])
|
||||
return (line,)
|
||||
# Set up the Matplotlib figures and axes.
|
||||
fig = plt.figure(figsize=(10, 5))
|
||||
|
||||
# Update function that reads from the serial port
|
||||
# and updates the plot with the new angle.
|
||||
def update(frame):
|
||||
line.set_data([], [])
|
||||
raw_data = ser.readline().strip()
|
||||
angle = 0
|
||||
if raw_data:
|
||||
try:
|
||||
angle = float(raw_data)
|
||||
except:
|
||||
angle = 0
|
||||
angle_rad = np.deg2rad(angle) # Convert to radians
|
||||
# Update the plot with the new angle.
|
||||
line.set_data([angle_rad, angle_rad], [0, 1])
|
||||
return (line,)
|
||||
# Create a normal subplot for the bar graph.
|
||||
ax_bar = fig.add_subplot(1, 2, 1)
|
||||
|
||||
# Create the animation object with a suitable update interval (ms).
|
||||
ani = animation.FuncAnimation(fig, update, init_func=init, blit=True, interval=1)
|
||||
# Create another subplot for the polar plot by specifying polar=True.
|
||||
ax_polar = fig.add_subplot(1, 2, 2, polar=True)
|
||||
|
||||
# Start the plot animation
|
||||
# Set the properties for polar plot.
|
||||
ax_polar.set_theta_zero_location('N')
|
||||
ax_polar.set_theta_direction(-1)
|
||||
|
||||
# Bar plot axis.
|
||||
bars = ax_bar.bar(['ADC0', 'ADC1', 'ADC2'], [0, 0, 0])
|
||||
ax_bar.set_ylim(0, 0.4) # Set the limit for your ADC values.
|
||||
|
||||
# Polar plot axis.
|
||||
ax_polar.set_theta_zero_location('N')
|
||||
ax_polar.set_theta_direction(-1)
|
||||
angle_plot, = ax_polar.plot([], [], 'go') # Initial empty plot.
|
||||
|
||||
# Update function for the animation.
|
||||
def update(i):
|
||||
# Global variables holding the shared state.
|
||||
global adc_values, angle
|
||||
|
||||
# Check if we have received new data.
|
||||
if all(v is not None for v in adc_values) and angle is not None:
|
||||
# Update the bar plot.
|
||||
for bar, value in zip(bars, adc_values):
|
||||
bar.set_height(value)
|
||||
|
||||
# Update the polar plot.
|
||||
angle_rad = angle / 180.0 * 3.14159 # Convert degrees to radians.
|
||||
angle_plot.set_data([angle_rad], [1]) # Set angle for the plot, using radial distance of 1.
|
||||
|
||||
return bars.patches + [angle_plot]
|
||||
|
||||
# Create the animation itself, which will call update function repeatedly.
|
||||
ani = FuncAnimation(fig, update, blit=True, interval=1) # Update interval is in milliseconds.
|
||||
|
||||
# Show the plot.
|
||||
plt.show()
|
||||
|
||||
# Closing the serial port after the plot is closed.
|
||||
ser.close()
|
Loading…
Add table
Add a link
Reference in a new issue