Arduino: 7-сегментный индикатор
Если вы научились пользоваться «световой шкалой», то следующий шаг в освоении нового компонента «7-сегментный индикатор» дастся вам легко. Он попадается практически во всех стартовых наборах.
Одноразрядный 7-сегментный индикатор

Мы имеем дело опять с набором светодиодов, только на этот раз их 8 (семь полосок и один кружочек) и они расположены не друг за другом, а в определённом порядке, которые позволяют вам выводить цифры от 0 до 9.
Важная отличительная черта — у индикатора имеются общие ножки для катода (ножки 3 и 8). Всего их две и они равноценны. Это удобно, вам не нужно будет от каждого катода вести отдельный провод на землю. Достаточно выбрать один из общих катодов и от неё соединиться с GND. Аноды у всех отдельные.
Также при желании вы можете установить несколько таких индикаторов подряд для вывода больших двухзначных, трёхзначных и т.д. чисел. Но существуют готовые компактные наборы для этих целей.
На 7-сегментный индикатор распространяются те же правила, что и на стандартные светодиоды — у каждого должен быть свой резистор. Поэтому для опытов приготовьте 8 резисторов.
Схематично можно изобразить следующим образом.



Собираем на макетной плате. Соединяем провода по порядку, начиная с первой ножки, которая идёт на второй порт. На землю идёт восьмая ножка индикатора.

Для проверки можно запустить стандартный пример Blink, только установите в качестве проверочного светодиода любой из ваших используемых портов. Я выбрал пятый порт, чтобы помигать точкой.
int led5 = 5;
Если мы хотим помигать цифрой 1, то нам надо использовать светодиоды 4 и 6, которые идут на порты 4 и 6 платы микроконтроллера.
int led4 = 4; int led6 = 6;
Если мы захотим вывести цифру 5, то понадобится работать с пятью светодиодами, цифру 8 — уже семь светодиодов. При сложных проектах работать с таким количеством становится затруднительно. Придётся каждый раз смотреть на схему, что вспомнить, какие светодиоды нужно включить для отображения каждой цифры.
Но можно пойти другим путём. А поможет нам единица информации — байт. Байт в своём двоичном представлении состоит из 8 бит. Каждый бит может принимать значения 0 или 1. А наш светодиодный индикатор как раз и состоит из восьми светодиодов. Таким образом мы можем представить цифру на индикаторе в виде набора байт, где единица будет отвечать за включённый диод, а ноль — за выключенный диод.
Число в двоичном виде записывается следующим образом:
0b00000000
Первые два символа 0b дают понять, что речь идёт о двоичном счёте. Все нули означают, что все светодиоды будут выключены.
У нас задействованы порты от 2 по 9. Второй порт записывается в самую правую позицию. Чтобы его включить, поставим единицу.
0b00000001
Можно самостоятельно включать по отдельности каждый диод, перемещая единицу в представленном байте. Поняв принцип, можно, например, заметить, что за точку отвечает четвёртый бит справа. Если мы его не будем использовать, то он всегда будет равен 0. За чёрточку посередине индикатора отвечает самый последний байт (или первый слева).
Комбинируя набор нулей и единиц, можно создать нужные нам цифры. Например, цифра 0 будет представлена как 0b01110111.
Давайте напишем пример вывода цифры 0.
#define FIRST_SEGMENT_PIN 2 #define SEGMENT_COUNT 8 byte number0 = 0b01110111; void setup() < for (int i = 0; i < SEGMENT_COUNT; ++i) pinMode(i + FIRST_SEGMENT_PIN, OUTPUT); >void loop() < int mask = number0; // для каждого из 7 сегментов индикатора определяем: // должен ли он быть включён. // Для этого считываем бит, соответствующий текущему // сегменту «i». Истина — он установлен (1), ложь — нет (0) for (int i = 0; i < SEGMENT_COUNT; ++i) < boolean enableSegment = bitRead(mask, i); // включаем/выключаем сегмент на основе полученного значения digitalWrite(i + FIRST_SEGMENT_PIN, enableSegment); >>
Код немного избыточен, переменная mask здесь лишняя, но она нам пригодится в следующем примере. Здесь важно, что мы пробегаемся в цикле по числу светодиодов и устанавливаем у всех режим OUTPUT. Затем также в цикле проходим через все светодиоды и узнаём, комбинацию бит с помощью метода bitRead(). Полученная информация помогает нам подсветить нужные светодиоды и получить цифру 0 на выходе.
Для остальных цифр можно также подготовить нужные наборы бит.
byte number0 = 0b01110111; byte number1 = 0b00010100; byte number2 = 0b10110011; . и так далее
Но мы пойдём другим путём. Все эти значения мы поместим в массив. И будем вытаскивать по индексу. А индексом для примера нам послужит метод millis. С его помощью мы можем получить число секунд, прошедших с запуска скетча, но выводить будем только последнюю цифру прошедших секунд.
#define FIRST_SEGMENT_PIN 2 #define SEGMENT_COUNT 8 // Всего цифр 10, поэтому в массиве 10 чисел. byte numberSegments[10] = < 0b01110111, 0b00010100, 0b10110011, 0b10110110, 0b11010100, 0b11100110, 0b11100111, 0b00110100, 0b11110111, 0b11110110, >; void setup() < for (int i = 0; i < SEGMENT_COUNT; ++i) pinMode(i + FIRST_SEGMENT_PIN, OUTPUT); >void loop() < // определяем число, которое следует отобразить. // Пусть им будет номер текущей секунды, зацикленный на десятке int number = (millis() / 1000) % 10; // получаем код из массива, в котором содержится полученная цифра int mask = numberSegments[number]; // для каждого из 7 сегментов индикатора for (int i = 0; i < SEGMENT_COUNT; ++i) < // определяем: должен ли он быть включён. boolean enableSegment = bitRead(mask, i); // включаем/выключаем сегмент на основе полученного значения digitalWrite(i + FIRST_SEGMENT_PIN, enableSegment); >>
Запустив пример, мы получим реальный секундомер. За точность не ручаюсь, но для простых задач подойдёт.
На видео некоторые цифры отображаются коряво, видимо из-за особенностей записи. В реальности все цифры работают как положено.
Позже я добавил на плату ещё один светодиод, который загорался при значении 0. При других значениях он был выключен.
// Перед циклом for if(number == 0) < digitalWrite(ledPin, HIGH); >else
На Амперке есть упоминания о двух компонентах, которые можно использовать для светодиодного индикатора. Я пока ими не пользовался:
Четырёхразрядный 7-сегментный индикатор

У четырёхразрядного 7-сегментного индикатора двенадцать выводов: 8 для каждого разряда с точкой и 4 для выбора нужного разряда. Чтобы разобраться в подключении, желательно иметь картинку перед глазами.
Если индикатор держать точкой вниз, то отсчёт идёт против часовой стрелки от нижнего левого угла.
Pin 12 11 10 9 8 7 | | | | | | Resistor | R R | | R | | | | | | +------------------+ Display | 8. 8. 8. 8. | +------------------+ | | | | | | Resistor R R R R R | | | | | | | Pin 1 2 3 4 5 6

Выводы 6, 8, 9 и 12 отвечают за конкретные разряды. Это могут быть общие катоды или общие аноды.
Выводы 1, 2, 3, 4, 5, 7, 10, 11 отвечают за конкретные сегменты. Например, самая верхняя полоска обозначена буквой A и имеет номер вывода 11. Таким образом, если подключить выводы 11 и 12 индикатора к выводу 11 и 12 на плате Arduino, то можем управлять этой полоской стандартным способом, например, помигать светодиодом.

Соедините все двенадцать выводов индикатора с выводами на плате. В своих примерах я использовал следующую схему.
int commonPins[] = < 2, 3, 4, 5 >; int segmentsPins[] = < 6, 7, 8, 9, 10, 11, 12, 13 >; // - распиновка сегментов
При необходимости используйте резисторы, хотя во многих примерах в интернете встречал схемы без них.
Включаем букву H на всех разрядах.
int commonPins[] = < 2, 3, 4, 5 >; int segmentsPins[] = < 6, 7, 8, 9, 10, 11, 12, 13 >; // - распиновка сегментов void setup() < for (int i = 0; i < 4; i++) < pinMode(commonPins[i], OUTPUT); >for (int i = 0; i < 8; i++) < pinMode(segmentsPins[i], OUTPUT); >> int seg[] = < 1, 0, 0, 1, 0, 0, 0, 1 >; //Буква H void loop() < // отображаем букву H на всех разрядах for (int i = 0; i < 4; i++) < for (int k = 0; k < 8; k++) < digitalWrite(segmentsPins[k], ((seg[k] == 1) ? LOW : HIGH)); >digitalWrite(commonPins[i], HIGH); delay(1); digitalWrite(commonPins[i], LOW); > >
Работа с индикатором показалась мне слишком муторной и сложной. Дополнительные материалы можно посмотреть на сайте, с которого я взял часть примеров.
Библиотека fDigitsSegtPin
К счастью есть библиотека fDigitsSegtPin, которую можно установить через менеджер библиотек. Подключаем библиотеку, указываем все двенадцать выводов по порядку и выводим нужное число.
#include fDigitsSegtPin Display(10, 9, 13, 8, 12, 3, 7, 4, 5, 11, 6, 2); void setup() < Display.begin(); Display.doPrint_lastDot = 1; Display.doPrint_firstZero = 1; Display.doReport_overRange = 0; >void loop()
Модули 7-сегментных дисплеев
Большое количество выводов у 7-сегментных дисплеев не слишком удобно использовать. Поэтому появились дисплеи в виде готовых модулей. Например, популярна модель TM1637.
7 сегментный дисплей и Ардуино

7-сегментные индикаторы состоят из 8 светодиодных сегментов. Они используются для отображения цифр ( 0 — 9 ) и некоторых букв алфавита (например, C, A, H, P и т. д.).
7 из этих светодиодных сегментов имеют форму линии, тогда как 1 сегмент имеет круглую форму и используется для десятичной точки.
Каждый из 8 элементов связан с контактом, через который происходит управление состоянием ВКЛ или ВЫКЛ (ВЫСОКИМ или НИЗКИМ уровнем напряжения).
Чтобы отобразить число или букву, нам нужно включить определенные светодиодные сегменты дисплея. Для получения дополнительной информации о 7-сегментном светодиодном дисплее и о том, как его использовать, ознакомьтесь со статьем 7-сегментный светодиодный дисплей в разделе Датчики и модули.
Модуль 7-сегментного индикатора для Ардуино
На рынке доступны различные модули 7-сегментного индикатора, в которых используются микросхемы, такие как MAX7219, для управления несколькими 7-сегментными дисплеями с использованием интерфейса связи SPI. Один из таких модулей показан на изображении ниже.

Эти модули компактны и требуют меньше контактов и проводов по сравнению с использованием отдельных 7-сегментных дисплеев в каскаде.
Давайте теперь посмотрим, как взаимодействовать как с одним 7-сегментным индикатором, так и с модулем 7-сегментного дисплея, на котором установлено восемь 7-сегментных индикаторов, на примере платы Arduino Uno.
Примеры использования 7 сегментного индикатора с Arduino Uno
Подключение одного индикатора

Здесь 7-сегментный индикатор управляется напрямую через Arduino. Резисторы необходимо подключать между индикатором и платой Arduino UNO. В зависимости от того, какая цифра или буква должны светиться, применяются необходимые управляющие сигналы.
Примечание
Мы использовали общий анод, поэтому общий вывод (com) подключен к 5 В. Если используется индикатор с общим катодом, то вывод необходимо соединить с землей (GND).
Для включения сегмента на индикаторе с общим анодом, установите на выводе низкий уровень напряжения LOW .
Для включения сегмента на индикаторе с общим катодом, установите на выводе низкий уровень напряжения HIGH .
Скетч для управления 7-сегментным индикатором в Arduino
int disp_pin[7]; void define_segment_pins(int a, int b, int c, int d, int e, int f, int g) < disp_pin[0] = a; disp_pin[1] = b; disp_pin[2] = c; disp_pin[3] = d; disp_pin[4] = e; disp_pin[5] = f; disp_pin[6] = g; >void display_number(int num) < switch(num) < case 0: digitalWrite(disp_pin[0], LOW); digitalWrite(disp_pin[1], LOW); digitalWrite(disp_pin[2], LOW); digitalWrite(disp_pin[3], LOW); digitalWrite(disp_pin[4], LOW); digitalWrite(disp_pin[5], LOW); digitalWrite(disp_pin[6], HIGH); break; case 1: digitalWrite(disp_pin[0], HIGH); digitalWrite(disp_pin[1], LOW); digitalWrite(disp_pin[2], LOW); digitalWrite(disp_pin[3], HIGH); digitalWrite(disp_pin[4], HIGH); digitalWrite(disp_pin[5], HIGH); digitalWrite(disp_pin[6], HIGH); break; case 2: digitalWrite(disp_pin[0], LOW); digitalWrite(disp_pin[1], LOW); digitalWrite(disp_pin[2], HIGH); digitalWrite(disp_pin[3], LOW); digitalWrite(disp_pin[4], LOW); digitalWrite(disp_pin[5], HIGH); digitalWrite(disp_pin[6], LOW); break; case 3: digitalWrite(disp_pin[0], LOW); digitalWrite(disp_pin[1], LOW); digitalWrite(disp_pin[2], LOW); digitalWrite(disp_pin[3], LOW); digitalWrite(disp_pin[4], HIGH); digitalWrite(disp_pin[5], HIGH); digitalWrite(disp_pin[6], LOW); break; case 4: digitalWrite(disp_pin[0], HIGH); digitalWrite(disp_pin[1], LOW); digitalWrite(disp_pin[2], LOW); digitalWrite(disp_pin[3], HIGH); digitalWrite(disp_pin[4], HIGH); digitalWrite(disp_pin[5], LOW); digitalWrite(disp_pin[6], LOW); break; case 5: digitalWrite(disp_pin[0], LOW); digitalWrite(disp_pin[1], HIGH); digitalWrite(disp_pin[2], LOW); digitalWrite(disp_pin[3], LOW); digitalWrite(disp_pin[4], HIGH); digitalWrite(disp_pin[5], LOW); digitalWrite(disp_pin[6], LOW); break; case 6: digitalWrite(disp_pin[0], LOW); digitalWrite(disp_pin[1], HIGH); digitalWrite(disp_pin[2], LOW); digitalWrite(disp_pin[3], LOW); digitalWrite(disp_pin[4], LOW); digitalWrite(disp_pin[5], LOW); digitalWrite(disp_pin[6], LOW); break; case 7: digitalWrite(disp_pin[0], LOW); digitalWrite(disp_pin[1], LOW); digitalWrite(disp_pin[2], LOW); digitalWrite(disp_pin[3], HIGH); digitalWrite(disp_pin[4], HIGH); digitalWrite(disp_pin[5], HIGH); digitalWrite(disp_pin[6], HIGH); break; case 8: digitalWrite(disp_pin[0], LOW); digitalWrite(disp_pin[1], LOW); digitalWrite(disp_pin[2], LOW); digitalWrite(disp_pin[3], LOW); digitalWrite(disp_pin[4], LOW); digitalWrite(disp_pin[5], LOW); digitalWrite(disp_pin[6], LOW); break; case 9: digitalWrite(disp_pin[0], LOW); digitalWrite(disp_pin[1], LOW); digitalWrite(disp_pin[2], LOW); digitalWrite(disp_pin[3], LOW); digitalWrite(disp_pin[4], HIGH); digitalWrite(disp_pin[5], LOW); digitalWrite(disp_pin[6], LOW); break; default: digitalWrite(disp_pin[0], HIGH); digitalWrite(disp_pin[1], LOW); digitalWrite(disp_pin[2], LOW); digitalWrite(disp_pin[3], LOW); digitalWrite(disp_pin[4], LOW); digitalWrite(disp_pin[5], HIGH); digitalWrite(disp_pin[6], LOW); break; >> void setup() < pinMode(6, OUTPUT); pinMode(7, OUTPUT); pinMode(8, OUTPUT); pinMode(9, OUTPUT); pinMode(10, OUTPUT); pinMode(11, OUTPUT); pinMode(12, OUTPUT); define_segment_pins(12,11,10,9,8,7,6); >void loop() < int i; for(i = 9; i>=0; i--) < display_number(i); delay(1000); >for(i = 0; i >
Подключение одного индикатора через драйвер

На рисунке выше, 7-сегментный дисплей управляется микросхемой SN7446AN. Данное подключение уменьшает количество контактов, необходимых для управления 7-сегментным индикатором.
Скетч для управления 7-сегментным индикатором в Arduino через драйвер SN7446AN
int bcd_pins[4]; void bcd_control_pins(int a, int b, int c, int d) < bcd_pins[0] = a; bcd_pins[1] = b; bcd_pins[2] = c; bcd_pins[3] = d; >void display_number(int num) < switch(num) < case 0: digitalWrite(bcd_pins[0], LOW); digitalWrite(bcd_pins[1], LOW); digitalWrite(bcd_pins[2], LOW); digitalWrite(bcd_pins[3], LOW); break; case 1: digitalWrite(bcd_pins[0], HIGH); digitalWrite(bcd_pins[1], LOW); digitalWrite(bcd_pins[2], LOW); digitalWrite(bcd_pins[3], LOW); break; case 2: digitalWrite(bcd_pins[0], LOW); digitalWrite(bcd_pins[1], HIGH); digitalWrite(bcd_pins[2], LOW); digitalWrite(bcd_pins[3], LOW); break; case 3: digitalWrite(bcd_pins[0], HIGH); digitalWrite(bcd_pins[1], HIGH); digitalWrite(bcd_pins[2], LOW); digitalWrite(bcd_pins[3], LOW); break; case 4: digitalWrite(bcd_pins[0], LOW); digitalWrite(bcd_pins[1], LOW); digitalWrite(bcd_pins[2], HIGH); digitalWrite(bcd_pins[3], LOW); break; case 5: digitalWrite(bcd_pins[0], HIGH); digitalWrite(bcd_pins[1], LOW); digitalWrite(bcd_pins[2], HIGH); digitalWrite(bcd_pins[3], LOW); break; case 6: digitalWrite(bcd_pins[0], LOW); digitalWrite(bcd_pins[1], HIGH); digitalWrite(bcd_pins[2], HIGH); digitalWrite(bcd_pins[3], LOW); break; case 7: digitalWrite(bcd_pins[0], HIGH); digitalWrite(bcd_pins[1], HIGH); digitalWrite(bcd_pins[2], HIGH); digitalWrite(bcd_pins[3], LOW); break; case 8: digitalWrite(bcd_pins[0], LOW); digitalWrite(bcd_pins[1], LOW); digitalWrite(bcd_pins[2], LOW); digitalWrite(bcd_pins[3], HIGH); break; case 9: digitalWrite(bcd_pins[0], HIGH); digitalWrite(bcd_pins[1], LOW); digitalWrite(bcd_pins[2], LOW); digitalWrite(bcd_pins[3], HIGH); break; default: digitalWrite(bcd_pins[0], LOW); digitalWrite(bcd_pins[1], LOW); digitalWrite(bcd_pins[2], LOW); digitalWrite(bcd_pins[3], LOW); break; >> void setup() < pinMode(8, OUTPUT); pinMode(9, OUTPUT); pinMode(10, OUTPUT); pinMode(11, OUTPUT); bcd_control_pins(11,10,9,8); /* A-D of driver IC to Arduino */ >void loop() < int i; for(i = 9; i>=0; i--) < display_number(i); delay(1000); >for(i = 0; i >
Подключение модуля 7 сегментных светодиодных индикаторов

При таком подключении необходимо использовать библиотеку LED Control от Wayoda из GitHub.
Используя эту библиотеку, можно управлять до восьми 7-сегментными модулями на основе интерфейса SPI (каждый модуль в свою очередь может иметь до восьми 7-сегментных индикаторов), соединенных каскадом, используя всего 3 контакта.
Загрузить эту библиотеку можно отсюда.
Извлеките библиотеку и добавьте в папку с библиотеками Arduino IDE.
Информацию о том, как добавить пользовательскую библиотеку в среду разработки Arduino и использовать примеры из нее, смотрите в статье «Подключение библиотек в Arduino IDE».
Скетч для управления модулем 7-сегментного индикатора в Arduino
#include «LedControl.h» LedControl new_disp = LedControl(7,5,6,1); void setup() < new_disp.shutdown(0,false); new_disp.setIntensity(0,8); new_disp.clearDisplay(0); >void loop()
Описание библиотеки LedControl
LedControl new_disp = LedControl(dataPin, clkPin, csPin, Devices)
Эта функция создает объект класса LEDControl (в данном конкретном случае объект с именем — new_disp ; пользователь также может использовать любое другое допустимое имя), который взаимодействует с MAX7219 на модуле с 7-сегментным дисплеем.
dataPin — это контакт Arduino, который подключен к контакту DataIn на модуле. Это контакт на Arduino, куда передаются данные.
clkPin — это контакт Arduino, который подключен к контакту CLK на модуле.
csPin — это контакт Arduino, который подключен к контакту CS/Load на модуле. Это контакт для выбора устройства, на которое должны быть отправлены данные.
Devices — определяет максимальное количество устройств, которыми можно управлять. Оно может быть от 1 до 8. Это количество устройств, соединенных каскадом. Устройство, непосредственно подключенное к определенным выводам, имеет адрес 0. Устройство, непосредственно следующее за ним в каскаде, имеет адрес 1. Устройство 8 (последнее устройство в каскадном соединении) имеет адрес 7.
new_disp.shutdown (addr, status)
Эта функция используется для энергосбережения. Если параметр status истинен true , то устройство, соответствующее адресу addr, переходит в режим пониженного энергопотребления. Если статус ложный false , устройство работает в обычном режиме.
new_disp.setIntensity(addr, intensity)
Эта функция используется для установки яркости дисплея с адресом addr. Параметр интенсивности свечения intensity может быть от 1 до 15. 1 — минимум, 15 — максимум.
new_disp.setDigit (addr, digit, value, dp)
Эта функция используется для отображения числа, переданного в параметре value, на дисплее с адресом addr.
Число отображается в позиции (единицы, десятки и т. д.), указанной в параметре digit (может быть от 0 до 7).
dp устанавливает десятичную точку. Если dp ложно false , десятичная точка отключена.
new_disp.setChar (addr, digit, value, dp)
Эта функция используется для отображения символа (значения), переданного в параметре value, на дисплее с адресом addr.
Символ отображается в позиции (единицы, десятки и т. д.), указанной в параметре digit (может быть от 0 до 7). dp устанавливает десятичную точку.
Если dp ложно , десятичная точка отключена.
Могут отображаться только определенные символы, например:
0, 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 0 , A , b , c , d , E , F , H , L , P , . , — , _ .
Загрузки
- Даташит на Arduino NANO
- Даташит на Arduino UNO
- Даташит на Arduino MEGA
- Даташит на SN7446
- Даташит на 7-сегментные дисплей
- Даташит на TM1637
Где купить
- Набор выводных резисторов
- 7-ми сегментные индикаторы (одно-, двух-, трех- и четырехразрядные, можно выбрать как с общим катодом, так и с общим анодом)
- Микросхема драйвера SN7446N
- Модуль 4-цифрового светодиодного дисплея TM1637 (5 цветов)
- Arduino NANO
- Arduino UNO
- Arduino MEGA
Как подключить 7-сегментный индикатор к Arduino


1 Описание сегментного светодиодного индикатора
Индикатор называется 7-сегментным из-за того, что он состоит из семи светодиодов, которые расположены в форме цифры «8». Зажигая определённые сегменты, можно изображать разные цифры. Это похоже на цифры индекса на почтовом конверте: закрашивая определённые участки, мы пишем разные индексы. Зачастую дополнительно к 7-ми сегментам, индикатор содержит десятичную точку. Также индикатор может иметь несколько цифр – разрядов. Обычно от одного до 4-х. Сегменты индикатора обозначаются латинскими буквами от A до G, а DP – это десятичная точка (decimal point).

К слову, существуют сегментные индикаторы, число сегментов которых отличается от 7-ми. Так, например, существуют 14- и 16-сегментные индикаторы. Кроме цифр от 0 до 9 они также позволяют выводить буквы. Принцип их работы и управления обычно идентичны таковым для 7-сегментных индикаторов.
Мы в качестве индикатора будем использовать семисегментный индикатор 3361AS-1. Он построен по принципу индикатора с общим катодом. Это значит, что индикатор состоит из нескольких светодиодов в одном корпусе, у которых общая земля, а питание на каждый светодиод подаётся отдельно.
Как не трудно догадаться, существуют индикаторы с общим анодом. У них всё наоборот: общее питание, а для зажигания отдельного светодиода необходимо подать на него нулевой уровень.
2 Подключение 7-сегментного индикатора непосредственно к Arduino
Мы можем подключить индикатор прямо к выводам Arduino. Для этого придётся задействовать сразу 7 ножек (или 8, если нужна десятичная точка). Обратим внимание, что индикатор 3361AS не имеет токоограничивающих резисторов. Необходимо обеспечить наличие сопротивления номиналом около 180…220 Ом на каждый вывод индикатора (т.к. питание подаём +5 В от Arduino).

Расположение выводов индикатора показано на иллюстрации:

Подключать индикатор будем в соответствии с таблицей. Будет выбран первый разряд, остальные два пока не будем трогать.
| Вывод индикатора 3361AS | Назначение | Вывод Arduino |
|---|---|---|
| 1 | Сегмент E | D6 |
| 2 | Сегмент D | D5 |
| 3 | DP | D9 |
| 4 | Сегмент C | D4 |
| 5 | Сегмент G | D8 |
| 7 | Сегмент B | D3 |
| 8 | Выбор 3-го разряда | 5V |
| 9 | Выбор 2-го разряда | 5V |
| 10 | Сегмент F | D7 |
| 11 | Сегмент A | D2 |
| 12 | Выбор 1-го разряда | GND |
Напишем скетч, который последовательно выводит числа от 0 до 9 на первом разряде индикатора.
Скетч управления индикатором 3361AS (разворачивается)
const int A = 2; const int B = 3; const int C = 4; const int D = 5; const int E = 6; const int F = 7; const int G = 8; const int DP = 9; void setup() < pinMode(A, OUTPUT); pinMode(B, OUTPUT); pinMode(C, OUTPUT); pinMode(D, OUTPUT); pinMode(E, OUTPUT); pinMode(F, OUTPUT); pinMode(G, OUTPUT); pinMode(DP, OUTPUT); >void loop() < for (int i=0; i> // зажигает на 7-сегментном индикаторе заданную цифру void printNumber(int num)< int numbers[10][8] = < // многомерный массив, в котором описаны состояния сегментов A…G и DP для цифр от 0 до 9 , // 0 , // 1 , // 2 , // 3 , // 4 , // 5 , // 6 , // 7 , // 8 // 9 >; lightSegments(numbers[num]); > // зажигает заданные сегменты void lightSegments(int segments[])

Небольшое пояснение по поводу массива numbers[] в функции printNumber(). Этот массив состоит из 10-ти подмассивов, каждый из которых определяет одну цифру от 0 до 9. В свою очередь подмассивы состоят из 8-ми элементов, которые задают состояния сегментов от A до G и DP. Например, первый подмассив описан как и он отвечает за вывод на индикатор нуля. Это означает, что сегменты A,B,C,D,E,F должны гореть, а сегменты G и DP – нет.
[1|1|1|1|1|1|0|0 ] [A|B|C|D|E|F|G|DP]
В результате получаем примерно следующее:

И вот так в динамике:
Это самый простой способ управления сегментным индикатором, но, как мы видим, он задействует почти все цифровые ножки Arduino. Особенно если мы решим использовать все разряды индикатора. Тогда кроме ножек для управления сегментами придётся дополнительно использовать столько выводов, сколько разрядов у индикатора. Получится, что для управления 7-сегментным индикатором с 3-мя разрядами необходимо 11 ножек (7 сегментов + 1 десятичная точка + 3 ножки для выбора разряда). Это расточительно, и не всегда можно такое себе позволить.
3 Драйвер для управления 7-сегментным индикатором
Чтобы сократить число задействованных выводов микроконтроллера обычно на практике используются различные решения. Например, популярным способом управления 7-сегментным индикатором является применение микросхемы CD4511 – двоично-десятичного преобразователя. Он переводит двоичный код числа в напряжение на соответствующих цифре сегментах индикатора. Такой преобразователь будет использовать всего 4 ножки Arduino. То есть, например, если необходимо отобразить на индикаторе десятичное число 7, необходимо выставить на входе преобразователя двоичное 0111 («LOW HIGH HIGH HIGH»). Микросхема CD4511 выполняется в разных типах корпусов. Назначение выводов в исполнении с 16-тью ножками, такое:
Отечественными аналогами данного преобразователя являются микросхемы серий ИД1…ИД7. Кстати, отечественные преобразователи изображают цифры «6» и «9», используя 6 сегментов, а зарубежные CD4511 – только 5 сегментов.

4 Управление 7-сегментным индикатором с помощью драйвера CD4511 и Arduino
При подключении двоичного декодера будем руководствоваться следующей таблицей:
| Вывод CD4511 | Назначение | Примечание |
|---|---|---|
| A0. A3 | Входы двоичного преобразователя | Соответствуют разрядам двоичного числа. |
| a. g | Выходы на сегменты индикатора | Подключаются через токоограничивающие резисторы к соответствующим сегментам светодиодного индикатора. |
| Lamp Test# | Тест индикатора (включает все сегменты) | Подключим к питанию, не использовать его. |
| Blanking# | Очистка индикатора (отключает все сегменты) | Подключим к питанию, чтобы не использовать его. |
| Latch Enabled# | Выход активен | Будет подключен к земле, чтобы выход был всегда активен. |
| VDD | Питание микросхемы и индикатора | От 3 до 15 В. |
| GND | Земля | Общая у CD4511, Arduino, 7-сегментного индикатора. |
Желательно также подключить керамический конденсатор ёмкостью примерно 1 мкФ между землёй и питанием микросхемы CD4511.

Теперь напишем простой скетч, чтобы проверить работоспособность 7-сегментного индикатора 3361AS-1 в связке с двоично-десятичным декодером, а также получить опыт работы с ними. Данный скетч будет поочерёдно перебирать числа от 0 до 9, перемещаясь по циклу от одного разряда индикатора к следующему.
Скетч для управления 7-сегментным индикатором (светится 1 разряд) (разворачивается)
// выводы Arduino для управления двоичным кодом на входе декодера CD4511: const byte D_0 = 11; const byte D_1 = 10; const byte D_2 = 9; const byte D_3 = 8; // выводы Arduino для выбора десятичного разряда индикатора: const byte B_0 = 7; const byte B_1 = 6; const byte B_2 = 5; void setup() < pinMode(D_0, OUTPUT); pinMode(D_1, OUTPUT); pinMode(D_2, OUTPUT); pinMode(D_3, OUTPUT); pinMode(B_0, OUTPUT); pinMode(B_1, OUTPUT); pinMode(B_2, OUTPUT); >void loop() < for (int i=0; i> > // выбирает разряд десятичного числа на счётчике: void setDigit(byte b) < switch (b) < case 0: digitalWrite(B_0, LOW); digitalWrite(B_1, HIGH); digitalWrite(B_2, HIGH); break; case 1: digitalWrite(B_0, HIGH); digitalWrite(B_1, LOW); digitalWrite(B_2, HIGH); break; case 2: digitalWrite(B_0, HIGH); digitalWrite(B_1, HIGH); digitalWrite(B_2, LOW); break; >> // зажигает заданную цифру 7-сегментного индикатора void printNumber(byte n) < switch(n)< case 0: digitalWrite(D_0, LOW); digitalWrite(D_1, LOW); digitalWrite(D_2, LOW); digitalWrite(D_3, LOW); break; case 1: digitalWrite(D_0, HIGH); digitalWrite(D_1, LOW); digitalWrite(D_2, LOW); digitalWrite(D_3, LOW); break; case 2: digitalWrite(D_0, LOW); digitalWrite(D_1, HIGH); digitalWrite(D_2, LOW); digitalWrite(D_3, LOW); break; case 3: digitalWrite(D_0, HIGH); digitalWrite(D_1, HIGH); digitalWrite(D_2, LOW); digitalWrite(D_3, LOW); break; case 4: digitalWrite(D_0, LOW); digitalWrite(D_1, LOW); digitalWrite(D_2, HIGH); digitalWrite(D_3, LOW); break; case 5: digitalWrite(D_0, HIGH); digitalWrite(D_1, LOW); digitalWrite(D_2, HIGH); digitalWrite(D_3, LOW); break; case 6: digitalWrite(D_0, LOW); digitalWrite(D_1, HIGH); digitalWrite(D_2, HIGH); digitalWrite(D_3, LOW); break; case 7: digitalWrite(D_0, HIGH); digitalWrite(D_1, HIGH); digitalWrite(D_2, HIGH); digitalWrite(D_3, LOW); break; case 8: digitalWrite(D_0, LOW); digitalWrite(D_1, LOW); digitalWrite(D_2, LOW); digitalWrite(D_3, HIGH); break; case 9: digitalWrite(D_0, HIGH); digitalWrite(D_1, LOW); digitalWrite(D_2, LOW); digitalWrite(D_3, HIGH); break; >>
Загрузим скетч в Arduino и посмотрим результат.
В один момент времени светится только один разряд индикатора. Как же задействовать одновременно сразу три разряда индикатора? Это будет немного сложнее. Сложность заключается в том, что нам одновременно нужно управлять тремя разрядами десятичного число, используя только один преобразователь CD4511. Но чисто физически это невозможно. Однако можно добиться иллюзии постоянного свечения всех разрядов светодиодного индикатора. Для этого придётся быстро переключаться между разрядами, постоянно обновляя показание каждого разряда. Мы будем поочерёдно активировать каждый из разрядов индикатора 3361AS, выставлять на нём с помощью двоичного преобразователя CD4511 нужную цифру, а затем переключаться на следующий разряд.
Для человеческого глаза такое переключение между разрядами будет незаметно, но если результат снять на видео, то его можно увидеть.
Также перепишем функцию setNumber() отправки двоичного кода на вход микросхемы преобразователя CD4511. Вместо использования оператора switch, используем массив массивов.
Скетч для управления трёхразрядным 7-сегментным индикатором (разворачивается)
// Выводы Arduino для управления двоичным конвертером CD4511: const byte bit0 = 11; const byte bit1 = 10; const byte bit2 = 9; const byte bit3 = 8; // Выводы Arduino для выбора десятичных разрядов индикатора 3361AS: const byte B_0 = 5; const byte B_1 = 6; const byte B_2 = 7; #define seconds() (millis()/1000) // макрос определения секунд, прошедших с начала работы скетча void setup() < pinMode(bit0, OUTPUT); pinMode(bit1, OUTPUT); pinMode(bit2, OUTPUT); pinMode(bit3, OUTPUT); pinMode(B_0, OUTPUT); pinMode(B_1, OUTPUT); pinMode(B_2, OUTPUT); digitalWrite(B_0, HIGH); digitalWrite(B_1, HIGH); digitalWrite(B_2, HIGH); >void loop() < // Каждую секунду увеличиваем показания индикатора на 1: int sec = seconds(); for (int i=0; isec = seconds(); > > // Выводит 3-разрядное число на 7-сегментный индикатор. void printNumber(int n) < setDigit(B_0, n/100); // выводим сотни десятичного числа setDigit(B_1, n/10 ); // выводим десятки setDigit(B_2, n/1 ); // выводим единицы >// Выводит заданное число на заданный разряд индикатора. void setDigit(byte digit, int value) < digitalWrite(digit, LOW); // выбираем разряд индикатора 3361AS-1 setNumber(value); // выводим на этот разряд число delay(4); digitalWrite(digit, HIGH); // снимаем выбор разряда индикатора >// Выставляет двоичный код на входе преобразователя CD4511 void setNumber(int n) < static const struct number < byte b3; byte b2; byte b1; byte b0; >numbers[] = < , // 0 , // 1 , // 2 , // 3 , // 4 , // 5 , // 6 , // 7 , // 8 , // 9 >; digitalWrite(bit0, numbers[n%10].b0); digitalWrite(bit1, numbers[n%10].b1); digitalWrite(bit2, numbers[n%10].b2); digitalWrite(bit3, numbers[n%10].b3); >
Получится вот такая картина.

В динамике это выглядит так. Тут как раз временами видны мерцания сегментов светодиодного индикатора.
Можно попробовать поиграть значением задержек в функции setDigit(). Если сделать задержки меньше, то мерцание станет меньше заметно. Но начнут сильнее засвечиваться соседние сегменты на выбранном разряде индикатора. Тут необходимо выбрать какое-то компромиссное решение.
5 Управление 7-сегментным индикатором с помощью драйвера TM1637 и Arduino
Существуют и другие драйверы для подключения 7-сегментных дисплеев. Один из них – TM1637. Есть готовые модули, в которых уже присутствует и индикатор, и драйвер, и вся необходимая «обвязка» (резисторы, конденсаторы). Пример – модуль HW-069. В качестве семисегментного индикатора здесь 4-разрядный индикатор 3642BS-1.

Подключение модуля к Arduino предельно простое, т.к. для обмена с драйвером используется интерфейс, очень похожий на I2C. Т.е. необходимо подключить питание от 5 В Arduino, а данные передаются по DIO и тактируются по CLK. Но тем не менее, интерфейс не эквивалентен полностью I2C, т.к. у дисплея нет своего адреса.

Как всегда, есть множество готовых библиотек для управления индикатором через драйвер TM1637. Например, библиотека Gyver TM1637 или библиотека Avishay TM1637.

Эти библиотеки работают прекрасно, и рассказывать, как загружать и устанавливать библиотеку для Arduino не буду: мы это делали уже миллион раз. Мы же не ищем лёгких путей, поэтому попробуем разобраться в работе драйвера TM1637 самостоятельно, верно?
Скачать вложения:
- Скачать тех. описание на 7-сегментный дисплей 3361AS (1188 Скачиваний)
- Скачать datasheet на драйвер TM1637 (869 Скачиваний)
7 сегментный индикатор. Урок 23. Ардуино

Привет! В начальном наборе для Ардуино осталось совсем немного датчиков. Сегодня посмотрим на одноразрядный 7 сегментный индикатор.
Такой индикатор это всего лишь несколько светодиодов собранных в корпус. Они собраны по схеме, которая позволяет нам использовать несколько светодиодов, чтобы отображать цифры и буквы.
Поскольку управлять таким индикатором можно также, как и простым светодиодом. Вспомним один из самых первых уроков. И используем программу из него. Посмотрите его еще раз, если уже забыли или пропустили.
Все светодиоды внутри корпуса индикатора соединены с общим катодом. Для катода даже выделено две ножки. Они находятся в центре с каждой стороны корпуса.
Подключать каждый светодиод нужно последовательно с сопротивлением. Поэтому каждый контакт платы подключаем к Ардуино через резистор.
Схема и программа

Схема кажется громоздкой. Но, на самом деле, тут всего лишь соединяются 8 светодиодов. Они соединяются с цифровыми портами Ардуино последовательно с резисторами.
Пока что не будем искать какой конкретно светодиод нужно подключить к конкретному порту. Определим это уже в программе.
Простейший код скетча позволит нам проверить работоспособность индикатора. Для начала включим все сегменты.
int leds[] = ; void setup() < for( int j=0; j > void loop()
Заполним массив номерами цифровых портов. И будем обращаться к ним с помощью этого массива.
Теперь, надо понять какие порты соответствуют конкретным сегментам на индикаторе. Для этого переберем их последовательно. Добавим небольшую паузу после каждого сегмента. После чего пронумеруем.
int leds[] = ; int del = 300; void setup() < for( int j=0; j > void loop()
Теперь мы можем добавить немного движения в схему. Для начала заставим точку мигать.
int leds[] = ; int del = 300; void setup() < for( int j=0; j > void loop()
Обратный отсчет
Ну и теперь напишем небольшую функцию, чтобы мы могли использовать индикатор для отображения цифр.
void digit(int x) < switch (x) < case 1: digitalWrite (leds[1],HIGH); digitalWrite (leds[4],HIGH); break; case 2: digitalWrite (leds[2],HIGH); digitalWrite (leds[3],HIGH); digitalWrite (leds[4],HIGH); digitalWrite (leds[5],HIGH); digitalWrite (leds[7],HIGH); break; case 3: digitalWrite (leds[1],HIGH); digitalWrite (leds[2],HIGH); digitalWrite (leds[4],HIGH); digitalWrite (leds[5],HIGH); digitalWrite (leds[7],HIGH); break; case 4: digitalWrite (leds[1],HIGH); digitalWrite (leds[4],HIGH); digitalWrite (leds[6],HIGH); digitalWrite (leds[7],HIGH); break; case 5: digitalWrite (leds[1],HIGH); digitalWrite (leds[2],HIGH); digitalWrite (leds[5],HIGH); digitalWrite (leds[6],HIGH); digitalWrite (leds[7],HIGH); break; case 6: digitalWrite (leds[1],HIGH); digitalWrite (leds[2],HIGH); digitalWrite (leds[3],HIGH); digitalWrite (leds[5],HIGH); digitalWrite (leds[6],HIGH); digitalWrite (leds[7],HIGH); break; case 7: digitalWrite (leds[1],HIGH); digitalWrite (leds[4],HIGH); digitalWrite (leds[5],HIGH); break; case 8: digitalWrite (leds[1],HIGH); digitalWrite (leds[2],HIGH); digitalWrite (leds[3],HIGH); digitalWrite (leds[4],HIGH); digitalWrite (leds[5],HIGH); digitalWrite (leds[6],HIGH); digitalWrite (leds[7],HIGH); break; case 9: digitalWrite (leds[1],HIGH); digitalWrite (leds[2],HIGH); digitalWrite (leds[4],HIGH); digitalWrite (leds[5],HIGH); digitalWrite (leds[6],HIGH); digitalWrite (leds[7],HIGH); break; >>
Теперь мы можем передать в функцию нужную нам цифру и получить ее на индикаторе.
Полный текст программы
Добавим в главный цикл программы вызов функции с увеличением счетчика. Напишем еще одну небольшую функцию очистки экрана. А потом посмотрим, что получилось в итоге.
int leds[] = ; int x = 0; int del = 500; void setup() < for( int j=0; j > void clean() < for( int j=0; j > void digit(int x) < switch (x) < case 1: digitalWrite (leds[1],HIGH); digitalWrite (leds[4],HIGH); break; case 2: digitalWrite (leds[2],HIGH); digitalWrite (leds[3],HIGH); digitalWrite (leds[4],HIGH); digitalWrite (leds[5],HIGH); digitalWrite (leds[7],HIGH); break; case 3: digitalWrite (leds[1],HIGH); digitalWrite (leds[2],HIGH); digitalWrite (leds[4],HIGH); digitalWrite (leds[5],HIGH); digitalWrite (leds[7],HIGH); break; case 4: digitalWrite (leds[1],HIGH); digitalWrite (leds[4],HIGH); digitalWrite (leds[6],HIGH); digitalWrite (leds[7],HIGH); break; case 5: digitalWrite (leds[1],HIGH); digitalWrite (leds[2],HIGH); digitalWrite (leds[5],HIGH); digitalWrite (leds[6],HIGH); digitalWrite (leds[7],HIGH); break; case 6: digitalWrite (leds[1],HIGH); digitalWrite (leds[2],HIGH); digitalWrite (leds[3],HIGH); digitalWrite (leds[5],HIGH); digitalWrite (leds[6],HIGH); digitalWrite (leds[7],HIGH); break; case 7: digitalWrite (leds[1],HIGH); digitalWrite (leds[4],HIGH); digitalWrite (leds[5],HIGH); break; case 8: digitalWrite (leds[1],HIGH); digitalWrite (leds[2],HIGH); digitalWrite (leds[3],HIGH); digitalWrite (leds[4],HIGH); digitalWrite (leds[5],HIGH); digitalWrite (leds[6],HIGH); digitalWrite (leds[7],HIGH); break; case 9: digitalWrite (leds[1],HIGH); digitalWrite (leds[2],HIGH); digitalWrite (leds[4],HIGH); digitalWrite (leds[5],HIGH); digitalWrite (leds[6],HIGH); digitalWrite (leds[7],HIGH); break; case 0: digitalWrite (leds[1],HIGH); digitalWrite (leds[2],HIGH); digitalWrite (leds[3],HIGH); digitalWrite (leds[4],HIGH); digitalWrite (leds[5],HIGH); digitalWrite (leds[6],HIGH); break; >> void loop() < digit(x); delay(del); clean(); x++; if (x == 10)>
Заключение
Мы рассмотрели одноразрядный 7 сегментный индикатор. Как и многие другие элементы, он служит для вывода информации из нашей схемы и программы для пользователя. Мы написали простейшую программу и функцию управления индикатором. Но также для него уже существуют удобные библиотеки. Рассмотрим одно такую в следующий раз.