reed_switch.py 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. """
  2. Reed switch monitoring module for Raspberry Pi GPIO.
  3. Used for angular homing to detect home position.
  4. """
  5. import logging
  6. import platform
  7. logger = logging.getLogger(__name__)
  8. class ReedSwitchMonitor:
  9. """Monitor a reed switch connected to a Raspberry Pi GPIO pin."""
  10. def __init__(self, gpio_pin=18):
  11. """
  12. Initialize the reed switch monitor.
  13. Args:
  14. gpio_pin: GPIO pin number (BCM numbering) for the reed switch
  15. """
  16. self.gpio_pin = gpio_pin
  17. self.gpio = None
  18. self.is_raspberry_pi = False
  19. # Try to import and initialize GPIO
  20. try:
  21. import RPi.GPIO as GPIO
  22. self.gpio = GPIO
  23. # Set up GPIO mode (BCM numbering)
  24. self.gpio.setmode(GPIO.BCM)
  25. # Set up the pin as input with pull-up resistor
  26. # Reed switch should connect pin to ground when triggered
  27. self.gpio.setup(self.gpio_pin, GPIO.IN, pull_up_down=GPIO.PUD_UP)
  28. self.is_raspberry_pi = True
  29. logger.info(f"Reed switch initialized on GPIO pin {self.gpio_pin}")
  30. except ImportError:
  31. logger.warning("RPi.GPIO not available. Reed switch monitoring disabled.")
  32. except Exception as e:
  33. logger.error(f"Error initializing reed switch: {e}")
  34. logger.info("Reed switch monitoring disabled.")
  35. def is_triggered(self):
  36. """
  37. Check if the reed switch is currently triggered.
  38. Returns:
  39. bool: True if reed switch is triggered (pin is HIGH), False otherwise
  40. """
  41. if not self.is_raspberry_pi or not self.gpio:
  42. return False
  43. try:
  44. # Pin is HIGH (1) when reed switch is closed (triggered)
  45. # This assumes the switch connects the pin to 3.3V when closed
  46. return self.gpio.input(self.gpio_pin) == 1
  47. except Exception as e:
  48. logger.error(f"Error reading reed switch: {e}")
  49. return False
  50. def wait_for_trigger(self, timeout=None):
  51. """
  52. Wait for the reed switch to be triggered.
  53. Args:
  54. timeout: Maximum time to wait in seconds (None = wait indefinitely)
  55. Returns:
  56. bool: True if triggered, False if timeout occurred
  57. """
  58. if not self.is_raspberry_pi or not self.gpio:
  59. logger.warning("Reed switch not available, cannot wait for trigger")
  60. return False
  61. try:
  62. # Wait for rising edge (pin goes from LOW to HIGH)
  63. channel = self.gpio.wait_for_edge(
  64. self.gpio_pin,
  65. self.gpio.RISING,
  66. timeout=int(timeout * 1000) if timeout else None
  67. )
  68. return channel is not None
  69. except Exception as e:
  70. logger.error(f"Error waiting for reed switch trigger: {e}")
  71. return False
  72. def cleanup(self):
  73. """Clean up GPIO resources."""
  74. if self.is_raspberry_pi and self.gpio:
  75. try:
  76. self.gpio.cleanup(self.gpio_pin)
  77. logger.info(f"Reed switch GPIO pin {self.gpio_pin} cleaned up")
  78. except Exception as e:
  79. logger.error(f"Error cleaning up reed switch GPIO: {e}")
  80. def __del__(self):
  81. """Destructor to ensure GPIO cleanup."""
  82. self.cleanup()