Подключение 4-х разрядного семисегментного индикатора

oliverm
Offline
Зарегистрирован: 06.10.2016

Здравствуйте, уважаемы форумчане!

Я у вас тут новеньки, начинающий. В коде пока не особо разбираюсь, так что прошу помощи.

Есть семисегментник. К ардуино подцепил, работает прекрасно, но как всегда есть "но".

Код:


uint8_t buf[8] = { 0 }; // байт с информацией о «нажатой» клавише

void setup() 
{
  Serial.begin(9600); // Устанавливаем скорость соединения
  pinMode(2, OUTPUT); // G
  pinMode(3, OUTPUT); // F
  pinMode(4, OUTPUT); // E
  pinMode(5, OUTPUT); // D
  pinMode(6, OUTPUT); // C
  pinMode(7, OUTPUT); // B
  pinMode(8, OUTPUT); // A
  pinMode(9, OUTPUT); // D4
  pinMode(10, OUTPUT); // D3
  pinMode(11, OUTPUT); // D2
  pinMode(12, OUTPUT); // D1

// Так как модуль сегментных индикаторов имеет общий анод, то для того, чтобы 
// светился сегмент, вывод Arduino должно быть в высокоимпедансном состоянии 
// и наоборот

// Выключаем все сегменты:

  digitalWrite(12, HIGH);
  digitalWrite(11, HIGH);
  digitalWrite(10, HIGH);
  digitalWrite(9, HIGH);
  delay(2000); // Пауза, чтобы «клавиатура» успела определиться в системе
}

void loop() 
{
  int dig1, dig2, dig3, dig4; // Цифры, которые будут последовательно вводиться
  int keys[10] = { 39, 30, 31, 32, 33, 
  34, 35, 36, 37, 38 }; // Массив с ASCII кодами цифер от 0 до 9 соответственно

// Перебор с 0000 до 9999:

  for(dig1=0; dig1<10; dig1++)
  {
    for(dig2=0; dig2<10; dig2++)
    {
      for(dig3=0; dig3<10; dig3++)
      {
        for(dig4=0; dig4<10; dig4++)
        {
          pressKey(keys[dig1]);
          pressKey(keys[dig2]);
          pressKey(keys[dig3]);
          pressKey(keys[dig4]);
          pressKey(40); // Клавиша Enter

// Текущий пароль будет отображаться в течение примерно 15-ти секунд (чуть больше времени задержки ввода)

          for(int i=0; i<1200; i++)
          {
            digLED(12, dig1);
            digLED(11, dig2);
            digLED(10, dig3);
            digLED(9, dig4);
          }
        }
      }
    }
  }
}

void pressKey(int dig) // Функция ввода
{
  buf[2] = dig;
  Serial.write(buf, 8); // Нажать клавишу
  buf[0] = 0;
  buf[2] = 0;
  delay(20);
  Serial.write(buf, 8); // Отпустить клавишу
  delay(300);
}

// Возможно, существуют библиотеки для сегментных индикторов, но мне не захотелось с ними разбираться, 
// поэтому набросал свой алгоритм обхода сегментов индикатора

void digLED(int pin, int dig) // Функция отображения цифер на индикаторе
{
  digitalWrite(pin, LOW);
  switch(dig)
  {
  case 0:
    digitalWrite(8, LOW);
    digitalWrite(7, LOW);
    digitalWrite(6, LOW);
    digitalWrite(5, LOW);
    digitalWrite(4, LOW);
    digitalWrite(3, LOW);
    digitalWrite(2, HIGH);
    break;
  case 1:
    digitalWrite(8, HIGH);
    digitalWrite(7, LOW);
    digitalWrite(6, LOW);
    digitalWrite(5, HIGH);
    digitalWrite(4, HIGH);
    digitalWrite(3, HIGH);
    digitalWrite(2, HIGH);
    break;
  case 2:
    digitalWrite(8, LOW);
    digitalWrite(7, LOW);
    digitalWrite(6, HIGH);
    digitalWrite(5, LOW);
    digitalWrite(4, LOW);
    digitalWrite(3, HIGH);
    digitalWrite(2, LOW);
    break;
  case 3:
    digitalWrite(8, LOW);
    digitalWrite(7, LOW);
    digitalWrite(6, LOW);
    digitalWrite(5, LOW);
    digitalWrite(4, HIGH);
    digitalWrite(3, HIGH);
    digitalWrite(2, LOW);
    break;
  case 4:
    digitalWrite(8, HIGH);
    digitalWrite(7, LOW);
    digitalWrite(6, LOW);
    digitalWrite(5, HIGH);
    digitalWrite(4, HIGH);
    digitalWrite(3, LOW);
    digitalWrite(2, LOW);
    break;
  case 5:
    digitalWrite(8, LOW);
    digitalWrite(7, HIGH);
    digitalWrite(6, LOW);
    digitalWrite(5, LOW);
    digitalWrite(4, HIGH);
    digitalWrite(3, LOW);
    digitalWrite(2, LOW);
    break;
  case 6:
    digitalWrite(8, LOW);
    digitalWrite(7, HIGH);
    digitalWrite(6, LOW);
    digitalWrite(5, LOW);
    digitalWrite(4, LOW);
    digitalWrite(3, LOW);
    digitalWrite(2, LOW);
    break;
  case 7:
    digitalWrite(8, LOW);
    digitalWrite(7, LOW);
    digitalWrite(6, LOW);
    digitalWrite(5, HIGH);
    digitalWrite(4, HIGH);
    digitalWrite(3, HIGH);
    digitalWrite(2, HIGH);
    break;
  case 8:
    digitalWrite(8, LOW);
    digitalWrite(7, LOW);
    digitalWrite(6, LOW);
    digitalWrite(5, LOW);
    digitalWrite(4, LOW);
    digitalWrite(3, LOW);
    digitalWrite(2, LOW);
    break;
  case 9:
    digitalWrite(8, LOW);
    digitalWrite(7, LOW);
    digitalWrite(6, LOW);
    digitalWrite(5, LOW);
    digitalWrite(4, HIGH);
    digitalWrite(3, LOW);
    digitalWrite(2, LOW);
    break;
  }
  delay(3);
  digitalWrite(pin, HIGH);
}

Индикатор с общим катодом (код под общий анод), соответственно поменял значения HIGH на LOW и наоборот. Подключил, и вместо ожидаемого результата (а должен он показывать значения начиная с 0000 до 9999) получилось так, что на всех сегментах загорается одинаковое число. Считалка идет так : 1111, 2222 и т.д. Потом снова по кругу. Код взят из статьи про брутфорс, индикатор там был модульный, с матричной разводкой и отдельным пином под питание. У меня же обычный 12-пиновый. Что нужно поменять в этом коде, чтобы все заработало так, как задумывалось?

Заранее огромное спасибо всем ответившим. 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Что-то я не понял, Вы бы как-то понятнее объяснили. Он у Вас

oliverm пишет:

работает прекрасно

или

oliverm пишет:

Считалка идет так : 1111, 2222 и т.д. Потом снова по кругу.

Как-то одновременно эти два высказывания не могут быть истинными.

Так как?

 

 

oliverm
Offline
Зарегистрирован: 06.10.2016

Т.е. все сегменты горят. Выразился не так.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Ну, в общем, комментарием в строке 19 про "высокоимпедансное" состояние Вы изоядно повеселили. Постарайтесь не употреблять слов, значения которых не знаете.

А по сути, динамическая индикация делается не совсем так. Вернее, совсем не так.

Вот Вы можете объяснить словами что именно Вы делаете? Попробуйте описать. Просто словами.

oliverm
Offline
Зарегистрирован: 06.10.2016

Все дело в том, что код не мой. Взят из статьи на хабре. Сам в кодостроении профан. Если бы знал, как заставить эту схему "шуршать" как надо - думаю, сюда не обратился бы. Вкратце - контроллер сейчас эмулирует клавиатуру. Нужно сделать так, чтобы в момент ввода числа на компьютере, на индикаторе отображалось вводимое число. Т.е. как я понял нужно штудировать статьи про динамическую индикацию? Или есть какие-то готовые скетчи с таким принципом работы?

З.Ы. - Просто одни очень нехорошие люди залочили мак. Нужен для работы, поэтому пытаюсь вот таким вот образом осуществить перебор паролей. В сервис обращаться жаба душит, да и ближайший в 300 километрах от дома.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

В общем, вот в этой теме, я другому новичку, наверное с пару недель рассказывал как работать с динамической индикацией. Сначала в простейшем случае. потом дошли до использования таймеров (с апрвилами их расчёта) и виртуальных экранов. Причём обсуждалась и схема и программа. Почитайте. Букв там много, но это полезно. Например, он там по ходу задавал вопросы. которые наверняка и у Вс возникнут. Думаю, прочитав ту тему, как-нибудь разберётесь.

oliverm
Offline
Зарегистрирован: 06.10.2016

Огромное Вам спасибо!

oliverm
Offline
Зарегистрирован: 06.10.2016

Добрый день, Евгений! 

Читал я тему. Понял то, что ничего не понял. Видимо, для меня это темный лес. Скетч с "Велосипедом" под 4 разряда переделать только смог. Времени свободного как такового нет, да и домашний ноутбук в вечных разъездах. Если немного видоизменить код с велосипедом - заработает? И как это реализовать?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Так велосипед у Вас работает?

Там ведь есть функция putNumber, которая позволяет любое число выводить. Она там в строке 146 используется. Так что можете выводить числа, а не только педали крутить.

А в чём Вам нужна переделка?

oliverm
Offline
Зарегистрирован: 06.10.2016

Нужно, чтобы он выполнял те же функции, что и код в начале темы. Т.е. последовательно вводил числа от 0000 до 9999 с интервалом в 15 секунд и, соответственно, отображал вводимое число на индикаторе. Как я понял, в исходном коде за это отвечает часть:

// Перебор с 0000 до 9999:

  for(dig1=0; dig1<10; dig1++)
  {
    for(dig2=0; dig2<10; dig2++)
    {
      for(dig3=0; dig3<10; dig3++)
      {
        for(dig4=0; dig4<10; dig4++)
        {
          pressKey(keys[dig1]);
          pressKey(keys[dig2]);
          pressKey(keys[dig3]);
          pressKey(keys[dig4]);
          pressKey(40); // Клавиша Enter

// Текущий пароль будет отображаться в течение примерно 15-ти секунд (чуть больше времени задержки ввода)

          for(int i=0; i<1200; i++)
          {
            digLED(12, dig1);
            digLED(11, dig2);
            digLED(10, dig3);
            digLED(9, dig4);
          }
        }
      }
    }
  }
}

void pressKey(int dig) // Функция ввода
{
  buf[2] = dig;
  Serial.write(buf, 8); // Нажать клавишу
  buf[0] = 0;
  buf[2] = 0;
  delay(20);
  Serial.write(buf, 8); // Отпустить клавишу
  delay(300);
}

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Ну, так и делайте

for (int n = 0; n < 10000; n++) {
    pressKey(n / 1000); // cамая старшая (левая) цифра)
    pressKey((n / 100) % 10); // Вторая цифра слева
    pressKey((n / 10) % 10); // Третья цифра слева
    pressKey(n % 10); // Самая правая цифра
    putNumber(n); // Показ числа на индикаторе
}

Вроде, больше ничего не надо. Фунцкия putNumber определена в скетче велосипеда.

oliverm
Offline
Зарегистрирован: 06.10.2016

Здесь? Для вывода тысяч нужно что? Или можно её упростить? 

// Функция разделяет число на сотни, десятки и единицы и складывает в массив масок
//	сотни в позицию 2
//	десятки в позицию 1
//	единицы в позицию 0
//
void putNumber(const unsigned number) {
	static const uint8_t allDigits[] = { D0, D1, D2, D3, D4, D5, D6, D7, D8, D9 }; 
	div_t divRes = div(number, 100);
	putMask(allDigits[divRes.quot], 2);
	divRes = div(divRes.rem, 10);
	putMask(allDigits[divRes.quot], 1);
	putMask(allDigits[divRes.rem], 0);
}

И в каком месте кода её расположить? Будет ли 15-секундная задержка? Прошу прощения за такое количесвто вопросов.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Не, ну саму функцию-то не трогайте, она нормальная.

Вы мне не ответили на ворос, у Вас велосипед работает? Мне надо от чего-то отталкиваться.

Он (велосипед) вообще-то на трёхразрядный индикатор, а у Вас четырёхразрядный, Вы его уже переделали, он работает?

oliverm
Offline
Зарегистрирован: 06.10.2016

Велосипед работает на последних трех разрядах. На первом постоянно горит средний сегмент и мерцают верхний и нижний. 

oliverm
Offline
Зарегистрирован: 06.10.2016

Евгений! Дико извиняюсь что отнял часть Вашего времени. Всё оказалось куда проще, чем казалось на первый взгляд. В коде, который я изначально скидывал, я допустил одну ошибку. А именно:

// Возможно, существуют библиотеки для сегментных индикторов, но мне не захотелось с ними разбираться, 
// поэтому набросал свой алгоритм обхода сегментов индикатора

void digLED(int pin, int dig) // Функция отображения цифер на индикаторе
{
  digitalWrite(pin, LOW);
  switch(dig)
  {
  case 0:
    digitalWrite(8, HIGH);
    digitalWrite(7, HIGH);
    digitalWrite(6, HIGH);
    digitalWrite(5, HIGH);
    digitalWrite(4, HIGH);
    digitalWrite(3, HIGH);
    digitalWrite(2, LOW);
    break;
  case 1:
    digitalWrite(8, LOW);
    digitalWrite(7, HIGH);
    digitalWrite(6, HIGH);
    digitalWrite(5, LOW);
    digitalWrite(4, LOW);
    digitalWrite(3, LOW);
    digitalWrite(2, LOW);
    break;
  case 2:
    digitalWrite(8, HIGH);
    digitalWrite(7, HIGH);
    digitalWrite(6, LOW);
    digitalWrite(5, HIGH);
    digitalWrite(4, HIGH);
    digitalWrite(3, LOW);
    digitalWrite(2, HIGH);
    break;
  case 3:
    digitalWrite(8, HIGH);
    digitalWrite(7, HIGH);
    digitalWrite(6, HIGH);
    digitalWrite(5, HIGH);
    digitalWrite(4, LOW);
    digitalWrite(3, LOW);
    digitalWrite(2, HIGH);
    break;
  case 4:
    digitalWrite(8, LOW);
    digitalWrite(7, HIGH);
    digitalWrite(6, HIGH);
    digitalWrite(5, LOW);
    digitalWrite(4, LOW);
    digitalWrite(3, HIGH);
    digitalWrite(2, HIGH);
    break;
  case 5:
    digitalWrite(8, HIGH);
    digitalWrite(7, LOW);
    digitalWrite(6, HIGH);
    digitalWrite(5, HIGH);
    digitalWrite(4, LOW);
    digitalWrite(3, HIGH);
    digitalWrite(2, HIGH);
    break;
  case 6:
    digitalWrite(8, HIGH);
    digitalWrite(7, LOW);
    digitalWrite(6, HIGH);
    digitalWrite(5, HIGH);
    digitalWrite(4, HIGH);
    digitalWrite(3, HIGH);
    digitalWrite(2, HIGH);
    break;
  case 7:
    digitalWrite(8, HIGH);
    digitalWrite(7, HIGH);
    digitalWrite(6, HIGH);
    digitalWrite(5, LOW);
    digitalWrite(4, LOW);
    digitalWrite(3, LOW);
    digitalWrite(2, LOW);
    break;
  case 8:
    digitalWrite(8, HIGH);
    digitalWrite(7, HIGH);
    digitalWrite(6, HIGH);
    digitalWrite(5, HIGH);
    digitalWrite(4, HIGH);
    digitalWrite(3, HIGH);
    digitalWrite(2, HIGH);
    break;
  case 9:
    digitalWrite(8, HIGH);
    digitalWrite(7, HIGH);
    digitalWrite(6, HIGH);
    digitalWrite(5, HIGH);
    digitalWrite(4, LOW);
    digitalWrite(3, HIGH);
    digitalWrite(2, HIGH);
    break;
  }
  delay(3);
  digitalWrite(pin, HIGH);
}

В этой части кода абсолютно все значения LOW и HIGH поменял на противоположные. Как теперь понял - не нужно было трогать digitalWrite (pin, LOW) и digitalWrite (pin, HIGH) в начале и в конце. В оригинальном коде значения стояли HIGH и LOW соответственно. Поменял - и все заработало. И все равно огромное Вам спасибо! Подогрели интерес к Arduino.) 

oliverm
Offline
Зарегистрирован: 06.10.2016

Последний вопрос: Какие резисторы ставить на индикатор? Везде пишут по-разному. Где-то номиналом 100 Ом, где-то 1кОм, где-то только на пины разрядов, а где-то на все пины. Вы бы что посоветовали? Светодиоды на индикаторе красного цвета.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016
ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Но Вы не обльщайтесь. Работать это будет криво. Ни с того, ни с сего будет мерцать экран. Хотите нормально - делайте через таймеры, дожмите велосипед, например.

Про резисторы. Я что-то не помню Вашей схемы. Давайте схему - поговорим о резисторах.

Там есть два типа резисторов - персональные на каждый сегмент. И резисторы в базах транзисторов, которые стоят на цифрах (надеюь, у Вас стоят транзисторы на цифрах?) Вас какие резисторы иетерсуют? Ну, и схему давайте.

oliverm
Offline
Зарегистрирован: 06.10.2016

Сейчас счетчик до 100 прогнал - мерцаний пока не заметил. Схемы, в принципе нет. Сразу с выходов ардуино на индикатор. Думаю, за это меня отругают.)

P.S. - числа на индикаторе меняются так: 0000 => Гаснет => 0001 => Гаснет и т.д. По сути мне сейчас нужно ардуино не спалить и индикатор.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

У вас самый большой минус программы. Ардуина работает только на индикатор. А вот если вы захотите сделать какое-то устройство, то будут траблы. Отображение должно быть или реализовано аппаратно, или программно в фоне. И повесте резисторы на a,b,c ...h -  100 ом -1к

oliverm
Offline
Зарегистрирован: 06.10.2016

Мне пока только это и нужно. Плюсом клавиатуру эмулирует, что как раз подходит для моей задачи.) Резисторы только на сегменты вешать? На разряды не нужны?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

oliverm пишет:
Сразу с выходов ардуино на индикатор.

Что цифры (общие выводы) идут прямо на ноги ардуины?

oliverm пишет:
По сути мне сейчас нужно ардуино не спалить и индикатор.
Если ещё жива, то это временно и на очень непродолжительное время. Немедленно прекращайте опыты, скачивайте книгу и изучайте схему на странице 9 слева.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

oliverm пишет:
Мне пока только это и нужно. Плюсом клавиатуру эмулирует, что как раз подходит для моей задачи.) Резисторы только на сегменты вешать? На разряды не нужны?

Как, у Вас вообще никаких нет? Блин, стойкая Вам ардуина попадась. Другая бы давно сдохла.

Что делать я Вам сказал в прошлом посте.

oliverm
Offline
Зарегистрирован: 06.10.2016

Резисторы нашёл на 100 Ом и на 1 кОм. По десятку каждых набралось.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Написал тоже свою программу. Но у меня видно бракованый индикатор, пришлось ужать до одиночного. Он у меня оказался.

/*  4 разрядный 7сегметный индикатор  SH5461AS
    12-D3 11-a 10-f  9-D2 8-D1 7-b
    1-e   2-d  3-dp 4-c  5-g  6-D0
11 - a ( a_pin) 1 горит 0 нет
7  - b ( b_pin)
4  - c ( c_pin)
2  - d ( d_pin)
1  - e ( e_pin)
10 - f ( f_pin)
5  - g ( g_pin)
3  - dp(dp_pin)

6  -D0 (D0_pin) 0 горит 1 нет
8  -D1 (D1_pin)
9  -D2 (D2_pin)
12 -D3 (D3_pin)

*/
//#1
uint8_t Count; // счетчик
//#2
const int e_pin =2 ;//  нога 1 SH5461AS
const int d_pin =3 ;//  нога 2 SH5461AS
const int dp_pin=4 ;//  нога 3 SH5461AS
const int c_pin =5 ;//  нога 4 SH5461AS 
const int  g_pin=6 ;//  нога 5 SH5461AS
const int D0_pin=7 ;//  нога 6 SH5461AS

const int D3_pin=8 ;//  нога 12 SH5461AS
const int a_pin =9 ;//  нога 11 SH5461AS 
const int f_pin =10;//  нога 10 SH5461AS
const int D2_pin=11;//  нога 9 SH5461AS
const int D1_pin=12;//  нога 8 SH5461AS
const int b_pin =13;//  нога 7 SH5461AS

// Вывод числа на экран
void WriteNumber(int Number) {
  WriteNumberToSegment(0 , Number / 1000);
  WriteNumberToSegment(1 , (Number / 100) % 10);
  WriteNumberToSegment(2 , (Number / 10) % 10);
  WriteNumberToSegment(3 , Number % 10);
}
// запись нужного числа (0-9) в нужную позицию(1-4) 
void WriteNumberToSegment(byte Segment, byte Value){
   Out_segment(Segment);
   Out_Number(Value);
}
// матрица выбора знакоместа 1 to 4 
const byte SEGMENT_SELECT[] = {
B11110111, // D4
B11111011, // D2
B11111101, // D1
B11111110};// D0
void Out_segment(byte Segment){
  digitalWrite(D0_pin,SEGMENT_SELECT[Segment]&0x08); 
  digitalWrite(D1_pin,SEGMENT_SELECT[Segment]&0x04); 
  digitalWrite(D2_pin,SEGMENT_SELECT[Segment]&0x02); 
  digitalWrite(D3_pin,SEGMENT_SELECT[Segment]&0x01); 
}
// матрица цифр 0 to 9 
const byte SEGMENT_MAP[] = {
B00111111,// 0
B00000110,//1
B01011011,//2
B01001111,//3
B01100110,//4
B01101101,//5
B01111100,//6
B00000111,//7
B01111111,//8
B01100111};//9
void Out_Number(byte Number){
  digitalWrite(dp_pin,SEGMENT_MAP[Number]&0x80);
  digitalWrite(g_pin,SEGMENT_MAP[Number]&0x40);
  digitalWrite(f_pin,SEGMENT_MAP[Number]&0x20);
  digitalWrite(e_pin,SEGMENT_MAP[Number]&0x10);
  digitalWrite(d_pin,SEGMENT_MAP[Number]&0x08);
  digitalWrite(c_pin,SEGMENT_MAP[Number]&0x04);
  digitalWrite(b_pin,SEGMENT_MAP[Number]&0x02);
  digitalWrite(a_pin,SEGMENT_MAP[Number]&0x01); 
  }
void setup() {
  //#1
  Count = 0;
  //#2
  pinMode(a_pin, OUTPUT);
  pinMode(b_pin, OUTPUT);
  pinMode(c_pin, OUTPUT);
  pinMode(d_pin, OUTPUT);
  pinMode(e_pin, OUTPUT);
  pinMode(f_pin, OUTPUT);
  
  pinMode(D0_pin, OUTPUT);
  pinMode(D1_pin, OUTPUT);
  pinMode(D2_pin, OUTPUT);
  pinMode(D3_pin, OUTPUT);
  pinMode( g_pin, OUTPUT);
  pinMode(dp_pin, OUTPUT);
}

void loop() {
  static uint32_t MILLIS ;
  MILLIS = millis() ;  
 //#1   100 милисек счетчик
  static uint32_t future1 = 0 ;
  if (MILLIS >= future1)   {
  future1 = MILLIS + 100 ;
  Count++;
  if(Count > 9999) Count = 0;
  }
 //#2
 WriteNumber(Count);
}

ПС: Может кому-то поможет.

А вот для одиночного

/* 7сегметный индикатор 5161as
10-g 9-f 8-D0 7-a 6-b
 1-e 2-d 3-D0 4-c 5-dp
5161as a ( a_pin) 1 горит 0 нет
       b-> ( b_pin)
       c->4 ( c_pin)
       d->3 ( d_pin)
       e->2 ( e_pin)
       f->7 ( f_pin)
       g->6 ( g_pin)
       dp->5(dp_pin)
      D0 ->GND 
*/
//#1
uint8_t Count; // счетчик
//#2
const int e_pin =2 ;//  нога 1 5161AS
const int d_pin =3 ;//  нога 2 5161AS
const int c_pin =4 ;//  нога 4 5161AS 
const int dp_pin=5 ;//  нога 5 5161AS
const int  g_pin=6 ;//  нога 10 5161AS
const int f_pin =7 ;//  нога 9  5161AS
const int a_pin =8 ;//  нога 7  5161AS
const int b_pin =9 ;//  нога 6  5161AS
// матрица цифр 0 to 9 
const byte SEGMENT_MAP[] = {
B00111111,// 0
B00000110,//1
B01011011,//2
B01001111,//3
B01100110,//4
B01101101,//5
B01111100,//6
B00000111,//7
B01111111,//8
B01100111};//9
void Write_Number(byte Value){
  digitalWrite(dp_pin,SEGMENT_MAP[Value]&0x80);
  digitalWrite(g_pin ,SEGMENT_MAP[Value]&0x40);
  digitalWrite(f_pin ,SEGMENT_MAP[Value]&0x20);
  digitalWrite(e_pin ,SEGMENT_MAP[Value]&0x10);
  digitalWrite(d_pin ,SEGMENT_MAP[Value]&0x08);
  digitalWrite(c_pin ,SEGMENT_MAP[Value]&0x04);
  digitalWrite(b_pin ,SEGMENT_MAP[Value]&0x02);
  digitalWrite(a_pin ,SEGMENT_MAP[Value]&0x01); 
  }
void setup() {
    //#1
  Count = 0;
  //#2
  pinMode(a_pin, OUTPUT);
  pinMode(b_pin, OUTPUT);
  pinMode(c_pin, OUTPUT);
  pinMode(d_pin, OUTPUT);
  pinMode(e_pin, OUTPUT);
  pinMode(f_pin, OUTPUT);
  pinMode( g_pin, OUTPUT);
  pinMode(dp_pin, OUTPUT);
}

void loop() {
    static uint32_t MILLIS ;
  MILLIS = millis() ;  
 //#1   500 милисек счетчик
  static uint32_t future1 = 0 ;
  if (MILLIS >= future1)   {
  future1 = MILLIS + 500 ;
  Count++;
  if(Count > 9) Count = 0;
  }
 //#2
 Write_Number(Count);
}