Подключение светодиодного дисплея 8x8 к Arduino

Обсуждаем Arduino, Raspberry Pi и другие электронные компоненты и проекты DIY
Аватара пользователя
Mr.Kubikus
Сотрудник ПАКПАК
Сообщения: 1020
Зарегистрирован: 22 окт 2010, 23:57

Подключение светодиодного дисплея 8x8 к Arduino

Сообщение Mr.Kubikus »

При разработке электронных устройств часто возникает задача, требующая отображения информации о состоянии устройства или организации меню для удобного доступа к настройкам параметров устройства. Например, в нашем проекте «Умный Цветок» нам потребовалось организовать вывод информации о текущей влажность грунта. Для этой задачи существует множество решений: текстовые или графические жидкокристаллические индикаторы, обычные светодиоды или светодиодные матрицы.
display-01.jpg
display-01.jpg (103.09 КБ) 46124 просмотра
Светодиодную матрицу удобно использовать, когда требуется отображать знаки или пиктограммы, задаваемые пользователем. В нашем проекте предполагался вывод разнообразных смайликов, поэтому СД матрица нам подходила по всем параметрам. И еще её хорошо видно в темноте.

Символы, которые мы будем выводить на дисплей:
led-matrix-8х8-2.png
led-matrix-8х8-2.png (24.08 КБ) 46124 просмотра
Далее я расскажу как работать с дисплеем на примере светодиодной матрицы COM-00769 и платы Arduino Leonardo, которые использовались в нашем проекте «Умный цветок».

Светодиодная матрица COM-00769
com-00759.jpg
com-00759.jpg (68.01 КБ) 46124 просмотра
Характеристики
  • Размер 50х50 мм.
  • 8x8 пикселей.
  • Цвета пикселей: красный, зеленый, желтый.
  • Встроенный контроллер.
  • Интерфейс SPI.
  • Частота FCLK <= 125 кГц.
Коды цветов
0 – СД погашен
1 – Зеленый
2 – Красный
3 - Желтый

Контроллер матрицы подключается к Arduino через синхронный интерфейс SPI.

Интерфейс SPI

Интерфейс SPI (Serial Peripheral Interface) обеспечивает высокоскоростной синхронный обмен данными между микроконтроллером ATmega, установленным на плате Arduino, и периферийными устройствами.

Схема соединения между Arduino Leonardo и дисплеем с использованием SPI интерфейса показана на рисунке ниже:
spi2.png
spi2.png (11.94 КБ) 46124 просмотра
На плате Arduino Leonardo для подключения к интерфейсу SPI используется разъем ICSP:
icsp.png
icsp.png (10.02 КБ) 46124 просмотра
В нем задействованы следующие выводы:
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 количество матриц в составе дисплея. Схема каскадного соединения матриц показана на рисунке ниже.
spi3.png
spi3.png (10.83 КБ) 46124 просмотра
Библиотека 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};
Аналогично объявлены массивы data_050 и data_000 для уровней 50% и 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); 
}
Теперь для вывода символа в теле основной программы достаточно вызвать функцию writeSymbol(int *pdata) и передать в качестве параметра указатель на массив с нужным символом:

Код: Выделить всё

void loop() {
  writeSymbol(data_100);
  delay(1000);
  writeSymbol(data_050);
  delay(1000);
  writeSymbol(data_000);
  delay(1000);
}
Результат
display-03.jpg
display-03.jpg (72.75 КБ) 46116 просмотров
Ссылки Полный код программы

Код: Выделить всё

/*
  Скетч выводит символы на дисплей через интерфейс 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); 
}
С уважением, Григорий
GitHub FB ВК
Кристина
Сообщения: 19
Зарегистрирован: 16 окт 2012, 16:19

Re: Подключение светодиодного дисплея 8x8 к Arduino

Сообщение Кристина »

Как подключить эту матрицу к Arduino Uno?
Аватара пользователя
Mr.Kubikus
Сотрудник ПАКПАК
Сообщения: 1020
Зарегистрирован: 22 окт 2010, 23:57

Re: Подключение светодиодного дисплея 8x8 к Arduino

Сообщение Mr.Kubikus »

Попробуйте следующую схему для соединения ARDUINO UNO <--> Дисплей:
5V <--> VCC
12 <--> SCLK
10 <--> CS
13 <--> MOSI
GND <--> GND

На дисплее следует подключаться к разъему, отмеченному желтым цветом на картинке:
00759-02.jpg
00759-02.jpg (84.18 КБ) 45998 просмотров
В программе для управления дисплеем мы использовали библиотеку SPI.
С уважением, Григорий
GitHub FB ВК
Аватара пользователя
Mr.Kubikus
Сотрудник ПАКПАК
Сообщения: 1020
Зарегистрирован: 22 окт 2010, 23:57

Re: Подключение светодиодного дисплея 8x8 к Arduino

Сообщение Mr.Kubikus »

Ну как успехи?
С уважением, Григорий
GitHub FB ВК
Кристина
Сообщения: 19
Зарегистрирован: 16 окт 2012, 16:19

Re: Подключение светодиодного дисплея 8x8 к Arduino

Сообщение Кристина »

Никак :( Даже стыдно задавать вопросы. Пытаюсь разобраться с библиотекой SPI но не могу вывести на дисплей даже один пиксель.
Аватара пользователя
Mr.Kubikus
Сотрудник ПАКПАК
Сообщения: 1020
Зарегистрирован: 22 окт 2010, 23:57

Re: Подключение светодиодного дисплея 8x8 к Arduino

Сообщение Mr.Kubikus »

Вопросы - задавать !
С уважением, Григорий
GitHub FB ВК
Кристина
Сообщения: 19
Зарегистрирован: 16 окт 2012, 16:19

Re: Подключение светодиодного дисплея 8x8 к Arduino

Сообщение Кристина »

Первая проблема в самом языке. Не то что я гигант программирования, просто к другому привыкла. В С++ для вывода на экран используется команда "cout". Вторая проблема - одномерный массив. Кажись было бы более целесообразней сделать его двумерным. То есть

Код: Выделить всё

int ar[i][j]={...}
cout<<ar[i][j]<<endl

Библиотека SPI дает команды контролеру, а мне нужно чтобы контроллер и матрица общались между собой. Устроить этот диалог мне не по силам. Потом вывод должен происходить не на мониторе компьютера, как я привыкла, а на матрице. Код который я компилирую, заставляет мигать светодиод на контролере, а не на матрице. Мне не нужно писать готовый код и разжёвывать все, главное дать понять в каком направлении двигаться и с чего начать (трамплин). Разобраться бы с выводом хоть какой-либо картинке на матрице.
Аватара пользователя
Mr.Kubikus
Сотрудник ПАКПАК
Сообщения: 1020
Зарегистрирован: 22 окт 2010, 23:57

Re: Подключение светодиодного дисплея 8x8 к Arduino

Сообщение Mr.Kubikus »

Ок. Давайте попробуем решить эту задачу в виде последовательности из нескольких простых шагов:

Шаг 1. Подключить дисплей к контроллеру

Вам понадобятся следующие компоненты:
1. Контроллер Arduino Uno
2. Светодиодная матрица 8x8
3. Соединительные провода - FIT0010

Выполните соединения, как это показано на рисунке ниже. Провода надо подключать к матрице в соответствии с подписями на соединениях, которые есть на рисунке
uno-sfe-matrix_bb-inkskp-4.png
uno-sfe-matrix_bb-inkskp-4.png (55.15 КБ) 45932 просмотра
Для каждого проводника вам надо найти соответствующее гнездо на матрице - они все подписаны. На картинке ниже нужный вам разъем выделен желтым цветом:

Изображение


Шаг 2. Написать программу и загрузить в Arduino

Вам понадобятся следующие компоненты:
1. Собранная схема из предыдущего шага (Шаг 1).
2. Кабель USB для подключения к компьютеру.
3. Установленная среда разработки Arduino IDE (можно скачать тут)

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

Код, который будет выполнять описанный выше алгоритм выглядит следующим образом:

Код: Выделить всё

#include <SPI.h> 

// Connect to "Output SPI" on LED Matrix
// DIO 10 = CSn  (JP4-3)
// DIO 11 = MOSI (JP4-2)
// DIO 13 = SCK  (JP4-4)
//     5V = VCC  (JP4-5 or JP4-6)
//    GND = GND  (JP4-1)

const int CSn = 10;
const int ColorRED = 2;
const int ColorGREEN = 1;

void setup()
{
    pinMode (CSn, OUTPUT);
    SPI.begin();
    SPI.setClockDivider(SPI_CLOCK_DIV128);
    SPI.setDataMode(SPI_MODE0);
}

void loop()
{
    SetLED(ColorRED);
    delay(1000);
    SetLED(ColorGREEN);
    delay(1000);
}

void SetLED(int color)
{
    digitalWrite(CSn, LOW);
    delay(1);
    for (int bytenum = 0; bytenum < 64; bytenum++)
        SPI.transfer(color);
    delay(1);
    digitalWrite(CSn, HIGH);
}
Скопируйте код программы в среду разработки Arudino IDE и загрузите программу в контроллер. Теперь матрица должна мигать двумя цветами.
С уважением, Григорий
GitHub FB ВК
Кристина
Сообщения: 19
Зарегистрирован: 16 окт 2012, 16:19

Re: Подключение светодиодного дисплея 8x8 к Arduino

Сообщение Кристина »

Не работает. Проверила подключения - все правильно. Контроллер и матрица - рабочии. Среда в порядке. Нажимаю на те кнопочки. В чем еще может быть проблема? :roll:
Аватара пользователя
Mr.Kubikus
Сотрудник ПАКПАК
Сообщения: 1020
Зарегистрирован: 22 окт 2010, 23:57

Re: Подключение светодиодного дисплея 8x8 к Arduino

Сообщение Mr.Kubikus »

После подачи питания первые 5 секунд на матрице бегают "полоски"?
С уважением, Григорий
GitHub FB ВК
Ответить