Arduino

Активный/пассивный зуммер и многоцветные светодиодные модули (RGB, двухцветные)

2 просмотров

Введение

Звуковая и световая индикация — два разных по природе, но часто объединяемых в одном проекте способа обратной связи с пользователем: набор включает активный и пассивный зуммер (различающиеся принципом генерации звука) и несколько разных светодиодных модулей (RGB, двухцветные, «автоматически мигающий» светодиод) для визуальной индикации.

Концепция

Активный зуммер содержит встроенный генератор и издаёт звук фиксированной частоты при простой подаче напряжения (управляется как обычный цифровой выход, HIGH/LOW), тогда как пассивный зуммер не имеет встроенного генератора и требует подачи переменного сигнала нужной частоты (через tone() или ШИМ), что даёт возможность генерировать разные тона и мелодии, недоступную для активного зуммера. RGB-модуль объединяет три отдельных светодиода (красный, зелёный, синий) в одном корпусе, управляемые тремя отдельными ШИМ-сигналами для получения произвольного смешанного цвета через аддитивное смешение, тогда как двухцветный светодиод содержит только два кристалла (часто красный и зелёный), управляемых независимо для получения трёх состояний (только красный, только зелёный, оба одновременно дают промежуточный, обычно желтоватый оттенок).

Пример кода

// Активный зуммер — простое включение/выключение
const int ACTIVE_BUZZER_PIN = 8;

void beepActive(int durationMs) {
    digitalWrite(ACTIVE_BUZZER_PIN, HIGH);
    delay(durationMs);
    digitalWrite(ACTIVE_BUZZER_PIN, LOW);
}
// Пассивный зуммер — генерация конкретных тонов и простой мелодии через tone()
const int PASSIVE_BUZZER_PIN = 9;

void playSimpleMelody() {
    int notes[] = {262, 294, 330, 349, 392}; // до, ре, ми, фа, соль — частоты в Гц
    int noteDuration = 300;

    for (int i = 0; i < 5; i++) {
        tone(PASSIVE_BUZZER_PIN, notes[i], noteDuration);
        delay(noteDuration + 50); // небольшая пауза между нотами
    }
    noTone(PASSIVE_BUZZER_PIN);
}
// RGB-модуль — смешение цветов через три ШИМ-канала
const int RGB_RED_PIN = 9;
const int RGB_GREEN_PIN = 10;
const int RGB_BLUE_PIN = 11;

void setRgbColor(int red, int green, int blue) {
    analogWrite(RGB_RED_PIN, red);
    analogWrite(RGB_GREEN_PIN, green);
    analogWrite(RGB_BLUE_PIN, blue);
}

void demonstrateRgbColors() {
    setRgbColor(255, 0, 0);   delay(500); // красный
    setRgbColor(0, 255, 0);   delay(500); // зелёный
    setRgbColor(0, 0, 255);   delay(500); // синий
    setRgbColor(255, 255, 0); delay(500); // жёлтый (красный + зелёный)
    setRgbColor(128, 0, 128); delay(500); // фиолетовый (приглушённый красный + синий)
}
// Двухцветный светодиод — только два независимых канала, без ШИМ-смешения в примере
const int BICOLOR_RED_PIN = 12;
const int BICOLOR_GREEN_PIN = 13;

void setBicolorState(bool red, bool green) {
    digitalWrite(BICOLOR_RED_PIN, red ? HIGH : LOW);
    digitalWrite(BICOLOR_GREEN_PIN, green ? HIGH : LOW);
}

Пояснения к коду

Принципиальное различие между beepActive() (простой digitalWrite) и playSimpleMelody() (использование tone() с конкретными частотами) напрямую отражает аппаратное различие зуммеров — попытка использовать tone() с активным зуммером не даст ожидаемого эффекта разных тонов (активный зуммер всё равно издаст свой единственный фиксированный звук независимо от частоты управляющего сигнала), и наоборот, простое digitalWrite(HIGH) на пассивном зуммере может издать лишь тихий щелчок или вовсе не дать слышимого звука, поскольку пассивному зуммеру нужен именно переменный, а не постоянный сигнал. setRgbColor() показывает использование analogWrite() (ШИМ) для всех трёх каналов одновременно, что даёт значительно больше 3 цветов (комбинации простого HIGH/LOW дали бы лишь 8 вариантов) — произвольное смешение интенсивностей через ШИМ позволяет получить весь спектр доступных цветов, ограниченный только разрешением ШИМ (обычно 256 уровней на канал на стандартном Arduino).

Подводные камни

  • Попытка генерировать мелодию или разные тона на активном зуммере, ожидая того же эффекта, что и для пассивного — поскольку активный зуммер не реагирует на частоту управляющего сигнала, такой код просто не даст ожидаемого музыкального эффекта; перед написанием кода важно точно знать, активный или пассивный зуммер используется в конкретном проекте (что обычно можно определить как по маркировке на самом модуле, так и эмпирически — простым тестом с tone() на разных частотах и проверкой, меняется ли реально слышимый звук).
  • Использование tone() одновременно с analogWrite() ШИМ на других пинах того же таймера микроконтроллераtone() на Arduino UNO внутренне использует один из аппаратных таймеров, и одновременное использование того же таймера для других целей (некоторые пины analogWrite() совместно используют таймеры с tone()) может привести к конфликтам, нарушающим как генерацию тона, так и ШИМ на затронутых пинах — конкретное распределение пинов по таймерам специфично для модели микроконтроллера и должно быть проверено в документации при возникновении необъяснимых конфликтов между одновременно используемыми tone() и analogWrite().
  • Игнорирование ограничения по току при управлении RGB-модулем без общего токоограничивающего резистора (если RGB-модуль рассчитан на использование с внешними резисторами, а не имеет их встроенными) — аналогично общим подводным камням про токоограничение светодиодов из основного Arduino-цикла, превышение максимально допустимого тока через любой из трёх кристаллов RGB-светодиода может повредить именно этот кристалл, что для смешения цветов особенно заметно (выгоревший один канал полностью меняет весь доступный диапазон получаемых цветов).
  • Восприятие «двухцветного» светодиода как способного давать произвольный, плавный градиент цветов между двумя базовыми, без ШИМ-управления (как в упрощённом примере с простым digitalWrite для обоих каналов) — без применения analogWrite() к обоим каналам двухцветный светодиод даёт лишь три дискретных состояния (только первый цвет, только второй, оба одновременно), и для получения промежуточных оттенков (а не просто фиксированного смешанного цвета при одновременном включении обоих) также требуется ШИМ-управление обоими каналами, аналогично подходу для полноценного RGB-модуля.