Proiectul consta dintr-un joculet, numit RUSH HOUR. Scopul este de a scoate o masina speciala(cea rosie, daca ne uitam in poza de mai sus) dintr-o parcare unde exista si alte masini. Masinile se pot misca doar sus-jos(cele verticale) si stanga-dreapta(cele orizontale). Joculetul se joaca cu 5 butoane. Cu 4 dintre ele se misca masinile sus, jos, stanga, dreapta, iar cu al cincilea se selecteaza masina.
In implementarea mea am folosit exact aceasta configuratie de masini(cea din poza).
Din punct de vedere hardware, asa cum se observa si din schema de mai sus am folosit placuta cu microcontroller-ul Atmega 16, un ecran LCD Nokia 3310 si o placuta de extensie care are rolul de a interconecta microcontroller-ul cu ecranul LCD.
Pe placuta de extensie se gasesc 6 butoane. Unul dintre ele nu foloseste la nimic. Intentionam sa-l folosesc la implementarea unei functionalitati in plus pentru joc, dar din motive de spatiu (Atmega 16 are doar 16 KB de memorie) am renuntat. In final, acest buton a ramas doar fizic pe placuta de extensie, el neavand nici o functionalitate.
Celelalte 5 butoane sunt folosite pentru a misca masinile sus, jos, stanga, dreapta, respectiv pentru a selecta masina.
Din punct de vedere software am folosit un driver functional, care contine functii utile de afisare de caractere si string-uri deja implementate. O modificare esentiala pentru functionarea proiectului a fost modificarea fisierului lcd.h pentru a asocia corect pinii lcd-ului cu pinii de pe portul B ai microcontroller-ului.
Functiile implementate de mine le voi detalia in partea de software design, precum si toate celelalte aspecte referitoare la software.
Am folosit 5 rezistente 3k3 si 5 rezistente 1k8(legate ca in figura de mai sus) pentru a crea divizori de tensiune. A fost nevoie de acestia pentru a lega porturile lcd-ului la porturile microcontroler-ului. De asemenea, a trebuit sa reducem tensiune de alimentare pentru LCD de la 5V la 3.3V. Am folosit 2 diode si am redus tensiunea de la 5V la 3.6V. Totul a fost in regula. Surplusul de 0.3V nu a afectat functionarea lcd-ului. Butoanele le-am conectat la portul D, dupa cum se observa in figura, de la PD2 la PD7. Corespondenta intre semnificatia butoanelor si porturi este urmatoarea:
Din punct de vedere software, am programat in Programmers Notepad [WinAVR]. Am folosit ca template 3 fisiere din driverul pentru LCD Nokia 3310 cu functii foarte utile deja implementate, gen afisare caracter si afisare string. De un mare ajutor mi-a fost programelul FastLCD cu ajutorul caruia am putut desena mai usor masinile, nefiind nevoie sa le creez manual pixel cu pixel.
Algoritmul de dedesubt presupune folosirea unei matrici ca suport pentru masini. Astfel, in matricea noastra fiecare masina este reprezentata de un sir de numere astfel(de exemplu): daca masina este orizontala si are lungimea de 2, in matrice vom avea pe un rand 11(cifra 1 semnifica prima masina); daca masina este verticala si are lungimea de 2 vom avea pe o coloana:
4 4
(cifra 4 semnifica a 4-a masina)
Aceasta matrice este definita, global, la inceput in fisierul rush_hour.c.
unsigned char m[6][6] =
{{'1', '1', '-', '-', '-', '7'}, {'4', '-', '-', '6', '-', '7'}, {'4', '?', '?', '6', '-', '7'}, {'5', '-', '-', '6', '-', '-'}, {'5', '-', '-', '-', '2', '2'}, {'5', '-', '3', '3', '3', '-'}, };
In aceasta imagine, facand abstractie de 0-urile inconjuratoare, avem matricea cu configuratia de masini.
Pentru afisarea masinilor am pornind de la functia de afisare a unui caracter deja implementata si am adaptat-o pentru ce aveam nevoie, adica pentru afisarea masinilor orizontale de lungime 2, a celor verticale de lungime 2, a celor orizontale de lungime 3 si a celor verticale de lungime 3. Initial am creat mai multe functii ce aveau scopul de a afisa fiecare tip de masina in parte, insa ocupau mult spatiu din cei 16 KB si astfel am fost nevoit sa le restrang intr-o singura functie.
Un alt aspect algoritmic ar fi faptul ca am definit 4 functii de mutare a masinilor stanga, dreapta, sus si jos, cu restrictiile de rigoare(masinile nu se pot intercala si nici nu pot depasi limitele ecranului), dupa ce in prealabil acestea au fost selectate.
Proiectul este functional, cu o singura problemuta nerezolvata inca. Desi in simulare merge corect, in mod real merge foarte rapid. Am concluzionat ca dintr-un motiv sau altul nu functioneaza delay-ul pe care l-am folosit.
Nu am momentan acces la un aparat foto pentru a pune poze cu proiectul in sine, dar in curand voi rezolva si acest aspect.
A fost interesant sa lucrez la un astfel de proiect. In primul rand as vrea sa le multumesc colegilor care m-au ajutat foarte mult. Fara ei nu stiu daca as fi reusit sa duc la capat proiectul. Mi-a facut placere mai mare implementarea partii software decat cea hardware. In general imi place programarea si proiectul de fata nu a constituit o exceptie.
As dori sa le dau un sfat celor care poate vor dori sa implementeze programele cu output pe Nokia LCD 3310. Daca se poate, sa testeze driverul folosit, in mod real, pe o placuta cu lcd functionala, inainte de a scrie codul propriu zis cu driverul respectiv. Eu am intalnit o situatie neplacuta pe parcurs. Am scris tot codul cu un driver, care in simulator mergea foarte bine, in schimb cand am incercat sa programez placuta, nu imi aparea nimic pe lcd. Am incercat sa schimb pinii din header ca sa se potriveasca cu contextul proiectului meu, dar tot nu a mers (poate nu am stiut eu ce sa modific, in final). Dupa ce mi-a aratat o colega driver-ul pe care l-a folosit ea(si care mergea pe lcd),l-am folosit si eu si am portat totul in contextul noului driver. Dupa ce am terminat de portat, a mers si la mine afisarea pe lcd.
Si sa exista o grija mare cu lcd-ul, inainte de a-l conecta si de a-l pune sub tensiune. Sa se masoare de 2-3 ori totul pe placuta de extensie pentru a exista certitudinea ca totul merge in regula. Ca altfel, se poate arde si este neplacut.
Arhiva cu codul joculetului + simularea Proteus se afla aici:
joculet_rush_hour_vaduva_silviu_333cb.zip
Contact: silviu.vaduva@gmail.com
Driver Nokia 3310 LCD: http://www.quantumtorque.com/content/view/32/37/