CUSTOMELECTRONICS.RU
Информационно-учебный блог о разработке электроники
Эл. почта: info@customelectronics.ru

Arduino. Сегментный индикатор

Сегментный индикатор позволяет выводить различную информация в виде цифр, букв и т.д., в зависимости от конфигурации индикатора. В этой статье вы найдете описание работы с одним разрядом индикатора.

Подготовка к работе

Прежде чем начинать программировать, разберемся с тем, как работает сегментный индикатор. По сути, он представляет собой матрицу светодиодов. В семисегментных индикаторах эти сегменты расположены так, что включая эти светодиоды, можно вывести цифры от 0 до 9. На рисунке показано расположение светодиодов на дисплее и его электрическая схема. Индикаторы бывают с общим анодом и общим катодом. На рисунке с общим анодом.

Схема индикатора

Схема индикатора

Управлять сегментным индикатором можно при помощи логических уровней. Для этого достаточно подключить общий анод к плюсу, а остальные выводы через резисторы к выводам микроконтроллера. Если на выводах МК выводить 0 сегменты будут загораться, если 1 — гаснуть.
Напоминаем, что все примеры выполнены с использованием EduBoard и TutorShield.
На нашем шилде двухразрядный индикатор. Схема подключения индикатора на нем:
TutorShield_Schematic
Этот индикатор предназначен для динамической индикации, поэтому аноды разрядов подключены через транзисторы, для того чтобы их можно было отключить. Если подать ноль на базу такого транзистора, то он откроется и на аноды требуемого разряда будет подано напряжение питания.
Теперь установите перемычки так, как показано на рисунке, подключите шилд к 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.

Заключение

В итоге мы научились работать с сегментым индикатором и написали две очень полезные функции. Теперь при подключении индикатора вам достаточно будет поправить значения идентификаторов и вставить код для работы с индикатором.

Индивидуальные задания

Попробуйте самостоятельно выполнить следующие задания:

  1. В последнем примере цифры в цикле loop() задаются простым перебором. Попробуйте организовать перебор значений, используя цикл for.
  2. В большинстве случаев информация на дисплее отображается непрерывно. Доработайте функцию Show() таким образом, чтобы не надо было каждый раз перед ее вызовом очищать дисплей
  3. Добавьте любой дополнительный символ, который может быть отображен на индикаторе. Например H, Г, А и так далее.

Остальные статьи цикла можно найти здесь.

Мы будем очень рады, если вы поддержите наш ресурс и посетите магазин наших товаров shop.customelectronics.ru.

Метки: , , , , Просмотров: 16170