Проекти ESP32 | Інтернет-радіо на ESP32S2 Mini

Basic BTN

Тест.

info.

warning.

message-negative.

ESP32 підключення 12 RGB LED WS2812

 У цій статті підключимо до моєї улюбленої *сороконіжки* ESP32 S2 mini адресні свтлодіоди у вигляді кільця NeoPixel 12 RGB LED WS2812 та керуватимемо 10 простими світлодіодними ефектами. Цей приклад коду був використаний у проекті інтернет-радіо на esp32 у корпусі, надрукованому на 3D-принтері. 

Компоненти:

  • ESP32-S2 Mini
  • Світлодіодне кільце на 12 RGB LED WS2812 (NeoPixel)
  • 3 кнопки (або тактові кнопки)
  • Резистори 10к (опціонально для підтягування кнопок)
  • Дроти
  • Живлення 5В (наприклад, від USB)
  • Arduino IDE
Призначення Пін ESP32-S2 Mini
LED кільце (DIN) GPIO16
Кнопка «Наступний» GPIO18
Кнопка «Попередній» GPIO35
Кнопка «Вкл/Вимк» GPIO33
Живлення кільця (5V) 5V
GND кільця та кнопок GND

 Передбачається, що у вас встановлено Arduino IDE (я використовую версію 2.3.3). Додайте у менеджері бібліотек FastLED для керування адресними світлодіодами. Якщо немає:

Скетч → Підключити бібліотеку → Керування бібліотеками

Знайдіть та встановіть FastLED

Як це працюватиме:

  • Світлодіоди підключені до піна 16 і керуються через бібліотеку FastLED.
  • Кнопка на піні 18 перемикає ефект вперед.
  • Кнопка на піні 35 перемикає назад.
  • Кнопка на піні 33 вмикає та вимикає анімацію.


#include <fastled.h>

#define LED_PIN     16
#define NUM_LEDS    12
#define BRIGHTNESS  100
#define LED_TYPE    WS2812
#define COLOR_ORDER GRB

CRGB leds[NUM_LEDS];

// Кнопки
#define BTN_NEXT     18
#define BTN_PREV     35
#define BTN_TOGGLE   33

bool effectOn = true;
int currentEffect = 0;
const int totalEffects = 10;

unsigned long lastDebounceTime = 0;
const unsigned long debounceDelay = 200;  // защита от дребезга

void setup() {
  FastLED.addLeds<led_type, led_pin,="" color_order="">(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
  FastLED.setBrightness(BRIGHTNESS);

  pinMode(BTN_NEXT, INPUT_PULLUP);
  pinMode(BTN_PREV, INPUT_PULLUP);
  pinMode(BTN_TOGGLE, INPUT_PULLUP);

  // Показать зелёный при старте
  fill_solid(leds, NUM_LEDS, CRGB::Green);
  FastLED.show();
  delay(2000);
  FastLED.clear();
  FastLED.show();
}

void loop() {
  handleButtons();

  if (effectOn) {
    switch (currentEffect) {
      case 0: rainbowCycle(); break;
      case 1: colorWipe(CRGB::Red); break;
      case 2: theaterChase(CRGB::Blue); break;
      case 3: setSolidColor(CRGB::White); break;
      case 4: setSolidColor(CRGB::Blue); break;
      case 5: setSolidColor(CRGB::Green); break;
      case 6: setSolidColor(CRGB::Red); break;
      case 7: fireEffect(); break;
      case 8: rainbowFill(); break;
      case 9: strobeEffect(); break;
    }
    FastLED.show();
    delay(30);
  } else {
    FastLED.clear();
    FastLED.show();
    delay(100);
  }
}

// === ЭФФЕКТЫ ===
void setSolidColor(CRGB color) {
  fill_solid(leds, NUM_LEDS, color);
}

void rainbowFill() {
  static uint8_t hue = 0;
  fill_rainbow(leds, NUM_LEDS, hue, 7);  // шаг изменения цвета
  hue++;
}

void strobeEffect() {
  static uint32_t lastBlinkTime = 0;
  static bool ledOn = false;

  if (millis() - lastBlinkTime >= 100) {
    lastBlinkTime = millis();
    ledOn = !ledOn;
    setSolidColor(ledOn ? CRGB::White : CRGB::Black);
  }
}

void fireEffect() {
  static uint8_t heat[NUM_LEDS];

  for (int i = 0; i < NUM_LEDS; i++) {
    heat[i] = qsub8(heat[i], random(0, 50));
  }

  for (int i = NUM_LEDS - 1; i >= 2; i--) {
    heat[i] = (heat[i - 1] + heat[i - 2] + heat[i - 2]) / 3;
  }

  if (random(0, 10) > 7) {
    int sparkIndex = random(0, 3);
    heat[sparkIndex] = qadd8(heat[sparkIndex], random(160, 255));
  }

  for (int i = 0; i < NUM_LEDS; i++) {
    leds[i] = HeatColor(heat[i]);
  }
}


void rainbowCycle() {
  static uint8_t hue = 0;
  for (int i = 0; i < NUM_LEDS; i++) {
    leds[i] = CHSV((hue + (i * 256 / NUM_LEDS)) % 256, 255, 255);
  }
  hue++;
}

void colorWipe(CRGB color) {
  static int pos = 0;
  leds[pos] = color;
  pos = (pos + 1) % NUM_LEDS;
}

void theaterChase(CRGB color) {
  static int step = 0;
  for (int i = 0; i < NUM_LEDS; i++) {
    leds[i] = ((i + step) % 3 == 0) ? color : CRGB::Black;
  }
  step = (step + 1) % 3;
}

// === ОБРАБОТКА КНОПОК ===

void handleButtons() {
  static bool lastStateNext = HIGH;
  static bool lastStatePrev = HIGH;
  static bool lastStateToggle = HIGH;

  bool currentStateNext = digitalRead(BTN_NEXT);
  bool currentStatePrev = digitalRead(BTN_PREV);
  bool currentStateToggle = digitalRead(BTN_TOGGLE);

  unsigned long currentTime = millis();

  // Обработка кнопки "Следующий эффект"
  if (currentStateNext == LOW && lastStateNext == HIGH && (currentTime - lastDebounceTime > debounceDelay)) {
    currentEffect = (currentEffect + 1) % totalEffects;
    lastDebounceTime = currentTime;
  }

  // Обработка кнопки "Предыдущий эффект"
  if (currentStatePrev == LOW && lastStatePrev == HIGH && (currentTime - lastDebounceTime > debounceDelay)) {
    currentEffect = (currentEffect - 1 + totalEffects) % totalEffects;
    lastDebounceTime = currentTime;
  }

  // Обработка кнопки "Вкл/Выкл"
  if (currentStateToggle == LOW && lastStateToggle == HIGH && (currentTime - lastDebounceTime > debounceDelay)) {
    effectOn = !effectOn;
    lastDebounceTime = currentTime;
  }

  // Обновляем предыдущее состояние
  lastStateNext = currentStateNext;
  lastStatePrev = currentStatePrev;
  lastStateToggle = currentStateToggle;
}