Доброго времени суток.

Уже несколько лет у меня есть идея реализовать одну вещь. Вот эта идея и отсутствие аккаунта на хабре (постоянным читателем которого я уже являюсь чуть менее года) меня вдохновила на разработку данного «девайса» и написание стати. Хочу поделиться с хабра-обществом своей разработкой. Это светловое шоу 8-ми диодов на микросхеме attiny2313.

Таких схем в инете можно накопать немало, но это свое, родное, может даже чем-то уникальное. Большинство помнят фильм, а потом уже и сериал «Рыцарь дорог» (Knight Rider)
Кто в детстве не мечтал о такой машине? Ну, вот я и решил, сделать анимацию, такою как впереди самой машины. Примерно такое image

За основу взято микросхему attiny2313 фирмы Atmel. Не буду углубляться в подробности прошивки, все это было на хабре. Вот и вот и под линукс

Из подручных материалов спаял схему по следующему принципу.


Под рукой были светодиоды на 3 вольта, точнее целая планка (8 штук), поэтому в моем варианте, последовательно диодам я добавил резисторы по 200 Ом. Но так как в новом КИДе (такое название носила чудо-машина) была уже другая анимация, поставил за задачу сделать легко перепрограммируемую анимацию.

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

const char mat[] =
{
10,0,0,0,0,0,0,0,
6,10,0,0,0,0,0,0,
2,6,10,0,0,0,0,0,
0,2,6,10,0,0,0,0,
0,0,2,6,10,0,0,0,
0,0,0,2,6,10,0,0,
0,0,0,0,2,6,10,0,
0,0,0,0,0,2,6,10,
0,0,0,0,0,0,2,6,
0,0,0,0,0,0,0,2,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,10,
0,0,0,0,0,0,10,6,
0,0,0,0,0,10,6,2,
0,0,0,0,10,6,2,0,
0,0,0,10,6,2,0,0,
0,0,10,6,2,0,0,0,
0,10,6,2,0,0,0,0,
10,6,2,0,0,0,0,0,
6,2,0,0,0,0,0,0,
2,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0
};


Матрица анимации задаётся следующим способом:
10 – это максимальное свечение, 0 – это выключенный диод (логический 0 на выходе, во всех фреймах). Промежуточные значения 1-9, задаются в цикле из 10 итераций. Например, значение 5 в матрице в половине из 10 итераций будет логической единицей, в другой половине будет логический ноль. Это задаст нам половинное свечение диода.

Вся анимация проходит за short timeAnim = 3000; час в мс. Ну и сама реализация.

//вычисляем время для одного фрейма
sPeriodTime = timeAnim * 4 / sizeof(mat) * 8;
iCycle = 0;

// вычисляем количество фреймов для анимации
iMaxCycle = sizeof(mat) / 8;

while (1)
{
PORTB = 0;
TCNT1 = 0;
iCycle = 0;
while(iCycle < iMaxCycle)
{
while(TCNT1 < (iCycle + 1)*sPeriodTime)//проверяем, истекло ли время для анимации одного фрейма
{
for(i = 0; i < 10; i++) //анимация 10 подфреймов
{
iTemp = 0;
for(j = 0; j < 8; j++)//формируем выходное значения
{
iTemp <<= 1;
iTemp |= (mat[iCycle*8 + j] - i) > 0;
}
PORTB = iTemp; //записываем значения в порт
}
};
iCycle++;
}
};


Компилируем, прошиваем, power-on и вот что получилось



Это моя первая серьезная схема и программа с использованием микроконтроллеров.

Исходники здесь