From 84514c7956c0c52497674400aa551ab5d29be7e6 Mon Sep 17 00:00:00 2001 From: Your Name Date: Sun, 7 Dec 2025 15:06:45 +0000 Subject: [PATCH] add gpio monitor scipt detects which gpio inputs are changing --- gpio-monitor.py | 109 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 gpio-monitor.py diff --git a/gpio-monitor.py b/gpio-monitor.py new file mode 100644 index 0000000..7bd020c --- /dev/null +++ b/gpio-monitor.py @@ -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.")