Светодиодную матрицу удобно использовать, когда требуется отображать знаки или пиктограммы, задаваемые пользователем. В нашем проекте предполагался вывод разнообразных смайликов, поэтому СД матрица нам подходила по всем параметрам. И еще её хорошо видно в темноте.
Символы, которые мы будем выводить на дисплей:
Далее я расскажу как работать с дисплеем на примере светодиодной матрицы COM-00769 и платы Arduino Leonardo, которые использовались в нашем проекте «Умный цветок».
Светодиодная матрица COM-00769
Характеристики
- Размер 50х50 мм.
- 8x8 пикселей.
- Цвета пикселей: красный, зеленый, желтый.
- Встроенный контроллер.
- Интерфейс SPI.
- Частота FCLK <= 125 кГц.
0 – СД погашен
1 – Зеленый
2 – Красный
3 - Желтый
Контроллер матрицы подключается к Arduino через синхронный интерфейс SPI.
Интерфейс SPI
Интерфейс SPI (Serial Peripheral Interface) обеспечивает высокоскоростной синхронный обмен данными между микроконтроллером ATmega, установленным на плате Arduino, и периферийными устройствами.
Схема соединения между Arduino Leonardo и дисплеем с использованием SPI интерфейса показана на рисунке ниже:
На плате Arduino Leonardo для подключения к интерфейсу SPI используется разъем ICSP:
В нем задействованы следующие выводы:
MOSI Выход данных (4)
SCK Тактовый сигнал (3 )
Внимание! На плате Arduino Uno будут использоваться другие контакты.
Передача данных через SPI
Сначала Arduino переводит линию CS в низкое состояние (0 В). Это необходимо для того, чтобы контроллер матрицы начал принимать данные, поступающие на вход MOSI. Использование нескольких выходов Arduino в качестве линий CS позволяет «посадить» на шину SPI несколько устройств и выбирать нужного абонента, переводя в низкое состояние сигнал CS для соответствующего устройства.
После установления низкого состояния на линии CS ведущее устройство (Arduino) начинает выдавать на выход MOSI данные, сопровождая каждый бит данных импульсом на линии SCK.
Данные, поступающие на вход MOSI ведомого устройства (дисплей), попадают во внутренний сдвиговый регистр. Сдвиг битов происходит по нарастающему фронту на входе SCK. Размер сдвигового регистра составляет 64 байта, что соответствует числу пикселей в матрице: 8 х 8 = 64. После передачи 64 байтов ведущее устройство останавливает обмен и переводит линию CS в высокое состояние (5 В). По этому сигналу данные, записанные в сдвиговый регистр, защелкиваются на его выходах и отображаются в виде пикселей на дисплее.
Во время передачи данных из Arduino в контроллер матрицы старые данные из внутреннего сдвигового регистра выдаются на выход MISO. Эту функцию можно использовать, если требуется объединить несколько матриц в один большой дисплей. Для этого выход MISO одного дисплея соединяется с входом MOSI следующего, а линии SCK всех дисплеев объединяются с выходом SCK Arduino. Таким образом, для вывода картинки на составной дисплей потребуется «задвинуть» в контроллер матрицы N = 64хNm байтов, где Nm количество матриц в составе дисплея. Схема каскадного соединения матриц показана на рисунке ниже.
Библиотека SPI для Arduino
Для работы с SPI на программном уровне используются функции из библиотеки SPI. Эта библиотека задействует аппаратные ресурсы AVR, причем, только в режиме ведущего устройства (SPI master). В библиотеку входят следующие функции:
begin()
Выполняет инициализацию интерфейса SPI. Лнии SCLK, MOSI и СS настраиваются на вывод, на выходах SCK и MOSI устанавливается низкий уровень, а на выходе CS — высокий уровень.
end()
Отключает интерфейс SPI микроконтроллера. Причем вызов end() не изменяет состояние линий SCLK, MOSI и СS — просто выключает блок SPI микроконтроллера.
setBitOrder(order)
Устанавливает порядок посылки битов данных (order):
MSBFIRST — первым идёт старший бит (по умолчанию)
LSBFIRST — первым идёт младший бит
setClockDivider(divider)
Устанавливает делитель частоты тактовых импульсов для интерфейса SPI. Доступны значения 2, 4, 8, 16, 32, 64 и 128. Соответствующие константы имеют имена вида SPI_CLOCK_DIVn, где n — делитель, например, SPI_CLOCK_DIV32. По умолчанию делитель равен 4 — при обычной тактовой частоте МК на Arduino в 16 МГц SPI будет работать на частоте 4 МГц.
setDataMode(mode)
Задаёт режим работы SPI, используя константы SPI_MODE0 (по умолчанию), SPI_MODE1, SPI_MODE2 и SPI_MODE3. Более подробно о режимах работы можно узнать в вики.
transfer(value)
Осуществляет двусторонний обмен данными: передаёт байт value и возвращает байт, принятый от ведомого устройства.
Программа Arduino для отображения символов
Готовую программу можно посмотреть в конце статьи, а здесь будет подробно разобран алгоритм вывода символов на дисплей.
Для начала надо как-то описать картинки, которые предполагается выводить на дисплее. Картинка для каждого символа кодируется в виде последовательности байтов, которые хранятся в массиве. Каждый байт массива соответствует одному пикселю. Размер массива 64 байта. Например, для уровня влажности 100% массив выглядит следующим образом:
Код: Выделить всё
int data_100[64] = {
0,0,1,1,1,1,0,0,
0,1,0,0,0,0,1,0,
1,0,1,0,0,1,0,1,
1,0,0,0,0,0,0,1,
1,0,1,0,0,1,0,1,
1,0,0,1,1,0,0,1,
0,1,0,0,0,0,1,0,
0,0,1,1,1,1,0,0};
Для вывода символа на дисплей используется функция int writeSymbol(int *pdata):
Код: Выделить всё
int writeSymbol(int *pdata) {
int i;
// устанавливаем низкий уровень на линии CS:
digitalWrite(displayCSPin,LOW);
delay(1);
// передаем данные через SPI:
for (i = 0; i < 64; i++) {
SPI.transfer(pdata[i]);
}
delay(1);
// устанавливаем высокий уровень на линии CS чтобы отключить контроллер дисплея:
digitalWrite(displayCSPin,HIGH);
}
Код: Выделить всё
void loop() {
writeSymbol(data_100);
delay(1000);
writeSymbol(data_050);
delay(1000);
writeSymbol(data_000);
delay(1000);
}
Ссылки
- Светодиодная матрица (http://pacpac.ru/product/com-00759-led- ... red-green/)
- Библиотека SPI (http://arduino.cc/en/Reference/SPI)
Код: Выделить всё
/*
Скетч выводит символы на дисплей через интерфейс SPI.
Дисплей COM-00759:
- Светодиодная матрица 8x8 пикселей.
- Цвета: зеленый, красный, желтый.
- Последовательный интерфейс SPI.
http://pacpac.ru/product/com-00759-led-matrix-serial-interface-red-green/
*/
// подключаем библиотеку SPI:
#include <SPI.h>
// для линии CS дисплея используется выход D2
const int displayCSPin = 2;
// символы для дисплея
// уровень 100-50%
int data_100[64] = {
0,0,1,1,1,1,0,0,
0,1,0,0,0,0,1,0,
1,0,1,0,0,1,0,1,
1,0,0,0,0,0,0,1,
1,0,1,0,0,1,0,1,
1,0,0,1,1,0,0,1,
0,1,0,0,0,0,1,0,
0,0,1,1,1,1,0,0};
// уровень 50-25%
int data_050[64] = {
0,0,1,1,1,1,0,0,
0,1,0,0,0,0,1,0,
1,0,1,0,0,1,0,1,
1,0,0,0,0,0,0,1,
1,0,1,1,1,1,0,1,
1,0,0,0,0,0,0,1,
0,1,0,0,0,0,1,0,
0,0,1,1,1,1,0,0};
// уровень 25-0%
int data_000[64] = {
0,0,1,1,1,1,0,0,
0,1,0,0,0,0,1,0,
1,0,1,0,0,1,0,1,
1,0,0,0,0,0,0,1,
1,0,0,1,1,0,0,1,
1,0,1,0,0,1,0,1,
0,1,0,0,0,0,1,0,
0,0,1,1,1,1,0,0};
//
// Инициализация
//
void setup() {
// инициализируем SPI:
pinMode (displayCSPin, OUTPUT);
digitalWrite(displayCSPin,HIGH);
SPI.begin();
// устанавливаем частоту импульсов SCK = 125 кHz:
SPI.setClockDivider(SPI_CLOCK_DIV128);
SPI.setDataMode(SPI_MODE0);
}
//
//
//
void loop() {
writeSymbol(data_100);
delay(1000);
writeSymbol(data_050);
delay(1000);
writeSymbol(data_000);
delay(1000);
}
//
// Вывод символа
// int *pdata - указатель на массив, в котором хранится символ
//
int writeSymbol(int *pdata) {
int i;
// устанавливаем низкий уровень на линии CS:
digitalWrite(displayCSPin,LOW);
delay(1);
// передаем данные через SPI:
for (i = 0; i < 64; i++) {
SPI.transfer(pdata[i]);
}
delay(1);
// устанавливаем высокий уровень на линии CS чтобы отключить контроллер дисплея:
digitalWrite(displayCSPin,HIGH);
}