Сообщество Engee

Arduino: LED матрица

Автор
avatar-alexevsalexevs
Notebook

Пакет поддержки Arduino: цифровые выходы - светодиодная матрица

Продолжаем работать с цифровыми выходами Arduino - в этот раз задействуем уже 16 пинов Arduino MEGA, подключая их к LED матрице 1088BS для вывода бинарных изображений.

Введение

В предыдущих примерах мы уже рассмотрели работу с цифровыми выводами - в примере Blink и примере с семисегментным индикатором. При помощи LED матриц в этом примере мы идём по пути повышения мерности отображаемых дискретных данных.

Мы используем тот же микроконтроллер Arduino MEGA и светодиодную матрицу 8x8 1088BS. Также понадобятся 2 макетные платы, 8 резисторов 330 Ом и соединительные провода.

Аппаратная часть

Устройство для этого примера соберём согласно представленной ниже схеме соединений:

scheme.png

Для удобства сборки можно опираться на таблицу подключений:

№ контакта 1088BS

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

Обозначение контакта

R5

R7

C2

C3

R8

C5

R6

R3

R1

C4

C6

R4

C1

R2

C7

C8

№ пина Arduino

34

36

41

42

37

44

35

32

30

43

45

33

40

31

46

47

Контакты с приставкой R (rows) отвечают за подачу в строку светодиодов с заданным номером высокого уровня напряжения. Напряжение на них подаётся через токоограничивающие резисторы

Контакты с приставкой C (columns) отвечают за подачу в колонку светодиодов с заданным номером низкого уровня напряжения.

Особенности управления

Чтобы по одному измерению матрицы гарантированно загорались все необходимые светодиоды из заданного изображения, необходимо реализовать динамическую индикацию. В случае LED матрицы это означает, что в один момент времени будет возможно зажечь требующиеся светодиоды только в одном столбце.

Статичность изображения таким образом достигается за счёт высокой частоты переключения между столбцами - такие переключения (мерцания) перестают быть видимы невооружённым взглядом.

Кроме того, чтобы при переключении не создавалось размытого изображения, необходимо между включениями столбцов сделать паузу, когда светодиоды не зажигаются. Это позволит выдержать необходимое время для гашения светодиодов на предыдущем шаге.

Также, для удобства кодирования изображения удобнее всего использовать заданные номера строк и колонок матрицы. Это позволит нам задавать только координаты точек, а их интерпретацию в набор битов выполнит наша модель.

Модель примера

Так, в модели примера:

model.png

кодирование координат выполняется следующим образом:

  1. На блоки дискретных выходов, соответствующих колонкам C1 - C8 передаётся вектор битов columns_code (начиная со старшего бита).
  2. Этот вектор инвертирован при помощи блоков Bias и Unary minus, так как в колонках матрицы за зажигание светодиода отвечает низкий уровень напряжения.
  3. Вектор битов вычисляется блоком Integer to Bit Convertor, при этом входное целое число - это десятичное представление числа, которое побитно разделяется в итоговый вектор.
  4. Это число определяется в интерполяционной таблице согласно следующему вектору значений:
In [ ]:
Y = 2 .^ (7:-1:0)
Out[0]:
8-element Vector{Int64}:
 128
  64
  32
  16
   8
   4
   2
   1

также в интерполяционной таблице нулевому значению входа соответствует нулевое выходное значение.

  1. Для динамической индикации (последовательного переключения столбцов) используется блок on_column. В нём задаётся значение включаемого столбца на текущем шаге и шаг дискретизации для определения скорости переключения между столбцами.
  2. Дополнительно, для того, чтоб изображение не было смазанным, в последовательности включаемых столбцов между этими значениями передаются нули - для гашения всех столбцов.
  3. Также, блок on_column передаёт свои значения на управляющий вход блока multipirtswitch для передачи последовательности, которая определяет строки с загорающимися светодиодами для текущего столбца.
  4. Далее, выбранная последовательность аналогично проходит через интерполяционную таблицу, на выходе которой все значения выходной последовательности суммируются. Затем определяется последовательность битов, которая зажжёт или погасит светодиоды в текущем столбце.
  5. Эта последовательность побитово передаётся на цифровые выходы Arduino, блоки R1 - R8.

Кодируемое изображение

Строки, в которых должны быть зажжены светодиоды, определены в блоках Constant на входах данных блока multiportswitch. Номера строк мы зададим согласно кодируемому изображению. Для матрицы 8×8, например, логотип платформы Engee можно представить в следующем упрощённом виде:

image.png

Отсюда, данные последовательностей в строках для блоков Constant можно определить таким образом:

In [ ]:
Col1 = zeros(8)
Col2 = vcat(zeros(5), [3,4,6])
Col3 = vcat(zeros(4), [2,3,6,7])
Col4 = vcat(zeros(6), [2,7])
Col5 = vcat(zeros(7), [7])
Col6 = vcat(zeros(4), [2,3,6,7])
Col7 = vcat(zeros(4), [3,4,5,6])
Col8 = zeros(8);

Здесь, вектора дополняются нулями для сохранения размерности выходного значения. Дополняемые нулями вектора содержат номера строк, в которых для заданного столбца должен зажигаться светодиод.

Подготовка

При помощи этого блока кода автоматизируем запуск серверной программы Engee.Интеграции:

In [ ]:
import .engee.package as epkg

const PKGNAME = "Engee-Device-Manager"

function epkg_start(pkg::String)
    if !epkg.isinstalled(pkg)
        @info "Package not installed. Installing and Starting..."
        epkg.install(pkg)
        @info "Package is up to date. Starting..."
        println("Ссылка для подключения к серверу:\n"*epkg.start(pkg))
    else
        updates = epkg.checkupdates(pkg)
        if isnothing(updates)
            @info "Package is up to date. Starting..."
            println("Ссылка для подключения к серверу:\n"*epkg.start(pkg))
        else
            @info "Updates available. Reinstalling and Starting..."
            epkg.update(pkg)
            @info "Package is up to date. Starting..."
            println("Ссылка для подключения к серверу:\n"*epkg.start(pkg))
        end
    end
end

epkg_start(PKGNAME)
Пакет поддержки 'Engee-Device-Manager' установлен.
У вас установлена актуальная версия пакета поддержки 'Engee-Device-Manager'.
[ Info: Package is up to date. Starting...

Также за кадром, как обычно, запустим клиентскую программу Engee.Интеграции и подключим наше устройство.

Выполнение модели

Теперь перейдём к выполнению модели. Запустим её в независимом режиме, так как Arduino в пакете поддержке имеется физическое ограничение в частоте дискретизации выполняемой модели из-за особенностей платформы. Ограничение периода дискретизации установлено на уровне 20 мс, тогда как для полноценной динамической индикации в этой модели требуется 100 мкс.

Как влияет частота дискретизации модели на статичность изображения при динамической индикации, хорошо видно на записи ниже.

Также, итоговый результат работы в виде статического изображения:

engeek.png

Ещё одна особенность текущей модели в сравнении с предыдущими из начальных примеров - порты блоков периферии Arduino, а также константы и преобразования в модели оптимизированы с точки зрения достаточных для работы типов данных - по максимуму используется тип UInt8, в том числе, в блоках CFunction периферии Arduino.

Заключение

В этом примере мы смогли задействовать ещё больше цифровых выходов Arduino MEGA. Так мы смогли из модели Engee управлять динамической индикацией на LED матрице 1088BS с выводом бинарного изображения.