agrobot_base/Python/raspi/pi/trigger_manager.py

74 lines
2.1 KiB
Python

import time
import threading
import RPi.GPIO as GPIO
class TriggerManager:
def __init__(self, pin: int, active_high: bool = True, pulse_ms: float = 5.0):
if pin is None or int(pin) < 0:
raise ValueError("Pin inválido")
pulse_ms = float(pulse_ms)
if pulse_ms <= 0:
raise ValueError("pulse_ms deve ser maior que zero")
self.pin = int(pin)
self.active_high = bool(active_high)
self.pulse_ms = pulse_ms
self.initialized = False
self._lock = threading.RLock()
self._active_level = GPIO.HIGH if self.active_high else GPIO.LOW
self._idle_level = GPIO.LOW if self.active_high else GPIO.HIGH
def begin(self):
with self._lock:
if self.initialized:
return True
try:
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(self.pin, GPIO.OUT)
GPIO.output(self.pin, self._idle_level)
except Exception as e:
raise RuntimeError(f"Falha ao inicializar trigger GPIO {self.pin}: {e}") from e
self.initialized = True
return True
def stop(self):
with self._lock:
if not self.initialized:
return True
try:
GPIO.output(self.pin, self._idle_level)
except Exception:
pass
try:
GPIO.cleanup(self.pin)
except Exception:
pass
self.initialized = False
return True
def pulse(self):
with self._lock:
if not self.initialized:
raise RuntimeError("TriggerManager não inicializado")
try:
GPIO.output(self.pin, self._active_level)
time.sleep(self.pulse_ms / 1000.0)
except Exception as e:
raise RuntimeError(f"Falha ao gerar pulso no GPIO {self.pin}: {e}") from e
finally:
try:
GPIO.output(self.pin, self._idle_level)
except Exception:
pass
return True