01 |
В статье разберемся с подключением 4-разрядного 7-сегментного индикатора 3641BS и рассмотрим практический пример его использования. |
|
02 |
|
Проверено — автор рекомендует: http://ali.pub/8bugx 4-разрядный 7-сегментный индикатор (12 pin, red, с общим анодом)
или аналоги: — http://ali.pub/iyk3o — http://ali.pub/l09do — http://ali.pub/tpixw — http://ali.pub/cswtv Видео-инструкция о покупке со скидками на Aliexpress |
03 |
Даташит на индикатор — datasheet-3641ax_bx.pdf (121 KB). |
|
04 |
Исходя из схемы, видим, что у нас индикатор с общим анодом (в маркировке буква B — 3641BS): |
|
06 |
Нумерация контактов стандартная — из нижнего левого угла против часовой стрелки: |
|
07 |
На схеме слева — 12, 9, 8 и 6 — пины-аноды для каждого разряда, на схеме справа — соответствие пинов индикатора его сегментам.
|
|
08 |
По аналогии с матрицей 8×8 для отображения нужной информации необходимо по очереди подавать напряжение на аноды, а катодами формировать нужную информацию — и так для каждого разряда по очереди. Делать это нужно так быстро, чтобы человеческому глазу казалось, что одновременно непрерывно горят все 4 разряда. Собираем схему: |
|
09 |
|
Ответ на вопрос, почему мы используем резисторы на катодах — на каждый отдельный светодиод, а не на анодах, на каждый отдельный разряд подробно описан в статье Как правильно подключать светодиоды.
|
10 |
Проверяем работоспособность: |
|
11 | Arduino (C++) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 int anodPins[] = {A1, A2, A3, A4};
int segmentsPins[] = {5, 6, 7, 8, 9, 10, 11, 12};
void setup() {
for (int i = 0; i < 4; i++) {
pinMode(anodPins[i], OUTPUT);
}
for (int i = 0; i < 8; i++) {
pinMode(segmentsPins[i], OUTPUT);
}
}
int seg[] = {0, 1, 1, 0, 1, 1, 1, 0}; //Буква 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(anodPins[i], HIGH); // Подали напряжение на анод - все индикаторы загорелись
delay(1); // Дали паузу глазу воспринять
digitalWrite(anodPins[i], LOW); // Сняли напряжение с анода, чтобы переключение катодов не вызывали мерцание
}
} |
|
12 |
Модифицируем код для отображения цифр: |
|
13 | Arduino (C++) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 int anodPins[] = {A1, A2, A3, A4}; // Задаем пины для кажого разряда
int segmentsPins[] = {5, 6, 7, 8, 9, 10, 11, 12}; //Задаем пины для каждого сегмента (из 7 + 1(точка))
void setup() {
// Все выходы программируем как OUTPUT
for (int i = 0; i < 4; i++) {
pinMode(anodPins[i], OUTPUT);
}
for (int i = 0; i < 8; i++) {
pinMode(segmentsPins[i], OUTPUT);
}
}
//{A, B, C, D, E, F, G,DP} - распиновка сегментов
int seg[10][8] = {
{1, 1, 1, 1, 1, 1, 0, 0}, //Цифра 0
{0, 1, 1, 0, 0, 0, 0, 0}, //Цифра 1
{1, 1, 0, 1, 1, 0, 1, 0}, //Цифра 2
{1, 1, 1, 1, 0, 0, 1, 0}, //Цифра 3
{0, 1, 1, 0, 0, 1, 1, 0}, //Цифра 4
{1, 0, 1, 1, 0, 1, 1, 0}, //Цифра 5
{1, 0, 1, 1, 1, 1, 1, 0}, //Цифра 6
{1, 1, 1, 0, 0, 0, 0, 0}, //Цифра 7
{1, 1, 1, 1, 1, 1, 1, 0}, //Цифра 8
{1, 1, 1, 1, 0, 1, 1, 0} //Цифра 9
};
int t = 0;
int digid = 0;
void loop() {
t += 1;
if (t > 9999) t = 0;
if ((t % 1000) == 0) {
digid = t / 1000; //Каждую секунду отображаем цифры подряд
}
for (int i = 0; i < 4; i++) { // Каждый разряд по очереди
for (int k = 0; k < 8; k++) {// Каждый сегмент по очереди - исходя из заданной карты
digitalWrite(segmentsPins[k], ((seg[digid][k] == 1) ? LOW : HIGH));
}
digitalWrite(anodPins[i], HIGH);
delay(1);
digitalWrite(anodPins[i], LOW);
}
} |
|
14 |
Напишем функцию, которая будет отображать заданные числа: |
|
15 | Arduino (C++) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 int anodPins[] = {A1, A2, A3, A4}; // Задаем пины для кажого разряда
int segmentsPins[] = {5, 6, 7, 8, 9, 10, 11, 12}; //Задаем пины для каждого сегмента (из 7 + 1(точка))
void setup() {
for (int i = 0; i < 4; i++) pinMode(anodPins[i], OUTPUT);
for (int i = 0; i < 8; i++) pinMode(segmentsPins[i], OUTPUT);
Serial.begin(9600);
}
//{A, B, C, D, E, F, G,DP}
int seg[12][8] = {
{1, 1, 1, 1, 1, 1, 0, 0}, //Цифра 0
{0, 1, 1, 0, 0, 0, 0, 0}, //Цифра 1
{1, 1, 0, 1, 1, 0, 1, 0}, //Цифра 2
{1, 1, 1, 1, 0, 0, 1, 0}, //Цифра 3
{0, 1, 1, 0, 0, 1, 1, 0}, //Цифра 4
{1, 0, 1, 1, 0, 1, 1, 0}, //Цифра 5
{1, 0, 1, 1, 1, 1, 1, 0}, //Цифра 6
{1, 1, 1, 0, 0, 0, 0, 0}, //Цифра 7
{1, 1, 1, 1, 1, 1, 1, 0}, //Цифра 8
{1, 1, 1, 1, 0, 1, 1, 0}, //Цифра 9
{0, 0, 0, 0, 0, 0, 1, 0}, //Знак -
{0, 0, 0, 0, 0, 0, 0, 0} //Пустой разряд
};
int err[4][8] = {
{0, 0, 0, 0, 0, 0, 0, 0}, //Пусто
{1, 0, 0, 1, 1, 1, 1, 0}, //E
{0, 0, 0, 0, 1, 0, 1, 0}, //r
{0, 0, 0, 0, 1, 0, 1, 0} //r
};
float numbers[] = {520.45, 251, -12, 3.14159, 100000, -85.2563}; // По очереди будем показывать числа - на 100000 на дисплее будет отображена ошибка Err
static int arr[4][8]; // Переменная-массив для хранения данных, которые не нужно каждый раз пересчитывать
int numindex = 0;
float value = 0.0;
int counter = -1;
void loop() {
counter += 1;
if ((counter % 200) == 0) { // Пауза между сменами 200 мс
counter = 0;
getDigits(numbers[numindex]);
numindex += 1;
if (numindex >= sizeof(numbers)/sizeof(float)) numindex = 0;
}
displayMessage(arr);
}
void getDigits (float value) {
Serial.println("");
// Выдаем ошибку на те значения, которые не можем показать
if ((value >= 10000) ||
(value <= -1000)) {
for (int i = 0; i < 4; i++) { // Каждый разряд по очереди
for (int k = 0; k < 8; k++) {// Каждый сегмент по очереди - исходя из заданной карты
arr[i][k] = err[i][k];
}
}
return; // Выходим
}
int digits = 4; // У нас 4 разряда
if (value < 0) digits = 3; // Из-за минуса один символ убирается*/
// Делим число на 2 группы - отдельно целую часть и дробную.
int intPart = (int)abs(value);
int intLength = ((String)intPart).length(); // Смотрим, сколько разрядов занимает целая часть
char valueChars[8]; // По нормальному float в String преобразовать нельзя, поэтому...
dtostrf(value, 5, 4, valueChars); //... копируем данные float в массив chars[]
// На дробную часть у нас остается разрядов: digits-intLength
String valueStr = valueChars; // Теперь с текстовым форматом можно работать
// Serial.print("valueStr: "); Serial.println(valueStr);
int fracIndex = valueStr.indexOf("."); // Получаем индекс начала дробной части
String fracPartStr = valueStr.substring(fracIndex + 1, valueStr.length()); // Выделяем цифры дробной части
int fracDigits = digits - intLength;
fracPartStr = fracPartStr.substring(0, fracDigits); // Вычленяем цифры, которые будут выводиться на дисплей
// Serial.print("fracDigits: "); Serial.println(fracDigits);
// Serial.print("fracPartStr: "); Serial.println(fracPartStr);
int fracInt = fracPartStr.toInt(); // Переменная для проверки, нужно ли что-то выводить, если нули, то нет
// Serial.print("fracInt: "); Serial.println(fracInt);
// Собираем строку для отображения
String output = (value < 0) ? "-" : "";
output += (String)intPart;
String outputFrac = ((digits - intLength <= 0) || (fracInt == 0)) ? "" : ((String)"." + fracPartStr);
output += (String)outputFrac;
// Дополняем символы спереди, если цифр слишком мало, например для "-1" делаем " -1"
String spaces = " ";
digits = 4;
if (~output.indexOf(".")) digits += 1;
if (output.length() < digits) output = spaces.substring(0, digits - output.length()) + output;
// Формирум данные для показа:
int dig = -1;
for (int i = 0; i < output.length(); i++) {
String _char = output.substring(i, i + 1);
if (_char != ".") dig += 1; // Точка не занимает сегмент - увеличиваем на 1
int actualdigit = 11; // По умолчанию пустой символ
if ((_char == "-")) {
actualdigit = 10;
}
else if (_char == " " || _char == ".") {
}
else {
actualdigit = _char.toInt();
}
if (_char == ".") {
arr[dig][7] = 1; // Если нужно - ставим точку
}
else {
for (int n = 0; n <= 7; n++) {
arr[dig][n] = seg[actualdigit][n];
}
}
}
}
void displayMessage(int dig[4][8]) {
for (int i = 0; i < 4; i++) { // Каждый разряд по очереди
for (int k = 0; k < 8; k++) {// Каждый сегмент по очереди - исходя из заданной карты
digitalWrite(segmentsPins[k], ((dig[i][k] == 1) ? LOW : HIGH));
}
digitalWrite(anodPins[i], HIGH);
delay(1);
digitalWrite(anodPins[i], LOW);
}
} |
|
16 |
Все как задумано!
|
Если на дисплей попробовать вывести число, которое он не может отобразить физически, например, 10000, то отобразится сообщение об ошибке Err
|
17 |
А теперь — к практической реализации. Подключим к нашей схеме датчик — ко входу платы Analog In, и будем передавать на дисплей значения, которые датчик будет передавать плате. Мы знаем, что плата интерпретирует входные данные от любого датчика в диапазон значений от 0 до 1024, поэтому их и будем передавать на наш индикатор. |
|
18 |
Предположим, мы создаем устройство с фотодатчиком, но мы не знаем как настроить схему (забудем, что у нас есть объект Serial), потому что не знаем чувствительность датчика — здесь нам и поможет индикатор: |
|
20 |
Немного измененный код, по факту изменилось всего несколько строк. Функции displayMassage() и getDigits() не приводятся — они остались без изменения: |
|
21 | Arduino (C++) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 int anodPins[] = {A1, A2, A3, A4}; // Задаем пины для кажого разряда
int segmentsPins[] = {5, 6, 7, 8, 9, 10, 11, 12}; //Задаем пины для каждого сегмента (из 7 + 1(точка))
int pinIn = A0;
void setup() {
for (int i = 0; i < 4; i++) pinMode(anodPins[i], OUTPUT);
for (int i = 0; i < 8; i++) pinMode(segmentsPins[i], OUTPUT);
pinMode(pinIn, INPUT);
}
//{A, B, C, D, E, F, G,DP}
int seg[12][8] = {
{1, 1, 1, 1, 1, 1, 0, 0}, //Цифра 0
{0, 1, 1, 0, 0, 0, 0, 0}, //Цифра 1
{1, 1, 0, 1, 1, 0, 1, 0}, //Цифра 2
{1, 1, 1, 1, 0, 0, 1, 0}, //Цифра 3
{0, 1, 1, 0, 0, 1, 1, 0}, //Цифра 4
{1, 0, 1, 1, 0, 1, 1, 0}, //Цифра 5
{1, 0, 1, 1, 1, 1, 1, 0}, //Цифра 6
{1, 1, 1, 0, 0, 0, 0, 0}, //Цифра 7
{1, 1, 1, 1, 1, 1, 1, 0}, //Цифра 8
{1, 1, 1, 1, 0, 1, 1, 0}, //Цифра 9
{0, 0, 0, 0, 0, 0, 1, 0}, //Знак -
{0, 0, 0, 0, 0, 0, 0, 0} //Пустой разряд
};
int err[4][8] = {
{0, 0, 0, 0, 0, 0, 0, 0}, //Пусто
{1, 0, 0, 1, 1, 1, 1, 0}, //E
{0, 0, 0, 0, 1, 0, 1, 0}, //r
{0, 0, 0, 0, 1, 0, 1, 0} //r
};
static int arr[4][8]; // Переменная-массив для хранения данных, которые не нужно каждый раз пересчитывать
float value = 0.0;
int counter = -1;
void loop() {
counter += 1;
if ((counter % 100) == 0) { // Пауза между сменами 100 мс
counter = 0;
value = analogRead(pinIn);
getDigits(value);
}
displayMessage(arr);
}
void getDigits (float value) {
//...
}
void displayMessage(int dig[4][8]) {
//...
} |
|
22 |
Подписывайтесь на канал
, чтобы быть в курсе обновлений! |
|
23 |
Похожие запросы:
|
|