add gpio monitor scipt
detects which gpio inputs are changing
This commit is contained in:
109
gpio-monitor.py
Normal file
109
gpio-monitor.py
Normal file
@@ -0,0 +1,109 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
GPIO‑monitor.py
|
||||
|
||||
* Sets every usable BCM pin as an input (pull‑down default)
|
||||
* Saves the last read state of each pin
|
||||
* In an infinite loop it polls the pins (≈10 ms per pass)
|
||||
* When one or more pins change it prints:
|
||||
- Which pins changed and old→new values
|
||||
- The full 32‑bit snapshot as a binary string (MSB = highest pin)
|
||||
|
||||
Run as root (or a user in the *gpio* group):
|
||||
sudo python3 GPIO‑monitor.py
|
||||
Press Ctrl‑C 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 40‑pin 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 Ctrl‑C / SIGTERM
|
||||
# ----------------------------------------------------------------------
|
||||
keep_running = True
|
||||
|
||||
def _handle_exit(signum, frame):
|
||||
global keep_running
|
||||
keep_running = False
|
||||
|
||||
signal.signal(signal.SIGINT, _handle_exit) # Ctrl‑C
|
||||
signal.signal(signal.SIGTERM, _handle_exit)
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# 5️⃣ Main monitoring loop
|
||||
# ----------------------------------------------------------------------
|
||||
prev_state = read_all() # initial snapshot
|
||||
|
||||
print("🔎 Monitoring {} GPIO pins – press Ctrl‑C 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 – 32‑bit 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) # 10 ms
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# 6️⃣ Cleanup
|
||||
# ----------------------------------------------------------------------
|
||||
GPIO.cleanup()
|
||||
print("\n✅ Monitoring stopped – GPIO pins released.")
|
||||
Reference in New Issue
Block a user