Autor: Gherghe David, grupa 332CA
Acest proiect este un ceas pentru meciuri de sah (sau pentru orice joc care presupune alternarea turelor a 2 jucatori) realizat pe placa ATmega328P Xplained Mini. Acesta permite setarea unui timp pentru ambii jucatori folosind un potentiometru, pornirea jocului cu un buton dedicat, schimbarea turei intre cei doi jucatori cu doua butoane separate si semnalizarea pierderii la timp printr-un buzzer si prin afisajul OLED.
Ceasul permite alegerea mai multor optiuni de timp, printre care si optiuni de timp cu increment (dupa finalizarea unei ture, jucatorul ce apasa butonul va primi un numar de secunde in plus la timpul sau), cum ar fi:
Ideea de la care am pornit a fost dorinta de a face un proiect legat de sah pe care sa il pot folosi in propriile meciuri, iar scopul proiectului este sa simuleze functionalitatea unui ceas real de sah, folosit in competitii, dar intr-o forma simpla si usor de implementat pe microcontroller.
Proiectul este construit in jurul placii ATmega328P Xplained Mini, care are rolul de unitate centrala de control si citeste datele de intrare de la utilizator, calculeaza timpul ramas pentru fiecare jucator si controleaza elementele de iesire, adica afisajul OLED si buzzerul.
ATmega328P primeste alimentare la 5V prin USB. Aceeasi sursa de alimentare este folosita si pentru modulele externe conectate la proiect. Pentru alegerea timpului de joc este folosit un potentiometru conectat la un pin analogic al placii. Microcontrollerul citeste valoarea analogica prin ADC si o transforma intr-unul dintre cele cinci preseturi disponibile. In functie de pozitia potentiometrului, pe ecran este afisat controlul de timp selectat, de exemplu 3+2, 10+3 sau 15+10. Dupa alegerea presetului, utilizatorul apasa butonul START/PAUSE pentru a porni meciul.
Cele trei butoane sunt conectate la pini digitali ai placii si sunt citite folosind rezistentele interne de pull-up. Butonul albului si butonul negrului controleaza schimbarea turei. Atunci cand este randul unui jucator si acesta apasa butonul sau, microcontrollerul adauga incrementul corespunzator la timpul acelui jucator si porneste scaderea timpului adversarului. Astfel, placa mentine permanent starea curenta a jocului: randul albului, randul negrului, pauza sau timeout.
Butonul START/PAUSE are mai multe roluri in functie de starea proiectului. In meniul de selectie porneste jocul. In timpul meciului, o apasare scurta pune ceasul pe pauza sau il reporneste. Daca butonul este tinut apasat timp de 10 secunde, jocul este resetat si sistemul revine la meniul de alegere a timpului. Dupa ce un jucator pierde la timp, acelasi buton opreste semnalizarea si readuce proiectul in meniul initial.
Afisajul OLED comunica cu placa prin interfata I2C, folosind liniile SDA si SCL. Microcontrollerul trimite catre display informatii despre timpul ramas pentru fiecare jucator, incrementul selectat si starea curenta a jocului. Pe durata meciului, ecranul afiseaza cei doi timpi separati printr-o linie, iar un indicator arata al cui timp scade. Cand jocul este pus pe pauza, pe ecran apare mesajul “Paused”.
Buzzerul este controlat printr-un pin digital/PWM. El ramane oprit in timpul functionarii normale si este activat doar in momentul in care unul dintre jucatori ajunge la 00:00. In acel moment, microcontrollerul trece jocul intr-o stare de timeout, opreste scaderea timpului, face ecranul sa clipeasca la interval de o secunda si activeaza buzzerul pana cand utilizatorul apasa butonul START/PAUSE.
Lista de piese folosite:
1. Mediu de dezvoltare:
2. Librarii:
In proiect sunt folosite urmatoarele librarii:
Arduino.h Wire.h Adafruit_GFX.h Adafruit_SSD1306.h
Libraria Arduino.h ofera functiile de baza pentru lucrul cu microcontrollerul: configurarea pinilor, citirea intrarilor digitale si analogice, masurarea timpului cu millis() si generarea sunetului pentru buzzer.
Libraria Wire.h este folosita pentru comunicatia I2C dintre ATmega328P si display-ul OLED. Display-ul OLED SSD1306 foloseste doua linii pentru comunicatie: SDA si SCL.
Librariile Adafruit_GFX si Adafruit_SSD1306 sunt folosite pentru afisarea informatiilor pe display. Acestea permit scrierea textului, setarea dimensiunii textului si desenarea unor elemente simple, cum ar fi linia care separa timpul albului de timpul negrului.
Display-ul OLED este folosit la adresa I2C 0x3C, adresa detectata in etapa de testare cu un I2C scanner.
3. Algoritmul:
Logica proiectului este organizata ca o masina de stari. Aceasta abordare este potrivita deoarece ceasul poate fi in mai multe situatii distincte: selectie timp, rulare timp alb, rulare timp negru, pauza sau timeout.
Starile principale ale aplicatiei sunt:
In starea SETUP, programul citeste valoarea potentiometrului prin ADC si o transforma intr-un preset de timp. Valoarea ADC este impartita in 5 intervale, iar fiecare interval corespunde unui time control diferit. Pentru reprezentarea acestor preseturi am folosit o structura care retine doua informatii: timpul initial in minute si incrementul in secunde. Timpul fiecarui jucator este retinut intern in secunde. La afisare, numarul de secunde este convertit in formatul MM:SS. De exemplu, valoarea 600 este afisata ca 10:00.
Cronometrarea este realizata cu functia millis(), nu cu delay(). Acest lucru este important deoarece programul trebuie sa poata verifica in continuare butoanele, sa actualizeze display-ul si sa controleze buzzerul in timp ce timpul scade. Practic, la fiecare iteratie a buclei principale, programul verifica daca a trecut o secunda fata de ultima actualizare si scade timpul jucatorului activ.
Schimbarea turei se face prin butoanele dedicate jucatorilor. Daca este randul albului, doar butonul albului este acceptat. Cand albul apasa butonul, timpul lui primeste incrementul selectat, apoi incepe sa scada timpul negrului. In mod similar, cand este randul negrului, apasarea butonului negrului adauga incrementul la timpul negrului si porneste timpul albului.
Pentru butonul START/PAUSE am implementat doua Documentatia oficiala ATMega328P XPlained Mini tipuri de apasare: apasare scurta, apasare lunga
Apasarea scurta este folosita pentru pornirea jocului, pauza si revenirea din pauza. Dupa timeout, aceeasi apasare scurta opreste buzzerul si intoarce sistemul in meniul de selectie. Apasarea lunga, de aproximativ 10 secunde, este folosita pentru resetarea jocului in timpul meciului si revenirea la meniul initial.
In cazul in care timpul unui jucator ajunge la zero, programul intra intr-o stare de timeout. In aceasta stare, timpul nu mai scade, buzzerul este activat, iar ecranul clipeste la interval de o secunda. Sistemul ramane in aceasta stare pana cand utilizatorul apasa butonul START/PAUSE.
Pe parcursul dezvoltarii au fost testate separat toate modulele: display-urile OLED, potentiometrul, butoanele si buzzerul. O problema intalnita a fost folosirea a doua display-uri I2C. Initial, ambele aveau aceeasi adresa, ceea ce nu permitea controlul separat. Problema a fost rezolvata prin folosirea a doua display-uri cu adrese diferite, 0x3C si 0x3D.
Proiectul indeplineste functionalitatile propuse initial si poate fi folosit ca un ceas de sah simplu. Ca imbunatatiri viitoare, se pot adauga o carcasa dedicata, butoane mai mari, mai multe preseturi de timp, un mod custom pentru alegerea timpului si afisarea zecimilor de secunda in ultimele secunde ale jocului.
Functionalitatea finala a proiectului se poate vedea in repo-ul de pe Github si pe Youtube.