Как подключить 7-сегментные дисплеи на Arduino
Семисегментные дисплеи используются во многих бытовых устройствах, таких как микроволновые печи, стиральные машины и кондиционеры. Это простой, но эффективный способ отображения числовых данных, таких как время или количество. Поскольку они сделаны из светодиодов, они являются недорогим вариантом отображения информации.
Семисегментных дисплеев бывает самых разных размеров и цветов. Красный, синий и зеленый - основные цвета. Размеры варьируются от небольших 1,5 см дисплеев до больших 10-и и даже 17 см дисплеев. Некоторые дисплеи имеют одну цифру(разряды), а другие две или четыре.
Прежде чем мы начнем работать с 7-сегментными дисплеями, необходимо понять некоторые основы светодиодов и способы их управления.
ОСНОВЫ СВЕТОДИОДОВ
Один светодиод состоит из двух клемм, анода и катода. Анод является положительным выводом, а катод - отрицательным выводом:
Для питания светодиода вы подключаете катод к земле, а анод - к источнику напряжения. Светодиод может быть включен или выключен путем переключения питания на аноде или катоде.
АНОД К GPIO
Когда анод светодиода подключен к цифровому выводу, катод заземлен:
Примечание. Всем светодиодам необходим резистор для ограничения тока, размещенный либо на стороне анода, либо на стороне катода для предотвращения выгорания светодиода. Значение резистора будет определять, насколько ярко светится светодиод. 1 кОм - хорошее место для начала, но вы можете рассчитать идеальное значение с помощью светодиодного резисторного калькулятора .
Чтобы зажечь светодиод с анодом, подключенным к цифровому контакту, подаем на цифровой контакт ВЫСОКИЙ (HIGH) уровень:
void setup(){
pinMode(7, OUTPUT);
digitalWrite(7, HIGH);
}
void loop(){
}
В блоке void setup () мы настраиваем вывод GPIO 7 как выход pinMode (7, OUTPUT); и подаем на него высокий уровень с помощью digitalWrite (7, HIGH);
КАТОД К GPIO
С катодом светодиода, подключенным к цифровому выводу, анод подключен к Vcc. Для включения светодиода цифровой вывод переключается на НИЗКИЙ уровень, что замыкает цепь на землю:
В этом случае мы подаем на контакт GPIO 7 НИЗКИЙ уровень с помощью digitalWrite (7, LOW); Это замыкает цепь и позволяет току течь от Vcc к земле:
void setup(){
pinMode(7, OUTPUT);
digitalWrite(7, LOW);
}
void loop(){
}
КАК РАБОТАЮТ 7-СЕГМЕНТНЫЕ ДИСПЛЕИ
Семисегментные дисплеи состоят из 7 светодиодов, называемых сегментами, расположенных в форме «8». Большинство 7-сегментных дисплеев на самом деле имеют 8 сегментов, с точкой справа от цифры, которая служит десятичной точкой. Каждый сегмент именуется буквой от A до G и DP для десятичной точки:
Каждый сегмент на дисплее может управляться индивидуально, как обычный светодиод.
Существует два типа 7-сегментных дисплеев - с общим катодом и с общим анодом .
ДИСПЛЕИ С ОБЩИМ КАТОДОМ
В обычных катодных дисплеях все катоды подключены к земле, а отдельные сегменты включаются и выключаются путем переключения питания на аноды:
ДИСПЛЕИ С ОБЩИМ АНОДОМ
В обычных анодных дисплеях все аноды подключены к Vcc, а отдельные сегменты включаются и выключаются путем переключения питания на катоды:
ПОДКЛЮЧЕНИЕ 7-СЕГМЕНТНЫХ ДИСПЛЕЕВ К ARDUINO
Одноразрядные семисегментные дисплеи обычно имеют 10 контактов. Два контакта подключаются к земле, а остальные 8 подключаются к каждому из сегментов. Вот схема контактов популярного катодного дисплея 5161AS :
Прежде чем вы сможете подключить свой дисплей к Arduino, вам необходимо знать, является ли он общим анодом или общим катодом, и какие контакты подключены к каждому сегменту. Эта информация должна быть в таблице данных, но если вы не можете найти таблицу данных или не знаете номер детали вашего дисплея, я покажу вам, как это выяснить ниже…
КАК ОПРЕДЕЛИТЬ, КАКОЙ У ВАС ДИСПЛЕЙ С ОБЩИМ АНОДОМ ИЛИ С ОБЩИМ КАТОДОМ
Это можно проверить с помощью тестовой схемы, сконструированной следующим образом:
Подключите заземляющий (черный) провод к любому выводу дисплея. Затем вставьте положительный (красный) провод в каждый из других контактов. Если ни один сегмент не загорелся, переместите провод заземления на другой контакт и повторите процесс. Делайте это, пока не загорится хотя бы один сегмент.
Когда загорится первый сегмент, оставьте провод заземления там, где он есть, и снова подключите положительный провод к каждому из других контактов. Если с каждым другим выводом загорается другой сегмент - у вас дисплей с общим катодом. Контакт, который подключен к заземляющему проводу, является одним из общих контактов. Таких должно быть два.
Если два разных контакта освещают один и тот же сегмент - у вас дисплей с общим анодом. Контакт, который подключен к положительному проводу, является одним из общих контактов. Теперь, если вы подключите провод заземления к каждому из других выводов, вы должны увидеть, что разные сегменты загораются с каждым другим выводом.
КАК ОПРЕДЕЛИТЬ РАСПИНОВКУ ДЛЯ ВАШЕГО ДИСПЛЕЯ
Теперь нарисуйте схему, показывающую контакты на вашем дисплее. Когда общий контакт подключен к заземляющему проводу (общий катод) или положительному проводу (общий анод), проверьте каждый контакт другим проводом. Когда сегмент загорается, запишите имя сегмента (AG или DP) рядом с соответствующим выводом на диаграмме.
ПОДКЛЮЧЕНИЕ ОДНОРАЗРЯДНЫХ ДИСПЛЕЕВ К ARDUINO
Как только вы разобрались с расположением выводов, подключить дисплей к Arduino уже будет довольно просто. На этой схеме показано, как подключить одноразрядный дисплей 5161AS (обратите внимание на ограничивающий ток резистор 1 кОм, подключенный последовательно с общими контактами):
В приведенных ниже примерах программ контакты сегментов подключаются к Arduino в соответствии с этой таблицей:
ПРОГРАММИРОВАНИЕ ОДНОРАЗРЯДНЫХ ДИСПЛЕЕВ
УСТАНОВИТЬ БИБЛИОТЕКУ
Мы будем использовать библиотеку SevSeg для управления дисплеем. Библиотека SevSeg работает с одноразрядными и многоразрядными семисегментными дисплеями. Вы можете скачать ZIP-файл библиотеки с GitHub :
Чтобы установить его, откройте Arduino IDE, перейдите в «Sketch»> «Включить библиотеку»> «Добавить .ZIP библиотеку» и выберите загруженный ZIP-файл SevSeg.
ВЫВОД ЧИСЕЛ НА ДИСПЛЕЕ
Эта программа напечатает число «4» на одноразрядном 7-сегментном дисплее:
#include "SevSeg.h"
SevSeg sevseg;
void setup(){
byte numDigits = 1;
byte digitPins[] = {};
byte segmentPins[] = {6, 5, 2, 3, 4, 7, 8, 9};
bool resistorsOnSegments = true;
byte hardwareConfig = COMMON_CATHODE;
sevseg.begin(hardwareConfig, numDigits, digitPins, segmentPins, resistorsOnSegments);
sevseg.setBrightness(90);
}
void loop(){
sevseg.setNumber(4);
sevseg.refreshDisplay();
}
В этой программе мы создаем объект sevseg в строке 2. Чтобы использовать дополнительные дисплеи, вы можете создать другой объект и вызвать соответствующие функции для этого объекта. Отображение инициализируется с помощью функции sevseg.begin () в строке 11. Другие функции описаны ниже:
hardwareConfig = COMMON_CATHODE; Этот параметр устанавливает тип дисплея. Я использую общий катод, но если вы используете общий анод, тогда используйте COMMON_ANODE.
byte numDigits = 1; Этот параметр устанавливает количество цифр на вашем дисплее. Я использую одноразрядный дисплей, поэтому я установил его на 1. Если вы используете 4-разрядный дисплей, установите это на 4.
byte digitPins [] = {}; Создает массив, который определяет заземляющие контакты при использовании 4-разрядного или многоразрядного дисплея. Оставьте его пустым, если у вас есть одноразрядный дисплей. Например, если у вас 4-разрядный дисплей и вы хотите использовать выводы Arduino 10, 11, 12 и 13 в качестве заземляющих выводов цифр, вы должны использовать это так: byte digitPins [] = {10, 11, 12, 13}; , См. ниже пример ипользования 4-разрядного дисплея для получения дополнительной информации.
byte segmentPins[] = {6, 5, 2, 3, 4, 7, 8, 9}; Это объявляет массив, который определяет, какие выводы Arduino подключены к каждому сегменту дисплея. Порядок в алфавитном порядке (A, B, C, D, E, F, G, DP, где DP - десятичная точка). Таким образом, в этом случае контакт 6 Arduino подключается к сегменту A, контакт 5 подключается к сегменту B, контакт 2 подключается к сегменту C и так далее.
resistorsOnSegments = true; Это должно быть установлено в true, если ваши текущие ограничивающие резисторы соединены последовательно с сегментными выводами. Если резисторы соединены последовательно с цифровыми выводами, установите для этого параметра значение false. Установите это значение true при использовании многозначных дисплеев.
sevseg.setBrightness (90); Эта функция устанавливает яркость дисплея. Его можно настроить от 0 до 100.
sevseg.setNumber (); Эта функция выводит номер на дисплей. Например, sevseg.setNumber (4); напечатает число «4» на дисплее. Вы также можете печатать числа с десятичными точками. Например, чтобы напечатать число «4.999», вы должны использовать sevseg.setNumber (4999, 3); , Второй параметр (3) определяет, где находится десятичная точка. В этом случае это 3 цифры от самой правой цифры. На одноразрядном дисплее установка второго параметра на «0» включает десятичную точку, а установка на «1» отключает его.
sevseg.refreshDisplay (); Эта функция требуется в конце секции цикла, чтобы продолжить отображение номера.
ТАЙМЕР ОБРАТНОГО ОТСЧЕТА
Эта простая программа будет отсчитывать от нуля до 9 и затем возвращаться к началу:
#include "SevSeg.h"
SevSeg sevseg;
void setup(){
byte numDigits = 1;
byte digitPins[] = {};
byte segmentPins[] = {6, 5, 2, 3, 4, 7, 8, 9};
bool resistorsOnSegments = true;
byte hardwareConfig = COMMON_CATHODE;
sevseg.begin(hardwareConfig, numDigits, digitPins, segmentPins, resistorsOnSegments);
sevseg.setBrightness(90);
}
void loop(){
for(int i = 0; i < 10; i++){
sevseg.setNumber(i, i%2);
delay(1000);
sevseg.refreshDisplay();
}
}
Код похож на предыдущий скетч. Единственное отличие состоит в том, что мы создаем переменную count «i» в операторе for в строке 16 и увеличиваем ее по одному числу за раз.
Sevseg.setNumber (I, I% 2); функция печатает значение i. Аргумент i% 2 делит i на 2 и возвращает остаток, в результате чего десятичная точка включает все остальные числа.
Таймер обратного отсчета - хороший способ продемонстрировать основы программирования дисплея, но теперь давайте попробуем сделать что-то более интересное.
ИГРАЛЬНЫЕ КОСТИ
Этот пример состоит из кнопки и одного 7-сегментного дисплея. Каждый раз, когда нажимается и удерживается кнопка, на дисплее быстро появляются цифры 0-9. Как только кнопка отпущена, дисплей продолжает цикл в течение того периода времени, почти равного времени нажатия кнопки, а затем отображает число вместе с десятичной точкой, чтобы указать новый номер.
Чтобы построить схему (с дисплеем 5161AS), подключите его следующим образом:
Затем загрузите эту программу в Arduino:
#include "SevSeg.h"
SevSeg sevseg;
const int buttonPin = 10; // the pin that the pushbutton is attached to
int buttonState = 0; // current state of the button
int lastButtonState = LOW; // previous state of the button
int buttonPushCounter = 0; // counter for the number of button presses
long counter = 0;
long max_long_val = 2147483647L;
void setup(){
byte numDigits = 1;
byte digitPins[] = {};
byte segmentPins[] = {6, 5, 2 , 3, 4 , 7, 8, 9};
bool resistorsOnSegments = true;
byte hardwareConfig = COMMON_CATHODE;
sevseg.begin(hardwareConfig, numDigits, digitPins, segmentPins, resistorsOnSegments);
sevseg.setBrightness(90);
pinMode(buttonPin, INPUT_PULLUP);
Serial.begin(9600);
lastButtonState = LOW;
}
void loop(){
buttonState = digitalRead(buttonPin);
if(buttonState == HIGH){
buttonState = LOW;
}
else
buttonState = HIGH;
if(buttonState == HIGH){
Serial.println("on");
lastButtonState = HIGH;
buttonPushCounter++;
if(counter < max_long_val)
counter++;
buttonPushCounter %= 9;
sevseg.setNumber(buttonPushCounter, 1);
sevseg.refreshDisplay();
delay(100 - (counter%99));
}
else{
Serial.println("off");
if(lastButtonState == HIGH){
Serial.println("in");
buttonPushCounter++;
buttonPushCounter %= 7;
if(buttonPushCounter == 0)
buttonPushCounter = 1;
counter--;
sevseg.setNumber(buttonPushCounter, 1);
sevseg.refreshDisplay();
delay(100 - (counter%99));
if(counter == 0){
lastButtonState = LOW;
sevseg.setNumber(buttonPushCounter, 0);
sevseg.refreshDisplay();
}
}
}
}
4-РАЗРЯДНЫЙ 7-СЕГМЕНТНЫЙ ДИСПЛЕЙ
До сих пор мы работали только с одноразрядными 7-сегментными дисплеями. Для отображения такой информации, как время или температура, нам нужно использовать 2- или 4-разрядный дисплей или подключать несколько одноразрядных дисплеев рядом.
В многоразрядных дисплеях один сегментный вывод (A, B, C, D, E, F, G и DP) контролирует один и тот же сегмент на всех цифрах. Многоразрядные дисплеи также имеют отдельные общие выводы для каждой цифры. Это цифровые контакты. Вы можете включить или выключить цифру, переключив цифровой pin.
Я использую 4-разрядный 7-сегментный дисплей марки 5641AH, но приведенные ниже схемы подключения также будут работать с 5461AS.
Вот схема, показывающая распиновку этих дисплеев:
Цифровые контакты D1, D2, D3 и D4 должны быть подключены к токоограничивающим резисторам, поскольку они являются общими клеммами цифр. Соединения показаны ниже:
Эта простая программа выведет число «4.999» на дисплей:
#include "SevSeg.h"
SevSeg sevseg;
void setup(){
byte numDigits = 4;
byte digitPins[] = {10, 11, 12, 13};
byte segmentPins[] = {9, 2, 3, 5, 6, 8, 7, 4};
bool resistorsOnSegments = true;
bool updateWithDelaysIn = true;
byte hardwareConfig = COMMON_CATHODE;
sevseg.begin(hardwareConfig, numDigits, digitPins, segmentPins, resistorsOnSegments);
sevseg.setBrightness(90);
}
void loop(){
sevseg.setNumber(4999, 3);
sevseg.refreshDisplay();
}
В приведенном выше коде мы устанавливаем количество цифр в строке 5 с помощью byte numDigits = 4; ,
Поскольку в многоразрядных дисплеях используются цифровые контакты, нам также необходимо определить, какие контакты Arduino будут подключаться к цифровым контактам. Использование byte digitPins [] = {10, 11, 12, 13}; в строке 6 вывод Arduino 10 в качестве первого разряда, Arduino 11 в качестве второго разряда и так далее.
Чтобы напечатать числа с десятичной точкой, мы устанавливаем второй параметр в sevseg.setNumber (4999, 3); до трех, что ставит его на три знака после запятой справа от цифры.
ДИСПЛЕЙ ТЕМПЕРАТУРЫ
Этот пример считывает температуру с термистора и отображает ее на четырехзначном дисплее.
Подключите схему следующим образом:
!Если у вас есть вопросы по использованию термистора или вы просто хотите узнать о них больше, ознакомьтесь с нашим другим руководством по использованию термистора с Arduino.
Как только все подключится, загрузите этот код в Arduino:
#include "SevSeg.h"
SevSeg sevseg;
int ThermistorPin = 0;
int Vo;
float R1 = 10000;
float logR2, R2, T;
float c1 = 1.009249522e-03, c2 = 2.378405444e-04, c3 = 2.019202697e-07;
void setup() {
byte numDigits = 4;
byte digitPins[] = {10, 11, 12, 13};
byte segmentPins[] = {9, 2, 3, 5, 6, 8, 7, 4};
bool resistorsOnSegments = true;
byte hardwareConfig = COMMON_CATHODE;
sevseg.begin(hardwareConfig, numDigits, digitPins, segmentPins, resistorsOnSegments);
}
void loop() {
Vo = analogRead(ThermistorPin);
R2 = R1 * (1023.0 / (float)Vo - 1.0);
logR2 = log(R2);
T = (1.0 / (c1 + c2 * logR2 + c3 * logR2 * logR2 * logR2));
T = T - 273.15;
T = (T * 9.0) / 5.0 + 32.0; //Comment out for Celsius
static unsigned long timer = millis();
if (millis() >= timer) {
timer += 300;
sevseg.setNumber(T, 2);
}
sevseg.refreshDisplay();
}
Это выведет температуру в градусах Фаренгейта. Чтобы отобразить температуру в градусах Цельсия, закомментируйте строку //Comment out for Celsius.
Сам по себе дисплей будет обновляться каждый раз, когда температура меняется даже незначительно. Это создает раздражающее мерцание. Чтобы справиться с этим, мы вводим механизм таймера, где мы читаем значение из термистора каждые 300 миллисекунд (строки с 30 по 34).
Переменная температуры «T» выводится на дисплей в строке 35 с sevseg.setNumber (T, 2, false); ,
Надеюсь, этой статьи будет достаточно, чтобы вы начали пользоваться семисегментными дисплеями. Если вы хотите отображать показания с других датчиков, вышеприведенный пример программы можно легко изменить под ваши нужды. Если у вас есть какие-либо вопросы или проблемы по настройке этих скетчей, не стесняйтесь оставлять комментарии ниже.