add serial readout. finish graph layout
This commit is contained in:
@@ -5,7 +5,8 @@ Display display;
|
|||||||
Adafruit_NAU7802 nau;
|
Adafruit_NAU7802 nau;
|
||||||
unsigned long _millis = 0;
|
unsigned long _millis = 0;
|
||||||
int32_t val = 0;
|
int32_t val = 0;
|
||||||
bool goToSleep = False;
|
bool goToSleep = false;
|
||||||
|
|
||||||
#if BLE
|
#if BLE
|
||||||
BLEServer *pServer = NULL;
|
BLEServer *pServer = NULL;
|
||||||
BLECharacteristic *millisCharacteristic = NULL;
|
BLECharacteristic *millisCharacteristic = NULL;
|
||||||
@@ -127,6 +128,8 @@ void loop() {
|
|||||||
}
|
}
|
||||||
val = nau.read();
|
val = nau.read();
|
||||||
|
|
||||||
|
Serial.print(millis()); Serial.print(","); Serial.println(val);
|
||||||
|
|
||||||
#if BLE
|
#if BLE
|
||||||
if (deviceConnected) {
|
if (deviceConnected) {
|
||||||
// Send the sensor reading
|
// Send the sensor reading
|
||||||
@@ -148,7 +151,5 @@ void loop() {
|
|||||||
// do stuff here on connecting
|
// do stuff here on connecting
|
||||||
oldDeviceConnected = deviceConnected;
|
oldDeviceConnected = deviceConnected;
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
Serial.print(millis()); Serial.print(","); Serial.println(val);
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import tkinter as tk
|
import tkinter as tk
|
||||||
import matplotlib.pyplot as plt
|
import matplotlib.pyplot as plt
|
||||||
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
|
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk
|
||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
|
|
||||||
@@ -20,19 +20,9 @@ class FilterDevApp(tk.Tk):
|
|||||||
|
|
||||||
self.title("JannTers Filter Evaluation Tool")
|
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
|
# Create a frame for sliders
|
||||||
self.toolbar = tk.Frame(self, width=200, padx=10)
|
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
|
# Device Settings
|
||||||
self.record_form = RecordForm(self.toolbar, self.record_data)
|
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)
|
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):
|
def update_plot(self):
|
||||||
if self.filter is None:
|
if self.filter is None:
|
||||||
return
|
return
|
||||||
@@ -61,19 +61,27 @@ class FilterDevApp(tk.Tk):
|
|||||||
# Generate data
|
# Generate data
|
||||||
x = df['timestamps']
|
x = df['timestamps']
|
||||||
y1 = df['weights']
|
y1 = df['weights']
|
||||||
# y1_g = df['calib_weights']
|
y2 = df['filtered']
|
||||||
# y2 = df['filtered']
|
|
||||||
y2_g = df['filtered_calib']
|
y2_g = df['filtered_calib']
|
||||||
|
|
||||||
# Plot the data
|
# Plot the data
|
||||||
self.ax.plot(x, y1)
|
self.ax.plot(x, y1, label="raw")
|
||||||
# self.ax.plot(x, y2)
|
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_xlabel("Time in ms")
|
||||||
self.ax.set_ylabel("Raw Weight")
|
self.ax.set_ylabel("Raw Weight")
|
||||||
self.ax.grid()
|
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.fig.tight_layout()
|
||||||
self.ax2.plot(x, y2_g, color="orange")
|
self.canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH)
|
||||||
|
|
||||||
# Draw the updated plot
|
# Draw the updated plot
|
||||||
self.canvas.draw()
|
self.canvas.draw()
|
||||||
|
|||||||
@@ -3,4 +3,4 @@ SERVICE_UUID = "9f0dfdb2-e978-494c-8f15-68dbe8d28672"
|
|||||||
MILLIS_UUID = "abb92561-a809-453c-8c7c-71d3fff5b86e"
|
MILLIS_UUID = "abb92561-a809-453c-8c7c-71d3fff5b86e"
|
||||||
WEIGHT_UUID = "123e4567-e89b-12d3-a456-426614174000"
|
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:
|
def __call__(self) -> pd.DataFrame:
|
||||||
calib_factor = 100. / float(self.calib_entry.get())
|
calib_factor = 100. / float(self.calib_entry.get())
|
||||||
df = self.device.data
|
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['filtered'], df['filtered_calib'] = self.filter(df, calib_factor)
|
||||||
df['calib_weights'] = df['weights'] * calib_factor
|
df['calib_weights'] = df['weights'] * calib_factor
|
||||||
return df
|
return df
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ from bleak import BleakClient, BleakScanner
|
|||||||
import pandas as pd
|
import pandas as pd
|
||||||
from tkinter.ttk import Entry
|
from tkinter.ttk import Entry
|
||||||
from tkinter.messagebox import showerror, showinfo
|
from tkinter.messagebox import showerror, showinfo
|
||||||
import asyncio
|
|
||||||
from time import time
|
from time import time
|
||||||
|
from serial import Serial
|
||||||
|
|
||||||
from ..config import MILLIS_UUID, WEIGHT_UUID
|
from ..config import MILLIS_UUID, WEIGHT_UUID
|
||||||
|
|
||||||
@@ -27,6 +27,11 @@ class Device:
|
|||||||
self.weights = []
|
self.weights = []
|
||||||
|
|
||||||
async def connect(self):
|
async def connect(self):
|
||||||
|
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())
|
self.device = await BleakScanner.find_device_by_name(self.device_name.get())
|
||||||
|
|
||||||
return self.device is not None
|
return self.device is not None
|
||||||
@@ -35,13 +40,36 @@ class Device:
|
|||||||
self.device = None
|
self.device = None
|
||||||
|
|
||||||
async def read_values(self, duration):
|
async def read_values(self, duration):
|
||||||
|
duration = int(duration)
|
||||||
|
|
||||||
if not await self.connect():
|
if not await self.connect():
|
||||||
showerror("Record Data", f"Device {self.device_name.get()} not found!")
|
showerror("Record Data", f"Device {self.device_name.get()} not found!")
|
||||||
return
|
return
|
||||||
|
|
||||||
|
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:
|
||||||
|
line = ser.readline()
|
||||||
|
_timestamp, _raw_weight = line.decode('utf-8').split(',')
|
||||||
|
|
||||||
|
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()
|
self.clear_data()
|
||||||
|
try:
|
||||||
async with BleakClient(self.device.address) as client:
|
async with BleakClient(self.device.address) as client:
|
||||||
showinfo("Recording Data", f"Recording data for {duration} seconds.")
|
showinfo("Record Data", f"Recording data for {duration} seconds.")
|
||||||
time_start = time()
|
time_start = time()
|
||||||
time_passed = 0
|
time_passed = 0
|
||||||
while time_passed < duration:
|
while time_passed < duration:
|
||||||
@@ -54,6 +82,8 @@ class Device:
|
|||||||
self.weights.append(weight)
|
self.weights.append(weight)
|
||||||
|
|
||||||
time_passed = time() - time_start
|
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):
|
def clear_data(self):
|
||||||
|
|||||||
@@ -3,17 +3,24 @@ from tkinter import ttk
|
|||||||
|
|
||||||
from ..slider import Slider
|
from ..slider import Slider
|
||||||
|
|
||||||
|
from serial.tools import list_ports
|
||||||
|
|
||||||
class RecordForm(tk.Frame):
|
class RecordForm(tk.Frame):
|
||||||
|
|
||||||
def __init__(self, master, record_command, **kwargs):
|
def __init__(self, master, record_command, **kwargs):
|
||||||
super().__init__(master, **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_label.pack(pady=10)
|
||||||
self.device_name = ttk.Entry(self)
|
self.device_name = ttk.Combobox(self, values=devices)
|
||||||
self.device_name.insert(0, "Smaage") # Set default value
|
self.device_name.set(devices[0])
|
||||||
self.device_name.pack()
|
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_time.pack(pady=10)
|
||||||
self.record_button = ttk.Button(self, text="Record Data", command=record_command)
|
self.record_button = ttk.Button(self, text="Record Data", command=record_command)
|
||||||
self.record_button.pack(pady=10)
|
self.record_button.pack(pady=10)
|
||||||
@@ -3,3 +3,4 @@ bleak
|
|||||||
pandas
|
pandas
|
||||||
tqdm
|
tqdm
|
||||||
numpy
|
numpy
|
||||||
|
pyserial
|
||||||
Reference in New Issue
Block a user