Мы простых путей не ищем.


image

Предыдущая, она же первая моя публикация вызвала резонанс среди пользователей Хабра. Решил не останавливаться. Продолжаем выжимать невозможное из ATtiny13. Сразу же предупреждаю, описанные решения снова нестандартны, и у кого-то могут вызвать негодование и когнитивный диссонанс («И в чём тогда смысл статьи? Показать, что можно соединять элементы?»). Мало того, такое решение ещё и действительно нецелесообразно, о чём я подробнее напишу ниже. Но так уж повелось, что стандартные решения давно известны, и читать о них не всегда интересно, а писать- неблагодарно.

Очень уж мне нравится этот малыш- ATtiny13. Мозгов у него вполне достаточно для решения многих бытовых задач (включить свет, вентиляцию, в магазин за пивом сбегать). И цена просто смешная. Вот только ножек мало, а ручек и совсем нет. Поэтому приходится идти на всяческие ухищрения, чтобы решить проблему нехватки ног.

В процессе изучения программирования микроконтроллеров (в среде Ардуино, только не говорите никому) я, как многие, прошёл этап подключения ультразвукового датчика расстояния, примерно такого:

image

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

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

Картинка
image

21 сегмент от 5 ног контроллера. Здорово! Мне столько даже не нужно, хватит и двух знаков, плюс точка, итого 15 сегментов. А если четырьмя ногами? Тогда получится максимум 13 сегментов, не хватает. При виде схемы сразу возникло желание собрать и попробовать, хотя алгоритм работы составить не просто. Но при более внимательном взгляде понимаешь, что собрать не получится, таких семисегментников не существует в природе (скорей всего). Изготовить можно, конечно, но это уже другой уровень. Тогда идея была отложена до лучших времён.

Оффтоп: Почему нет семисегментных индикаторов со встроенной логикой? Куда смотрят разработчики? Насколько удобно в монтаже и управлении- две ножки питания и 3 (1, 2) ноги данных. И ведь были же даже в СССР: 490ИП1, 490ИП2. Внутри самого заурядного индикатора на 2...4 разряда полно места для размещения кристалла микросхемы, а цена сдвигового регистра 0,064 у.е вместе с корпусом. Ну да ладно.

И вот я снова задумался, как же уменьшить количество ног для работы с семисегментным индикатором? Выходы контроллера могут принимать три состояния (на самом деле 4, но сейчас это не важно). Можно ли как-то это использовать? Если два состояния по отношению к светодиоду можно трактовать только как светит-не светит, то с тремя немного интересней. Я ещё не сообразил, как этим пользоваться, но пришла в голову такая схема:

image

Если выход контроллера в состоянии нуля, светодиоды не светятся (что очевидно).

Если выход в состоянии единицы, то светодиоды светятся, что тоже понятно.

А вот если выход вовсе не выход, а включён на вход, то через цепь из двух резисторов и светодиод HL1 протекает ток, создающий на точке соединения резисторов падение напряжения примерно (5-1,7)/(2,2+1,5)*1,5+1,7=3,0 В. Этого недостаточно для того, чтобы ток пошёл через цепь VD1_R3_HL2 (нужно примерно 3,4 В). VD1- это дополнительный светодиод, используемый в качестве стабилитрона (стабистор правильней), поэтому мы не будем считать его светодиодом, чтобы не путаться. При этом неважно, включён ли подтягивающий резистор внутри микроконтроллера, его сопротивление (20 кОм) практически не влияет на ситуацию. К таким номиналам я пришёл не сразу, до этого пробовал с обычным диодом в качестве VD1, также вполне сносно работает с одинаковыми резисторами R1 и R2. Но лучше, чтоб R2 был примерно в полтора раза больше, чем R1. И чуть не забыл самое главное: всё описанное возможно только при использовании красных светодиодов и в индикаторе, и дополнительных. В крайнем случае или индикатор, или дополнительные светодиоды можно применить зелёные. И при напряжении питания от 4,5 В до 5 В.

Что мы имеем в итоге? Три состояния: не светит ни один светодиод (0), светит HL1 (1), или светят HL1 и HL2 (2). Очень напоминает троичную систему. Но мы не можем засветить HL2 без HL1, об этом нужно помнить. Зато теперь при помощи четырёх ног микроконтроллера можем управлять восемью светодиодами (хотелось так думать).

Дальше я попытался разбить сегменты индикатора на пары (прям как в детском саду: мальчик-девочка). Главное условие- в каждой паре один из сегментов не может светить самостоятельно, такая вот дискриминация. Вот что у меня получилось:

image

Четыре пары сегментов, в каждой большой буквой обозначен доминирующий сегмент, который может работать сам, второй может только с ним вместе. Можно заметить, что сегмент «а» мутит сразу с двумя, а бедной точке вообще никто не достался. Как это похоже на жизнь!

Зато этими парами можно отобразить (почти) все цифры:

Картинка
image

Каждая пара раскрашена своим цветом. Внимательный зритель заметил, что с двойкой что-то не то. Не будем пока акцентировать на этом внимание. Перепробовал ещё несколько вариантов группировки сегментов, лучше не придумал. Может, кто предложит. Возможно, нейросеть справилась бы.

На втором этапе экспериментов мне пришлось применять индикатор с общим анодом. Поэтому итоговая схема получилась такая:

Схема
image

Кто-то может спросить: куда подевались резисторы 100 ом? Давно известно (и активно используется), что при правильно сделанной динамической индикации можно обойтись без токоограничивающих резисторов. Даже если с выхода контроллера на последовательно соединённые два светодиода по ошибке постоянно подавать напряжение, микроконтроллер и светодиоды нормально это выдерживают, ток ограничивается сопротивлением перехода внутри МК. И ещё о резисторах. Максимальный ток через HL1 по предыдущей схеме около 2 мА, а через HL2 достигает 25...40 мА (предположительно, позже я скажу, откуда взялись эти цифры). Значит, и светоотдача у разных сегментов будет разная. Но поскольку будет использоваться динамическая индикация, это легко можно решить за счёт разного времени отображения сегментов.

Все эксперименты я проводил на Arduino Nano в среде Arduino IDE. Отличная плата для прототипирования, хорошо становится в breadboard, прошивается по USB без заморочек. Что-то не получилось? Исправил скетч и через минуту залил новую прошивку. А когда отладил код, можно перейти к прошивке в ATtiny13, это всё-таки занимает чуть больше телодвижений.

Кстати, тоже прошиваю с помощью Arduino и в среде Arduino, это практически исключает возможность залочить МК неправильными фьюзами, да и проще намного.

Вот пример отображения цифры 4 в коде:

pinMode(f_a, INPUT); // ножку подключения сегментов f_a делаем входом
digitalWrite(f_a, 1); // зажёгся сегмент F
pinMode(d_e, OUTPUT); // ножку подключения сегментов d_e делаем выходом
digitalWrite(d_e, 1); // ставим её в состояние 1, при этом не светят D и E
pinMode(b_a, INPUT); // ножку подключения сегментов b_a делаем входом
digitalWrite(b_a, 1); // зажёгся сегмент B
pinMode(c_g, OUTPUT); // ножку подключения сегментов c_g делаем выходом
digitalWrite(c_g, 0); // ставим её в состояние 0, зажглись и C, и G
delayMicroseconds (150); // F, B, C, G cветят ещё 150 микросекунд
pinMode(c_g, INPUT); // ножку подключения сегментов c_g делаем входом
digitalWrite(c_g, 1); // теперь сегмент G потух, светится только сегмент С
delay (time_2); // F, B, C cветят ещё 2 миллисекунды 

В принципе, всё должно быть понятно даже тем, кто не знаком с Arduino, но немного понимает в контроллерах. Цифры 150 микросекунд и 2 миллисекунды подобраны экспериментально по яркости сегментов. В окончательном коде их нужно вынести в отдельные переменные, чтобы можно было изменить при отладке. Из этих цифр можно приблизительно определить порядок различия токов через два сегмента в одной паре. Поскольку сегмент G светится примерно в 13 раз меньше времени, чем остальные, и обеспечивает такую же яркость, можно предположить, что ток через этот сегмент в 13 раз больше, чем через другие. На самом деле зависимость яркости от тока нелинейная, поэтому ток может быть больше и в 25 раз, то есть 50 мА. Что при такой скважности вполне безопасно для выхода МК. Кстати, эта разница в токах сыграла на руку при решении проблемы цифры 2. Как я писал выше, сегмент G можно засветить только вместе с сегментом C. Но если подать 0 на ножку МК, отвечающую за C и G, на 150 мксек, а после 2 мсек держать на ней 1, то сегмент G «отработает» на полную яркость, а сегмент С за те же 150 мксек успеет лишь чуть подсветиться. Получаем почти полноценную двойку. Таким образом мне удалось нарушить правило, которое я сам же установил. Что не сделаешь от безысходности.

Итак, цифру четырьмя ножками МК мы зажгли. Собственно, я этот этап для себя пропустил, сразу выводил два знака. Для этого отсоединяем вывод общего анода одного из разрядов индикатора от плюса питания, и подсоединяем к ещё одному выводу МК, и анод другого разряда- к следующему выводу (уже 6 ножек). Теперь по очереди выставляем 1 на аноде младшего разряда, отображаем цифру младшего разряда, дальше 1 на аноде старшего разряда, и отображаем цифру старшего разряда, и так по кругу. Этот эксперимент я проводил с Arduino Nano, у неё ног достаточно. Весь код отлаживал на ней, далеко не с первого раза. И вот всё заработало, как надо.

Схема
image

Поскольку аноды подключаются поочерёдно, при помощи простой доработки можно освободить ещё один вывод МК. Вот итоговая схема:

Схема
image

Итого используем 5 ног МК для отображения двухзначного числа. На этом этапе уже можно попробовать с крошкой ATtiny. Что я и сделал. Но не сразу. Скомпилированный в среде Arduino скетч для ATtiny13 занял примерно 1,7 кБ памяти при 1 кБ доступной. Чтобы уменьшить размер, пришлось обратиться к портам напрямую, что я и так собирался сделать позже. Кстати, на Arduino я использовал те же порты, что собирался использовать на ATtiny, очень удобно. Они уже обозначены на последней схеме. После обработки код похудел на килобайт.

Вот итоговый код для ATtiny13:

Код

#define  time_2  2 // время отображения неярких сегментов, миллисекунд
#define  time_3  150 // время отображения ярких сегментов, микросекунд

byte in1_;
byte in2_;
int disp_;
int d_ = 0;
void setup()
{
}
void loop()
{
  d_ = d_ + 1;
  if (d_ > 150) { // просто раз в 150 циклов увеличиваем число на 1
    d_ = 0;
    disp_ = disp_ + 1;
    if (disp_ > 99)(disp_ = 0); // считаем от 0 до 99
  }
    in2_ = disp_ / 10; // пишем в левый разряд - цифру делёную на 10
    in1_ = disp_ % 10; // пишем в правый разряд цифру оставшуюся от деления на 10
  }

  switch (in1_) {
    case 0:
      DDRB = B00001111;
      PORTB = B00010000;
      delayMicroseconds (time_3);
      DDRB = B00000001;
      delay (time_2);
      break;
    case 1:
      DDRB = B00000111;
      PORTB = B00000110;
      delay (time_2);
      break;
    case 2:
      DDRB = B00011111;
      PORTB = B00000010;
      delayMicroseconds (time_3);
      DDRB = B00010011;
      PORTB = B00010010;
      delay (time_2);
      break;
    case 3:
      DDRB = B00011011;
      PORTB = B00000110;
      delayMicroseconds (time_3);
      DDRB = B00000011;
      delay (time_2);
      break;
    case 4:
      DDRB = B00010101;
      PORTB = B00001110;
      delayMicroseconds (time_3);
      DDRB = B00000101;
      delay (time_2);
      break;
    case 5:
      DDRB = B00011011;
      PORTB = B00001100;
      delayMicroseconds (time_3);
      DDRB = B00001001;
      delay (time_2);
      break;
    case 6:
      DDRB = B00011111;
      PORTB = B00001000;
      delayMicroseconds (time_3);
      DDRB = B00001001;
      delay (time_2);
      break;
    case 7:
      DDRB = B00001111;
      PORTB = B00010110;
      delayMicroseconds (time_3);
      DDRB = B00000111;
      delay (time_2);
      break;
    case 8:
      DDRB = B00011111;
      PORTB = B00000000;
      delayMicroseconds (time_3);
      DDRB = B00000001;
      delay (time_2);
      break;
    case 9:
      DDRB = B00011011;
      PORTB = B00000100;
      delayMicroseconds (time_3);
      DDRB = B00000001;
      delay (time_2);
      break;
  }

  switch (in2_) {
    case 0:
      DDRB = B00001111;
      PORTB = B00010001;
      delayMicroseconds (time_3);
      DDRB = B00000001;
      delay (time_2);
      break;
    case 1:
      DDRB = B00000111;
      PORTB = B00000111;
      delay (time_2);
      break;
    case 2:
      DDRB = B00011111;
      PORTB = B00000011;
      delayMicroseconds (time_3);
      DDRB = B00010011;
      PORTB = B00010011;
      delay (time_2);
      break;
    case 3:
      DDRB = B00011011;
      PORTB = B00000111;
      delayMicroseconds (time_3);
      DDRB = B00000011;
      delay (time_2);
      break;
    case 4:
      DDRB = B00010101;
      PORTB = B00001111;
      delayMicroseconds (time_3);
      DDRB = B00000101;
      delay (time_2);
      break;
    case 5:
      DDRB = B00011011;
      PORTB = B00001101;
      delayMicroseconds (time_3);
      DDRB = B00001001;
      delay (time_2);
      break;
    case 6:
      DDRB = B00011111;
      PORTB = B00001001;
      delayMicroseconds (time_3);
      DDRB = B00001001;
      delay (time_2);
      break;
    case 7:
      DDRB = B00001111;
      PORTB = B00010111;
      delayMicroseconds (time_3);
      DDRB = B00000111;
      delay (time_2);
      break;
    case 8:
      DDRB = B00011111;
      PORTB = B00000001;
      delayMicroseconds (time_3);
      DDRB = B00000001;
      delay (time_2);
      break;
    case 9:
      DDRB = B00011011;
      PORTB = B00000101;
      delayMicroseconds (time_3);
      DDRB = B00000001;
      delay (time_2);
      break;
  }

  DDRB = B00011111;//пауза между отображениями
  PORTB = B00011110;
  delay (5);
}



Приведённый код позволит вашей ATtiny13 считать от 0 до 99. Правильнее было бы предусмотреть возможность переназначения ножек МК. Гуру программирования могли бы уменьшить код в несколько раз (Где предел минимального Hello World на AVR?).

Вы можете добавить в код нужную функцию, чтобы МК отображал что-то осознанное. Правда, у Тиньки уже все ножки заняты. Есть ещё ножка сброса, которую можно использовать как порт ввода-вывода. Но воспользоваться ней оказалось сложней, чем я думал. Поэтому для себя оставлю «на потом». Но есть интересная особенность, о которой не все знают. На эту же ножку выведен аналоговый вход ADC0, и он работает! Правда, при напряжении на нём менее 1/4 от напряжения питания МК переходит в режим сброса. Зато от 1/4 и до напряжения питания вполне можно измерять напряжение на входе. Этим я и воспользовался:

Код

#define  time_2  2 // время отображения неярких сегментов, миллисекунд
#define  time_3  150 // время отображения ярких сегментов, микросекунд

byte in1_;
byte in2_;
int disp_;
int d_ = 0;
void setup()
{
}
void loop()
{
  d_ = d_ + 1;
  if (d_ > 50) { // раз в 50 циклов...
    d_ = 0;
    disp_ = analogRead(A0) / 10; // ...измеряем напряжение на входе, делим на 10, чтобы вложиться в диапазон.
    if (disp_ > 99)(disp_ = 99);
    in2_ = disp_ / 10; // пишем в левый разряд - цифру делёную на 10
    in1_ = disp_ % 10; // пишем в правый разряд цифру оставшуюся от деления на 10
  }

  switch (in1_) {
    case 0:
      DDRB = B00001111;
      PORTB = B00010000;
      delayMicroseconds (time_3);
      DDRB = B00000001;
      delay (time_2);
      break;
    case 1:
      DDRB = B00000111;
      PORTB = B00000110;
      delay (time_2);
      break;
    case 2:
      DDRB = B00011111;
      PORTB = B00000010;
      delayMicroseconds (time_3);
      DDRB = B00010011;
      PORTB = B00010010;
      delay (time_2);
      break;
    case 3:
      DDRB = B00011011;
      PORTB = B00000110;
      delayMicroseconds (time_3);
      DDRB = B00000011;
      delay (time_2);
      break;
    case 4:
      DDRB = B00010101;
      PORTB = B00001110;
      delayMicroseconds (time_3);
      DDRB = B00000101;
      delay (time_2);
      break;
    case 5:
      DDRB = B00011011;
      PORTB = B00001100;
      delayMicroseconds (time_3);
      DDRB = B00001001;
      delay (time_2);
      break;
    case 6:
      DDRB = B00011111;
      PORTB = B00001000;
      delayMicroseconds (time_3);
      DDRB = B00001001;
      delay (time_2);
      break;
    case 7:
      DDRB = B00001111;
      PORTB = B00010110;
      delayMicroseconds (time_3);
      DDRB = B00000111;
      delay (time_2);
      break;
    case 8:
      DDRB = B00011111;
      PORTB = B00000000;
      delayMicroseconds (time_3);
      DDRB = B00000001;
      delay (time_2);
      break;
    case 9:
      DDRB = B00011011;
      PORTB = B00000100;
      delayMicroseconds (time_3);
      DDRB = B00000001;
      delay (time_2);
      break;
  }

  switch (in2_) {
    case 0:
      DDRB = B00001111;
      PORTB = B00010001;
      delayMicroseconds (time_3);
      DDRB = B00000001;
      delay (time_2);
      break;
    case 1:
      DDRB = B00000111;
      PORTB = B00000111;
      delay (time_2);
      break;
    case 2:
      DDRB = B00011111;
      PORTB = B00000011;
      delayMicroseconds (time_3);
      DDRB = B00010011;
      PORTB = B00010011;
      delay (time_2);
      break;
    case 3:
      DDRB = B00011011;
      PORTB = B00000111;
      delayMicroseconds (time_3);
      DDRB = B00000011;
      delay (time_2);
      break;
    case 4:
      DDRB = B00010101;
      PORTB = B00001111;
      delayMicroseconds (time_3);
      DDRB = B00000101;
      delay (time_2);
      break;
    case 5:
      DDRB = B00011011;
      PORTB = B00001101;
      delayMicroseconds (time_3);
      DDRB = B00001001;
      delay (time_2);
      break;
    case 6:
      DDRB = B00011111;
      PORTB = B00001001;
      delayMicroseconds (time_3);
      DDRB = B00001001;
      delay (time_2);
      break;
    case 7:
      DDRB = B00001111;
      PORTB = B00010111;
      delayMicroseconds (time_3);
      DDRB = B00000111;
      delay (time_2);
      break;
    case 8:
      DDRB = B00011111;
      PORTB = B00000001;
      delayMicroseconds (time_3);
      DDRB = B00000001;
      delay (time_2);
      break;
    case 9:
      DDRB = B00011011;
      PORTB = B00000101;
      delayMicroseconds (time_3);
      DDRB = B00000001;
      delay (time_2);
      break;
  }

  DDRB = B00011111;//пауза между отображениями
  PORTB = B00011110;
  delay (5);
}


Опыт показывает, что показания индикатора можно уменьшать аж до 21, только потом МК переходит в режим сброса, и начинает работать при возврате примерно до 25 и выше. Так что можно сделать очень неправильный «показометр» для индикации напряжения от 25 до 99 вольт, естественно, с делителем на измерительном входе.

Теперь о практическом применении. Изначальная идея отображать данные с датчика расстояния отложилась до лучших времён из-за нехватки одного цифрового входа. Для чего ещё можно применить схему, пока идеи не приходят. Ещё нюанс: ни о какой экономичности не может быть и речи. Даже если погасить все сегменты, через резистор R2 (по первой схеме) будет протекать ток 2,5 мА, в сумме 10 мА на индикатор, плюс управление транзистором добавляет ещё около 5 мА. Я не упомянул, транзистор практически любой p-n-p современный.

О целесообразности. Самый дешёвый вариант вывода на семисегментник- ATtiny13 плюс 74HC595. Два SMD корпуса обойдутся мне примерно в 0,50 у.е. Самый простой- ATmega8 (и всё, ни резисторов, ничего больше), это 0,68 у.е. И описанный выше вариант- стоимость ATtiny, 9 резисторов, 4 светодиода, транзистор (всё SMD)- это около 0,46 у.е., правда поштучно всё дороже в разы. К тому же собрать всё в кучу сложней, чем в предыдущих вариантах.

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

В общем, несколько дней я потратил зря.

Кроме критики, жду предложений по улучшению кода и упрощению схемы. Или улучшению функциональности без усложнения. Больше всего меня интересует, как зажечь точку, это бы расширило область применения. А вот если бы ещё и освободить один вывод из 5 задействованных, то можно было бы разгуляться.

Буду рад, если моё нестандартное решение принесёт пользу кому нибудь, не сейчас, так когда-нибудь.

UPD: Я знаю про Чарлиплексинг! Сторонняя схема, которую я привёл в начале статьи, это и есть Чарлиплексинг. И там же я написал, почему Чарлиплексинг не подходит.
Прошу не писать комментарии, если Вы прочитали статью по диагонали.

Комментарии (62)


  1. little-brother
    06.04.2019 17:26
    +4

    Учитывая, что полезных ног осталось полштуки (RESET), то по мне получился троллейбус.


  1. FForth
    06.04.2019 17:31

    На Attiny2313 есть, например, и такой проект
    почти «экстремального» программирования
    Достаточно компактное использование памяти флэш контроллера.

    P.S. Есть даже какая то aвторская книга по данному проекту
    Для AVR на eForth есть и такая книга
    Неплохой ещё вариант использования системы amForth, но есть и другие варианты.
    так что, нет пределу компактных решений и даже вне ассемблера :)


  1. Ivanii
    06.04.2019 20:11
    +1

    Единственная ценность — опыт, развитие логического мышления, стоимость рассыпухи и ее монтажа съест всю выгоду от применения тиньки.


    1. seri0shka Автор
      06.04.2019 20:44
      +3

      Согласен.


  1. masai
    06.04.2019 21:16
    +1

    Раз уж заговорили о «ненормальных» схемах управления светодиодами, интересно, заработает ли следующая. Перед каждым светодиодом ставим полосовой фильтр. Полоса пропускания у каждого своя. А при помощи МК генерируем сигнал с таким спектром, чтоб горели нужные светодиоды. Тогда вообще одной ноги хватит.


    1. pfg21
      06.04.2019 22:08

      только «за этой ногой» будет некислых размеров код :)
      вслед за браинфаками и иже с ними вы предлагаете создать эзотерическую сМеХотехнику :)
      в принципе возможно все.
      с год назад мне попадалась статейка — на одном проводе висело несколько светодиодов и выключателей и они по отдельности друг другом управляли. пардон ссыль не приложу.


      1. staticmain
        06.04.2019 22:52
        +1

        Статья для этого не нужна, достаточно одной схемы
        image


      1. KN_Dima
        06.04.2019 23:48
        +1

        Переключение периода PWM по таймеру — это «некислых размеров код»?


      1. masai
        07.04.2019 17:36

        вслед за браинфаками и иже с ними вы предлагаете создать эзотерическую сМеХотехнику :)

        Ну, в реальном проекте я, конечно, поставил бы что-то более подходящее. Сдвиговый регистр хотя бы. Но почему бы не добавить немного безумия just for fun? :)


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

        Я когда свой комментарий писал, думал об этом :)


        1. pfg21
          09.04.2019 10:59

          да именно именно это я и имел ввиду. :)


    1. sim31r
      07.04.2019 01:09

      Перед каждым светодиодом ставим полосовой фильтр

      Причем полосовой фильтр можно сделать на микроконтроллере, и код готовый есть в статье на Хабре ))


    1. hfinn
      07.04.2019 02:12
      +1

      На таком принципе как раз цветомузыка устроена.


  1. vasiaplaton
    06.04.2019 23:36
    +1

    easyelectronics.ru/multipleksirovanie.html
    Там в конце жлобоплексинг есть. Правда он только для отдельных светодиодов. к 3 выводам 12 светиков. Но мож кому пригодиться. Плюс сама статья неплохо много моментов по мультиплексу объясняет.


  1. Psychosynthesis
    07.04.2019 01:48
    +1

    Прочитайте про Чарлиплексинг

    Upd. Опередили.


    1. seri0shka Автор
      07.04.2019 10:38

      Ну неужели Вы думаете, что я ее знаю про Чарлиплексинг!? Сторонняя схема, которую я привёл в начале статьи, это и есть Чарлиплексинг. Только ни один семисегментный индикатор Вы так подключить не сможете. Внимательно посмотрите на схему.


      1. seri0shka Автор
        07.04.2019 11:25

        неужели Вы думаете, что я не знаю про Чарлиплексинг? (очепятка)


  1. IgorPie
    07.04.2019 02:33
    +2

    И снова stm32f0 в tssop20 зарулил бы одной левой, еще и на размере платы можно сэкономить, а не только на рассыпухе и монтаже.


    1. seri0shka Автор
      07.04.2019 10:35
      -2

      Только он дороже, чем Атмега8, с которой тоже «и на размере платы можно сэкономить, а не только на рассыпухе и монтаже.»
      С таким успехом можно сказать «Фигня этот ваш Запорожец, Крузак лучше!»


      1. BARSRAB
        07.04.2019 13:13

        Есть stm8 в tssop корпусе. Дешевле меги имеют больше плюшек


      1. IgorPie
        07.04.2019 13:34
        +2

        stm32f030f4p6 30р. на алиэкспрессе, включая доставку, при покупке десятка.
        atmega8 в tqfp — от 42р., при покупке десятка.

        Я тоже скрепя сердце переходил с любимых, как ZX-Spectrum tiny13 на stm, но с тех пор сделал много интересных штук и понял, что оно того стоило.
        Хотя бы потому, что без кварца тинька может 10МГц (или 8) тактовой, а стм — 48. Но если лень конфигурировать, можно и на 8 МГц работать.
        STM32f042f6p6 уже может в аппаратный USB и запас ПЗУ 32 килобайта, можно еще лучше вещи делать.

        Причина полного перехода на стм — была лень.


        1. seri0shka Автор
          07.04.2019 14:42

          Порог вхождения в STM гораздо выше. Давно посматриваю, но пока нет. 48 МГц и 12 бит мне пока не нужно. А цена для меня на сегодня точно такая же, как Атмега8, но у этой ног больше.


          1. IgorPie
            07.04.2019 17:57

            В стм32 порог ± такой же. Куча примеров и сниппетов, можно копипастить не особо вдаваясь в детали, по первости. Есть Cube MX.
            Си будет попроще ассемблера, да и ассемблер не запрещен, если очень хочется, или прижмёт.
            А главное, что код портируем на железки на голову-две выше.

            На stm32f042 уже сделан осциллограф, чип те же 20 ног, осцилл — с USB выходом.
            На stm32f103 сделано большинство китайских осциллографов (с внешними АЦП, но всё же), да и DSO осцилл — тоже. 72МГц, цена около доллара за чип.
            На stm32f4 можно распаковывать mp3 на ходу, у него аппаратная плавающая точка (single), DSP ядро. 180-216МГц
            STM32F7 уже с аппаратным double
            А stm32h7 — 400МГц тактовой.


            1. seri0shka Автор
              07.04.2019 19:51

              В стм32 порог ± такой же
              Почему-то очень много хороших специалистов уверены «Это же просто. Как можно этого не знать?!»
              Уж поверьте, я далеко не тупой, но stm для меня сложно. Возможно, со временем я тоже буду говорить: это просто.


              1. Ivanii
                07.04.2019 22:29
                -1

                Чем STM32 хуже ATmega?
                1 Убогий АЦП, на меге без танцев легко 9 реально значащих бит.
                2 Не поддерживает питание 5 В.
                3 Нет среды Ардуино.
                4 Нет выходного тока 40+ мА на ногу.
                5 Нет бронебойных защитных диодов на выводах.
                6 Нет триггеров шмидта на входах.
                7 Сложно конфигурировать периферию/нужна либа конфигурирования.
                Поправьте если где-то не прав.


                1. DolphinSoft
                  08.04.2019 16:34

                  BluePill, он же Maple, (STM32F103C8T6), поддерживается Arduino IDE,
                  Причем включая 128кб флеша (после правки конфига), и вплоть до частоты 144МГц (после перепайки кварца и реконфига)


                  1. Ivanii
                    08.04.2019 17:52

                    Пару лет назад смотрел этот проект, как большинство помигал светодиодом, неудачно попытался адаптировать пару скетчей от наны и бросил.
                    Смотрю сейчас — вроде проект ожил, смотрю редми — все как у истинных линуксоводов = 12 пунктов для запуска примера :)
                    Почему нельзя сделать как у людей — подключить USBasp/STLink и нажать кнопку «Записать загрузчик»?


                    1. DolphinSoft
                      08.04.2019 18:07

                      >Почему нельзя сделать как у людей — подключить USBasp/STLink и нажать кнопку «Записать загрузчик»?
                      Потому что нужно прошить бут, после которого появится возможность перешивать монстрика прямо по USB, причем даже джамперы передергивать не нужно будет. И все проблемы становятся неактуальными.


                      1. Ivanii
                        08.04.2019 20:20

                        Попробован завести этот конструктор — комп находит Maple DFU, Maple Serial не находит, из среды Ардуино через встроенный USB не шьется, STlink из среды Ардуино шьет, команда «Записать загрузчик» выдает ошибку…


                        1. DolphinSoft
                          09.04.2019 04:27

                          Загрузчик шьется через UART, или SWD, после этого плата становится «Ардуино-совместимой»


  1. BARSRAB
    07.04.2019 12:51

    Нафига переменная d_ типа int, если она не бывает больше 50 по коду? Почему не char?


    1. seri0shka Автор
      07.04.2019 14:33

      Во-первых, просто не обратил внимания, во-вторых, некоторое время назад заметил, что в среде Ардуино int и char занимают одинаково 2 байта при компиляции, как ни странно. Особо не вникал, просто констатирую факт.


      1. sav13
        07.04.2019 16:20

        Делайте тип byte. А char может быть уже уникодным


        1. seri0shka Автор
          07.04.2019 16:43

          byte так само при компиляции.


  1. master__v
    07.04.2019 14:22

    Как-то не минималистично. Используя всего три ноги, пару сдвиговых регистров можно рулить сразу четырьмя семисегментниками, четырьмя кнопками и четырьмя светодиодами.


    1. seri0shka Автор
      07.04.2019 14:29

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


      1. master__v
        09.04.2019 17:33

        вот где-то так это выглядит на регистрах:
        image


    1. sav13
      07.04.2019 16:22

      Тогда уж MAX7219 сразу взять. Там и яркость встроенная и ограничение по току и 8 разрядов


    1. AndyKorg
      08.04.2019 07:38

      А можно использовать STLED316, и индикация будет и кнопок навалом. Например Таймер на tiny13 и STLED316


  1. moviq
    07.04.2019 15:00

    Этого недостаточно для того, чтобы ток пошёл через цепь VD1_R3_HL1

    Наверное всё-таки HL2


    1. seri0shka Автор
      07.04.2019 16:12

      Да. Спасибо. Хоть кто-то вникает.


  1. Sekira
    07.04.2019 15:32

    Стоит заметить, что есть недорогие готовые 4-разрядные индикаторы на TM1637 управляемые по двум проводам.


    1. seri0shka Автор
      07.04.2019 16:23

      Аттини13+индикатор+рассыпуха=0,80 у.е.
      Атмега8+индикатор=1,00 у.е.
      Аттини13+TM1637с_индикатором=1,93 у.е.
      Вы всё ещё считаете индикаторы на TM1637 недорогими?


      1. sav13
        07.04.2019 16:27

        Микросхема TM1637 стоит 0.2$. Правильнее все таки рассыпуху сравнивать
        Итого те же $1


        1. seri0shka Автор
          07.04.2019 16:51

          Итого те же $1

          Даже если так (я нашёл по 0,3), то с Атмегой лучше по всем параметрам.


      1. Polaris99
        07.04.2019 17:32

        ATtiny1616 — почти два десятка ног и 16 кб за 0.6 у.е. Смысл телодвижений?


  1. sav13
    07.04.2019 16:24

    TM1637 еще и кнопками можно управлять
    Есть MAX7219 и еще много чего
    Мне кажется, программирование на Attiny13 — это такое хобби из цикла — «а слабо вот так?»


    1. DolphinSoft
      08.04.2019 16:37

      Все верно, это спорт :)


  1. CHolfield
    07.04.2019 16:33

    У меня вопрос: а ежели сгорит один светодиод и токи перекосит непредусмотренным образом?

    Заголовок спойлера
    Светодиоды обозначаются не так


    1. seri0shka Автор
      07.04.2019 16:57

      Я за свои 46 лет не встречал случаев сгорания индикаторных светодиодов. Осветительные- да. Ну и в любой схеме при сгорании любого элемента могут быть разные варианты. Но не смертельные.


      1. Polaris99
        07.04.2019 17:33

        Мне всегда нравилась аргументация вида — я никогда не встречал, значит, такого не бывает! А я вот встречал, и как теперь с этим жить?


      1. CHolfield
        07.04.2019 18:09

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


        1. seri0shka Автор
          07.04.2019 20:01

          Попытаюсь ответить объективно, несмотря на Ваш тон.
          Прелесть любой динамической индикации в том, что даже при большом количестве ошибок за единицу времени картинка на индикаторе не меняется, потому что обновляется каждые несколько миллисекунд. Хотя в данной схеме совсем не микротоки, и нарушить отображение очень сложно.
          А наструячил я для саморазвития, и никого применять не призываю.


          1. CHolfield
            07.04.2019 23:20

            вопросы вроде по теме, ваша холодность меня сильно печалит. За ответы спасибо.


          1. DolphinSoft
            08.04.2019 16:47

            Не преувеличивай, далеко не все тут пытаются выставить тебя клоуном или дурачком.
            Люди реально не понимают, зачем это нужно и какая от этого польза.
            Развивайся, не останавливайся, направление у тебя верное, и из таких проектиков у тебя родится шедевр однажды. Кто ищет — тот найдет!
            По-большому счету, проект интересен только схемотехнически. Ищи более логические вещи.
            Из достойных проектов, могу посоветовать цветомузыку на Тиньке, с Фурье и ws2812. Правда 13я Тинька уже возможно не вывезет, хотя зависит от окна и количества ледов. А с другой стороны — 85я Тиня — такая же, только жирная :)
            В общем не расстраивайся, будь молодцом! ;)


            1. seri0shka Автор
              08.04.2019 17:58

              Спасибо за поддержку.

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


  1. VT100
    07.04.2019 18:08

    В общем — плюсую. Но в частностях — должен заминусовать:

    Кто-то может спросить: куда подевались резисторы 100 ом? Давно известно (и активно используется), что при правильно сделанной динамической индикации можно обойтись без токоограничивающих резисторов.

    «Грязная» схемотехника с непредсказуемой надёжностью и возможностью мало очевидных побочных эффектов.
    На самом деле зависимость яркости [светодиода] от тока нелинейная, ...

    Просто — «Шта-а-а?» Посмотри в доке на любой светодиод или индикатор график "[Relative] Luminous intensity vs. Forward current". Даже у осветительных СД он мало отклоняется от прямой линии.
    Может быть — уместно вести речь об относительной яркости восприятия глазом в зависимости от длительности импульса? Кто знаком с этой отраслью знаний?


  1. lingvo
    07.04.2019 18:19

    Если предыдущая статья еще хоть чем-то оправдывалась, то эта уже верх безумия.
    Неистово плюсую автора!


  1. Bookvarenko
    07.04.2019 22:35

    Интересно, для Lixie-индикатора сколько ног понадобится по минимуму?


  1. lingvo
    08.04.2019 07:57

    Кстати, рискну предложить, что я соберу эту схему с четырех ног. Ключевое слово — дешифратор.


    1. seri0shka Автор
      08.04.2019 18:11

      Четыре ноги на дешифратор, чтоб на выходе получить семь сегментов. А аноды? Уже минимум 5 ног. Если я сознательно отказался от сдвигового регистра стоимостью 0,065 у.е. (который даёт 8 сегментов с 3 ног), то вряд ли бы меня устроил дешифратор за 0,4 у.е. или дороже.


      1. lingvo
        08.04.2019 21:22

        Почему семь сегментов? 15 + 1 на гашение. Т.е дешифратор 155ИД3(74HC154) — выходы вешаем на катоды матрицы, аноды на +. 15 сегментов — это два семисегментника + точка между ними. Дешифраторы, насколько я помню, это достаточно дешевая штука. Есть и другие


        1. seri0shka Автор
          08.04.2019 22:54

          Ну если так, то да, 4 ноги. Но это уже другой индикатор (статический, хотя индикация динамическая). И в концепцию проекта не вписывается, с микрухами есть гораздо лучшие варианты. Я не говорю уже о том, что ид3 больше Тиньки раз в 300 по объёму. Хотя о 155ид3 у меня только самые тёплые воспоминания. Лежат в кладовке несколько новеньких.