Курс Arduino с нуля · Индикаторы и экраны
Урок 25. Семисегментный индикатор: счётчик нажатий
Учим плату показывать цифры. Разбираемся, из чего собирается цифра, и знакомимся с микросхемой-счётчиком CD4026: она считает импульсы сама и освобождает плате пять выводов.
Что понадобится
- Плата Uno из набора
- Кабель USB
- Макетная плата
- Семисегментный индикатор
- Микросхема-счётчик CD4026
- Тактовая кнопка
- 2 резистора 470 Ом
- 18 проводов «папа-папа»
Все детали есть в обучающем наборе, по которому идёт курс.
До сих пор наши устройства говорили с нами светом и звуком: горит — не горит, пищит — молчит. Сегодня плата научится показывать цифры. Для этого в наборе есть семисегментный индикатор — та самая деталь, из которой сделаны табло на микроволновке, электронные часы и счётчик на бензоколонке.
А ещё мы познакомимся с помощником — микросхемой, которая умеет считать сама и снимет с платы почти всю работу.
Что это за деталь
Цифра собирается из семи палочек — их и называют сегментами. У каждой есть своё имя, буквы идут по кругу: a — верхняя палочка, дальше по часовой стрелке b, c, d, e, f, а g — перекладина посередине. Восьмая, отдельная — точка, её обозначают h.
Любая цифра — это просто свой набор зажжённых палочек. Единица — две правые, b и c. Семёрка — те же две плюс верхняя a. Восьмёрка — все семь сразу.
Что у индикатора внутри
Никакой хитрости: индикатор — это восемь светодиодов в одном корпусе. Минусы у них соединены вместе, поэтому такой индикатор называют с общим катодом («катод» — это как раз минус светодиода).
Отсюда правило подключения: общий вывод идёт на «минус», а на каждый сегмент подаётся плюс — как мы делали со светодиодом в шестом уроке. И резистор нужен по той же причине: без него светодиод сгорит.
Как найти нужный вывод. Поверните индикатор точкой вправо-вниз — так, как пишут цифры. Тогда в верхнем ряду слева направо идут g, f, общий, a, b, а в нижнем — e, d, общий, c и точка.
Первый опыт: зажигаем одну палочку
Начнём с малого — с одного сегмента. Индикатор садится верхом на канавку макетки, чтобы верхний и нижний ряды выводов попали в разные половины и не замкнулись между собой.
b и c идут через резисторы 470 Ом на выводы 2 и 3 платы.Для начала — только сегмент b на выводе 2. Программа знакомая до последней строчки:
// Урок 25. Первый опыт: зажигаем один сегмент индикатора.
// Сегмент b идёт через резистор 470 Ом на вывод 2,
// общий вывод индикатора — на «минус».
const int SEG_B = 2;
void setup() {
pinMode(SEG_B, OUTPUT);
}
void loop() {
digitalWrite(SEG_B, HIGH); // палочка зажглась
delay(500);
digitalWrite(SEG_B, LOW); // погасла
delay(500);
}
Мигает одна палочка. Ничего нового мы не сделали — это тот же светодиод из шестого урока, просто он живёт внутри чёрного корпуса.
Шаг 2. Две палочки — уже цифра
Добавим сегмент c на вывод 3, и на индикаторе появится настоящая единица.
// Урок 25. Две палочки — и получается единица.
// Сегмент b на выводе 2, сегмент c на выводе 3.
const int SEG_B = 2;
const int SEG_C = 3;
void setup() {
pinMode(SEG_B, OUTPUT);
pinMode(SEG_C, OUTPUT);
}
void loop() {
// «1» — это две правые палочки, верхняя и нижняя
digitalWrite(SEG_B, HIGH);
digitalWrite(SEG_C, HIGH);
delay(1000);
digitalWrite(SEG_B, LOW);
digitalWrite(SEG_C, LOW);
delay(1000);
}
Вот и весь секрет. Хотите семёрку — зажгите ещё a. Хотите восьмёрку — все семь.
А теперь плохая новость
Чтобы плата могла показать любую цифру, к ней нужно протянуть семь проводов — по одному на сегмент — и к каждому свой резистор. Семь выводов платы будут заняты только одним разрядом. А если разрядов четыре, как на часах?
И в программе придётся для каждой цифры перечислять, какие палочки зажечь, — таблица на десять строк, и это только начало.
Есть решение красивее: поручить эту работу отдельной микросхеме. Она возьмёт на себя и провода, и таблицу.
Микросхема-счётчик CD4026
CD4026 — это счётчик с готовым «переводчиком в цифры». Она умеет ровно две вещи, зато отлично:
- пришёл короткий импульс на вход счёта — внутренний счётчик прибавил единицу;
- какое число внутри — такую цифру она и зажигает на индикаторе, сама выбирая нужные сегменты.
После девятки счётчик сам возвращается к нулю. А если подать импульс на вход сброса — цифра сразу становится нулём, не дожидаясь остальных нажатий.
Итого плате нужно всего два вывода вместо семи: один — «считай», другой — «сбрось».
Какая ножка за что отвечает
Ножки у микросхем считают от ключа — полукруглой выемки на торце корпуса. От ключа, против часовой стрелки, идут номера 1, 2, 3 и так далее.
Нам понадобятся:
- 1 — вход счёта: каждый импульс прибавляет единицу;
- 15 — вход сброса: импульс возвращает цифру к нулю;
- 16 и 8 — питание: плюс и минус;
- 3 — разрешение показа, его сажают на плюс, иначе индикатор молчит;
- 2 — запрет счёта, его сажают на минус, иначе счётчик не считает;
- 10, 12, 13, 9, 11, 6, 7 — выходы на сегменты
a,b,c,d,e,f,g.
Ножки 4, 5 и 14 в нашей схеме не нужны — они пригодились бы, если бы разрядов было несколько.
Собираем схему
Отключите USB, прежде чем что-то втыкать. Проводов здесь много, ошибиться легко, а микросхема не любит, когда плюс и минус меняют местами. Собрали — ещё раз пробежались глазами по схеме — и только потом подключили кабель.
Резисторы к сегментам здесь не нужны: выходы CD4026 сами отдают безопасно малый ток. Если хочется приглушить яркость, поставьте резисторы на 220–470 Ом — цифра станет тусклее, и только.
Обратите внимание на две мелочи, из-за которых схема чаще всего не работает с первого раза. Ножка 3 обязательно на плюс, ножка 2 обязательно на минус — это не питание, это разрешения. И общий вывод индикатора — на минус: у нас индикатор с общим катодом.
Шаг 3. Микросхема считает сама
Первая программа с микросхемой ничего не спрашивает — она просто раз в секунду подаёт импульс. Индикатор должен считать: 0, 1, 2 … 9 и снова 0.
// Урок 25. Микросхема CD4026 считает импульсы сама.
// Вывод 2 платы — на ножку 1 (счёт), вывод 3 — на ножку 15 (сброс).
const int CLOCK_PIN = 2;
const int RESET_PIN = 3;
void setup() {
pinMode(CLOCK_PIN, OUTPUT);
pinMode(RESET_PIN, OUTPUT);
resetCounter(); // начинаем с нуля
}
void loop() {
tick(); // прибавили единицу
delay(1000); // и раз в секунду ещё
}
// Один короткий импульс — счётчик прибавляет единицу.
// После девятки он сам возвращается к нулю.
void tick() {
digitalWrite(CLOCK_PIN, HIGH);
delay(1);
digitalWrite(CLOCK_PIN, LOW);
delay(1);
}
// Импульс сброса — на индикаторе снова ноль
void resetCounter() {
digitalWrite(RESET_PIN, HIGH);
delay(1);
digitalWrite(RESET_PIN, LOW);
delay(1);
}
Импульс — это «включили и тут же выключили». Микросхема замечает именно момент включения, поэтому миллисекунды хватает с запасом.
Мы завели две маленькие команды — tick и resetCounter. Дальше в уроке они будут повторяться слово в слово: один раз написали — везде пользуемся.
Шаг 4. Счётчик нажатий
А теперь главное, ради чего всё затевалось: пусть импульс подаёт не таймер, а кнопка.
// Урок 25. Счётчик нажатий: щёлкнули — цифра выросла.
// Кнопка на выводе 4, второй её вывод — на «минус».
const int CLOCK_PIN = 2;
const int RESET_PIN = 3;
const int BUTTON_PIN = 4;
bool wasPressed = false; // была ли кнопка нажата в прошлый раз
void setup() {
pinMode(CLOCK_PIN, OUTPUT);
pinMode(RESET_PIN, OUTPUT);
pinMode(BUTTON_PIN, INPUT_PULLUP);
resetCounter();
}
void loop() {
bool pressed = (digitalRead(BUTTON_PIN) == LOW);
// считаем только сам момент нажатия, а не всё время, пока держат
if (pressed && !wasPressed) {
tick();
delay(50); // пауза, пока контакты кнопки успокоятся
}
wasPressed = pressed;
}
void tick() {
digitalWrite(CLOCK_PIN, HIGH);
delay(1);
digitalWrite(CLOCK_PIN, LOW);
delay(1);
}
void resetCounter() {
digitalWrite(RESET_PIN, HIGH);
delay(1);
digitalWrite(RESET_PIN, LOW);
delay(1);
}
Приём с wasPressed знаком по десятому уроку: программа считает не «кнопка нажата», а «кнопку только что нажали». Иначе за одно нажатие счётчик пролетел бы всю десятку — плата успевает опросить кнопку тысячи раз в секунду.
Щёлкайте: 1, 2, 3… После девяти цифра сама станет нулём. Это не ошибка — в счётчике всего один разряд, и больше девятки он показать не может.
Шаг 5. Показать любую цифру
Пока мы умеем только прибавлять по единице. А как показать сразу семёрку? Хитрость простая: сбросить счётчик в ноль и быстро дать семь импульсов. Глаз этого не заметит — всё произойдёт за доли миллисекунды.
// Урок 25. Показываем любую цифру от 0 до 9.
// Приём простой: сбрасываем счётчик в ноль и даём столько импульсов,
// какую цифру хотим увидеть.
const int CLOCK_PIN = 2;
const int RESET_PIN = 3;
void setup() {
pinMode(CLOCK_PIN, OUTPUT);
pinMode(RESET_PIN, OUTPUT);
}
void loop() {
showNumber(7);
delay(2000);
showNumber(3);
delay(2000);
showNumber(0);
delay(2000);
}
// Показать цифру: сброс, а потом нужное число импульсов
void showNumber(int number) {
resetCounter();
for (int i = 0; i < number; i++) {
tick();
}
}
void tick() {
digitalWrite(CLOCK_PIN, HIGH);
delay(1);
digitalWrite(CLOCK_PIN, LOW);
delay(1);
}
void resetCounter() {
digitalWrite(RESET_PIN, HIGH);
delay(1);
digitalWrite(RESET_PIN, LOW);
delay(1);
}
Теперь у нас есть команда showNumber, которой можно сказать: «покажи 7». Это уже полноценное табло — плата может выводить на него что угодно: сколько раз сработал датчик, какая скорость, сколько секунд осталось.
Шаг 6. Обратный отсчёт
Проверим команду делом — сделаем отсчёт перед стартом, как на соревнованиях.
// Урок 25. Обратный отсчёт: 9, 8, 7 … 0 — и снова сначала.
const int CLOCK_PIN = 2;
const int RESET_PIN = 3;
void setup() {
pinMode(CLOCK_PIN, OUTPUT);
pinMode(RESET_PIN, OUTPUT);
}
void loop() {
for (int number = 9; number >= 0; number--) {
showNumber(number);
delay(1000);
}
delay(2000); // пауза перед новым отсчётом
}
void showNumber(int number) {
resetCounter();
for (int i = 0; i < number; i++) {
tick();
}
}
void tick() {
digitalWrite(CLOCK_PIN, HIGH);
delay(1);
digitalWrite(CLOCK_PIN, LOW);
delay(1);
}
void resetCounter() {
digitalWrite(RESET_PIN, HIGH);
delay(1);
digitalWrite(RESET_PIN, LOW);
delay(1);
}
Не работает? Разбираемся
- Индикатор совсем не горит. Проверьте ножки 16 и 3 — обе должны быть на плюсе. Ножка 3 разрешает показ, без неё микросхема считает молча.
- Горит восьмёрка и не меняется. Скорее всего, не подключена ножка 8 (минус питания) или общий вывод индикатора. Свет идёт «не тем путём».
- Цифра не растёт. Ножка 2 должна быть на минусе — это запрет счёта. И проверьте провод от вывода 2 платы к ножке 1.
- Некоторые палочки не зажигаются. Значит, потерялся один из семи проводов к сегментам. Посмотрите, какая палочка молчит, и найдите её по списку:
a— ножка 10,b— 12,c— 13,d— 9,e— 11,f— 6,g— 7. - Цифры показываются вверх ногами. Индикатор вставлен наоборот. Точка должна быть справа внизу.
- За одно нажатие счётчик перескакивает на несколько. Кнопка «дребезжит». Увеличьте паузу после
tickс 50 до 80 миллисекунд.
Задания для тренировки
- РазминкаСделайте, чтобы кнопка не прибавляла, а убавляла. Подсказка: своё число храните в переменной, а на индикатор выводите командой
showNumber. - ПосложнееДобавьте вторую кнопку — сброс. Нажали — на индикаторе снова ноль.
- Со звёздочкой ⭐Соедините индикатор с датчиком света из пятнадцатого урока: пусть цифра показывает, насколько светло в комнате, — от 0 в темноте до 9 при ярком свете. Разбор ниже.
Показать разбор «яркость света цифрой»
Датчик даёт число от 0 до 1023, а нам нужно от 0 до 9. Ровно для этого есть команда map: она пересчитывает одно в другое. Дальше — уже знакомая showNumber.
Только не зовите её без остановки: если цифра не изменилась, показывать её заново незачем. Запомните прошлое значение в переменной и обновляйте индикатор, лишь когда число стало другим. Иначе микросхема будет получать импульсы тысячи раз в секунду, а цифра — еле заметно мерцать.
Что мы узнали
- Семисегментный индикатор — это восемь светодиодов в одном корпусе; цифра собирается из палочек.
- У индикатора с общим катодом общий вывод идёт на минус, а на сегменты подаётся плюс.
- Микросхема CD4026 считает импульсы и сама зажигает нужные сегменты — плате хватает двух выводов вместо семи.
- Ножки микросхем считают от ключа на торце корпуса.
- Чтобы показать нужную цифру, достаточно сбросить счётчик и дать столько импульсов, какое число нужно.
В следующем уроке возьмём экран посерьёзнее — на нём поместятся уже не одна цифра, а целые строки текста.
Частые вопросы
Как подключить семисегментный индикатор к Arduino?
Индикатор ставят верхом на канавку макетной платы, общий вывод соединяют с минусом, а каждый сегмент — через резистор 470 Ом с отдельным выводом платы. Так на один разряд уходит семь выводов, поэтому чаще ставят микросхему-счётчик.
Зачем нужна микросхема CD4026?
Она считает импульсы и сама зажигает нужные сегменты. Плате остаётся два вывода вместо семи: один подаёт импульс счёта, другой сбрасывает цифру в ноль. Таблицу цифр в программе писать не нужно.
Как считать ножки микросхемы?
От ключа — полукруглой выемки на торце корпуса. Держа микросхему выемкой к себе, номера идут против часовой стрелки: 1, 2, 3 и дальше по кругу до 16.
Почему индикатор не загорается совсем?
Чаще всего забыта ножка 3 — разрешение показа, её нужно соединить с плюсом. Проверьте также питание микросхемы: ножка 16 на плюс, ножка 8 на минус, и общий вывод индикатора на минус.
Как показать на индикаторе нужную цифру, а не следующую?
Сбросить счётчик в ноль и сразу подать столько импульсов, какая цифра нужна. Всё это занимает доли миллисекунды, и глаз промежуточных цифр не замечает.
