Сегодня не большая статья о готовом проекте — это таймер для игры в быстрые шашки. Устройство получилось простое, на его панели располагаются два светодиода, указывающие на ход первого или второго игрока, 7-сегментный индикатор с один разрядом, на котором происходит отсчет секунд от 9 до 0, а также несколько кнопок управления и две кнопки для передачи хода сопернику. Работу готового устройства можно посмотреть на видео ниже.
Схема подключения atmega328 к arduino uno для прошивки
В устройстве нет ни чего серьезного, но мне было интересно им заниматься, поскольку тут я использовал микроконтроллер atmega328 отдельно, без платформы arduino. В этот раз программирование все точно такое же, как и при других проектах на ардуино, но схема отличается. Вместо привычной платы ардуино использовались atmega328 и кварц на 16 Mhz. В идеале еще необходимо добавить два конденсатора по 22 пФ, но их я не нашел на тот момент, хотя в следующем подобном проекте обязательно их добавлю. Ниже приведена официальная схема подключения микроконтроллера, кварца и конденсаторов. Также на картинке изображено как, подключить arduino uno к МК atmega328 для загрузки скетча. При таком подключении arduino uno будет выступать в роли программатора. Как заливать прошивку я писать не буду, об этом и так много статьей, если кому-то нужно, то можно посмотреть в мануале: тут.
Пример работы с atmega328
Оказалось что, работать с atmega328 также просто, как и с любой ардуиной. Достаточно отладить программу использую arduino, а уже готовый скетч просто залить в atmega328, которая имеет все те же самые пины и точно также с ними работает. Ниже находится картинка, с подписанными ножками микроконтроллера.
Логика работы устройства
Как работает устройство, наглядно показывает видео в начале статьи. Для реализации проекта помимо atmega328 использовался 7-сегментный индикатор, принцип работы подобного индикатора я уже описывал с статье « 4-разрядный 7-сегментный индикатор hs420561k-32». Управлять индикатором помогал сдвиговый регистр 74hc595. Так же было задействовано 5 кнопок, три из которых используются для настройки и запуска таймера, а две для передачи хода между игроками. Чтобы во время игры не забыть про таймер, был добавлен зуммер – пищалка, ее тоном можно управлять с помощью аналогового пина.
Корпус устройства
Корпус был напечатан на 3D принтере, но с размерами платы и корпуса я как обычно накосячил, и пришлось еще печатать удлинители для кнопок, поскольку после сборки устройства, достать до кнопок пальцами, не было возможности.
Что использовалось в проекте:
- Atmega328. Покупал тут: Atmega328
- Кварцевый резонатор 16MHz. Покупал тут: Кварцевый резонатор 16MHz, 10шт
- 2 конденсатора 22 пФ. Покупал тут: Керамические конденсаторы 22 пф, 200 шт
- 1-разрядный 7-сегментный дисплей. Покупал тут: 1-разрядный 7-сегментный дисплей, 10шт
- Зуммер. Покупал тут: Зуммер 10 шт
- 1 Сдвиговый регистр 74HC595. Покупал тут: сдвиговые регистры 10 штук
- 9 резисторов сопротивлением 300 Ом. Покупал тут:набор резисторов 700 шт. От 10 Ом до 1 МОм
- 5 резисторов сопротивлением 10 кОм. Покупал тут:набор резисторов 700 шт. От 10 Ом до 1 МОм
- 2 светодиода. Покупал тут: 100 светодиодов, 10 разных цветов
- 3 тактовые кнопки 6x6x5мм. Покупал тут: Тактовые кнопки 6x6x5мм, 100шт
- 2 тактовые кнопки 12x12x7мм. Покупал тут: Тактовые кнопки 12x12x7мм, 20шт
- Тумблер. Покупал тут: Тумблеры 6-пиновые 5шт
- 1 Кусок фольгированного текстолита. Покупал тут: 10 кусков одностороннего текстолита 70x100x1.2 мм
Код скетча таймера для шашек на atmega328
Посмотреть код скетча приведен ниже, так же его можно скачать тут.
//Пин подключен к ST_CP входу 74HC595 int latchPin = 10; //Пин подключен к SH_CP входу 74HC595 int clockPin = 12; //Пин подключен к DS входу 74HC595 int dataPin = 11; // Кнопка увеличения таймера int btn_up = 2; bool status_btn_up = false; // Кнопка уменьшения таймера int btn_down = 3; bool status_btn_down = false; // Кнопка старта/паузы int btn_select = 4; bool status_btn_select = false; // Кнопка 1 игрока int btn_red_1 = 5; // положение кнопки bool status_btn_red_1 = false; // Кнопка 2 игрока int btn_red_2 = 7; // положение кнопки bool status_btn_red_2 = false; // пин пищалки int pin_beep = 9; // Светодиод 1 int led_1 = 6;//A0; // Светодиод 2 int led_2 = 8;//A1; // количество секунд в таймере, по умолчанию 5 сек int countSeconds = 5; // флаг таймера, запущен или нет bool startGame = false; // отсчет итераций, считаем миллисекунды, по 100 за итерацию int timer = 0; // количество установленных секунд для таймера int currentSec = 5; // функция вывода цифры на 7-сегментом индикаторе void writeNum(int num){ byte arrayNums[] = { B10111111, B00001100, B01011011, B01011110, B01101100, B01110110, B01110111, B00011100, B11111111, B11111110 }; digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, MSBFIRST, arrayNums[num]); digitalWrite(latchPin, HIGH); } // функция пищалки void beep(unsigned char delayms){ analogWrite(pin_beep, 20); delay(delayms); analogWrite(pin_beep, 0); delay(delayms); } void setup() { // настройка пинов pinMode(latchPin, OUTPUT); pinMode(clockPin, OUTPUT); pinMode(dataPin, OUTPUT); pinMode(btn_up, INPUT); pinMode(btn_down, INPUT); pinMode(btn_select, INPUT); digitalWrite(btn_up, LOW); digitalWrite(btn_down, LOW); digitalWrite(btn_select, LOW); pinMode(led_1, OUTPUT); pinMode(led_2, OUTPUT); digitalWrite(led_1, LOW); digitalWrite(led_2, LOW); pinMode(pin_beep, OUTPUT); } void loop() { if(startGame){ writeNum(currentSec); }else{ writeNum(countSeconds); } if(digitalRead(btn_up)){ if(!status_btn_up) { if(countSeconds < 9) countSeconds++; } status_btn_up = true; }else{ status_btn_up = false; } if(digitalRead(btn_down)){ if(!status_btn_down){ if(countSeconds > 1) countSeconds--; } status_btn_down = true; }else{ status_btn_down = false; } if(digitalRead(btn_select)){ if(!status_btn_select){ startGame = !startGame; timer = 0; currentSec = countSeconds; if(startGame){ digitalWrite(led_1, HIGH); digitalWrite(led_2, LOW); }else{ digitalWrite(led_1, LOW); digitalWrite(led_2, LOW); } } status_btn_select = true; }else{ status_btn_select = false; } if(startGame){ timer++; // прошла секунда if(timer > 10){ timer = 0; if(currentSec > 0) { currentSec--; beep(50); } } if(currentSec == 0){ beep(50); } if(digitalRead(btn_red_1)){ if(!status_btn_red_1) { timer = 0; currentSec = countSeconds; digitalWrite(led_1, LOW); digitalWrite(led_2, HIGH); } status_btn_red_1 = true; }else{ status_btn_red_1 = false; } if(digitalRead(btn_red_2)){ if(!status_btn_red_2) { timer = 0; currentSec = countSeconds; digitalWrite(led_1, HIGH); digitalWrite(led_2, LOW); } status_btn_red_2 = true; }else{ status_btn_red_2 = false; } } delay(100); }
Послесловие
Использование в данном устройстве atmega328 — это большое расточительство, тут будет даже много и atmega8. Но цель была — использовать микроконтроллер отдельно от платы arduino, а не экономия ресурсов, заниматься оптимизаций пока нет возможности. Так же схема собрана не совсем правильно — не были добавлены конденсаторы, для более стабильной и корректной работы МК. И еще одной серьезной ошибкой является сборка схемы без стабилизатора напряжение — так делать нельзя, следующий раз обязательно буду его использовать.