Сопряжение с необычным дисплеем из 4 цифр и 7 сегментов
Имеется общий анод и общий катод из 7 сегментов дисплея. Но мне попался один необычный случай.
Имеется 7 контактов, управляющих 4 цифрами и 7 сегментами.
Я нахожу распиновку с помощью мультиметра. По сути, каждый вывод может быть анодом или катодом.
Мои вопросы:
- Каково точное название этого 7-сегментного дисплея?
- Как управлять этим дисплеем с помощью Arduino, любого веб-сайта / примера кода?
- Если я использую плату с допуском 5 В, какой резистор мне нужно использовать? А как выглядит схема?
@Allen Chak, 👍0
Обсуждение2 ответа
Лучший ответ:
Этот дисплей, по-видимому, имеет 32 адресуемых светодиода, управляемых только 7 булавок. Судя по этому факту и из предоставленной таблицы распиновки, это выглядит как запутанная матрицаЧарли.
Типичным способом управления такого рода матрицей является зацикливание на
катодах. Вы опускаете один контакт катода ВНИЗ
, а затем поднимаете ВВЕРХ
все
аноды светодиодов, которые вы хотите осветить, которые подключены к этому
конкретному катоду. Подождите несколько миллисекунд, затем переходите к следующему
катоду. Важно, чтобы все контакты, которые не участвуют в освещении
светодиода, оставались в режиме ввода.
Например, предположим, вы хотите осветить все сегменты первой
цифры (отобразить “8”), оставив все остальное выключенным. Сначала вы вытягиваете
НИЖНИЙ штифт 1
(первый катод) и вытягиваете ВЕРХНИЕ
штифты 2-5 (сегменты F, G, C
и D). Дайте ему светить несколько миллисекунд, затем переведите все в
режим высокого импеданса (контакты на ВХОД
) и переходите к следующему катоду: вывод 2
становится НИЗКИМ
, а вывод 1 (сегмент А) - ВЫСОКИМ
. И так далее, пока вы не
сделаете все катоды.
Что касается части кодирования, я бы предложил использовать матрицу булевых значений размером 7 × 7 , указывающую, должен ли определенный сегмент быть освещен. Индексы массива будут следующими: строка = номер катода и столбец = номер анода. Массив будет иметь ту же структуру, что и опубликованная вами таблица распиновки, за исключением того факта, что строки и столбцы будут иметь индексы в диапазоне 0-6 вместо 1-7. Это должно упростить процесс обновления дисплея.
Вывод цифр немного сложнее, чем на традиционных 7-сегментных дисплеях, так как для каждого сегмента вам нужно будет найти его координаты в матрице (номер катода и номер анода). Для этого я бы использовал “матрицу сопоставления”, в которой хранится сопоставление (номер цифры, номер сегмента). → (номер катода, номер анода).
Ниже приведена предварительная и непроверенная реализация этих стратегий.
Обратите внимание, что я не писал функцию для вывода цифры, но это должно
быть легко реализовать поверх функции set_segment()
, определенной
здесь. Кроме того, вопрос о том, как нарисовать цифру, если вы знаете, как
управлять отдельными сегментами, - это стандартная 7-сегментная задача, для которой
вы должны быть в состоянии найти много руководств.
Обратите внимание, что этот код предполагает, что вы управляете дисплеем напрямую, не используя никаких итерационных поверхностей, кроме токоограничивающих резисторов. Это чревато либо перегрузкой катодных выходов, либо слишком тусклым отображением, в зависимости от токоограничивающих резисторов. Возможно, вы захотите использовать транзисторы для катодов, и в этом случае у вас будет набор катодных выводов, отличный от набора анодных выводов.
// Контакты Arduino подключены к дисплею.
const uint8_t display_pins[7] = {2, 3, 4, 5, 6, 7, 8};
// Какие сегменты освещены. Каждый сегмент расположен в этой матрице по адресу
// координаты [катод][анод].
bool segment_lit[7][7];
// Координаты в приведенной выше матрице, где можно найти сегмент.
struct SegmentCoordinates {
uint8_t cathode;
uint8_t anode;
};
// segments[цифра][сегмент] задает координаты
// любого сегмента (0 = A) любой цифры (0 = 1-я цифра).
const SegmentCoordinates segments[4][7] = {
// сегмент: A B C D E F G
{{1, 0}, {2, 0}, {0, 3}, {0, 4}, {3, 0}, {0, 1}, {0, 2}},
{{2, 1}, {3, 1}, {1, 4}, {5, 1}, {4, 1}, {1, 2}, {1, 3}},
{{3, 4}, {4, 2}, {4, 3}, {0, 5}, {2, 5}, {2, 3}, {2, 4}},
{{5, 6}, {6, 5}, {5, 4}, {3, 5}, {5, 3}, {4, 5}, {6, 4}}
};
// Выключите сегмент (lit = false) или ВКЛЮЧИТЕ (lit = true).
void set_segment(uint8_t digit, uint8_t segment, bool lit) {
SegmentCoordinates coordinates = segments[digit][segment];
segment_lit[coordinates.cathode][coordinates.anode] = lit;
}
void setup(){}
void loop() {
static uint8_t cathode; // используемый в настоящее время катод
// Установите ток катода на НИЗКИЙ ВЫХОДНОЙ сигнал.
digitalWrite(display_pins[cathode], LOW);
pinMode(display_pins[cathode], OUTPUT);
// Установите соответствующие аноды на ВЫСОКИЙ ВЫХОДНОЙ сигнал.
for (int anode = 0; anode < 7; anode++) {
if (segment_lit[cathode][anode]) {
digitalWrite(display_pins[anode], HIGH);
pinMode(display_pins[anode], OUTPUT);
}
}
// Пусть это сияет какое-то время.
delay(10);
// Выключите все.
for (int pin = 0; pin < 7; pin++) {
pinMode(display_pins[pin], INPUT);
}
// Переходите к следующему катоду.
if (++cathode >= 7) cathode = 0;
}
Я использовал delay()
здесь для простоты. В производственном коде вы бы
обрабатывали тайминги с помощью millis()
неблокирующим способом, в
духе руководства “Мигать без задержек”.
Спасибо, это работает. Я просто изменяю delay (10)
на delay (1)
и добавляю 'set_segment() в
setup()`, @Allen Chak
Я не знаю. Если бы мне пришлось говорить об этом, я бы сказал, что это светодиодный сегментный дисплей с матричным расположением и дополнительным приводом.
Если в качестве катода используется контакт, необходимо подавать НИЗКИЙ сигнал. Если он используется в качестве анода, необходимо подавать ВЫСОКИЙ сигнал.
Вы могли бы определить константы для каждого сегмента анода и катода, которые определяют контактный номер. например:
#define CAT_1A = 2
#define AN_1A = 1
и так далее. Затем, если вы хотите показать сегмент 1A, установите CAT_1A на НИЗКИЙ, а AN_1A на ВЫСОКИЙ.
Конечно, весь этот процесс гораздо сложнее. Вы должны определить, какие сегменты должны быть подсвечены, чтобы показать определенную цифру. Вы должны показать все четыре цифры одну за другой в быстром цикле и так далее. Но это то же самое, что вы сделали бы для обычной светодиодной сегментной панели. Разница в том, что вы должны настраивать пары контактов, а не отдельные контакты.
- Используйте свой мультиметр для измерения прямого напряжения сегментов. Если они красные, то напряжение должно составлять от 1,8 до 2,4 Вольт. Вычтите это напряжение из 5 Вольт. Затем разделите на 0,02 (20 мА), и вы получите резистор в Омах. Стандартный светодиод достаточно яркий, около 20 мА.
Пример:
(5V - 1.8V) / 0.02A) = 160 Ohm
Используйте резистор, скажем, 100 Ом на каждом выводе. Он широко доступен, и поскольку ток всегда проходит через 2 контакта, у вас получается 200 Ом вместе.
Также возможно, что светодиодная панель имеет внутренние резисторы. Постарайтесь измерить сопротивление между контактами.
Обновление Когда я сказал: "каждая цифра должна отображаться в быстром цикле", я забыл уточнить, что для каждой цифры сегменты должны переключаться последовательно.
Вы можете сделать это еще сложнее и показать все сегменты с общим катодом или общим анодом сразу. Тогда вам потребуется меньше циклов, но поскольку вы используете резисторы для всех контактов (см. Пункт 3.), Это может привести к значительному затемнению светодиодов. Кроме того, поскольку технически прямое напряжение разных светодиодов может отличаться, некоторые из них могут быть ярче других.
Есть и еще одна вещь, о которой я не подумал, когда писал ответ. Если вы подключаете сегмент, скажем, от контакта A (+ 5 В) к контакту B (GND), у вас есть резистор (100 Ом), светодиод (минус 1,8 Вольт) и второй резистор (100 Ом) последовательно. Таким образом, в идеальной ситуации напряжение на выводе B (также на втором резисторе) будет составлять около 1,6 Вольта. Вывод B является катодом сегмента светодиода, но также может быть анодом другого сегмента (S2). Если катод S2 подключен к GND, то вероятность того, что сегмент загорится, очень мала. Если вы не видите (призрачных) огней, все в порядке. Но если некоторые сегменты загораются (но намного темнее, чем правильные), вам нужно найти лучшее решение.
Re “_ Вы должны указать все четыре цифры одну за другой в быстром цикле_”: это не сработает. В любой момент времени вы можете зажигать только те сегменты, которые имеют один и тот же анод или один и тот же катод. Таким образом, вместо того, чтобы перебирать цифры, вам придется перебирать аноды (или катоды)., @Edgar Bonet
@EdgarBonet * Отображение цифр по одному * предназначено в дополнение к отображению каждого сегмента по одному. Жаль, что я не выразился ясно. Я отредактирую ответ., @Peter Paul Kiefer
Re “_ показать, что все сегменты с общим катодом [...] могут заметно затемнить светодиоды”: не более, чем показывать сегменты один за другим. Если вы хотите получить более яркий дисплей, вам придется заменить катоды транзисторами. Re “_Если катод S2 подключен к GND, вероятность того, что сегмент загорится, очень мала”: вот почему этот катод не следует опускать "НИЗКО" (подключен к GND): его следует оставить плавающим (режим ввода, он же. “высокий импеданс”)., @Edgar Bonet
@EdgarBonnet Поскольку несколько светодиодов с общим катодом или общим анодом имеют один источник или сток с резистором. Ток через все светодиоды вместе такой же, как и ток через этот единственный резистор. Таким образом, каждый светодиод видит только часть тока. Допустим, у вас есть 5 светодиодов с общим катодом, тогда ток через общий резистор составляет 5 В / (100 Ом + 20 Ом) ~ ~ 41 мА. Ток через каждый светодиод составляет 1/5 от этого ~ 8,3 мА. Я думаю, вы бы увидели разницу. Использование состояния с высоким импедансом для неиспользуемых контактов - одно из лучших решений, о которых я упоминал., @Peter Paul Kiefer
Вы, конечно, правы, дисплей будет тусклым. Но это не моя точка зрения. Я хочу сказать, что он будет очень тусклым, если вы будете обрабатывать сегменты один за другим. Подумайте о рабочем цикле и усредните яркость за полный цикл сканирования., @Edgar Bonet
@EdgarBonnet Это хороший момент. Я не ожидал, что светодиод сильно потускнеет из-за рабочего цикла, но теперь я уже не уверен. Мне нужно будет достать такой светодиодный дисплей и попробовать его. Спасибо вам за комментарий., @Peter Paul Kiefer
Вы ответили на мой последний вопрос и дали мне идею для резистора, но я понятия не имею, как реализовать ваш код., @Allen Chak
- 74HC595 к 4 значному 7 сегменту с использованием библиотеки SevSegShift
- 3-значный 7-сегментный дисплей
- Запуск двух циклов одновременно на Arduino
- Как записать и прочитать из файла SPIFFS как данные объекта на ESP8266
- Почему у меня 7 сегмент не обновляется каждую секунду как в программе?
- 7-сегментный дисплей с потенциометром
- Как прочитать выходные данные с разъема SPI с помощью Arduino Uno?
- отображение 3-значного времени часов на 4-значном 7-сегментном дисплее
Похоже, это какой-то фирменный 7-сегментный дисплей, возможно, от часов или радиочасов. Я сомневаюсь, что вы найдете какую-либо библиотеку Arduino, которая поддерживает это напрямую, и вам может быть лучше просто получить стандартный дисплей, который может работать с существующими библиотеками. В противном случае вы наверняка многому научитесь, выяснив, как заставить это работать, и написав свою собственную библиотеку. Что касается резисторов, то трудно сказать, поскольку мы не знаем, что находится внутри этой штуковины. Начните с чего-нибудь консервативного, скажем, 1K, и двигайтесь дальше., @jwh20
Выглядит как [Запутанная матрица Чарли] (https://en.wikipedia.org/wiki/Charlieplexing ). Вы можете попробовать выполнить поиск в Интернете по запросу “Arduino Charlieplexing”., @Edgar Bonet