Files
waveform-draw/gpio-monitor.py
Your Name 84514c7956 add gpio monitor scipt
detects which gpio inputs are changing
2025-12-07 15:06:45 +00:00

110 lines
3.8 KiB
Python
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/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.")