This is an old revision of the document!


Simon Says - Joc de memorie cu LEDs, LCD si buzzer

Introducere

Proiectul reprezinta o implementare a jocului clasic Simon Says pe placa ATmega328P Xplained Mini. Jocul afiseaza secvente de lumini prin 4 LED-uri colorate, iar jucatorul trebuie sa reproduca secventa in ordinea corecta, apasand butoanele corespunzatoare. Cu fiecare nivel reusit, secventa creste in lungime, iar viteza de afisare creste progresiv.

Proiectul integreaza:

  • LCD 16×2 cu modul I2C pentru afisarea scorului, nivelului, vitezei si mesajelor de stare
  • EEPROM persistent pentru salvarea celui mai bun scor intre resetari
  • Dificultate adaptiva — viteza creste la succese si scade la greseli
  • Feedback sonor prin buzzer pasiv, cu note diferite per culoare
  • Animatii la pornire, victorie si game over

Schema bloc:

Descriere Generala

Logica jocului

  1. La pornire, LCD afiseaza “SIMON SAYS” si cel mai bun scor din EEPROM
  2. LED-urile executa o animatie de bun-venit (se aprind pe rand)
  3. La apasarea oricarui buton, jocul incepe
  4. Microcontrolerul genereaza un element aleator (0-3) si il adauga la secventa
  5. LED-urile se aprind pe rand, in ordinea secventei, cu sunet specific fiecarei culori
  6. Jucatorul reproduce secventa apasand butoanele in ordinea corecta
  7. La raspuns corect: animatie de victorie, nivel urmator, viteza crescuta
  8. La raspuns gresit: sunet de eroare, toate LED-urile clipesc, dificultatea scade usor (dificultate adaptiva)
  9. Scorul cel mai bun este salvat in EEPROM si persista intre resetari

Masina de stari

IDLE (ecran start)
    │ apasare buton
    ▼
SHOW_SEQUENCE (afisare secventa LED-uri)
    │ secventa terminata
    ▼
WAIT_INPUT (asteapta input jucator)
    ├─ corect → CORRECT (animatie + nivel urmator) → SHOW_SEQUENCE
    └─ gresit → GAME_OVER (animatie + salvare scor) → IDLE

Hardware Design

Lista de componente

Componenta Model/Valoare Cantitate Rol in proiect
Microcontroller ATmega328P Xplained Mini 1 Unitate centrala de control
Display LCD 16×2 cu modul I2C (PCF8574) 1 Afisare scor, nivel, mesaje
LED rosu 5mm, 2V, 20mA 1 Culoarea 1 a jocului
LED albastru 5mm, 3.2V, 20mA 1 Culoarea 2 a jocului
LED verde 5mm, 2.1V, 20mA 1 Culoarea 3 a jocului
LED galben 5mm, 2V, 20mA 1 Culoarea 4 a jocului
Rezistenta 220Ω 4 Protectie LED-uri
Butoane tactile 6x6mm 4 Input jucator
Buzzer pasiv 5V 1 Feedback sonor
Breadboard 830 puncte 1 Prototipare
Fire jumper M-M ~25 Conexiuni

Pinii folositi

Componenta Pin ATmega Pin Arduino Motivatie alegere
LED rosu PD4 D4 GPIO simplu, fara functii speciale
LED albastru PD5 D5 GPIO simplu, fara functii speciale
LED verde PD6 D6 GPIO simplu, fara functii speciale
LED galben PD7 D7 GPIO simplu, fara functii speciale
Buton rosu PB0 D8 GPIO cu pull-up intern disponibil
Buton albastru PB1 D9 GPIO cu pull-up intern disponibil
Buton verde PB2 D10 GPIO cu pull-up intern disponibil
Buton galben PB3 D11 GPIO cu pull-up intern disponibil
Buzzer PB4 D12 Compatibil cu functia tone()
LCD SDA PC4 A4 Pin hardware TWI/I2C al ATmega
LCD SCL PC5 A5 Pin hardware TWI/I2C al ATmega

Motivatia alegerii pinilor:

  • PD0/PD1 au fost evitati — sunt RX/TX, folositi de comunicatia seriala USB cu mEDBG
  • PC4/PC5 sunt pinii hardware TWI (I2C) ai ATmega328P, oferind comunicatie stabila cu LCD-ul
  • PB4 (D12) este compatibil cu timer-ul folosit intern de functia tone() pentru generarea de frecvente audio
  • LED-urile pe PD4-PD7 permit setarea simultana prin operatii pe registrul PORTD

Schema electrica

LED-uri (x4, conectare identica):

Pin GPIO (PD4-PD7) ──────── Anod LED (+, picior lung)
                             Catod LED (-, picior scurt) ── Rezistenta 220Ω ── GND

Butoane (x4, cu pull-up intern):

Pin GPIO (PB0-PB3) ──────── Pin 1 buton
GND ─────────────────────── Pin 2 buton (opus)
Pull-up intern activat in cod prin INPUT_PULLUP
Butonul citeste LOW cand e apasat, HIGH cand e liber

Buzzer pasiv:

PB4 (D12) ──────────────── Pin + buzzer
GND ─────────────────────── Pin - buzzer

LCD I2C:

PC4 (A4/SDA) ───────────── SDA modul I2C
PC5 (A5/SCL) ───────────── SCL modul I2C
5V ──────────────────────── VCC modul I2C
GND ─────────────────────── GND modul I2C
Potentiometru albastru pe modul = reglaj contrast

Alimentare breadboard:

5V placa  ──── linia rosie (+) breadboard
GND placa ──── linia albastra (-) breadboard

5211176995717324748.jpg

Software Design

Mediu de dezvoltare

  • PlatformIO + framework Arduino (MiniCore pentru ATmega328P)
  • Arduino IDE (alternativ, pentru upload rapid)
  • Limbaj: C++ cu API Arduino

Biblioteci folosite

Biblioteca Sursa Motivatie
Wire.h Built-in Arduino Comunicatie I2C hardware cu LCD — nu necesita instalare externa
EEPROM.h Built-in Arduino Acces la memoria EEPROM a ATmega328P pentru persistenta high score
Arduino.h Built-in API de baza: pinMode, digitalWrite, tone, delay

Motivatia alegerii Wire.h in loc de LiquidCrystal_I2C: Libraria LiquidCrystal_I2C a prezentat probleme de compatibilitate cu toolchain-ul MiniCore pentru ATmega328P Xplained Mini. Solutia adoptata a fost implementarea directa a protocolului I2C pentru LCD folosind Wire.h (built-in), scriind manual functiile de initializare, trimitere nibble/byte, setare cursor si print. Aceasta abordare ofera control complet si elimina dependentele externe.

Elementul de noutate

  • Dificultate adaptiva bidiectionala: viteza creste la succese si scade la greseli, mentinand jocul accesibil indiferent de nivelul jucatorului
  • Sistem de bonus: 3 raspunsuri consecutive corecte declanseaza o crestere suplimentara a vitezei
  • Persistenta high score in EEPROM: scorul maxim supravietuieste resetarilor si deconectarii de la alimentare
  • Animatii procedurale: secventele de LED-uri la pornire, victorie si eroare sunt generate programatic, fara timere hardware blocante

Functionalitati din laborator utilizate

Functionalitate Utilizare in proiect
GPIO output Control LED-uri: PORTD pentru afisarea secventei
GPIO input cu pull-up Citire butoane fara rezistente externe: INPUT_PULLUP pe PB0-PB3
Timer (tone()) Generare frecvente audio pentru buzzer pasiv — intern foloseste Timer2
TWI/I2C (Wire.h) Comunicatie cu modulul LCD prin 2 fire (SDA/SCL)
EEPROM Stocare persistenta a high score-ului la adresa 0
Intreruperi soft (debounce) Eliminarea zgomotului mecanic al butoanelor prin delay 50ms + asteptare release

Scheletul proiectului

// Masina de stari implementata prin apeluri recursive de functii:
 
asteaptaStart()
  └─> animatieStart() + afisare LCD "SIMON SAYS + Best Score"
  └─> asteapta apasare buton → incepeJoc()
 
incepeJoc()
  └─> reseteaza lungime=1, viteza=600ms, scor=0
  └─> genereazaSecventa() → arataSiAsteapta()
 
arataSiAsteapta()
  └─> afiseaza nivel + viteza pe LCD
  └─> aprinde LED-urile pe rand cu sunet (secventa)
  └─> pentru fiecare element din secventa:
        asteaptaButon()
          └─> corect: feedback LED+sunet, continua
          └─> gresit: gameOver()
  └─> dupa secventa completa: animatieVictorie()
  └─> dificultate adaptiva: scade viteza (creste dificultatea)
  └─> bonus daca 3 consecutive corecte
  └─> genereazaSecventa() + arataSiAsteapta() (nivel urmator)
 
gameOver()
  └─> dificultate adaptiva: creste viteza (scade dificultatea)
  └─> verifica si salveaza high score in EEPROM
  └─> afisare LCD "Game Over + Scor + Best"
  └─> asteaptaStart()

Validare functionare

Validarea s-a realizat in mai multe etape:

1. Testare LED-uri individual:

// Cod de test: fiecare buton aprinde LED-ul corespunzator
if (digitalRead(butoane[i]) == LOW) digitalWrite(leduri[i], HIGH);

2. Validare prin Serial Monitor: La fiecare eveniment (nivel, apasare buton, corect/gresit) se afiseaza mesaje pe Serial Monitor la 9600 baud:

=== Nivel: 3 | Viteza: 540ms ===
  -> ROSU
  -> VERDE
  -> ALBASTRU
Randul tau!
  Apasat: ROSU -> Corect!
  Apasat: VERDE -> Corect!
  Apasat: ALBASTRU -> Corect!
BONUS VITEZA! 3 consecutive corecte!

3. Testare EEPROM: Dupa game over cu scor nou, s-a verificat ca la resetare hardware scorul persista (afisat pe LCD la pornire).

Optimizari realizate

  • Debounce software: dupa detectarea apasarii, se asteapta 50ms si release-ul butonului, eliminand bouncing-ul mecanic
  • randomSeed(analogRead(A3)): pinul A3 (neconectat) citeste zgomot analogic, asigurand secvente cu adevarat aleatorii la fiecare pornire
  • Implementare I2C manuala: elimina overhead-ul unei librarii externe, reducand dimensiunea codului compilat
  • Dificultate adaptiva bidiectionala: mentine jocul engageable indiferent de skill-ul jucatorului

Rezultate Obtinute

Proiectul functioneaza conform specificatiilor:

  • Secventele sunt generate aleator si afisate corect pe LED-uri cu sunet
  • Butoanele sunt detectate corect cu debounce
  • LCD-ul afiseaza nivel, viteza curenta si scor in timp real
  • High score-ul persista in EEPROM intre resetari
  • Dificultatea se ajusteaza dinamic in functie de performanta jucatorului

Concluzii

Proiectul Simon Says a fost implementat cu succes pe placa ATmega328P Xplained Mini, demonstrand utilizarea GPIO, I2C, EEPROM si timer-e in cadrul framework-ului Arduino.

Principalele provocari intampinate:

  • Compatibilitatea librariei LiquidCrystal_I2C cu toolchain-ul MiniCore — rezolvata prin implementare manuala Wire.h
  • Conflicte de pini intre RX/TX si LED-uri — rezolvate prin relocarea LED-urilor pe PD4-PD7
  • Calibrarea debounce-ului butoanelor pentru raspuns fluid

Bibliografie

pm/prj2026/alexandru.jipa2803/valentina.ceban.1779637113.txt.gz · Last modified: 2026/05/24 18:38 by valentina.ceban
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0