Arduino. Сегментный индикатор
Сегментный индикатор позволяет выводить различную информация в виде цифр, букв и т.д., в зависимости от конфигурации индикатора. В этой статье вы найдете описание работы с одним разрядом индикатора.
Подготовка к работе
Прежде чем начинать программировать, разберемся с тем, как работает сегментный индикатор. По сути, он представляет собой матрицу светодиодов. В семисегментных индикаторах эти сегменты расположены так, что включая эти светодиоды, можно вывести цифры от 0 до 9. На рисунке показано расположение светодиодов на дисплее и его электрическая схема. Индикаторы бывают с общим анодом и общим катодом. На рисунке с общим анодом.
Управлять сегментным индикатором можно при помощи логических уровней. Для этого достаточно подключить общий анод к плюсу, а остальные выводы через резисторы к выводам микроконтроллера. Если на выводах МК выводить 0 сегменты будут загораться, если 1 — гаснуть.
Напоминаем, что все примеры выполнены с использованием EduBoard и TutorShield.
На нашем шилде двухразрядный индикатор. Схема подключения индикатора на нем:
Этот индикатор предназначен для динамической индикации, поэтому аноды разрядов подключены через транзисторы, для того чтобы их можно было отключить. Если подать ноль на базу такого транзистора, то он откроется и на аноды требуемого разряда будет подано напряжение питания.
Теперь установите перемычки так, как показано на рисунке, подключите шилд к EduBoard и подключите платы к USB.
Первый пример
Для примера введите код, запускающий на индикаторе последовательность цифр 0, 1, 2:
int dig1 = 4; int dig2 = 5; int a = 6; int b = 7; int c = 8; int d = 9; int e = 10; int f = 11; int g = 12; void setup() { pinMode(a, OUTPUT); pinMode(b, OUTPUT); pinMode(c, OUTPUT); pinMode(d, OUTPUT); pinMode(e, OUTPUT); pinMode(f, OUTPUT); pinMode(g, OUTPUT); pinMode(dig2, OUTPUT); digitalWrite(a,HIGH); digitalWrite(b,HIGH); digitalWrite(c,HIGH); digitalWrite(d,HIGH); digitalWrite(e,HIGH); digitalWrite(f,HIGH); digitalWrite(g,HIGH); digitalWrite(dig2,LOW); } void loop() { digitalWrite(a,LOW); digitalWrite(b,LOW); digitalWrite(c,LOW); digitalWrite(d,LOW); digitalWrite(e,LOW); digitalWrite(f,LOW); delay(500); digitalWrite(a,HIGH); digitalWrite(b,HIGH); digitalWrite(c,HIGH); digitalWrite(d,HIGH); digitalWrite(e,HIGH); digitalWrite(f,HIGH); digitalWrite(g,HIGH); delay(500); digitalWrite(b,LOW); digitalWrite(c,LOW); delay(500); digitalWrite(a,HIGH); digitalWrite(b,HIGH); digitalWrite(c,HIGH); digitalWrite(d,HIGH); digitalWrite(e,HIGH); digitalWrite(f,HIGH); digitalWrite(g,HIGH); delay(500); digitalWrite(a,LOW); digitalWrite(b,LOW); digitalWrite(d,LOW); digitalWrite(e,LOW); digitalWrite(g,LOW); delay(500); digitalWrite(a,HIGH); digitalWrite(b,HIGH); digitalWrite(c,HIGH); digitalWrite(d,HIGH); digitalWrite(e,HIGH); digitalWrite(f,HIGH); digitalWrite(g,HIGH); delay(500); }
Приведенный пример наглядно показывает насколько просто работать с индикатором. В разделе void setup(), на вывод dig2 выводится низкое напряжение. Это подает на анод второго разряда питающее напряжение.
Сама программа заключается в том, что на требуемые сегменты подается низкое напряжение на 500мс. Затем все сегменты гасятся и программа останавливается еще на 500мс.
Попробуйте по тому же принципу дополнить код так, чтобы цифры изменялись от 0 до 9.
Второй пример
Обратите внимание, что при этом код принимает нечитаемый вид. Это плохой стиль программирования, которого стоит избегать. Помочь в этом может использование функций.
Рассмотрим работу с ними на примере:
int dig1 = 4; int dig2 = 5; int a = 6; int b = 7; int c = 8; int d = 9; int e = 10; int f = 11; int g = 12; void setup() { pinMode(a, OUTPUT); pinMode(b, OUTPUT); pinMode(c, OUTPUT); pinMode(d, OUTPUT); pinMode(e, OUTPUT); pinMode(f, OUTPUT); pinMode(g, OUTPUT); pinMode(dig2, OUTPUT); digitalWrite(a,HIGH); digitalWrite(b,HIGH); digitalWrite(c,HIGH); digitalWrite(d,HIGH); digitalWrite(e,HIGH); digitalWrite(f,HIGH); digitalWrite(g,HIGH); digitalWrite(dig2,LOW); } void loop() { Show(0); delay(500); Clean(); delay(500); Show(1); delay(500); Clean(); delay(500); Show(2); delay(500); Clean(); delay(500); } void Show(int digit) { if (digit==0) { digitalWrite(a,LOW); digitalWrite(b,LOW); digitalWrite(c,LOW); digitalWrite(d,LOW); digitalWrite(e,LOW); digitalWrite(f,LOW); } if (digit==1) { digitalWrite(b,LOW); digitalWrite(c,LOW); } if (digit==2) { digitalWrite(a,LOW); digitalWrite(b,LOW); digitalWrite(d,LOW); digitalWrite(e,LOW); digitalWrite(g,LOW); } } void Clean() { digitalWrite(a,HIGH); digitalWrite(b,HIGH); digitalWrite(c,HIGH); digitalWrite(d,HIGH); digitalWrite(e,HIGH); digitalWrite(f,HIGH); digitalWrite(g,HIGH); }
Метод Show() – функция с параметром. Это значит, что при ее вызове в подпрограмму передается значение, указанное в скобках. Фактически, когда очередь выполнения программы в основном цикле программы loop() доходит до вызова этой подпрограммы выполнение основного цикла прекращается и происходит выполнение подпрограммы. Применение подпрограмм позволяет исключить из основного цикла повторяющиеся части кода.
Обратимся к самой подпрограмме. В зависимости от того, какое значение ей передано, должна загораться требуемая цифра. Для это используется оператор сравнения if. Если условие истинно, то выполняется код, следующий за этим оператором. Следует отметить, что “=” это оператор присваивания, а “==” – сравнения. В условии должно происходить именно сравнение.
Вторая функция — Clean(). В этой функции все сегменты индикатора гасятся.
На первый взгляд из-за того что объем кода не изменился, может показаться, что в такой организации нет смысла. Но обратите внимание, что содержания основного цикла loop() значительно сократилось. Логика работы с аппаратной частью вынесена за его пределы и в самом цикле уже можно сконцентрироваться на том, ЧТО нужно показать на индикаторе, а не КАК это сделать.
Однако код до сих пор далек от идеала. Продолжим его улучшение.
Третий пример
Ранее выводы микроконтроллера мы записывали в виде переменных, но есть гораздо более простой способ их определения — это применение директивы компилятора #define. Директива #define определяет идентификатор и последовательность символов, которая будет подставляться вместо идентификатора каждый раз, когда он встретится в исходном файле.
Во-вторых можно оптимизировать функцию Show(), если использовать оператор switch. Синтаксис оператора:
switch (var) { case label: // выражение1 break; case label: // выражение2 break; default: // выражение3 }
Этот оператор выполняет только одно сравнение. Введите пример, перебирающий цифры от 0 до 9 с использованием этих дополнений:
#define DIG1 4 #define DIG2 5 #define A 6 #define B 7 #define C 8 #define D 9 #define E 10 #define FF 11 #define G 12 #define TAKT 1000 void setup() { pinMode(A, OUTPUT); pinMode(B, OUTPUT); pinMode(C, OUTPUT); pinMode(D, OUTPUT); pinMode(E, OUTPUT); pinMode(FF, OUTPUT); pinMode(G, OUTPUT); pinMode(DIG2, OUTPUT); digitalWrite(A,HIGH); digitalWrite(B,HIGH); digitalWrite(C,HIGH); digitalWrite(D,HIGH); digitalWrite(E,HIGH); digitalWrite(FF,HIGH); digitalWrite(G,HIGH); digitalWrite(DIG2,LOW); } void loop() { Clean(); Show(0); delay(TAKT); Clean(); Show(1); delay(TAKT); Clean(); Show(2); delay(TAKT); Clean(); Show(3); delay(TAKT); Clean(); Show(4); delay(TAKT); Clean(); Show(5); delay(TAKT); Clean(); Show(6); delay(TAKT); Clean(); Show(7); delay(TAKT); Clean(); Show(8); delay(TAKT); Clean(); Show(9); delay(TAKT); } void Show(int digit) { switch(digit) { case 0: { digitalWrite(A,LOW); digitalWrite(B,LOW); digitalWrite(C,LOW); digitalWrite(D,LOW); digitalWrite(E,LOW); digitalWrite(FF,LOW); } break; case 1: { digitalWrite(B,LOW); digitalWrite(C,LOW); } break; case 2: { digitalWrite(A,LOW); digitalWrite(B,LOW); digitalWrite(D,LOW); digitalWrite(E,LOW); digitalWrite(G,LOW); } break; case 3: { digitalWrite(A,LOW); digitalWrite(B,LOW); digitalWrite(C,LOW); digitalWrite(D,LOW); digitalWrite(G,LOW); } break; case 4: { digitalWrite(B,LOW); digitalWrite(C,LOW); digitalWrite(FF,LOW); digitalWrite(G,LOW); } break; case 5: { digitalWrite(A,LOW); digitalWrite(C,LOW); digitalWrite(D,LOW); digitalWrite(FF,LOW); digitalWrite(G,LOW); } break; case 6: { digitalWrite(A,LOW); digitalWrite(C,LOW); digitalWrite(D,LOW); digitalWrite(E,LOW); digitalWrite(FF,LOW); digitalWrite(G,LOW); } break; case 7: { digitalWrite(A,LOW); digitalWrite(B,LOW); digitalWrite(C,LOW); } break; case 8: { digitalWrite(A,LOW); digitalWrite(B,LOW); digitalWrite(C,LOW); digitalWrite(D,LOW); digitalWrite(E,LOW); digitalWrite(FF,LOW); digitalWrite(G,LOW); } break; case 9: { digitalWrite(A,LOW); digitalWrite(B,LOW); digitalWrite(C,LOW); digitalWrite(D,LOW); digitalWrite(FF,LOW); digitalWrite(G,LOW); } break; } } void Clean() { digitalWrite(A,HIGH); digitalWrite(B,HIGH); digitalWrite(C,HIGH); digitalWrite(D,HIGH); digitalWrite(E,HIGH); digitalWrite(FF,HIGH); digitalWrite(G,HIGH); }
Обратите внимание, что в директиве #define идентификатор везде написан большими буквами. Это необходимо для единой стилистики программирования. Здесь и далее мы будем писать идентификаторы прописными буквами, а переменные строчными.
Идентификатор F уже используется в библиотеках Arduino, поэтому нам пришлось обозначить это сегмент как FF.
Заключение
В итоге мы научились работать с сегментым индикатором и написали две очень полезные функции. Теперь при подключении индикатора вам достаточно будет поправить значения идентификаторов и вставить код для работы с индикатором.
Индивидуальные задания
Попробуйте самостоятельно выполнить следующие задания:
- В последнем примере цифры в цикле loop() задаются простым перебором. Попробуйте организовать перебор значений, используя цикл for.
- В большинстве случаев информация на дисплее отображается непрерывно. Доработайте функцию Show() таким образом, чтобы не надо было каждый раз перед ее вызовом очищать дисплей
- Добавьте любой дополнительный символ, который может быть отображен на индикаторе. Например H, Г, А и так далее.
Остальные статьи цикла можно найти здесь.
Мы будем очень рады, если вы поддержите наш ресурс и посетите магазин наших товаров shop.customelectronics.ru.
Метки: Arduino, динамическая индикация, курс, программирование, сегментный индикатор Просмотров: 18452