Skip to main content

ЦИФРОВОЙ СПИННЕР 🎡

БАЗОВАЯ РЕАЛИЗАЦИЯ

Логика работы:

Энкодер поворот → циклический сдвиг битового паттерна
Кнопка энкодера → смена направления сдвига
Светодиоды в круге → визуализация "бегущего огня"
Автоматический режим → непрерывное вращение паттерна

Компоненты:

  • ✅ Энкодер роторный (с кнопкой)
  • ✅ Светодиоды - 6 шт (круговое расположение)
  • ✅ Резисторы 220 Ом - 6 шт
  • ✅ Arduino Uno + макетка
  • ✅ ✅ Дополнительно: кнопка для смены режимов

Схема подключения:

Энкодер:
  CLK (A) → pin 2
  DT (B) → pin 3  
  SW (кнопка) → pin 4 + pull-up резистор
  VCC → 5V
  GND → GND

Светодиоды (круг):
  LED0 (позиция 0) → pin 5 → резистор → GND
  LED1 (позиция 1) → pin 6 → резистор → GND
  LED2 (позиция 2) → pin 7 → резистор → GND
  LED3 (позиция 3) → pin 8 → резистор → GND
  LED4 (позиция 4) → pin 9 → резистор → GND  
  LED5 (позиция 5) → pin 10 → резистор → GND

ЛОГИКА РАБОТЫ 🔄

Псевдокод для обсуждения:

// ИНИЦИАЛИЗАЦИЯ:
текущий_паттерн = 0b000001 (только один светодиод горит)
направление = ВПРАВО
режим = РУЧНОЙ

// ОСНОВНОЙ ЦИКЛ:
если (режим == АВТОМАТИЧЕСКИЙ):
  если (прошло > интервал):
    сдвигаем_паттерн(направление)
    обновляем_таймер()

обрабатываем_энкодер():
  если (поворот вправо):
    сдвигаем_паттерн(ВПРАВО)
  если (поворот влево):
    сдвигаем_паттерн(ВЛЕВО)

обрабатываем_кнопку():
  если (нажата):
    меняем_направление()
    ждем отпускания

отображаем_паттерн_на_светодиодах(текущий_паттерн)

ДЕТАЛЬНАЯ РЕАЛИЗАЦИЯ АЛГОРИТМОВ

Циклические сдвиги:

uint8_t circularShiftLeft(uint8_t pattern) {
  // Для 6 бит: убираем старшие 2 бита, циклически сдвигаем
  pattern &= 0x3F; // маска 00111111
  uint8_t lostBit = (pattern >> 5) & 1; // сохраняем старший бит
  return ((pattern << 1) | lostBit) & 0x3F;
}

uint8_t circularShiftRight(uint8_t pattern) {
  pattern &= 0x3F; // маска 00111111  
  uint8_t lostBit = (pattern & 1) << 5; // сохраняем младший бит
  return ((pattern >> 1) | lostBit) & 0x3F;
}

Обработка энкодера:

void handleEncoder() {
  int encoderA = digitalRead(ENCODER_A_PIN);
  int encoderB = digitalRead(ENCODER_B_PIN);
  
  if (encoderA != lastEncoderA) {
    if (encoderB != encoderA) {
      // Поворот вправо
      currentPattern = circularShiftRight(currentPattern);
    } else {
      // Поворот влево
      currentPattern = circularShiftLeft(currentPattern);
    }
  }
  lastEncoderA = encoderA;
}

Смена режимов и направлений:

void handleEncoderButton() {
  if (digitalRead(ENCODER_BUTTON_PIN) == LOW) {
    delay(50); // антидребезг
    if (digitalRead(ENCODER_BUTTON_PIN) == LOW) {
      // Меняем направление
      direction = (direction == RIGHT) ? LEFT : RIGHT;
      
      // Ждем отпускания кнопки
      while (digitalRead(ENCODER_BUTTON_PIN) == LOW) {
        delay(10);
      }
    }
  }
}

УСЛОЖНЕНИЯ И ВАРИАЦИИ 🎛️

1. Мультирежимный спиннер:

enum SpinnerMode {
  SINGLE_LED,    // один бегущий светодиод
  DOUBLE_LED,    // два противоположных светодиода  
  WAVE,          // плавная волна
  RANDOM         // случайные вспышки
};

void changeMode() {
  currentMode = (currentMode + 1) % 4;
  resetPattern(); // сброс паттерна для нового режима
}

2. Управление скоростью:

// Энкодер управляет скоростью вращения в автоматическом режиме
void handleSpeedControl() {
  if (encoderTurned) {
    rotationSpeed = constrain(rotationSpeed + encoderDirection, 50, 1000);
    // 50ms - быстро, 1000ms - медленно
  }
}

3. Цветной спиннер (RGB):

// Используем RGB светодиоды или разные цвета
// Каждый режим - свой цветовая схема:
// - SINGLE_LED: красный
// - DOUBLE_LED: синий  
// - WAVE: зеленый
// - RANDOM: разноцветный

ОЛИМПИАДНАЯ СВЯЗЬ 🏆

ПРЯМАЯ ПОДГОТОВКА К ЗАДАНИЯМ 10-11 КЛАССОВ:

// Олимпиадное задание 10-11 классов:
"Поворотом потенциометра можно произвести циклический битовый сдвиг\
 (круговой сдвиг) влево или вправо. Каждые 15° поворота потенциометра \
 сдвигают число на 1 бит."

"При удержании кнопки №3 потенциометр не производит сдвиг и свободно \
 вращается, не оказывая влияние на систему."

Критерии успеха в олимпиаде:

  • Корректные циклические сдвиги - биты не теряются
  • Точное управление энкодером - каждый шаг = одно изменение
  • Стабильная работа режимов - четкие переходы между состояниями
  • Визуальная понятность - сразу видно направление и скорость

Типичные олимпиадные ошибки:

  • Некорректный циклический сдвиг - теряются биты или появляются лишние
  • Дребезг энкодера - multiple срабатывания на один шаг
  • Путаница с направлениями - влево/вправо работают наоборот
  • Нет блокировки управления - не реализовано удержание кнопки

МЕТОДИЧЕСКИЕ СОВЕТЫ 👨‍🏫

Поэтапная реализация:

// ЭТАП 1: Простой бегущий огонь (автоматический)
currentPattern = circularShiftLeft(currentPattern);
displayPattern(currentPattern);
delay(speed);

// ЭТАП 2: Добавляем управление энкодером
handleEncoder();
if (encoderTurned) {
  currentPattern = (direction == RIGHT) ? 
    circularShiftRight(currentPattern) : 
    circularShiftLeft(currentPattern);
}

// ЭТАП 3: Режимы работы
handleEncoderButton();
if (buttonPressed) {
  changeMode();
}

// ЭТАП 4: Блокировка управления (олимпиадное требование)
if (holdButtonPressed) {
  isLocked = true;
  // игнорируем повороты энкодера
}

Визуализация для понимания:

🔄 Циклический сдвиг (6 бит):
Исходное:   0 1 0 1 1 0  (42)
Влево:      1 0 1 1 0 0  → перенос: 0 → 1 0 1 1 0 0 (44)
Правильно:  1 0 1 1 0 0  → перенос: 0 → 1 0 1 1 0 0 (44)

🎛️  Энкодер:
Поворот → CLK/DT изменения → определение направления
Нажатие → смена режима/направления

Практические упражнения:

Упражнение 1: “Слепое управление”

  • Научить определять направление сдвига по звуку/тактильно
  • Развить мышечную память для работы с энкодером
  • Тренировка без визуального контроля

Упражнение 2: “Режим программирования”

  • Запрограммировать определенную последовательность сдвигов
  • Воспроизвести запомненный паттерн
  • Создать “хореографию” для светодиодов

Упражнение 3: “Синхронизация”

  • Сделать два синхронных спиннера
  • Реализовать зеркальное и встречное движение
  • Создать сложные световые эффекты

Диагностика проблем:

  • Энкодер работает рывками → добавьте антидребезг и фильтрацию
  • Сдвиги некорректные → проверьте маскирование и битовые операции
  • Кнопка срабатывает несколько раз → реализуйте правильный антидребезг
  • Автоматический режим неравномерный → используйте millis() вместо delay()

Критерии оценки проекта:

  • 4 балла - плавные циклические сдвиги в обоих направлениях
  • +2 балла - точное управление энкодером с антидребезгом
  • +2 балла - несколько режимов работы с четкими переходами
  • +2 балла - блокировка управления и дополнительные функции

РЕАЛЬНОЕ ПРИМЕНЕНИЕ 🎮

Где это используется:

  • Аудио оборудование - энкодеры для регулировки параметров
  • Промышленные пульты - управление станками и роботами
  • Медицинская техника - точная настройка приборов
  • Игровые контроллеры - джойстики и рулевое управление

Профессиональные аналоги:

  • Роторные переключатели в радиотехнике
  • Бегущие строки и световые дисплеи
  • Цифровые потенциометры с энкодерным управлением
  • Системы анимации для световых шоу

Этот проект - МОСТ между базовыми битовыми операциями и сложными олимпиадными заданиями 10-11 классов! Освоив циклические сдвиги и энкодерное управление, ученик будет готов к любым задачам про битовые операции! 🚀