Назад к каталогу
Проект 4. LED-матрица и индикация состояния
Сложность: СреднийДлительность: 60-90 минутРобототехника

Проект 4. LED-матрица и индикация состояния

В этом проекте мы добавим роботу «лицо» — светодиодную матрицу 8×8 на базе драйвера MAX7219. Это отличный способ визуализировать то, что «думает» или делает робот в данный момент, без необходимости смотреть в монитор порта. Матрица состоит из 64 светодиодов. Управляя ими по отдельности, можно рисовать цифры, буквы, стрелки и простые анимации. Драйвер MAX7219 берет на себя всю рутину по управлению светодиодами, а Arduino общается с ним всего по трем проводам. Мы начнем с простого: зажжем несколько светодиодов, чтобы понять принцип координат. Затем создадим анимацию бегущей точки, используя функцию millis() для плавности без задержек. В финальной части проекта мы запрограммируем матрицу так, чтобы она показывала режимы робота: стрелку вперед, назад, повороты или квадрат «СТОП».

Теги

  • STEM
  • Arduino
  • Робототехника
  • LED-матрица
  • MAX7219
  • Визуализация

В этом проекте робот получает «лицо» — светодиодную матрицу 8×8, которая может показывать различную информацию. Теперь вы не только по датчикам или моторам сможете понять, что делает робот, но и по символам на дисплее. Это очень удобно для отладки и делает проект намного нагляднее. Светодиодная матрица состоит из 64 отдельных светодиодов, расположенных в виде сетки 8 строк на 8 столбцов. Управляя каждым светодиодом отдельно, можно рисовать простые картинки, цифры, буквы или анимацию. В нашем проекте матрица будет показывать текущее состояние робота: едет ли он вперёд, назад, поворачивает или стоит на месте. Для управления матрицей используется специальная микросхема MAX7219, которая берёт на себя всю сложную работу. Arduino отправляет ей данные через три провода, а микросхема уже сама зажигает нужные светодиоды. Это позволяет не перегружать основной контроллер и получать стабильную картинку.

Подключение LED-матрицы

У матрицы с драйвером MAX7219 обычно есть контакты DIN (Data In), CLK (Clock) и CS (Chip Select). В этом проекте мы подключаем их к аналоговым пинам Arduino: DIN к A0, CLK к A1, CS к A2. Аналоговые пины здесь работают как обычные цифровые — это абсолютно нормально. Питание матрицы подключается к 5V, земля к GND. Важно обеспечить хорошее питание, потому что когда горит много светодиодов одновременно, потребление может быть довольно высоким.

Установка библиотеки LedControl

Для работы с матрицей нужна библиотека LedControl. Она уже умеет общаться с микросхемой MAX7219 и предоставляет простые команды для управления светодиодами. Откройте Arduino IDE. В меню выберите «Скетч» → «Подключить библиотеку» → «Управлять библиотеками…». В поиске введите LedControl. Найдите библиотеку и нажмите «Установить». После установки библиотека будет доступна во всех проектах.

Первый проект: статичное изображение

Начнём с самого простого — выведем на матрицу цифру «1». Это поможет понять базовый принцип работы.

#include <LedControl.h>

// Пины подключения матрицы: DIN, CLK, CS
const int MATRIX_DIN = A0;
const int MATRIX_CLK = A1;
const int MATRIX_CS  = A2;

// Создаём объект для работы с матрицей (1 устройство)
LedControl matrix = LedControl(MATRIX_DIN, MATRIX_CLK, MATRIX_CS, 1);

void setup() {
  // Пробуждаем матрицу (по умолчанию она в спящем режиме)
  matrix.shutdown(0, false);
  
  // Устанавливаем яркость: 0 (мин) — 15 (макс)
  matrix.setIntensity(0, 8);
  
  // Очищаем дисплей
  matrix.clearDisplay(0);
  
  // Выводим цифру "1" в центр (строка 3, столбец 4)
  matrix.setLed(0, 3, 4, true);
  matrix.setLed(0, 4, 4, true);
  matrix.setLed(0, 5, 4, true);
}

void loop() {
  // Ничего не делаем — изображение статичное
}

Разбор программы

Первая строка #include <LedControl.h> подключает библиотеку. Без неё Arduino не сможет управлять матрицей. Далее мы задаём три пина: MATRIX_DIN, MATRIX_CLK и MATRIX_CS. Это те самые пины, к которым подключена матрица. Если вы используете другие пины, измените эти значения. Строка LedControl matrix = LedControl(...) создаёт объект для работы с матрицей. Последняя единица означает, что у нас подключена одна матрица. Если бы мы соединили несколько матриц последовательно, здесь было бы их количество. В функции setup() происходят важные настройки. Команда matrix.shutdown(0, false) «пробуждает» матрицу. По умолчанию MAX7219 находится в спящем режиме для экономии энергии, поэтому эту команду нужно вызывать всегда. Функция matrix.setIntensity(0, 8) устанавливает яркость. Число 8 — это среднее значение. Можно поставить от 0 (очень тускло) до 15 (максимальная яркость). Слишком высокая яркость может слепить, а слишком низкая — плохо видно. Команда matrix.clearDisplay(0) очищает матрицу, выключая все светодиоды. Это хорошая привычка — начинать с чистого экрана. Наконец, три вызова matrix.setLed() зажигают три светодиода вертикально. Параметры: номер матрицы (0), строка, столбец, и true означает «включить». Строки и столбцы считаются с нуля, поэтому значения от 0 до 7. Функция loop() пустая, потому что нам не нужно ничего менять — мы просто показываем статичную картинку.

Анимация: движущаяся точка

Теперь усложним проект — заставим светодиод «бежать» по матрице. Это покажет, как создавать простую анимацию.

#include <LedControl.h>

const int MATRIX_DIN = A0;
const int MATRIX_CLK = A1;
const int MATRIX_CS  = A2;

LedControl matrix = LedControl(MATRIX_DIN, MATRIX_CLK, MATRIX_CS, 1);

int currentRow = 0;
int currentCol = 0;
unsigned long lastUpdate = 0;
const int DELAY_MS = 150;  // Скорость анимации

void setup() {
  matrix.shutdown(0, false);
  matrix.setIntensity(0, 10);
  matrix.clearDisplay(0);
}

void loop() {
  // Обновляем анимацию только когда прошло нужное время
  if (millis() - lastUpdate >= DELAY_MS) {
    lastUpdate = millis();
    
    // Очищаем матрицу перед новым кадром
    matrix.clearDisplay(0);
    
    // Включаем светодиод в текущей позиции
    matrix.setLed(0, currentRow, currentCol, true);
    
    // Переходим к следующей позиции
    currentCol++;
    if (currentCol >= 8) {
      currentCol = 0;
      currentRow++;
      if (currentRow >= 8) {
        currentRow = 0;
      }
    }
  }
}

Как работает анимация

Анимация — это быстрая смена кадров. В каждом кадре мы зажигаем один светодиод в новой позиции. Если делать это достаточно быстро, глаз воспринимает это как движение. Переменные currentRow и currentCol хранят текущую позицию светодиода. Мы начинаем с левого верхнего угла (0, 0). Переменная lastUpdate запоминает время последнего обновления, а DELAY_MS задаёт задержку между кадрами в миллисекундах. Чем меньше задержка, тем быстрее движется точка. В функции loop() мы используем millis() вместо delay(). Это важно, потому что delay() останавливает всю программу, а millis() позволяет продолжать работу других частей кода. Условие if (millis() - lastUpdate >= DELAY_MS) проверяет, прошло ли достаточно времени с последнего кадра. Если да, мы обновляем lastUpdate и рисуем новый кадр. Сначала мы очищаем матрицу командой matrix.clearDisplay(0). Если этого не сделать, старые светодиоды останутся гореть, и вместо одной движущейся точки у нас будет расти «хвост». Затем зажигаем светодиод в новой позиции. После этого переходим к следующему столбцу: currentCol++. Когда столбец достигает 8, мы переходим на следующую строку и сбрасываем столбец в 0. Когда достигаем последней строки, начинаем сначала с верхней. Так получается обход всей матрицы слева направо, сверху вниз.

Практическое применение: индикатор состояния робота

Теперь самое интересное — используем матрицу для отображения того, что делает робот. Вместо абстрактной анимации мы будем показывать реальные команды: вперёд, назад, повороты и остановку.

#include <LedControl.h>

const int MATRIX_DIN = A0;
const int MATRIX_CLK = A1;
const int MATRIX_CS  = A2;

LedControl matrix = LedControl(MATRIX_DIN, MATRIX_CLK, MATRIX_CS, 1);

// Режимы робота
enum RobotMode { STOP, FORWARD, BACKWARD, TURN_LEFT, TURN_RIGHT };
RobotMode robotMode = STOP;

void setup() {
  matrix.shutdown(0, false);
  matrix.setIntensity(0, 12);
  matrix.clearDisplay(0);
}

void loop() {
  // Здесь можно добавить чтение датчиков или ИК-сигналов
  // Для примера просто меняем режим каждые 2 секунды
  static unsigned long lastChange = 0;
  if (millis() - lastChange >= 2000) {
    lastChange = millis();
    robotMode = (RobotMode)((robotMode + 1) % 5);
    updateDisplay();
  }
}

void updateDisplay() {
  matrix.clearDisplay(0);
  
  switch(robotMode) {
    case FORWARD:
      // Вертикальная линия в центре — едет вперёд
      for (int i = 2; i <= 5; i++) {
        matrix.setLed(0, i, 3, true);
      }
      break;
      
    case BACKWARD:
      // Вертикальная линия внизу — едет назад
      for (int i = 4; i <= 7; i++) {
        matrix.setLed(0, i, 3, true);
      }
      break;
      
    case TURN_LEFT:
      // Точки слева — поворот влево
      matrix.setLed(0, 3, 1, true);
      matrix.setLed(0, 4, 0, true);
      matrix.setLed(0, 5, 1, true);
      break;
      
    case TURN_RIGHT:
      // Точки справа — поворот вправо
      matrix.setLed(0, 3, 6, true);
      matrix.setLed(0, 4, 7, true);
      matrix.setLed(0, 5, 6, true);
      break;
      
    case STOP:
    default:
      // Центральная точка — стоп
      matrix.setLed(0, 3, 3, true);
      matrix.setLed(0, 3, 4, true);
      matrix.setLed(0, 4, 3, true);
      matrix.setLed(0, 4, 4, true);
      break;
  }
}

Разбор программы

В начале программы мы подключаем библиотеку и задаём пины, как в предыдущих примерах. Далее идёт интересная конструкция: enum RobotMode { STOP, FORWARD, BACKWARD, TURN_LEFT, TURN_RIGHT };. Это перечисление — способ задать набор именованных констант. Вместо того чтобы использовать числа 0, 1, 2, мы используем понятные имена. Это делает код читаемым. Переменная robotMode хранит текущий режим робота. Изначально она равна STOP. В функции setup() мы настраиваем матрицу как обычно. В loop() для демонстрации мы просто меняем режим каждые 2 секунды. В реальном проекте здесь было бы чтение датчиков, ИК-пульта или других источников команд. Строка robotMode = (RobotMode)((robotMode + 1) % 5); переключает режимы по кругу. Оператор % 5 обеспечивает возврат к началу после достижения последнего режима. После изменения режима вызывается функция updateDisplay(), которая обновляет картинку на матрице.

Функция updateDisplay()

Эта функция — сердце визуализации. Она очищает матрицу и в зависимости от текущего режима рисует соответствующий символ. Мы используем конструкцию switch-case, которая позволяет удобно работать с перечислением. Для каждого режима свой блок кода. Режим FORWARD: мы рисуем вертикальную линию в центре матрицы. Цикл for зажигает светодиоды в строках 2, 3, 4, 5 столбца 3. Это создаёт стрелку, направленную вверх — интуитивно понятно, что робот едет вперёд. Режим BACKWARD: вертикальная линия в нижней части матрицы. Это символизирует движение назад. Режим TURN_LEFT: три светодиода слева образуют стрелку, указывающую влево. Координаты (3,1), (4,0), (5,1) создают форму, похожую на стрелку. Режим TURN_RIGHT: зеркальная версия левого поворота, но справа. Режим STOP: квадрат 2×2 в центре матрицы. Четыре зажжённых светодиода рядом создают заметный символ остановки.

Как нарисовать свой символ

Чтобы нарисовать свой символ на матрице, представьте сетку 8×8. Строки нумеруются от 0 до 7 сверху вниз, столбцы от 0 до 7 слева направо. Например, чтобы нарисовать букву «L», нужно зажечь светодиоды: Вертикальная линия: (0,0), (1,0), (2,0), (3,0), (4,0), (5,0) Горизонтальная линия: (5,1), (5,2), (5,3) Каждый вызов matrix.setLed(0, строка, столбец, true) зажигает один светодиод. Если нужно выключить светодиод, используйте false вместо true.

После загрузки программы посмотрите на матрицу. Вы должны увидеть, как каждые 2 секунды меняется символ. Если матрица не светится: Проверьте подключение питания и земли Убедитесь, что вызвали matrix.shutdown(0, false) Проверьте правильность подключения пинов DIN, CLK, CS Если светится не то, что ожидалось: Проверьте, правильно ли указаны пины Убедитесь, что используете нужные координаты (строки и столбцы от 0 до 7) Если яркость слишком высокая или низкая: Измените параметр в matrix.setIntensity(0, значение) от 0 до 15

Материалы

  • контроллер
  • Светодиодная матрица 8x8 с драйвером MAX7219
  • Соединительные провода

Этапы

  1. 1

    Подключение матрицы

    Подключите DIN к пину A0, CLK к A1, CS к A2, а также питание 5V и землю GND

  2. 2

    Установка библиотеки

    В Arduino IDE через менеджер библиотек найдите и установите библиотеку LedControl

  3. 3

    Тестовый запуск

    Загрузите код matrix_hello.ino, чтобы зажечь статичный символ и проверить правильность координат

  4. 4

    Создание анимации

    Загрузите matrix_animation.ino, чтобы увидеть бегущий светодиод и понять работу таймера millis()

  5. 5

    Настройка режимов

    Изучите код matrix_status.ino, где через enum задаются режимы STOP, FORWARD, BACKWARD, TURN_LEFT, TURN_RIGHT

  6. 6

    Отрисовка символов

    Настройте функцию updateDisplay(), которая рисует стрелки и квадрат в зависимости от текущего режима

  7. 7

    Интеграция с роботом

    Замените тестовое переключение режимов в loop() на реальные данные от датчиков или ИК-пульта

  8. 8

    Финальная проверка

    Убедитесь, что матрица корректно отображает направление движения и остановки робота на трассе

Комментарии

0
Загрузка комментариев...