diff --git a/micro_ondes/esp_lora/main.py b/micro_ondes/esp_lora/main.py index 08cc2f8..fd175d6 100644 --- a/micro_ondes/esp_lora/main.py +++ b/micro_ondes/esp_lora/main.py @@ -1,6 +1,6 @@ import _thread from machine import Pin -from shared import get_lora, get_uart, deviceTypes, config +from sensors import RGBLED import time # --- Configuration Matérielle --- @@ -19,6 +19,11 @@ except Exception: lora = get_lora() lora.configure(freq=868.1, sf=7) +# --- Création des lEDs RGB --- +magnetron_led = RGBLED(red_pin=48, green_pin=47, blue_pin=33) +magnetron_led.set_color(RGBLED.YELLOW) +magnetron_led.off() + print(f"ESP32 initialisé avec l'ID : '{DEVICE_ID}' (Type : {deviceTypes.DEVICE_TYPES['MICROWAVE']})") def heartbeat_loop(): diff --git a/micro_ondes/esp_lora/sensors/rgb_led.py b/micro_ondes/esp_lora/sensors/rgb_led.py new file mode 100644 index 0000000..6a18bab --- /dev/null +++ b/micro_ondes/esp_lora/sensors/rgb_led.py @@ -0,0 +1,116 @@ +from machine import Pin, PWM + +class RGBLED: + """ + MicroPython driver for 4-pin RGB LEDs on ESP32 / Heltec boards. + Supports state tracking, color setting, brightness scaling, and state toggling. + """ + + # Preset RGB tuples for quick use + RED = (255, 0, 0) + GREEN = (0, 255, 0) + BLUE = (0, 0, 255) + YELLOW = (255, 150, 0) + ORANGE = (255, 50, 0) + WHITE = (255, 255, 255) + OFF = (0, 0, 0) + + def __init__(self, red_pin, green_pin, blue_pin, common_anode=False, freq=1000): + """ + :param red_pin: GPIO pin number for Red channel + :param green_pin: GPIO pin number for Green channel + :param blue_pin: GPIO pin number for Blue channel + :param common_anode: Set True if cathode is connected to 3.3V instead of GND + :param freq: PWM frequency in Hz (default 1000Hz) + """ + self._r_pwm = PWM(Pin(red_pin, Pin.OUT), freq=freq) + self._g_pwm = PWM(Pin(green_pin, Pin.OUT), freq=freq) + self._b_pwm = PWM(Pin(blue_pin, Pin.OUT), freq=freq) + + self._common_anode = common_anode + + # State tracking variables + self._color = (0, 0, 0) # Current (R, G, B) tuple [0-255] + self._brightness = 1.0 # Brightness factor [0.0 to 1.0] + self._is_on = True # Master power state + + self._apply() + + def _apply(self): + """Recalculates and applies PWM duty cycles based on state.""" + if not self._is_on: + r, g, b = 0, 0, 0 + else: + r = int(self._color[0] * self._brightness) + g = int(self._color[1] * self._brightness) + b = int(self._color[2] * self._brightness) + + for pwm, val in ((self._r_pwm, r), (self._g_pwm, g), (self._b_pwm, b)): + # Clamp value between 0 and 255 + val = max(0, min(255, val)) + # Convert 8-bit (0-255) to MicroPython's 16-bit PWM duty (0-65535) + duty = int((val / 255.0) * 65535) + + if self._common_anode: + duty = 65535 - duty + + pwm.duty_u16(duty) + + # --- Properties and Setters --- + + @property + def color(self): + """Returns the active RGB tuple (R, G, B).""" + return self._color + + @color.setter + def color(self, rgb_tuple): + """Sets the RGB color tuple (e.g., (255, 128, 0)).""" + if isinstance(rgb_tuple, (tuple, list)) and len(rgb_tuple) == 3: + self._color = tuple(rgb_tuple) + self._apply() + else: + raise ValueError("Color must be a tuple of 3 integers: (R, G, B)") + + @property + def brightness(self): + """Returns the current brightness level (0.0 to 1.0).""" + return self._brightness + + @brightness.setter + def brightness(self, level): + """Sets brightness level from 0.0 (0%) to 1.0 (100%).""" + self._brightness = max(0.0, min(1.0, float(level))) + self._apply() + + @property + def is_on(self): + """Returns True if the LED is currently powered on.""" + return self._is_on + + # --- Helper Methods --- + + def set_rgb(self, r, g, b): + """Alternative setter for individual R, G, B integer values.""" + self.color = (r, g, b) + + def on(self): + """Turns the LED on using its stored color and brightness.""" + self._is_on = True + self._apply() + + def off(self): + """Turns the LED off without resetting the active color state.""" + self._is_on = False + self._apply() + + def toggle(self): + """Toggles between ON and OFF states.""" + self._is_on = not self._is_on + self._apply() + + def deinit(self): + """Releases the hardware PWM pins when finished.""" + self._r_pwm.deinit() + self._g_pwm.deinit() + self._b_pwm.deinit() \ No newline at end of file