Урок 21. Подключение к Ардуино LED индикаторов и матрицы кнопок, используя общие выводы.

LED индикаторы

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

Предыдущий урок     Список уроков     Следующий урок

В предыдущих уроках мы подключали к плате Ардуино матрицу кнопок и светодиодный семисегментный индикатор. Легко заметить, что сигналы сканирования вертикальных линий матрицы кнопок и сигналы выбора разрядов индикатора совершенно аналогичны по форме, длительности, амплитуде. Да и назначение у них одинаково – выбрать группу кнопок или светодиодов. Почему бы не использовать общие сигналы для матрицы кнопок и индикаторов.

 

Вот схема подключения по такому принципу матрицы кнопок и LED индикатора GNQ-3641BUE к плате Ардуино.

Схема подключения индикаторов и клавиатуры к АрдуиноСформировав высокий уровень на одном из сигналов выбора разряда индикатора, мы одновременно выбираем вертикальную линию матрицы кнопок.

Такая схема подключения позволяет сэкономить четыре вывода платы. Часто в приложениях требуется индикатор и всего 2-4 кнопки. Так вот, четыре кнопки можно подключить, используя только один вывод платы.

На макетной плате это все выглядит так.

Подключение индикаторов и клавиатуры к Ардуино

Для управления такой схемой в системе Ардуино я написал библиотеку LedDigitsKeys.h.  Эта библиотека практически объединяет две библиотеки:

 Зарегистрируйтесь и оплатите. Всего 25 руб. в месяц за доступ ко всем ресурсам сайта! 

Библиотека LedDigitsKeys.h имеет такие же  методы и свойства, как и ее прообразы. Отличие заключается в том, что метод regen() одновременно осуществляет регенерацию индикаторов и сканирование кнопок. Естественно, несколько изменился конструктор.

 

Библиотека LedDigitsKeys.h  для управления LED индикатором и матрицей кнопок, подключенных к плате Ардуино по общим сигналам выбора разрядов.

Загрузить библиотеку LedDigitsKeys.h можно по этой ссылке:

 Зарегистрируйтесь и оплатите. Всего 25 руб. в месяц за доступ ко всем ресурсам сайта! 

Библиотека управляет семисегментными LED индикаторами:

  • с размерностью до 4 разрядов;
  • поддерживает любые варианты полярностей управляющих импульсов;
  • работает параллельным процессом;
  • позволяет выводить на семисегментный индикатор:
    • отдельно сегменты каждого разряда;
    • символ каждого разряда;
    • целое число от 0 до 9999;
  • при выводе целого числа задается число разрядов;
  • может быть включен режим гашения незначащих нулей.

Для матрицы кнопок библиотека:

  • формирует признаки состояния для каждой кнопки;
  • формирует признаки ”была нажата ” (клики) для каждой кнопки;
  • устраняет дребезг контактов.

Конструктор.

    LedDigitsKeys (byte typeLed, byte digitPin0,  byte digitPin1, byte digitPin2, byte digitPin3,
                   byte segPinA, byte segPinB, byte segPinC, byte segPinD,
                   byte segPinE, byte segPinF, byte segPinG, byte segPinH,               
                   byte horizontalPin1, byte horizontalPin2, byte horizontalPin3, byte horizontalPin4,
                   byte numAckn);                                    

typeLed  Задает полярности управляющих импульсов для сигналов выбора разрядов и сегментов. Поддерживает любые схемы подключения (Урок 19).

typeLed Выбор разряда Выбор сегмента Тип схемы
0 -_- -_- Общий анод с ключами выбора разряда
1 _-_ -_- Общий анод
2 -_- _-_ Общий катод
3 _-_ _-_ Общий катод с ключами выбора разряда

digitPin0 … digitPin3 – выводы выбора разрядов. Если digitPin = 255, то разряд отключен. Это позволяет подключать индикаторы с меньшим количеством разрядов. digitPin0 – младший (правый) разряд.

segPinA … segPinH – выводы управления сегментами.

horizontalPin1 ... horizontalPin4 - выводы горизонтальных линий матрицы.

numAckn - число подтверждений состояния кнопок.

// тип индикатора 1; выводы разрядов 5,4,3,2; выводы сегментов 6,7,8,9,10,11,12,13;
// горизонтальные линии матрицы кнопок: 14,15,16,17; число подтверждений 6
LedDigitsKeys disp(1, 5,4,3,2, 6,7,8,9,10,11,12,13, 14,15,16,17, 6);

Метод void regen().

Метод должен вызываться в параллельном процессе с частотой регенерации. В нем происходит сканирование матрицы кнопок и регенерация индикаторов.

// обработчик прерывания 2 мс
void  timerInterrupt() {
disp.regen(); //
регенерация индикатора

}

Массив byte digit[4].

Управляет состоянием сегментов индикатора. Состояние бита 1 вызывает свечение соответствующего сегмента. digit[0] – младший разряд, младший бит это сегмент ”A”.

digit[0] = B0000110; // зажечь сегменты B и C младшего разряда     

Метод void tetradToSegCod(byte dig, byte tetrad)

Позволяет выводить цифры и буквы шестнадцатеричного кода на на отдельные разряды индикатора. Аргументы:

  • dig – номер разряда 0…3;
  • tetrad – десятичный код символа.

tetrad(0, 3); // цифра 3 в младшем разряде

Метод  boolean print(unsigned int value, byte digitNum, byte blank)

Выводит на индикаторы целое число.

  • value – число, которое выводится на индикатор.
  • digitNum – количество разрядов для числа. Позволяет использовать только часть разрядов индикатора. На остальные можно выводить символы, используя другие методы.
  • blank – признак гашения незначащих нулей. blank=0 означает, что число отображается со всеми нулями. При blank, отличном от 0 незначащие разряды гасятся.

disp.print(i, 4, 1); // вывод переменной i, 4 разряда, гашение незначащих
disp.print(i, 3, 0); // вывод переменной i, 3 разряда

При выходе размера числа за допустимый диапазон с учетом количества разрядов, функция отобразит на индикаторе ”---” и вернет признак ошибки – false.

Массивы bollean flagPress[4][4] и bollean flagClick[4][4].

  • flagPress это признаки состояния кнопок. True означает, что кнопка в данный момент нажата.
  • flagClick это признаки того, что кнопка была нажата (клики). Вырабатываются по нажатию кнопки, должны быть сброшены программно.

Подробно обо всех этих методах можно прочитать в уроке 18 и уроке 20. Там же есть примеры и программы для тестирования функций.

 

Пример программы.

В качестве примера использования библиотеки LedDigitsKeys.h напишем  программу, которая выводит на индикаторы символы нажатых кнопок.

// LED индикаторы и матрица кнопок
#include <LedDigitsKeys.h>
#include <MsTimer2.h>

#define SOUND_PIN 18  // вывод звукового излучателя

// тип индикатора 1; выводы разрядов 5,4,3,2; выводы сегментов 6,7,8,9,10,11,12,13;
// горизонтальные линии матрицы кнопок: 14,15,16,17; число подтверждений 6
LedDigitsKeys disp(1, 5,4,3,2, 6,7,8,9,10,11,12,13, 14,15,16,17, 6);

// массив кодов кнопок
const byte codKeys[4][4] = 
{ {1, 4, 7, 0xb},
  {2, 5, 8, 0 },
  {3, 6, 9, 0xd},
  {0xe, 0xe, 0xe, 0xe}
};

byte soundCount=0;  // счетчик звука на нажатие

void setup() {
  MsTimer2::set(2, timerInterrupt); // задаем период прерывания по таймеру 2 мс
  MsTimer2::start();               // разрешаем прерывание по таймеру
  pinMode(SOUND_PIN, OUTPUT);     // вывод звука
}

void loop() {

  // вычисление кода нажатой кнопки
  // перебор столбцов
  for (int i = 0; i < 4; i++) {
    // перебор строк
    for (int j = 0; j < 4; j++) {
      if (disp.flagClick[i][j] == true) {
        disp.flagClick[i][j]=0; 

        // кнопка нажата, сдвиг разрядов
        disp.digit[3]=disp.digit[2];
        disp.digit[2]=disp.digit[1];
        disp.digit[1]=disp.digit[0];        
        disp.tetradToSegCod(0, codKeys[i][j]);
        soundCount= 30; // звук 30*2 мс
        } 
    }      
  }   
}

//------------------------ обработчик прерывания 2 мс
void  timerInterrupt() {
  disp.regen(); // регенерация индикатора

  // звук
  if (soundCount != 0) {
    digitalWrite(SOUND_PIN, ! digitalRead(SOUND_PIN));
    soundCount--;
  }
}

Пояснять особенно нечего. Программа определяет код нажатой кнопки и выводит его на индикатор.

Звук на нажатие кнопок формируется в функции обработки прерывания. Инвертируется состояние выхода для звука, пока счетчик soundCount не станет равным 0. Таким образом, чтобы инициировать звуковой сигнал достаточно загрузить в этот  счетчик длительность сигнала в периодах прерывания. Формирование простых звуковых сигналов таким способ является наиболее предпочтительным вариантом. Не затрагиваются никакие таймеры системы.

 

Эту библиотеку будем использовать практически во всех проектах с LED индикаторами. В следующем уроке создадим на Ардуино секундомер.

Предыдущий урок     Список уроков     Следующий урок

0

Автор публикации

не в сети 3 дня

Эдуард

8
Комментарии: 1128Публикации: 124Регистрация: 13-12-2015

28 комментариев на «Урок 21. Подключение к Ардуино LED индикаторов и матрицы кнопок, используя общие выводы.»

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

    0
  2. здравствуйте. не меняя схемы из предыдущего урока загружаю пример программы текущего урока и ничего не работает: индикатор не светится, при нажатии клавиш отображения нет. при попытке просто зажечь какой-нибудь сегмент с помощью tetradToSegCod или print ничего не происходит. при загрузке примеров из предыдущего урока всё работоспособно. в чём моя ошибка? спс.

    0
      • Здравствуйте. Используя монитор порта выяснил ошибку: у меня схема управления индикаторами №4, а не №1, как в вашем примере. Соответственно, подключение кнопок иное и их управляющие сигналы другой полярности. По сути, разобрался благодаря вашим предыдущим урокам:). Спасибо

        0
    • у меня библиотека тоже не работает по схеме с ОК я в regen() перед опросом кнопок поставил {digitalWrite(_digitPin[0], LOW); digitalWrite(_digitPin[1], LOW); digitalWrite(_digitPin[2], LOW); digitalWrite(_digitPin[3], LOW);}
      digitalWrite(_digitPin[_digitNumber], HIGH); и после опроса тоже самое но с признаком HIGH. Но опять же в библиотеке это почему-то не работает пришлось всю библиотеку вставит в программу.

      0
  3. Здравствуйте. Подскажите можно ли изменить библиотеку чтобы задействовать для горизонтальных линий кнопок входы А6 и А7. На многих проектах (на ProMini) они свободные, а выходов не хватает.

    0
  4. Так вот, четыре кнопки можно подключить, используя только один вывод платы.
    Это как это…???

    0
    • Здравствуйте!
      Если используется индикатор с динамической индикацией, то для подключения 4х кнопок достаточно использовать 1 вывод. В первой схеме вывод A0, кнопки S1.1, S2.1, S3.1, S4.1.

      0
  5. Добрый день!
    Пытаюсь повторить схему, только индикатор у меня с общим катодом. Выбор разряда, получается, должен быть низким уровнем, а сегмента — высоким. Не могу понять, как подключить клавиатуру. Уже голову сломал. Подать на резисторы +5, а диоды развернуть?

    0
    • Здравствуйте!
      Да, я не предусмотрел изменения полярности кнопок. Попробуйте изменить полярность диодов наоборот, резисторы подключить к + 5В. И в файле библиотеки LedDigitsKeys.cpp изменить строку:
      if ( flagPress[_digitNumber][_scanHorizLine] == digitalRead(_horizontalPins[_scanHorizLine]) )
      на
      if ( flagPress[_digitNumber][_scanHorizLine] == (! digitalRead(_horizontalPins[_scanHorizLine])) )
      Новой строкой мы инвертируем состояние кнопок при чтении (! digitalRead).
      Не забудьте перезапустить Arduino IDE.

      0
      • Спасибо за ответ!
        А если там написать (для сохранения универсальности):
        boolean tempRead;
        tempRead = digitalRead(_horizontalPins[_scanHorizLine]);
        if ( (_typeLed & 1) == 0 ) tempRead = ! tempRead;
        if ( flagPress[_digitNumber][_scanHorizLine] == tempRead )
        Вроде все должно работать.
        И еще, у вас в библиотеке небольшая опечатка (но она не влияет на работу). В конструкторе, где сбрасываются все признаки должно быть не while (i < 3), а while (i < 4)

        0
  6. Добрый день!
    Товарищ собрал мне такую схему, необходимо её подключить с маленького дисплея на большой, где сегментами являются LED ленты. Пытаюсь сделать спортивное табло. Пробовал через uln2003 ничего не получается. Подскажите с помощь чего можно это сделать?
    Лента будет питаться от 12 вольт.

    0
  7. Здравствуйте Эдуард. Имеется LED дисплей с платой, выходит 5 проводов + — и три не известных мне, от китайского стабилизатора. На плате только версия платы. Возможно ли подключить такой LCD к ардуино? Питание 5 вольт подключал — светится. В интернете даже аналогичное фото не нашел, только вместе со стабилизатором, но описания нет.

    0
    • Здравствуйте!
      Если плата от стабилизатора, то возможно, это цифровой вольтметр. Попробуйте схему срисовать с платы или посмотреть, какие микросхемы используются.

      0
  8. Добрый день.
    Опечатка:
    tetrad – десятичный код символа.
    tetrad(0, 3); // цифра 3 в младшем разряде

    0
  9. Желательно бы напомнить и об отключении
    horizontalPin1 … horizontalPin4 — выводы горизонтальных линий матрицы.
    Спасибо.

    0
  10. Добрый день.
    Как правильно подключить,например,два трехразрядных индикатора,чтобы не возникли конфликты?

    0
    • Здравствуйте!
      Подключите 2 индикатора к Ардуино. Создайте 2 объекта. В прерывании по таймеру вызывайте два метода regen().

      0
      • Здравствуйте.
        Скорее всего выводы сегментов нужно будет сделать общими.В этом случае не будет ли засвечиваться другой индикатор?

        0
  11. Снаскоку не понятна функция
    void LedDigitsKeys::tetradToSegCod(byte dig, byte tetrad) {
    digit[dig]= (digit[dig] | _segCod[tetrad & 0x0f]) & ((_segCod[tetrad & 0x0f]) | 0x80) ;
    }
    Поясните пожалуйста.

    0
      • В уроке 20 непонятно что такое tetrad(2, 7);.
        Метод void tetradToSegCod(byte dig, byte tetrad):
        1.Берет мл.тетраду входного числа,переводит её в коды для индикации(segCod),делает с этим ИЛИ с digit (что уже на индикации).
        2.Берет мл.тетраду входного числа,переводит её в коды для индикации,зажигает запятую.
        3.делает 1 И 2.Это для индикации (digit[dig])
        Нельзя ли сделать что-то попроще?А то кажется уж как-то заумно.

        0
  12. Очень интересное инженерное решение. Теперь мне стало понятно почему в уроке 18 Ваша программа опрашивает матрицу по столбикам а не всю сразу, как предлагал Ярослав.

    0
  13. Спасибо за уроки,хорошо оформлены.
    Почему бы ни упомянуть о схеме включения из апноут AVR242,
    где опросные линии кнопок подключены к выводам сегментов индикатора. ведь если число разрядов индикатора будет меньше 8,а на матрицу клавиатуры надо 8,то для экономии выводов контроллера опросные линии желательно подключить к сегментам.
    Это же уроки.

    0

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *