add serial readout. finish graph layout
This commit is contained in:
@@ -5,7 +5,8 @@ Display display;
|
||||
Adafruit_NAU7802 nau;
|
||||
unsigned long _millis = 0;
|
||||
int32_t val = 0;
|
||||
bool goToSleep = False;
|
||||
bool goToSleep = false;
|
||||
|
||||
#if BLE
|
||||
BLEServer *pServer = NULL;
|
||||
BLECharacteristic *millisCharacteristic = NULL;
|
||||
@@ -127,6 +128,8 @@ void loop() {
|
||||
}
|
||||
val = nau.read();
|
||||
|
||||
Serial.print(millis()); Serial.print(","); Serial.println(val);
|
||||
|
||||
#if BLE
|
||||
if (deviceConnected) {
|
||||
// Send the sensor reading
|
||||
@@ -148,7 +151,5 @@ void loop() {
|
||||
// do stuff here on connecting
|
||||
oldDeviceConnected = deviceConnected;
|
||||
}
|
||||
#else
|
||||
Serial.print(millis()); Serial.print(","); Serial.println(val);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import tkinter as tk
|
||||
import matplotlib.pyplot as plt
|
||||
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
|
||||
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk
|
||||
|
||||
import asyncio
|
||||
|
||||
@@ -20,19 +20,9 @@ class FilterDevApp(tk.Tk):
|
||||
|
||||
self.title("JannTers Filter Evaluation Tool")
|
||||
|
||||
# Create a frame for the plot and sliders
|
||||
self.frame = tk.Frame(self)
|
||||
self.frame.pack(side=tk.LEFT, fill=tk.BOTH)
|
||||
|
||||
# Create a figure for plotting
|
||||
self.fig, self.ax = plt.subplots()
|
||||
self.ax2 = self.ax.twinx()
|
||||
self.canvas = FigureCanvasTkAgg(self.fig, master=self.frame)
|
||||
self.canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH)
|
||||
|
||||
# Create a frame for sliders
|
||||
self.toolbar = tk.Frame(self, width=200, padx=10)
|
||||
self.toolbar.pack(side=tk.RIGHT, fill=tk.Y)
|
||||
self.toolbar.pack(side=tk.LEFT)
|
||||
|
||||
# Device Settings
|
||||
self.record_form = RecordForm(self.toolbar, self.record_data)
|
||||
@@ -46,6 +36,16 @@ class FilterDevApp(tk.Tk):
|
||||
|
||||
self.data_stats = DataStats(self.toolbar, self.reset)
|
||||
|
||||
# Create a figure for plotting
|
||||
self.frame = tk.Frame(self)
|
||||
self.frame.pack(side=tk.RIGHT)
|
||||
|
||||
self.fig, self.ax = plt.subplots()
|
||||
self.ax2 = self.ax.twinx()
|
||||
self.canvas = FigureCanvasTkAgg(self.fig, master=self.frame)
|
||||
self.canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH)
|
||||
NavigationToolbar2Tk(self.canvas, self.frame)
|
||||
|
||||
def update_plot(self):
|
||||
if self.filter is None:
|
||||
return
|
||||
@@ -61,19 +61,27 @@ class FilterDevApp(tk.Tk):
|
||||
# Generate data
|
||||
x = df['timestamps']
|
||||
y1 = df['weights']
|
||||
# y1_g = df['calib_weights']
|
||||
# y2 = df['filtered']
|
||||
y2 = df['filtered']
|
||||
y2_g = df['filtered_calib']
|
||||
|
||||
# Plot the data
|
||||
self.ax.plot(x, y1)
|
||||
# self.ax.plot(x, y2)
|
||||
self.ax.plot(x, y1, label="raw")
|
||||
self.ax.plot(x, y2, label="filtered")
|
||||
|
||||
# self.ax2.plot(x, y1_g)
|
||||
self.ax2.plot(x, y2_g, label="filtered", color='green')
|
||||
self.ax2.set_ylabel("Weight", color="green")
|
||||
|
||||
self.ax.set_xlabel("Time in ms")
|
||||
self.ax.set_ylabel("Raw Weight")
|
||||
self.ax.grid()
|
||||
self.ax.legend(loc='upper left')
|
||||
self.ax2.yaxis.set_label_position("right")
|
||||
self.ax2.yaxis.tick_right()
|
||||
self.ax2.legend(loc='lower right')
|
||||
|
||||
# self.ax2.plot(x, y1_g)
|
||||
self.ax2.plot(x, y2_g, color="orange")
|
||||
self.fig.tight_layout()
|
||||
self.canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH)
|
||||
|
||||
# Draw the updated plot
|
||||
self.canvas.draw()
|
||||
|
||||
@@ -3,4 +3,4 @@ SERVICE_UUID = "9f0dfdb2-e978-494c-8f15-68dbe8d28672"
|
||||
MILLIS_UUID = "abb92561-a809-453c-8c7c-71d3fff5b86e"
|
||||
WEIGHT_UUID = "123e4567-e89b-12d3-a456-426614174000"
|
||||
|
||||
DEFAULT_CALIB = 104167.17
|
||||
DEFAULT_CALIB = 307333.83
|
||||
@@ -32,6 +32,10 @@ class Filter:
|
||||
def __call__(self) -> pd.DataFrame:
|
||||
calib_factor = 100. / float(self.calib_entry.get())
|
||||
df = self.device.data
|
||||
|
||||
df = df[df['weights'] < 10e9]
|
||||
df['timestamps'] -= df['timestamps'].min()
|
||||
|
||||
df['filtered'], df['filtered_calib'] = self.filter(df, calib_factor)
|
||||
df['calib_weights'] = df['weights'] * calib_factor
|
||||
return df
|
||||
|
||||
@@ -2,8 +2,8 @@ from bleak import BleakClient, BleakScanner
|
||||
import pandas as pd
|
||||
from tkinter.ttk import Entry
|
||||
from tkinter.messagebox import showerror, showinfo
|
||||
import asyncio
|
||||
from time import time
|
||||
from serial import Serial
|
||||
|
||||
from ..config import MILLIS_UUID, WEIGHT_UUID
|
||||
|
||||
@@ -27,7 +27,12 @@ class Device:
|
||||
self.weights = []
|
||||
|
||||
async def connect(self):
|
||||
self.device = await BleakScanner.find_device_by_name(self.device_name.get())
|
||||
device_name = self.device_name.get()
|
||||
|
||||
if device_name.startswith('/dev'):
|
||||
self.device = device_name
|
||||
else:
|
||||
self.device = await BleakScanner.find_device_by_name(self.device_name.get())
|
||||
|
||||
return self.device is not None
|
||||
|
||||
@@ -35,25 +40,50 @@ class Device:
|
||||
self.device = None
|
||||
|
||||
async def read_values(self, duration):
|
||||
duration = int(duration)
|
||||
|
||||
if not await self.connect():
|
||||
showerror("Record Data", f"Device {self.device_name.get()} not found!")
|
||||
return
|
||||
|
||||
self.clear_data()
|
||||
async with BleakClient(self.device.address) as client:
|
||||
showinfo("Recording Data", f"Recording data for {duration} seconds.")
|
||||
|
||||
if isinstance(self.device, str):
|
||||
self._read_values_serial(duration)
|
||||
else:
|
||||
await self._read_values_ble(duration)
|
||||
|
||||
def _read_values_serial(self, duration):
|
||||
with Serial(self.device, baudrate=115200) as ser:
|
||||
showinfo("Record Data", f"Recording data for {duration} seconds.")
|
||||
time_start = time()
|
||||
time_passed = 0
|
||||
while time_passed < duration:
|
||||
millis = await client.read_gatt_char(MILLIS_UUID)
|
||||
millis = int.from_bytes(millis, byteorder='little') # Adjust based on your data format
|
||||
weight = await client.read_gatt_char(WEIGHT_UUID)
|
||||
weight = int.from_bytes(weight, byteorder='little') # Adjust based on your data format
|
||||
line = ser.readline()
|
||||
_timestamp, _raw_weight = line.decode('utf-8').split(',')
|
||||
|
||||
self.timestamps.append(millis)
|
||||
self.weights.append(weight)
|
||||
self.timestamps.append(int(_timestamp))
|
||||
self.weights.append(int(_raw_weight))
|
||||
|
||||
time_passed = time() - time_start
|
||||
|
||||
async def _read_values_ble(self, duration):
|
||||
self.clear_data()
|
||||
try:
|
||||
async with BleakClient(self.device.address) as client:
|
||||
showinfo("Record Data", f"Recording data for {duration} seconds.")
|
||||
time_start = time()
|
||||
time_passed = 0
|
||||
while time_passed < duration:
|
||||
millis = await client.read_gatt_char(MILLIS_UUID)
|
||||
millis = int.from_bytes(millis, byteorder='little') # Adjust based on your data format
|
||||
weight = await client.read_gatt_char(WEIGHT_UUID)
|
||||
weight = int.from_bytes(weight, byteorder='little') # Adjust based on your data format
|
||||
|
||||
self.timestamps.append(millis)
|
||||
self.weights.append(weight)
|
||||
|
||||
time_passed = time() - time_start
|
||||
except:
|
||||
showerror("Record Data", f"Client could not be started for {self.device_name.get()}: {self.device.address}.")
|
||||
|
||||
|
||||
def clear_data(self):
|
||||
|
||||
@@ -3,17 +3,24 @@ from tkinter import ttk
|
||||
|
||||
from ..slider import Slider
|
||||
|
||||
from serial.tools import list_ports
|
||||
|
||||
class RecordForm(tk.Frame):
|
||||
|
||||
def __init__(self, master, record_command, **kwargs):
|
||||
super().__init__(master, **kwargs)
|
||||
|
||||
self.device_label = ttk.Label(self, text="Device Name:")
|
||||
# get serial ports
|
||||
serials = [d.device for d in list_ports.grep('usbmodem')]
|
||||
devices = serials + ["Smaage"]
|
||||
default_record_len = 10 if len(serials) > 0 else 30
|
||||
|
||||
self.device_label = ttk.Label(self, text="Device:")
|
||||
self.device_label.pack(pady=10)
|
||||
self.device_name = ttk.Entry(self)
|
||||
self.device_name.insert(0, "Smaage") # Set default value
|
||||
self.device_name = ttk.Combobox(self, values=devices)
|
||||
self.device_name.set(devices[0])
|
||||
self.device_name.pack()
|
||||
self.record_time = Slider(self, "Record Time:", 10, 30, 10, lambda: None)
|
||||
self.record_time = Slider(self, "Record Time:", 10, 60, default_record_len, lambda: None)
|
||||
self.record_time.pack(pady=10)
|
||||
self.record_button = ttk.Button(self, text="Record Data", command=record_command)
|
||||
self.record_button.pack(pady=10)
|
||||
@@ -2,4 +2,5 @@ matplotlib
|
||||
bleak
|
||||
pandas
|
||||
tqdm
|
||||
numpy
|
||||
numpy
|
||||
pyserial
|
||||
Reference in New Issue
Block a user