Обсуждаем контроллеры компании Atmel.
Ответить

Re: Семисегментный LED-индикатор. Эффекты анимации

Вт сен 08, 2020 14:08:30

Так и я также попался... Казалось бы, а ...

Re: Семисегментный LED-индикатор. Эффекты анимации

Вт сен 08, 2020 15:07:39

Demiurg писал(а):Ну, есть способы. "Заменить на xxxx"
Куда уж проще.
В ексель делается табличка, один раз, на видео все покажу

Re: Семисегментный LED-индикатор. Эффекты анимации

Вт сен 08, 2020 15:49:04

Я уже делал. Есть опыт...

Re: Семисегментный LED-индикатор. Эффекты анимации

Вт сен 08, 2020 20:46:15

не раскрыли вы тему эффектов на семи сегментах... :)))

Re: Семисегментный LED-индикатор. Эффекты анимации

Сб авг 13, 2022 13:58:10

как нарисовать анимацию, я понял.


но как цифру нарисовать на семи сегментном индикаторе :shock: ??? ни как не могу понять :dont_know: как у этого парня получается...


может он выводит цифру на сегмент, а яркость ноль и потом яркость включает на сегменте нужном... :idea:

может кто подкинет идею, совет, предложение любой помощи буду рад. :beer:
Вложения
chasy2.rar
(46.46 KiB) Скачиваний: 37

Re: Семисегментный LED-индикатор. Эффекты анимации

Сб авг 13, 2022 16:06:54

Надо помедленнее, покадрово бы посмотреть, станет понятнее, что в каком порядке включается/выключается.
А так то в принципе он там сами цифры не трогает, а эффекты сделаны методом наложения посегментной маски по AND для гашения части сегментов. То есть, эффект представляет собой отдельный алгоритм, накладываемый на сегменты в процессе динамической индикации.
Как это реализовать. То есть, нужно иметь карту анимации всех сегментов в виде массива N*7*4 элементов, в котором N - количество кадров анимации, 7 - число сегментов, 4 - число разрядов. В массиве 1 означает пропускание сигнала на сегмент, 0 - запрет включения сегмента. И дальше при запуске эффекта через операцию AND эта маска подмешивается к формирователю выходных состояний индикации.
С анимационными эффектами конечно нужно поработать в плане красивости. Для этого нужно медленно покадрово просмотреть показанное видео и записать всё по порядку в карту анимации.

Re: Семисегментный LED-индикатор. Эффекты анимации

Сб авг 13, 2022 16:21:31

Надо помедленнее, покадрово бы посмотреть, станет понятнее

на ютубе есть шестеренка (в правом нижнем углу ) нажать и уменьшить скорость воспроизведения до 0,25

А так то в принципе он там сами цифры не трогает, а эффекты сделаны методом наложения посегментной маски по AND для гашения части сегментов.

это как? какой-нибудь примерчик или ссылку почитать.

Re: Семисегментный LED-индикатор. Эффекты анимации

Сб авг 13, 2022 18:54:58

2Serzh2000. Самый простой и тупой способ следующий: 7 сегментов. Дискретность времени мультиплексирования делаем кратно 7. Точка живёт сама по себе. Либо подумать.
Маски.
Скажем, нужно вывести по сегментно. Делаем маски:
Seg_A - 0x00000001
Seg_B - 0x00000010
Seg_C - 0x00000100
Seg_D - 0x00001000
Seg_E - 0x00010000
Seg_F - 0x00100000
Seg_G - 0x01000000
Теперь мы делаем так:
Нам нужно вывести 1234. Сами нарисуйте. У нас кратно 7. Первый такт. Маска A. В этот момент будут выводиться только сегменты A. И так далее. Нужна синхронизация. Чтобы первый выводимый символ совпадал с сегментом A.
Как то так. На каждый эффект свой алгоритм и свои маски.
Я создавал графические конструкторы. Есть программы, редакторы 7 сегментных дисплеев. Там тебе сразу и хексы сегментов выдает.
Если что, пиши в личку. Поэкспериментируем.

Re: Семисегментный LED-индикатор. Эффекты анимации

Сб авг 13, 2022 20:14:45

Ух, давно я не занимался семисегментниками.
Как я уже говорил, суть в чем должна быть: ни символы цифр, ни переменные, хранящие активируемые сегменты, не изменяются в процессе анимации. А при выводе каждого разряда в процессе динамическоей индикации происходит наложение маски эффекта по логическому AND на сегменты текущего разряда. Этот метод позволяет не влиять на формирование символов цифр, но независимо добавлять анимированный эффект гашения сегментов в разрядах в любом порядке по карте анимации
.
То есть, функция, реализующая динамическую индикацию, должна выглядеть вот в таком виде:
Код:
/** ----------
 * @brief   Переключение шагов динамической индикации.
 */
void SegmentLED_DynaScan(void)
{
   static uint8_t digit = 0;
   uint8_t mask;

   mask = SegmentLED_Animation_GetMask(digit);
   SegmentLED_DigitOut(digit, buf[digit] & mask);
   digit++;
   if(digit >= NUM_DIG) digit = 0;
}

через интервал переключения разрядов вызывается эта функция, она для каждого текущего разряда индикатора берет из таблицы анимации значение накладываемой маски и накладывает по AND эту маску на данные для отображения сегментов в текущем разряде. Когда анимация остановлена, маска возвращается 0xFF, пропуская все сегменты. Текущая маска сегментов всего индикатора переключается другой функцией, ответственной за непосредственно воспроизведение анимации.

Re: Семисегментный LED-индикатор. Эффекты анимации

Сб авг 13, 2022 20:38:07

Логическая операция AND (и)
AND обозначается знаком &.

Оператор AND выполняется с 2-мя битами, возьмём, к примеру, a и b. Результат выполнения операции AND равен 1, если a и b равняются 1. В остальных случаях результат равен 0. Например, с помощью AND мы можем вкл/выкл сегмента по нашему массиву эффектов

вот почти понимаю ... разжуйте еще немного желательно с примерами :shock:

Re: Семисегментный LED-индикатор. Эффекты анимации

Сб авг 13, 2022 21:05:32

Операция побитового AND между двумя числами с удовольствием применяется для наложения так называемой маски на число.
То есть,
0110 1111 - число
&
0001 1110 - маска
=
0000 1110 - результат. Только совпадение 1 в одноименных позициях битов числа и маски пропускает на выход 1 в этой позиции бита, а где нет совпадения - там бит на выход 0. Это свойство и используется для гашения разрядов, не влияя на исходные данные символа.

Щас, допишу до полноценной анимации, соберу на макетке, попробую показать. Давно с семисегментниками не работал уже.

Re: Семисегментный LED-индикатор. Эффекты анимации

Сб авг 13, 2022 21:13:30

спасибо! покажите ... и код покажите.

Re: Семисегментный LED-индикатор. Эффекты анимации

Сб авг 13, 2022 21:49:55

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



А впрочем, вот демонстрационный набросок как есть:
Собственно, сам "смеситель" по маске:
Код:
/** ----------
 * @brief   Переключение шагов динамической индикации.
 */
void SegmentLED_DynaScan(void)
{
   static uint8_t digit = 0;
   uint8_t mask;

   mask = SegmentLED_Animation_GetMask(digit);  // получить маску сегментов в текущем разряде
   SegmentLED_DigitOut(digit, buf[digit] & mask);  // смешать отображаемую цифру и маску и вывести в разряд
   digit++;
   if(digit >= NUM_DIG) digit = 0;
}


Анимация:
Код:
/* положение сегментов в байте */
#define SEG_A      (1 << 0)
#define SEG_B      (1 << 1)
#define SEG_C      (1 << 2)
#define SEG_D      (1 << 3)
#define SEG_E      (1 << 4)
#define SEG_F      (1 << 5)
#define SEG_G      (1 << 6)

/* карта анимации сегментов в четырех разрядах, по шагам */
static uint8_t anim1[][4] = {{SEG_A, SEG_D, SEG_A, SEG_D},
      {(SEG_A | SEG_B), (SEG_D | SEG_E), (SEG_A | SEG_B), (SEG_D | SEG_E)},
       {(SEG_A | SEG_B | SEG_C), (SEG_D | SEG_E | SEG_F), (SEG_A | SEG_B | SEG_C), (SEG_D | SEG_E | SEG_F)},
       {(SEG_A | SEG_B | SEG_C | SEG_D), (SEG_A | SEG_D | SEG_E | SEG_F), (SEG_A | SEG_B | SEG_C | SEG_D), (SEG_A | SEG_D | SEG_E | SEG_F)},
       {0xFF, 0xFF, 0xFF, 0xFF}};

uint8_t *ptr = &anim1[0][0]; //указатель на текущую карту анимации и текущий шаг

/** ----------
 * @brief   Получение маски сегментов в текущем разряде
 * @param digit - текущий активированный разряд
 * @return маска сегментов в текущем разряде
 */
uint8_t SegmentLED_Animation_GetMask(uint8_t digit)
{
   return *(ptr + digit);
}

/** ----------
 * @brief   Переключение шагов анимации сегментов
 */
void AnimationStep(void)
{
   static uint8_t step = 0;

   ptr = &anim1[step][0];  // указатель ставится на первый разряд текущего шага анимации в карте
   step++;
   if(step > 4) step = 0;
}


Взаимодействие с индикатором (активация разряда, отображение сегментов):
Код:
/** ----------
 * @brief   Активация сегментов выбранного разряда.
 * @param digit - номер разряда
 * @param seg_data - данные сегментов
 */
void SegmentLED_DigitOut(uint8_t digit, uint8_t seg_data)
{
   ALLSEGs_OFF();   // гашение всех сегментов

   switch(digit){
   case 0:        // разряд 1
      SELECT_DIGIT(DIG1_Pin);  // активация разряда
      SEGs_OUT(seg_data);   // активация сегментов
      break;

   case 1:   // разряд 2
      SELECT_DIGIT(DIG2_Pin);  // активация разряда
      SEGs_OUT(seg_data);   // активация сегментов
      break;

   case 2:
      SELECT_DIGIT(DIG3_Pin);
      SEGs_OUT(seg_data);
      break;

   case 3:
      SELECT_DIGIT(DIG4_Pin);
      SEGs_OUT(seg_data);
      break;
   }
}

Последний раз редактировалось MLX90640 Сб авг 13, 2022 22:03:21, всего редактировалось 1 раз.

Re: Семисегментный LED-индикатор. Эффекты анимации

Сб авг 13, 2022 22:25:17

да!!! есть над чем подумать :shock:
спасибо! :beer:

Добавлено after 24 minutes 9 seconds:
а buf - это что? какую цифру хотим высветить.

Re: Семисегментный LED-индикатор. Эффекты анимации

Сб авг 13, 2022 22:36:39

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

Код:
#define NUM_DIG         4

/* кодирование сегментов в байте */
#define SEG_A      (1 << 0)
#define SEG_B      (1 << 1)
#define SEG_C      (1 << 2)
#define SEG_D      (1 << 3)
#define SEG_E      (1 << 4)
#define SEG_F      (1 << 5)
#define SEG_G      (1 << 6)
#define SEG_dp      (1 << 7)

/* символы шрифта */
#define CH_0      (SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F        )
#define CH_1      (        SEG_B | SEG_C                                )
#define CH_2      (SEG_A | SEG_B |         SEG_D | SEG_E         | SEG_G)
#define CH_3      (SEG_A | SEG_B | SEG_C | SEG_D                 | SEG_G)
#define CH_4      (        SEG_B | SEG_C                 | SEG_F | SEG_G)
#define CH_5      (SEG_A         | SEG_C | SEG_D         | SEG_F | SEG_G)
#define CH_6      (SEG_A         | SEG_C | SEG_D | SEG_E | SEG_F | SEG_G)
#define CH_7      (SEG_A | SEG_B | SEG_C                                )
#define CH_8      (SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F | SEG_G)
#define CH_9      (SEG_A | SEG_B | SEG_C | SEG_D         | SEG_F | SEG_G)

#define CH_A      (SEG_A | SEG_B | SEG_C         | SEG_E | SEG_F | SEG_G)
#define CH_B      (                SEG_C | SEG_D | SEG_E | SEG_F | SEG_G)
#define CH_C      (SEG_A                 | SEG_D | SEG_E | SEG_F        )
#define CH_D      (        SEG_B | SEG_C | SEG_D | SEG_E         | SEG_G)
#define CH_E      (SEG_A                 | SEG_D | SEG_E | SEG_F | SEG_G)
#define CH_F      (SEG_A                         | SEG_E | SEG_F | SEG_G)


static uint8_t buf[NUM_DIG] = {CH_0, CH_3, CH_5, CH_6}; // на индикаторе отображается число "0356"

Re: Семисегментный LED-индикатор. Эффекты анимации

Сб авг 13, 2022 22:50:34

а это что за функция ALLSEGs_OFF();
блин сложно это для меня :facepalm:
Вы полностью код покажите, пожалуйста

Добавлено after 5 minutes 1 second:
а это потушить все сегменты

Re: Семисегментный LED-индикатор. Эффекты анимации

Вс авг 14, 2022 06:46:06

Ааа, вон чо.. Ну так я пишу только для STM32, на AVR уже давно ничего не делаю. Поэтому полный код будет вам непонятен.
На том видео показан индикатор, работающий в режиме динамической индикации. Сегменты A-G всех четырех разрядов запараллелены, поэтому чтобы отобразить разные цифры в каждом разряде, в один момент времени активируется только один разряд. Индикаторы различаются по направлению светодиодов - с общим анодом (CA) и с общим катодом (CC). У индикатора CC чтобы зажечь сегмент, нужно на вывод разряда подать 0, а на выводы сегментов подавать высокие уровни.
Порядок работы с дин.индикацией будет таков
* Отображение первого разряда:
    - погасить все сегменты
    - активировать разряд 1 (подав на него низкий уровень) и деактивировать разряды 2,3,4 (подав на них высокие уровни)
    - подать на сегменты нужную комбинацию для первого разряда, и он включится

*Выждать интервал времени, равный 1/4 периода дин.индикации.

* Отображение второго разряда:
    - погасить все сегменты
    - активировать разряд 2 и деактивировать разряды 1,3,4
    - подать на сегменты нужную комбинацию для второго разряда

...и так далее до последнего разряда, и далее по кругу. Гашение сегментов перед сменой активированных разрядов нужно для исключения паразитной засветки сегментов в соседнем разряде. Интервалы переключения разрядов задаются каким-нибудь таймером и функция переключения разрядов вызывается в прерывании этого таймера. Весь круг индикации проходит например за 1/80 с, таким образом интервал переключения разрядов - 1/(80/4) = 1/20 или 0,05 с.

Такая хитрая посегментная анимация делается, как я показал выше, с помощью наложения маски сегментов. А анимация "бегущая строка" делается просто изменением содержимого переменных, хранящих данные сегментов для каждого разряда. Эти переменные - как раз и есть массив buf[4].

Re: Семисегментный LED-индикатор. Эффекты анимации

Вс авг 14, 2022 07:57:34

2Serzh2000. Развивайте у себя алгоритмическое мышление. Любой проект, даже рукоблудие выходного дня состряпанное на коленке левой пяткой рассматривается как полноценный проект. Это развивает отношение к своему труду.
Мне в свое время тоже это сказали. Берете бумагу, карандаш, стирательную резинку. И начинаете проектировать. Проектирование сверху вниз. Верх - это устройство в целом. Функционал, интерфейс. И начинаем дербанить на кубики. Эти кубики вы тоже дербаните. На каждом этапе анализируете. Представьте себе это устройство и кубики. Взаимодействие кубиков. И рисуйте, рисуйте. Да, лень порой. Переламывайте. Смотрите внутри себя на будущий результат.
Декомпозиция, анализ, синтез.

Re: Семисегментный LED-индикатор. Эффекты анимации

Вс авг 14, 2022 15:48:01

вот есть, к примеру число h1=2;
из сегментов оно выстраивается так
DDRB = 0b11101101; //2
мне нужно читать биты в произвольном порядке и записывать и в переменную rezultat

DDRB = 0b11101101; // читаем
rezultat = 0b00100000; //записали

DDRB = 0b11101101; // читаем
rezultat = 0b00100001; //записали

DDRB = 0b11101101; // читаем
rezultat = 0b00100001; //записали
.
.
.
DDRB = 0b11101101; // читаем
rezultat = 0b11101101; //записали

как это написать :facepalm:

Re: Семисегментный LED-индикатор. Эффекты анимации

Вс авг 14, 2022 20:32:19

Чё бл@?!
Ответить