add gpio monitor scipt

detects which gpio inputs are changing
This commit is contained in:
Your Name
2025-12-07 15:06:45 +00:00
parent 63de9b0d3d
commit 84514c7956

109
gpio-monitor.py Normal file
View File

@@ -0,0 +1,109 @@
#!/usr/bin/env python3
"""
GPIOmonitor.py
* Sets every usable BCM pin as an input (pulldown default)
* Saves the last read state of each pin
* In an infinite loop it polls the pins (≈10ms per pass)
* When one or more pins change it prints:
- Which pins changed and old→new values
- The full 32bit snapshot as a binary string (MSB = highest pin)
Run as root (or a user in the *gpio* group):
sudo python3 GPIOmonitor.py
Press CtrlC to stop the script cleans up the GPIO pins.
"""
import sys
import time
import signal
import RPi.GPIO as GPIO
# ----------------------------------------------------------------------
# 1⃣ Pin list all BCM pins that exist on the 40pin header
# ----------------------------------------------------------------------
GPIO_PINS = [
2, 3, 4, 5, 6, 7, 8, 9,
10, 11, 12, 13, 14, 15, 16, 17,
18, 19, 20, 21, 22, 23, 24, 25,
26, 27
]
# ----------------------------------------------------------------------
# 2⃣ Initialise GPIO
# ----------------------------------------------------------------------
GPIO.setmode(GPIO.BCM)
# keep only those pins we can actually configure
active_pins = []
failed = []
for pin in GPIO_PINS:
try:
GPIO.setup(pin, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
active_pins.append(pin)
except Exception as e:
failed.append((pin, str(e)))
if failed:
sys.stderr.write("⚠️ Could not initialise the following pins (they will be ignored):\n")
for p, msg in failed:
sys.stderr.write(f" Pin {p}: {msg}\n")
# ----------------------------------------------------------------------
# 3⃣ Helper to read the current snapshot (dict pin→0/1)
# ----------------------------------------------------------------------
def read_all():
return {pin: GPIO.input(pin) for pin in active_pins}
# ----------------------------------------------------------------------
# 4⃣ Signal handling graceful exit on CtrlC / SIGTERM
# ----------------------------------------------------------------------
keep_running = True
def _handle_exit(signum, frame):
global keep_running
keep_running = False
signal.signal(signal.SIGINT, _handle_exit) # CtrlC
signal.signal(signal.SIGTERM, _handle_exit)
# ----------------------------------------------------------------------
# 5⃣ Main monitoring loop
# ----------------------------------------------------------------------
prev_state = read_all() # initial snapshot
print("🔎 Monitoring {} GPIO pins press CtrlC to stop".format(len(active_pins)))
while keep_running:
cur_state = read_all()
# Find pins whose value differed from the previous snapshot
changed = [(pin, prev_state[pin], cur_state[pin])
for pin in active_pins
if prev_state[pin] != cur_state[pin]]
if changed:
# Build a readable change list e.g. "4:0→1, 17:1→0"
changes_txt = ", ".join(f"{pin}:{old}{new}" for pin, old, new in changed)
# Build a compact binary view 32bit with pins sorted ascending
# (higher pins become more significant bits)
bits = "".join(str(cur_state[p]) for p in sorted(active_pins, reverse=True))
# Pad to a multiple of 4 for readability
pad_len = (4 - len(bits) % 4) % 4
bits = "0" * pad_len + bits
print(f"[{time.strftime('%H:%M:%S')}] Change detected {changes_txt}")
print(f" Current snapshot: 0b{bits}")
# Update reference for the next iteration
prev_state = cur_state
# Polling interval adjust if you need faster/slower response
time.sleep(0.01) # 10ms
# ----------------------------------------------------------------------
# 6⃣ Cleanup
# ----------------------------------------------------------------------
GPIO.cleanup()
print("\n✅ Monitoring stopped GPIO pins released.")