[Из песочницы] Игральный кубик на Attiny2313

С недавних пор мы с друзьями плотно подсели на настольные игры, а незадолго до этого я решил попробовать программировать под микроконтроллеры. Чередуя настольные игры с пляской вокруг микроконтроллера (я игрался всё это время с Attiny2313), родилась идея применить на практике небольшие знания, которые приобрёл на начальных этапах работы с этим МК и сделать игральный кубик. Была поставлена примерно следующая задача: Кубик должен отображать информацию по аналогии со своим костяным собратом; Кубик должен выдавать два значения; Кубик должен быть максимально простым в использовании. Далее начал формализовать задачу.Итак, было решено из SMD светодиодов выложить два кубика по 7 точек. В каждом кубике есть 4 отдельных группы светодиодов (0 — точка по середине, 1 — левый верхний правый нижний, 2 — правый верхний левый нижний, 3 — правый посередине левый посередине). Таким образом всё замечательно, для управления нам потребуется 8 ног или 1 байт, а это значит что один порт идеально для этого подойдёт.

Управление решил делать максимально простым, при старте активен только один из кубиков, при клике на кнопку кубик показывает рандомное число, при длительном нажатии переключается режим.

Сказано — сделано. Закупился SMD компонентами, к слову сказать, это был мой первый опыт работы с SMD и фена у меня нет, в размерностях также не ориентируюсь. Когда я забрал заказанные детали, то прифигел размеру сопротивлений в миллиметр на полмиллиметра. Одногруппник обнадёжил и сказал, что обычным паяльником тоже реально такие запаять, поэтому я немного приободрился о том, что не придётся ждать неделю, пока соберут новый заказ.

Заказывал сопротивления, Attiny2313 в корпусе под SMD и светодиоды; фольгированный текстолит и тактовая кнопка у меня уже были.

Накидал в eagle схемку и развёл плату:

754d9c864a1b4db8a4c5ef38f44b7d83.png

Далее приступил к программированию. Так как групп светодиодов 8, то используем пины PB0-PB7. Создадим массив со значениями для первого кубика:

int digs[6]={ 0×01,//1 0×02,//2 0×03,//3 0×06,//4 0×07,//5 0×0E,//6 }; Для второго нам отдельный массив не потребуется, достаточно будет использовать только смещение на 4 бита.Нажатие на клавишу обрабатывается в прерывании, а логика проверки долгое или короткое нажатие реализована на счётчике, который наращивается по таймеру. Это помогло ещё и от плясок вокруг дребезга контактов избежать. Просто когда наступает прерывание по кнопке, переводим переменную из false в true и начинаем считать пока значение истино. Если до определённого интервала клавиша отпущена, значит, это короткое нажатие. Запускаем бросок кубика и сбрасываем все значения, в противном случае считаем, что надо переключить режим.

SIGNAL (INT0_vect) { sleepTimer=SLEEP_TIMEOUT; cli (); toggleButton=TRUE; sei (); }

SIGNAL (TIMER0_COMPA_vect) { sleepTimer--;

if (toggleButton==TRUE){ timer++; }

if (timer>40&&timer<250){ if((PIND & (1 << PD2)) !=0){ toggleButton=FALSE; timer=0; shuffleDice(); } }else if(timer>250){ if ((PIND & (1 << PD2)) == 0){ setMode(); } toggleButton=FALSE; timer=0; } } Результат работы можно увидеть на видео ниже:[embedded content]

Код доступен по ссылке (не вижу смысла его на github выкладывать).

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

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

© Habrahabr.ru