Обзор дисплея на базе драйвера TM1637

11.03.2017 10:36

jazon



        Продолжаем обозревать модули от нашего любимого магазина RobotDyn, в этот раз у нас на обзоре 4-х разрядный семисегментный дисплей на базе драйвера TM1637. В этой статье мы рассмотрим как стандартный дисплей с разделителем типа "двоеточие" между вторым и третьим разрядом, так и дисплей с десятичными точками в разрядах. На изображениях ниже видно, какие типы модулей мы рассмотрим в этой статье. Первый модуль - обычный китайчик от магазина Catalex, размер 0.38", по качеству пайки изготовлен так себе на уровне. Второй - от магазина RobotDyn, тут даже и придраться не к чему - качество на высоте, отличная пайка и прочие прелести, размер 0.56".

Фото простого китайского модуля от магазина Catalex, фронтальный вид и вид с тыльной стороны

Фото модуля от магазина RobotDyn, фронтальный вид и вид с тыльной стороны.

        Существует хорошая в общем то библиотека для подключения этого модуля к платам Arduino, это TM1637.h. Она позволяет выводить в основном как отдельные цифры(и даже в шестнадцатиричном формате), так и время, но к сожалению в ней не продумано как выводить пользовательские сгенерированые символы. Решение этой проблемы в общем то скрывается в самой библиотеке... Но, обо всём по порядку. 


  • Подключение модуля TM1637 - дисплей с разделителем типа "двоеточие"

        Оба типа этих модулей, подключаются к платам Arduino по двум проводам. Мы начнем пожалуй с модуля у которого есть разделитель "двоеточие". Подключать модуль можно к любым пинам на плате Arduino, кроме тех что являются аналоговыми(помеченные как А0..А7), мы же подключим модуль по следующей таблице:

  • Arduino Nano [PIN 5V]    - TM1637 Module[PIN 5V]
  • Arduino Nano [PIN GND] - TM1637 Module[PIN GND]
  • Arduino Nano [PIN 3]      - TM1637 Module[PIN CLK]
  • Arduino Nano [PIN 2]      - TM1637 Module[PIN DIO]

        Библиотека TM1637.h содержит три примера работы с модулем, поэтому можно кое что почерпнуть оттуда для обзора, но не обязательно заливать примеры скетчей сразу в плату. Для начала - просто возьмем необходимые куски кода что бы испытать модуль. Простой скетч, показывающий числа от 1-го до 4-х поразрядно, и включение/выключение часового разделителя через каждую секунду:

Скетч №1
#include "TM1637.h"

int8_t DispMSG[] = {1, 2, 3, 4};

//Определяем пины для подключения к плате Arduino
#define CLK 3
#define DIO 2

//Создаём объект класса TM1637, в качестве параметров
//передаём номера пинов подключения
TM1637 tm1637(CLK, DIO);

void setup()
{
  //Инициализация модуля
  tm1637.init();

  //Установка яркости горения сегментов
  /*
   * BRIGHT_TYPICAL = 2 Средний
   * BRIGHT_DARKEST = 0 Тёмный
   * BRIGHTEST = 7      Яркий
   */
  tm1637.set(BRIGHT_TYPICAL);
}

void loop()
{
  //Задание на включение разделителя
  tm1637.point(true);
  //Выводим массив на дисплей
  tm1637.display(DispMSG);
  //Задержка
  delay(1000);
  //Задание на выключение разделителя
  tm1637.point(false);
  //Выводим массив на дисплей
  tm1637.display(DispMSG);
  //Задержка
  delay(1000);
}

Результат работы скетча можно видеть на двух фото ниже:

        В самом начале скетча, объявляется переменная DispMSG[], представляющая собой массив из 4-х элементов типа uint8_t. Функция display() класса tm1637 выводит каждый элемент массива DispMSG[] на дисплей, при чем вывод значений осуществляется поразрядно начиная с крайнего левого и заканчивая крайним правым разрядом. Чтобы было легче понять как работает функция display(), можно изменить код в функции loop() на следующий:

Скетч №2
void loop() 
{
  //Задание на включение разделителя
  tm1637.point(true);
  //Выводим массива на дисплей порязрядно
  tm1637.display(0, DispMSG[0]);
  tm1637.display(1, DispMSG[1]);
  tm1637.display(2, DispMSG[2]);
  tm1637.display(3, DispMSG[3]);
  //Задержка
  delay(1000);
  //Задание на выключение разделителя
  tm1637.point(false);
  //Выводим массива на дисплей порязрядно
  tm1637.display(0, DispMSG[0]);
  tm1637.display(1, DispMSG[1]);
  tm1637.display(2, DispMSG[2]);
  tm1637.display(3, DispMSG[3]);
  //Задержка
  delay(1000);
}

        Как видно из листинга скетча, такая запись кода программы делает его более доступным для понимания, но в то же время код сильно разрастается. Для рассматриваемого нами дисплея с разделителем типа двоеточие всё же подойдет предыдущий вариант(Скетч №1), потому что в нём отсутствует разделитель десятичная точка в каждом разряде(по умолчанию является сегментом DP). Функция point() управляет зажиганием сегмента DP, в рассматриваемом нами варианте дисплея сегмент DP это и есть разделитель двоеточие между вторым и третьим разрядом. В качестве параметра, функция point() принимает значение типа bool - true включает сегмент, false выключает. Что же... Идем дальше.


  • Подключение модуля TM1637 - дисплей с десятичной точкой в каждом разряде.

        Модуль с дисплеем такого типа подключается к плате Arduino таким же образом как и предыдущий, потому что пины подключения те же самые. Также выводятся на дисплей цифры, остаётся понять - как зажечь десятичную точку для каждого разряда? В этом нам может помочь вышеописанный вариант скетча(Скетч №2), нужно только немного его изменить. А именно - если мы хотим зажечь десятичную точку в определённом разряде, то придётся перед выводом каждого значения в свой разряд, вызывать функцию point(), тем самым явно задавать в каком из разрядов должна зажечься десятичная точка. Вот как это выглядит, изменяем код только в функции loop():

Скетч №3
void loop() 
{
  tm1637.point(false);
  tm1637.display(0, DispMSG[0]);
  
  tm1637.point(false);
  tm1637.display(1, DispMSG[1]);
  //Задание на включение десятичной точки во втором разряде дисплея
  tm1637.point(true);
  tm1637.display(2, DispMSG[2]);
  
  tm1637.point(false);
  tm1637.display(3, DispMSG[3]);
}

Результат работы скетча можно видеть на следующем изображении:

        Итак, как видно из скетча №3 зажиганием десятичной точки управляет функция point(), вызванная явно перед выводом значения в определённый разряд функцией display(). В общем то здесь нет ничего сложного, остаётся только разобраться - как генерировать пользовательские символы для модулей дисплея на базе драйвера TM1637


  • Модуль дисплея на базе драйвера TM1637 - вывод сгенерированных пользовательских символов на дисплей.

        К сожалению, разработчик библиотеки TM1637.h не предоставил нам необходимых функций для кодирования пользовательских символов. Поэтому мы решили этот вопрос по своему, так сказать сами разработали один из вариантов решения. В библиотеке есть файл - TM1637.CPP, именно он нам и нужен. Сразу же предупреждаем - перед внесением изменений желательно создать резервную копию этого файла. Сам файл лежит по следующему пути:

 C:\Users\*Имя вашего компьютера либо учетной записи*\Documents\Arduino\libraries\tm1637

Открываем файл TM1637.CPP  текстовым редактором и ищем вот эту строку:

static int8_t TubeTab[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}

        В этом массиве хранятся байты, в которых закодированы значения, зажигающие нужные сегменты в разрядах дисплея. Всего в массиве лежит 16 байт кодирующих 16 цифр в шестнадцатиричной системе счисления - от 0 до F. Массив не имеет фиксированного размера, мы можем добавить в этот массив свои значения(байты) которыми будут закодированы наши символы. Итак, чтобы было нагляднее приведём ниже таблицу с закодированными значениями символов включая имеющийся массив TubeTab[]. Некоторые символы можно отобразить на дисплее используя имеющиеся байты кодирующие цифры шестнадцатиричной системы счисления, такие как 0, 1, 5, A, B, C, D, E, F. Но как говорится обо всём этом расскажет таблица: 

                            Таблица №1 Существующие элементы массива TubeTab[] - символы и цифры

 

                            Таблица №2 Элементы которые будут добавлены в массив TubeTab[]

       

После добавления элементов, массив TubeTab[] должен выглядеть примерно так:

 static int8_t TubeTab[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,

                                             0x3d,//G
                                             0x76,//H
                                             0x74,//h
                                             0x04,//i
                                             0x1e,//J
                                             0x38,//L
                                             0x18,//l
                                             0x37,//M
                                             0x54,//n
                                             0x73,//P
                                             0x50,//r
                                             0x78,//t
                                             0x3e,//U
                                             0x1c,//u
                                             0x6E,//Y   };

      

        Теперь используя дополненный массив TubeTab[], можно отображать нужные нам символы на дисплее. Чтобы использовать тот или иной символ из таблицы, достаточно всего лишь использовать индекс его элемента в массиве TubeTab[]. В качестве примера нам послужит скетч, который выводит несколько слов(SEGA, LEGO, HEAT, init, StOP) по порядку через каждые 2 секунды. Изменим предыдущий  скетч, добавив в него массивы со словами: 

Скетч №4
#include "TM1637.h"
               //S   E  G    A
int8_t SEGA[] = {5, 14, 16, 10};
               //L   E   G   O  
int8_t LEGO[] = {21, 14, 16, 0};
               //H   E   A   t
int8_t HEAT[] = {17, 14, 10, 27};
               //i    n   i   t
int8_t INIT[] = {19, 24, 19, 27};
               //S   t  O   P
int8_t STOP[] = {5, 27, 0, 25};

//Определяем пины для подключения к плате Arduino
#define CLK 3
#define DIO 2

//Создаём объект класса TM1637, в качестве параметров
//передаём номера пинов подключения
TM1637 tm1637(CLK, DIO);

void setup()
{
  //Инициализация модуля
  tm1637.init();

  //Установка яркости горения сегментов
  /*
   * BRIGHT_TYPICAL = 2 Средний
   * BRIGHT_DARKEST = 0 Тёмный
   * BRIGHTEST = 7      Яркий
   */
  tm1637.set(BRIGHT_TYPICAL); 
}

void loop() 
{
  tm1637.point(false);
  
  tm1637.display(SEGA);
  delay(2000);
  tm1637.display(LEGO);
  delay(2000);
  tm1637.display(HEAT);
  delay(2000);
  tm1637.display(INIT);
  delay(2000);
  tm1637.display(STOP);
  delay(2000);
}

        После того как скетч будет залит в плату Arduino, можно будет видеть сообщения, которые сменяют друг друга каждые две секунды. Результат вы можете видеть на изображениях ниже, и да, кстати, результат будет таким же и на другом типе дисплея(с разделителем "двоеточие"):

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

        После кодирования сегментов, установив нужные биты в байте, для сокращения записи можно перевести байт из двоичного в шестнадцатиричный формат, как - b00011110 -> 0x1E. Ну и в конце конечно мы предлагаем посмотреть видеоролик, с обзором работы вышеописанных скетчей на дисплеях с драйвером TM1637. Приятного просмотра !!!


P.S. Если кому то интересно - то можете скачать все четыре скетча по следующим ссылкам:

Скетч №1

Скетч №2

Скетч №3

Скетч №4

Изменённый и дополненный файл TM1637.CPP



Расскажи о нас

Сообщение

Если у Вас есть опыт в работе с Arduino и собственно есть время для творчества, мы приглашаем всех желающих стать авторами статей публикуемых на нашем портале. Это могут быть как уроки, так и рассказы о ваших экспериментах с Arduino. Описание различных датчиков и модулей. Советы и наставления начинающим. Пишите и размещайте свои статьи в соответсвующей ветке форума.