Обновлено 25 мая 2016
Кравченко Виктор

Arduino UNO + 4-разрядный 7-сегментный индикатор (12 pin, 3641BS, red)

Arduino Arduino Lang
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 со скидкой от 5,5%

Видео-инструкция о покупке со скидками на Aliexpress
03

Даташит на индикатор — datasheet-3641ax_bx.pdf (121 KB).

04

Исходя из схемы, видим, что у нас индикатор с общим анодом (в маркировке буква B — 3641BS):

05
06

Нумерация контактов стандартная — из нижнего левого угла против часовой стрелки:

07
На схеме слева — 12, 9, 8 и 6 — пины-аноды для каждого разряда, на схеме справа — соответствие пинов индикатора его сегментам.
На схеме слева — 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), потому что не знаем чувствительность датчика — здесь нам и поможет индикатор:

19
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

Похожие запросы:

  • arduino LED-Display 4×7
  • 4 разрядный 7 сегментный индикатор и Arduino
comments powered by HyperComments

Яндекс.Метрика