Skip to content

Instantly share code, notes, and snippets.

@Lyrkan
Created December 2, 2023 02:56
Show Gist options
  • Save Lyrkan/59891d932db17d82d41ad3e4b35aedc2 to your computer and use it in GitHub Desktop.
Save Lyrkan/59891d932db17d82d41ad3e4b35aedc2 to your computer and use it in GitHub Desktop.
Moon Rocket LED ESP32 controller
#include <Arduino.h>
#include <math.h>
#include <esp_task_wdt.h>
#define TOUCH_SENSOR_PIN GPIO_NUM_4
#define LED_1_PIN GPIO_NUM_25
#define LED_2_PIN GPIO_NUM_27
#define LED_3_PIN GPIO_NUM_32
#define PWM_RESOLUTION 8
#define PWM_FREQUENCY 1000
#define TOUCH_SENSOR_THRESHOLD 40
#define TOUCH_SENSOR_DELAY 500
#define LED_1_CHANNEL 0
#define LED_2_CHANNEL 1
#define LED_3_CHANNEL 2
#define LEDS_LOW_DUTY 50
#define LEDS_MEDIUM_DUTY 125
#define LEDS_HIGH_DUTY 255
#define WDT_TIMEOUT_SECONDS 60
typedef enum {
LED_MODE_LOW = 0,
LED_MODE_MEDIUM = 1,
LED_MODE_HIGH = 2,
LED_MODE_OFF = 3
} led_mode_t;
inline led_mode_t &operator++(led_mode_t &mode, int) {
mode = static_cast<led_mode_t>((static_cast<int>(mode) + 1) % 4);
return mode;
}
// Loop task handle created by arduino-esp32
extern TaskHandle_t loopTaskHandle;
static led_mode_t current_led_mode = LED_MODE_LOW;
void touch_sensor_callback() {
static long last_call_time = 0;
long current_time = millis();
if ((last_call_time + TOUCH_SENSOR_DELAY) < current_time) {
last_call_time = current_time;
if (current_led_mode < LED_MODE_OFF) {
current_led_mode++;
xTaskNotifyFromISR(loopTaskHandle, 0, eNoAction, NULL);
}
}
}
void update_leds_duty(led_mode_t mode) {
uint32_t duty = 0;
switch (mode) {
case LED_MODE_LOW:
duty = LEDS_LOW_DUTY;
break;
case LED_MODE_MEDIUM:
duty = LEDS_MEDIUM_DUTY;
break;
case LED_MODE_HIGH:
duty = LEDS_HIGH_DUTY;
break;
default:
duty = 0;
}
ledcWrite(LED_1_CHANNEL, duty);
ledcWrite(LED_2_CHANNEL, duty);
ledcWrite(LED_3_CHANNEL, duty);
}
void setup() {
Serial.begin(115200);
if (esp_sleep_get_wakeup_cause() == ESP_SLEEP_WAKEUP_TOUCHPAD) {
Serial.println("Waking up from deep sleep");
}
// WDT setup
esp_task_wdt_init(WDT_TIMEOUT_SECONDS, true);
esp_task_wdt_add(NULL);
// LEDs setup
ledcSetup(LED_1_CHANNEL, PWM_FREQUENCY, PWM_RESOLUTION);
ledcSetup(LED_2_CHANNEL, PWM_FREQUENCY, PWM_RESOLUTION);
ledcSetup(LED_3_CHANNEL, PWM_FREQUENCY, PWM_RESOLUTION);
ledcAttachPin(LED_1_PIN, LED_1_CHANNEL);
ledcAttachPin(LED_2_PIN, LED_2_CHANNEL);
ledcAttachPin(LED_3_PIN, LED_3_CHANNEL);
update_leds_duty(current_led_mode);
}
void loop() {
static bool touch_sensor_enabled = false;
if (!touch_sensor_enabled) {
// Enable touch sensor after TOUCH_SENSOR_DELAY milliseconds
vTaskDelay(pdMS_TO_TICKS(TOUCH_SENSOR_DELAY));
Serial.println("Enabling touch sensor");
touchAttachInterrupt(TOUCH_SENSOR_PIN, touch_sensor_callback, TOUCH_SENSOR_THRESHOLD);
esp_sleep_enable_touchpad_wakeup();
touch_sensor_enabled = true;
}
// Update LEDs brightness
update_leds_duty(current_led_mode);
if (current_led_mode == LED_MODE_OFF) {
// Enter deep sleep if LEDs were turned off
Serial.println("Shutting down...");
vTaskDelay(pdMS_TO_TICKS(1000));
Serial.println("Entering deep sleep...");
esp_deep_sleep_start();
} else {
// Wait for either a notification from the touch_sensor_callback ISR
// or 75% of the WDT timeout
xTaskNotifyWait(pdFALSE, ULONG_MAX, NULL, pdMS_TO_TICKS((WDT_TIMEOUT_SECONDS * 1000) * 0.75));
esp_task_wdt_reset();
}
}
[platformio]
description = "Moon Rocket LEDs controller"
default_envs = wemos-d1-mini-esp32
[env]
framework = arduino
[env:wemos-d1-mini-esp32]
platform = espressif32
board = wemos_d1_mini32
monitor_speed = 115200
[env:wemos-d1-mini-esp32-debug]
extends = env:wemos-d1-mini-esp32
build_type = debug
build_flags =
-D DEBUG
${env.build_flags}
monitor_filters =
esp32_exception_decoder
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment