динамическая индикация 7 сегментов

0259
0259 аватар
Offline
Зарегистрирован: 30.03.2014

Всем пирвет если что то не так прошу прошения 

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

сейчас у меня высвечивается дублирования цыфра на обоих разрядах я понимаю что нужно выключить один высвитить цыфру выключить включеный и включить другой но как это сделать програмно? помогите схем много видил и находил но двух сдвиговых регистров у меня у вы нет в наличии купить тоже нет возможности!

примерная схема


int data = 2;
int clock = 3;
int G1 = 4;
int G2 = 5;

void setup() {
  Serial.begin(9600);
 pinMode(data,OUTPUT);
 pinMode(clock,OUTPUT);
 pinMode(4,OUTPUT);
 pinMode(5,OUTPUT);
 digitalWrite(4,HIGH);
 digitalWrite(5,HIGH);
}

// digit 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
byte z[]={B001000,B1101110,B0010010,
          B0100010,B1100100,B0100001,
          B000001,B1101010,B000000,B0100000};

void loop() {

    for (byte i=0;i<10;i++) {
      
      shiftOut(data, clock, MSBFIRST, z[i]);
      
      delay(10);
      Serial.println("i");
      Serial.print(i);

    }
}

 

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

Вам нужно настроить один из тамеров счётчиков, чтобы от "тикал" с частотой 100Гц (тогда весь экран будет обновляться с частотой 50Гц 0 этого достаточно, чтобы цифры не "дёргались"). В программе обработки прерывания таймера Вам нужно переключать цифру (т.е. гасить текущую и включать другую).

Какой таймер настраивать - зависит от остальной Вашей програмы, т.к. некоторые библиотеки используют таймеры и ШИМ на ногах от них зависит.

Как настраивать таймер, тут много материалов, ну, например, вот здесь.

Если совсем не хочется занимать под это дело целый таймер, можно немного попаразитировать на нулевом таймере, который используется millis. Как это сделать написано вот здесь.

Не ведитесь на советы обойтись без таймеров вовсе (всё в loop через milli). При таком подходе каждый глупый delay или просто долговатое исполнение loop будет ломать Ваш экран.

Удачи!

Да, кстати, имейте в виду,есть такая микросхема MAX7219 - она сама делает динамическую индикацию до 8 знаков (если одна). От Вас требуется только сказать ей что показывать на экране.

0259
0259 аватар
Offline
Зарегистрирован: 30.03.2014

ЕвгенийП пишет:

Вам нужно настроить ...

спасибо буду читать!

 

0259
0259 аватар
Offline
Зарегистрирован: 30.03.2014

вот что написал я. работает! только опять же как применить!


int data = 4;
int clock = 5;
int G1 = 6;
int G2 = 7;


void setup() {
  Serial.begin(9600);
 pinMode(data,OUTPUT);
 pinMode(clock,OUTPUT);
 pinMode(6,OUTPUT);
 pinMode(7,OUTPUT);
 digitalWrite(6,HIGH);
 digitalWrite(7,HIGH);

}

// digit 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
byte z[]={B001000,B1101110,B0010010,
          B0100010,B1100100,B0100001,
          B000001,B1101010,B000000,B0100000,B1111111};

void loop() {
  
    for (byte i=0;i<2;i++) {
      if(i==0){digitalWrite(6,LOW); digitalWrite(7,HIGH);a = 0;}/// первая цифра
      if(i==1){digitalWrite(6,HIGH); digitalWrite(7,LOW);a = 2;}/// вторая цифра

      
      
      shiftOut(data, clock, MSBFIRST, z[a]);
      
    
      delay(10);
      
     

    }

}

отображается дез мерцаний и коректно

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

0259 пишет:

отображается дез мерцаний и коректно

Ну, это то, о чём я писал - любая задержка в loop всё сломает. Для демонстрации - нормально, а для практики - только если контроллер используется исключительно для дисплея и ни для чего больше. Нет, надо на таймерах делать.

0259
0259 аватар
Offline
Зарегистрирован: 30.03.2014

читаю спатью пока не понятно но ве равно буду перечитывать пока не дойдет! а в обшем идея такая 

2 независимых табло и 2 независимих счетчика на одном контролере

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

Ну, во-первых, надеюсь Вы знаете, что красных линиях должны стоять транзисторы - Вы их просто для простоты опустили, так? А в чёрных линиях (от сдвигового регистра к сегментам) нужны токоограничивающие резисторы - в каждой линии.

Во втоорых, по мне, Вы выбрали неудачную микросхему. По нескольким причинам.

1.
Посмотрите таблицу 7 даташита. Максимальный ток на каждый канал вроде и 25ma, но при этом на все каналы сразу - только 50mA! Т.е. Вы не можете превышать 50mA на весь регистр. Что это значит? Это значит, что Вы должны ограничить ток через каждый сегмент индикатора 6мА (тогда, если Вы включите "8.", то суммарный ток будет как раз 48мА). При токе в 6мА они и при статической индикации светятся тусклее, чем при оптимальном токе (20мА на сегмент), а уж при динамической и подавно. Это можно обойти, если на каждый сегмент поставить по транзистору (с парой резисторов обвязки) или надо ставить микросхему - "массив транзисторов" - Вам это надо?

2.
При использовании этой микросхемы Вам потребуется ставить по резистору на каждый сегмент для ограничения тока. Обязательно и никуда Вы от этого не денетесь. Нет, в сети полно примеров и без резисторов, но ... в общем, я не буду ругаться. Для примера это поработает, но не очень долго.

3.
Ну, и от транзисторов на "красных линиях" Вы никуда не денетесь.

Для Вашей задачи гораздо лучше подойдёт TLC5940. С ней Вы можете делать 2-разрядный индикатор БЕЗ динамической индикации вообще! Он поддерживает до 16 светодиодов, так что Вы может включить всё со статической индикацией на оптимальные 20мА/сегмент - никаких проблем. При этом, кроме самой микросхемы нужен только один резистор (ну и конденсатор для фильтра питания). Никаких транзисторов - всё уже есть. Ну, если хочется, чтобы при включении питания дисплей не мигал, то ещё один резистор. Если надо "два по два" (как Вы написали) поставьте две TLC5940.

При использовании TLC5940 Вы автоматом получаете дополнительный бонус - возможность менять яркость сввечния экрана (например, в темноте стандартная яркость глаза режет) и даже возможность менять яркость индивидуальных сегментов (обычно точку немного понижают).

Да, "стандартная" библиотека для TLC5940 больно "кучеряво живёт" и занимает аж два таймера. Но это не беда, я здесь уже писал как можно умерить её аппетиты.

0259
0259 аватар
Offline
Зарегистрирован: 30.03.2014

я расчитал печатку сделал её по фен - шуй все нормально индикатор работает!

и токоограничеваюшие резисторы стояи и транзисторы на катодах стоят даже ток колектора транзистора ограничел если хотите скину печатку со всем расчетом только печатать её придется фото резистором оно все под SMD дело в том что у меня нет других микросхем самая ближайшая только эта заказывать слишком долго по вашей статье я понял что я не смогу запустить два индикатора так как у ардуины всего 3 таймера два можно отключить так как они нужны для шим а вот третий системный трудность в том что один из каймеров занимает третий пин какраз тот который идет на прерывания а им я пожертвовать не могу

0259
0259 аватар
Offline
Зарегистрирован: 30.03.2014
///////////////////////////////////////////////////////////////////////////////////////////
// Право использования ПО:данный код не для коммерческого использования                   //
// Автор: Колесников Дмитрий Владимирович                                                //
// Цель создания ПО:                                                                     //
// Название программы:                                                                   //
// Контактные данные: 0259@list.ru                                                       //
///////////////////////////////////////////////////////////////////////////////////////////

int data = 4;
int clock = 5;
int G1 = 6;
int G2 = 7;
int a = 0;
int b = 0;
int c = 0;

void setup() {
 Serial.begin(9600);
 pinMode(data,OUTPUT);
 pinMode(clock,OUTPUT);
 pinMode(6,OUTPUT);
 pinMode(7,OUTPUT);
 digitalWrite(2,HIGH);
 digitalWrite(3,HIGH);
}

// digit 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
byte z[]={B001000,B1101110,B0010010,
          B0100010,B1100100,B0100001,
          B000001,B1101010,B000000,B0100000,B1111111};

void loop() {
  
    for (byte i=0;i<2;i++) {
      if(i==0){digitalWrite(6,LOW); digitalWrite(7,HIGH);
      if(c==0){a = 0;}
      if(c==1){a = 1;} 
      if(c==2){a = 2;} 
      if(c==3){a = 3;} 
      if(c==4){a = 4;} 
      if(c==5){a = 5;}
      if(c==6){a = 6;} 
      if(c==7){a = 7;} 
      if(c==8){a = 8;} 
      if(c==9){a = 9;}
      }/// первая цифра
      if(i==1){digitalWrite(6,HIGH); digitalWrite(7,LOW); 
      if(b==0){a = 0;}
      if(b==1){a = 1;} 
      if(b==2){a = 2;} 
      if(b==3){a = 3;} 
      if(b==4){a = 4;} 
      if(b==5){a = 5;}
      if(b==6){a = 6;} 
      if(b==7){a = 7;} 
      if(b==8){a = 8;} 
      if(b==9){a = 9;} 
      }/// вторая цифра

      
      
      shiftOut(data, clock, MSBFIRST, z[a]);
      
    
      delay(10);
      
     

    }
    attachInterrupt(0, step1, CHANGE);
    attachInterrupt(1, step2, CHANGE);
}

void step1(){
 int bt = 0;
 int bt_old = 0;
 bt = digitalRead(2);
 if (bt != bt_old){bt = bt_old; b++; if(b == 10){c=c+1; b = 0;}}
 delay(10);
  Serial.println(b);
}

void step2(){

}

вот счетчик! готов но пока только на один дисплей!

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

0259 пишет:

по вашей статье я понял что я не смогу запустить два индикатора так как у ардуины всего 3 таймера 

Почему не сможете? Ещё как сможете, хоть три! И даже вовсе не занимая таймеров.

Делаете как статье про метроном без занимания таймеров, а в функции-обработчике спокойно обрабатываете оба дисплея, кто Вам не даёт-то? Никаких проблем.

 

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

0259 пишет:

вот счетчик! готов но пока только на один дисплей!

Ой!

1. А зачем attachInterrupt? Вы что его чем-то внешним тактируете?

2. Два-то зачем? КТо мешает оба дисплея обновить в одной функции, у них же одинаковая частота обновления!

3. Ну и наконец, зачем attachInterrupt в loop - достаточно один раз его приаттачить - зачем это делать постоянно?

 

0259
0259 аватар
Offline
Зарегистрирован: 30.03.2014

у меня два счетчика которые тактируются внешне от магнитного датчика

датчиков два контролер один все из за того что нет возможности ждать микрухи

а вот за атач спасибо ошибся не пользовался я им давно

так сказать делаю из того что есть на даный момент потому что нужен срочно 

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

Всё же, вместо строк 34-69, сделайте через нулевой таймер, ну несолидно это, неправильно :)

0259
0259 аватар
Offline
Зарегистрирован: 30.03.2014

ок сейчас займемся! попробую все версии а таймер наверно я еще много где применю это же уже не язвк ардуино!?

это ближе к си!? мне нравится ваша статья есть то что я совсем не знал хочу потом перейти на чистые аврки а так пока ардуино

andrey14
Offline
Зарегистрирован: 19.04.2015

ЕвгенийП пишет:
Для Вашей задачи гораздо лучше подойдёт TLC5940.

Или MAX7219.

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

andrey14 пишет:

ЕвгенийП пишет:
Для Вашей задачи гораздо лучше подойдёт TLC5940.

Или MAX7219.

Про мах я ему уже писал в посте №1.

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

0259 вы когда нибудь замечали , что весь дисплей с компьютере выведен на отдельную видеокарту. Как вы думаете, почему? Наверно потому что в основной программе не нужен гембель с выводом на экран . Так и здесь. Или аппаратное решение. LCD 1602 или программное, вывод на динамическую индикацию организован независимым вычислительным потоком через millis() или прерывание. Для основной программы дисплей выглядит в виде массива - display[4]. А вот подпрограмма дисплея в нужный момент выдергивает от туда значение и выводит на экран.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

ЕвгенийП пишет:

Да, кстати, имейте в виду,есть такая микросхема MAX7219 - она сама делает динамическую индикацию до 8 знаков (если одна). От Вас требуется только сказать ей что показывать на экране.

А что посоветуете для высоковольтных индикаторов. Ну, тех, у которых большие цифры с тремя светодиодами последовательно и прямым напряжением около 8 вольт?

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

andriano пишет:

А что посоветуете для высоковольтных индикаторов. Ну, тех, у которых большие цифры с тремя светодиодами последовательно и прямым напряжением около 8 вольт?

Советовать не возьмусь, могу только сказать как бы поступил сам.

1.
Посмотрел бы на воторостепенные условия задачи и подумал бы о TLC5940 (у неё нагрузка может кушать до 17В), но надо смотреть токи и т.п.

2.
Почитал бы application note от Maxim Integrated об использовании той же MAX7219 для высоких напряжений и токов.

3.
Если бы решил делать на MAX7219, то делал бы не на рассыпухе, как там нарисовано, а на транзисторных массивах. Общая идея там ровно таже, но всё компактнее получается. Смысл поняен из картинки:

Источник картинки. Кстати, автор статьи предлагает купить у него готовую печатку для этого устройства меньше. чем за 10 баксов :)