Подключение семисегментного индикатора

avgustdon
Offline
Зарегистрирован: 28.02.2016


Добрый день.

Прошу помочь в такой ситуации. Нужно подключить семисегментный двухразрядный индикатор к ардуино уно через 74HC595.

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

Прошу помочь разобраться. Заранее благодарен.

 

 

#include <SPI.h> //подключаем библиотеку SPI

const int RCK = 7; //pin7 запись в вых.регистр 74НС595
char datr[9] = "1834 790"; //выводимые на индик. знаки
int i;
byte razr = 0;

void setup() {
pinMode(RCK, OUTPUT); // строб записи в парал.регистр
digitalWrite(RCK, LOW);
SPI.begin(); //иниц. SPI: "по умолчанию" нам подходит
SPI.transfer(0); //очистим регистр разрядов
SPI.transfer(0xff); //очистим регистр сегментов
digitalWrite(RCK, HIGH); //запись в вых.парал.регистр
digitalWrite(RCK, LOW);
}

void loop() {
for (i=0; i < 8; i++) { //один цикл развертки по всем разрядам
razr = 1 << i; //определяем "1" в нужный разряд
SPI.transfer(razr); //запись в регистр разряда
SPI.transfer(CodeSeven(datr[i])); //в регистр сегментов
digitalWrite(RCK, HIGH); //запись в вых.парал.регистр
digitalWrite(RCK, LOW);
delay(3); //время индикации одного разряда
}
}

//перекодировка символа в 7-сегментное представление
byte CodeSeven(char inv) {
byte rez;
switch (inv) {
case '0': rez = 0xc0; //"0" все светятся кроме G
break;
case '1': rez = 0xf9; //"1" светятся только B и С
break;
case '2': rez = 0xa4;
break;
case '3': rez = 0xb0;
break;
case '4': rez = 0x99;
break;
case '5': rez = 0x92;
break;
case '6': rez = 0x82;
break;
case '7': rez = 0xf8;
break;
case '8': rez = 0x80;
break;
case '9': rez = 0x90;
break;
default: rez = 0xff; //все иные символы - гашение
}
return rez;
}

 

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

1. Выложите код нормально, чтобы его можно было обсуждать (например, ссылаться на номера строк).

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

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

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

я просто напряжение питания регистров понизил до 3.3В через стабилизатор ams1117. светодиоды были белые и как раз с напряжением в районе 3,5В

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

avgustdon пишет:



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

А теперь осталось взять за основу код прилагающий к этой схеме. Но выводить не 8 разрядов , а только 2 нужные вам.

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

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

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

jeka_tm пишет:

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

Вот и я ж про то же :)

Можно и биполярники, но не "в лоб" же.

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

мне нужна была яркость. для семисегментного если устроит небольшая яркость можно и без транзисторов, а чтобы не перегрузить регистр разрядов ток не должен превышать 35ма. значит делим на 8 =4.375ма, округляем до 4. подать на светодиод 4ма и посмотреть достаточно ли будет такой яркости, яркость изза динамической индикации еще немного визуально уменьшится. если достаточно измерить какое напряжение было на светодиоде и питать таким регистры. но не менее 2В. как то так. мало яркости значит ставить транзисторы. но тут есть оговорка. регулируя напряжение питания регистров можно увеличить яркость и поднять ток, так как 35ма это максимальный постоянный ток, а импульсный и больше держит

nik182
Offline
Зарегистрирован: 04.05.2015

По даташиту http://www.nxp.com/documents/data_sheet/74HC_HCT595.pdf максимальный выходной ток ноги сегмента 35 мА. Как его можно перегрузить светодиодом матрицы? Например большой 45 мм индикатор http://www.chipdip.ru/product/sba18-11egwa/ допускае максимальный ток 30 ма, а светимость приводится при 10 мА. Ставим резистор 100 Ом на каждый сегмент и никаких перегрузок. Код, который тикакет раз в секунду от 0 до 99,  может быть таким:

byte Segments[10] = {
  0b01110111, 
  0b00010100, 
  0b10110011, 
  0b10110110, 
  0b11010100, 
  0b11100110, 
  0b11100111, 
  0b00110100, 
  0b11110111,
  0b11110110,
};

byte i,c,dataPin=3, clockPin=4,latchPin=5;
void setup() {
 i=0; 
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);

}

void loop() {
   digitalWrite(latchPin, LOW);
   c=i/10;
  shiftOut(dataPin, clockPin, MSBFIRST, Segments[c]);
  c=i % 10;
  shiftOut(dataPin, clockPin, MSBFIRST, Segments[c]);
  digitalWrite(latchPin, HIGH);
  i++;
  if (i>99) i=0;
 delay(1000);
}

Единички в Segments должны соответствовать вашей распайке регистр - индикатор.

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

nik182 пишет:

По даташиту http://www.nxp.com/documents/data_sheet/74HC_HCT595.pdf максимальный выходной ток ноги сегмента 35 мА. Как его можно перегрузить светодиодом матрицы? 

Два вопроса:

1) а каков (по томуже самому даташиту) максимальный ток всех ног вместе взятых? Ток через Vcc или Gnd?

2) Вы не заметили, что общие выводы разрядов у ТС тоже заведены на ноги 595? Каков будет ток этой ноги, если в разряде загорится цифра 8, да ещё и точка?

nik182
Offline
Зарегистрирован: 04.05.2015

По тому же даташиту суммарный ток 70 мА. Если в сегменты поставить 100 Ом резисторы, то суммарный ток будет как раз где-то около того, так как ток сегмета будет меньше 5 мА. У меня уже полгода работают часы на этих индикаторах. В них последовательно 2 диода на сегмент, падение на них около 3,5В и резисторы ставил по 50 Ом. На точки - один диод- по 120 Ом. Светятся ярко. Ничего не греется и не ломается.

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

Ну, это смотря что там за диоды. Если красные с падением 1.8, то на резисторе падает 3,2В. Максимальный ток на сегмент - 70/8 = 8,75. Значит резистор нужен 3,2 / 0,00875 - 366 Ом, а никак не 100 (кажется, ближайший по E24 - 390 Ом).

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

А что по второму моему вопросу? Тоже можно? Или таки транзисторы нужны?

Я не понимаю, что Вы пытаетесь доказать. Сбить ТС с толку?

nik182
Offline
Зарегистрирован: 04.05.2015

Я хочу сказать, что светодиоды приводятся в действие не напряжением, а током. Поэтому прямое подключение диода к ноге микросхемы это не правильный путь. Если очень хочется транзистор - пожалуйста, но по схеме стабилизатора тока. Прощё поставить резистор. Схема сама сбалансируется.

На счёт величины резистора, вы правы. Я погорячился со 100 омами.

Не перегрузится, если поставить резистор.

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

nik182 пишет:

Не перегрузится, если поставить резистор.

Простите, если Вы это о моём втором вопросе, то у меня твёрдое ощущение, что Вы не поняли о чём ресь. У ТС к ногам правого по схеме 595 поключены общие аноды разрядов! Какой ток пойдёт через этот общий анод, если на каждом сегменте скажем по 8мА, а всего сегментов 8! Как же он не перегрузится, если Ва сми писали - 35мА на ногу максимум!

MacSim
Offline
Зарегистрирован: 28.11.2012

бросьте эти сдвиговые, возьмите Max7219 будет качественнее и меньше гемора получите.

nik182
Offline
Зарегистрирован: 04.05.2015

Да. Если загрузить весь индикатор восьмёрками будут проблемы, ecли ток сегмента будет больше 4 mA. По транзистору на каждый анод решит проблему. Резисторы в катоды тоже нужны. Грузить цифры можно вордами через shiftout. Первый байт eдиничка в разряде, второй собственно число. И так 8 раз. И всё это в прерывании таймера раз в 20 мс.

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

nik182 пишет:
Да. Если загрузить весь индикатор восьмёрками будут проблемы, ecли ток сегмента будет больше 4 mA. По транзистору на каждый анод решит проблему. Резисторы в катоды тоже нужны.

Ну так вот именно это я написал ТС ещё в посте №1 и о чём мы тут дискутируем совершенно непонятно :)))

avgustdon
Offline
Зарегистрирован: 28.02.2016


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

Схема взята из первоисточника и там тоже подключена одним резистором на анод. И тоже сомнения по перегрузке по току. Я решил пока не париться и просто увеличил резистор. Позже когда все настрою поставлю резисторы нормально. Теперь сложность вот в чем. Не могу допереть как сделать чтобы информацию вводить с другого устройства. Вроде понимаю что надо вводить туда, куда сейчас вручную ввожу, но как, не пойму. Опять прошу помощи однако. )

#include <SPI.h> //подключаем библиотеку SPI

const int RCK = 7; //pin7 запись в вых.регистр 74НС595
char datr[9] = "1834 790"; //выводимые на индик. знаки
int i;
byte razr = 0;

void setup() {
pinMode(RCK, OUTPUT); // строб записи в парал.регистр
digitalWrite(RCK, LOW);
SPI.begin(); //иниц. SPI: "по умолчанию" нам подходит
SPI.transfer(0); //очистим регистр разрядов
SPI.transfer(0xff); //очистим регистр сегментов
digitalWrite(RCK, HIGH); //запись в вых.парал.регистр
digitalWrite(RCK, LOW);
}

void loop() {
for (i=0; i < 8; i++) { //один цикл развертки по всем разрядам
razr = 1 << i; //определяем "1" в нужный разряд
SPI.transfer(razr); //запись в регистр разряда
SPI.transfer(CodeSeven(datr[i])); //в регистр сегментов
digitalWrite(RCK, HIGH); //запись в вых.парал.регистр
digitalWrite(RCK, LOW);
delay(3); //время индикации одного разряда
}
}

//перекодировка символа в 7-сегментное представление
byte CodeSeven(char inv) {
byte rez;
switch (inv) {
case '0': rez = 0xc0; //"0" все светятся кроме G
break;
case '1': rez = 0xf9; //"1" светятся только B и С
break;
case '2': rez = 0xa4;
break;
case '3': rez = 0xb0;
break;
case '4': rez = 0x99;
break;
case '5': rez = 0x92;
break;
case '6': rez = 0x82;
break;
case '7': rez = 0xf8;
break;
case '8': rez = 0x80;
break;
case '9': rez = 0x90;
break;
default: rez = 0xff; //все иные символы - гашение
}
return rez;
}

вот снова вставил код. на этот раз вроде нормально получилось.