Last active
November 25, 2024 22:52
-
-
Save parkerlreed/6d48fe3a9cb5bdab78cf3feecc94f67a to your computer and use it in GitHub Desktop.
Wii Balance Board Scale
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os | |
import struct | |
import time | |
import numpy as np | |
import pyfiglet # For ASCII art text | |
# Path to the joystick device | |
JOYSTICK_DEVICE = "/dev/input/js0" | |
# Joystick event format | |
EVENT_FORMAT = "IhBB" | |
EVENT_SIZE = struct.calcsize(EVENT_FORMAT) | |
# Polynomial coefficients from np.polyfit | |
POLY_COEFF = [1.89584106e-08, 9.73656453e-03, 5.30274624] # Replace with your coefficients | |
poly_func = np.poly1d(POLY_COEFF) | |
def open_joystick(device_path): | |
"""Open the joystick device.""" | |
try: | |
return open(device_path, "rb") | |
except FileNotFoundError: | |
print(f"Joystick device not found at {device_path}.") | |
return None | |
def process_joystick_event(event): | |
"""Process a single joystick event.""" | |
timestamp, value, event_type, axis_number = struct.unpack(EVENT_FORMAT, event) | |
# Only process axis events (event type 2) | |
if event_type == 2: # 2 is for axis events | |
return axis_number, value | |
return None, None | |
def estimate_weight(total_load): | |
"""Estimate weight using the polynomial calibration model.""" | |
return poly_func(total_load) | |
def main(): | |
# Open the joystick device | |
js_device = open_joystick(JOYSTICK_DEVICE) | |
if not js_device: | |
return | |
print("Reading data from the Wii Balance Board...") | |
try: | |
# Baseline values for each axis | |
baselines = [-32767] * 4 # Assuming 4 axes | |
relative_loads = [0] * 4 | |
# Variables for averaging | |
total_loads = [] # Accumulates total loads for averaging | |
start_time = time.time() | |
while True: | |
event = js_device.read(EVENT_SIZE) | |
if event: | |
axis_number, value = process_joystick_event(event) | |
if axis_number is not None and axis_number < 4: | |
# Calculate relative load | |
relative_load = value - baselines[axis_number] | |
relative_loads[axis_number] = relative_load | |
# Calculate total load | |
total_load = sum(relative_loads) | |
total_loads.append(total_load) | |
# Every 5 seconds, calculate and print the average | |
if time.time() - start_time >= 5: | |
if total_loads: | |
avg_total_load = sum(total_loads) / len(total_loads) | |
avg_weight_kg = estimate_weight(avg_total_load) | |
avg_weight_lbs = avg_weight_kg * 2.20462 | |
# Clear the screen for a clean display | |
os.system('clear') | |
# Print large ASCII text for weight | |
ascii_weight = pyfiglet.figlet_format(f"{avg_weight_lbs:.2f} lbs") | |
print(ascii_weight) | |
# Print regular details | |
print(f"Average Total Load (5s): {avg_total_load:.2f}") | |
print(f"Estimated Average Weight (5s): {avg_weight_kg:.2f} kg ({avg_weight_lbs:.2f} lbs)") | |
# Reset for the next interval | |
total_loads = [] | |
start_time = time.time() | |
time.sleep(0.01) | |
except KeyboardInterrupt: | |
print("\nExiting...") | |
finally: | |
js_device.close() | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment