mirror of
https://github.com/maziggy/bambuddy.git
synced 2026-10-09 15:35:39 +02:00
The NAU7802 ADC returns a stale max-scale value (0x7FFFFF) on its first conversion after power-up, polluting the moving average and making the initial weight report wildly inaccurate. Flush the first reading during init(). Also extract both hardware drivers out of diagnostic scripts into proper daemon modules: - NAU7802 scale driver: scripts/scale_diag.py -> daemon/nau7802.py - PN5180 NFC driver: scripts/read_tag.py -> daemon/pn5180.py The production daemon was importing driver classes from test scripts since the original SpoolBuddy commit. Diagnostic scripts now import from the driver modules. Removed the sys.path hack from main.py.
134 lines
4.4 KiB
Python
134 lines
4.4 KiB
Python
#!/usr/bin/env python3
|
|
"""NAU7802 Scale Diagnostic.
|
|
|
|
Standalone diagnostic script — the NAU7802 driver lives in
|
|
spoolbuddy/daemon/nau7802.py and is imported from there.
|
|
"""
|
|
|
|
import sys
|
|
import time
|
|
from pathlib import Path
|
|
|
|
import smbus2
|
|
|
|
# Add daemon package to sys.path so we can import the driver
|
|
sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
|
|
from daemon.nau7802 import I2C_BUS, NAU7802, NAU7802_ADDR
|
|
|
|
|
|
def main():
|
|
print("=" * 60)
|
|
print("NAU7802 Scale Diagnostic")
|
|
print("=" * 60)
|
|
|
|
print(f"Configured bus: {I2C_BUS}, address: 0x{NAU7802_ADDR:02X}")
|
|
|
|
# Probe both common I2C buses and show where devices are actually visible.
|
|
found_by_bus: dict[int, list[int]] = {}
|
|
for bus_num in (0, 1):
|
|
found_by_bus[bus_num] = []
|
|
try:
|
|
with smbus2.SMBus(bus_num) as probe_bus:
|
|
for addr in range(0x03, 0x78):
|
|
try:
|
|
probe_bus.read_byte(addr)
|
|
found_by_bus[bus_num].append(addr)
|
|
except OSError:
|
|
continue
|
|
except FileNotFoundError:
|
|
continue
|
|
except PermissionError:
|
|
continue
|
|
|
|
for bus_num, addrs in found_by_bus.items():
|
|
if addrs:
|
|
pretty = " ".join(f"0x{a:02X}" for a in addrs)
|
|
print(f"Bus {bus_num} devices: {pretty}")
|
|
else:
|
|
print(f"Bus {bus_num} devices: (none)")
|
|
|
|
if NAU7802_ADDR not in found_by_bus.get(I2C_BUS, []):
|
|
for alt in (1, 0):
|
|
if alt != I2C_BUS and NAU7802_ADDR in found_by_bus.get(alt, []):
|
|
print(f"\nHint: NAU7802 (0x{NAU7802_ADDR:02X}) appears on bus {alt}, not configured bus {I2C_BUS}.")
|
|
print(f"Try: SPOOLBUDDY_I2C_BUS={alt} .../scale_diag.py")
|
|
break
|
|
|
|
scale = NAU7802()
|
|
try:
|
|
print("[1] Initializing...")
|
|
scale.init()
|
|
print(" Initialized OK")
|
|
|
|
print("[2] Waiting for first reading...")
|
|
for _ in range(200):
|
|
if scale.data_ready():
|
|
break
|
|
time.sleep(0.010)
|
|
else:
|
|
print(" Timeout waiting for data ready")
|
|
sys.exit(1)
|
|
|
|
print("[3] Reading 10 samples (10 SPS = ~1 second)...")
|
|
readings = []
|
|
for i in range(10):
|
|
# Wait for data ready
|
|
for _ in range(200):
|
|
if scale.data_ready():
|
|
break
|
|
time.sleep(0.010)
|
|
raw = scale.read_raw()
|
|
readings.append(raw)
|
|
print(f" Sample {i + 1:2d}: {raw:>10d}")
|
|
|
|
avg = sum(readings) / len(readings)
|
|
spread = max(readings) - min(readings)
|
|
print(f"\n Average: {avg:>10.0f}")
|
|
print(f" Min: {min(readings):>10d}")
|
|
print(f" Max: {max(readings):>10d}")
|
|
print(f" Spread: {spread:>10d}")
|
|
|
|
print("\n" + "=" * 60)
|
|
print("Diagnostic complete!")
|
|
print("=" * 60)
|
|
|
|
except Exception as e:
|
|
print(f"\nERROR: {e}")
|
|
is_known_error = False
|
|
|
|
if isinstance(e, OSError):
|
|
if e.errno == 16: # Device or resource busy
|
|
is_known_error = True
|
|
print("\nI2C DEVICE BUSY (Errno 16): Another process is using the I2C bus.")
|
|
print("This typically means the SpoolBuddy daemon is already reading the scale.")
|
|
print("\nTo run this diagnostic, stop the daemon first:")
|
|
print(" sudo systemctl stop bambuddy")
|
|
print(" # Run diagnostic")
|
|
print(" .../scale_diag.py")
|
|
print(" # Restart daemon when done:")
|
|
print(" sudo systemctl start bambuddy")
|
|
elif e.errno == 121:
|
|
is_known_error = True
|
|
print("\nI2C NACK (Errno 121): the device did not acknowledge reads at 0x2A.")
|
|
print("Check:")
|
|
print(" - NAU7802 SDA/SCL are on the configured bus pins")
|
|
print(" - 3.3V and GND are correct and stable")
|
|
print(" - Sensor address is really 0x2A")
|
|
print(" - No loose wire or swapped SDA/SCL")
|
|
else:
|
|
print(f"\nI2C Error (Errno {e.errno}): {e}")
|
|
|
|
# Only print full traceback for unexpected errors
|
|
if not is_known_error:
|
|
import traceback
|
|
|
|
traceback.print_exc()
|
|
|
|
sys.exit(1)
|
|
finally:
|
|
scale.close()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|