This is an old revision of the document!


Slot Machine - Truta Robert

Descriere generală

Slot machine unde poti paria si castiga bile de sticla. Pentru a paria trebuie introdusa cel putin o bila si selectata una dintre cele 4 culori (rosu, verde, albastru sau mov). Una dintre culori va fi aleasa random si afisata pe un led ring. Daca culoarea aleasa este aceeasi cu cea pariata, sunt eliberate de 3 ori mai multe bile decat numarul introdus. Slot machine-ul emite si muzica cu ajutorul unui buzzer.

Componente

  • Arduino UNO,
  • Servo Motor,
  • Senzor de atingere,
  • Led ring,
  • Leds,
  • Buzzer,
  • Butoane,
  • Rezistente,
  • Fire,
  • Breadboard.

Schemă Bloc

Hardware Design

Schema Hardware

Implementare fizica

Pentru a putea realiza proiectul in forma fizica, pe langa piesele electronice am folosit si placaj MDF, carton, suruburi, aracet, carioci. Breadbordul este folosit doar pentru a alimenta piesele la 5V, inclusiv rezistentele fiind lipite in serie direct de leduri. Ii multumesc lui Florin pentru ajutorul acordat la lipit.

Software Design

Pe langa functiile standard loop si setup, proiectul contine inca 5 alte functii: color_leds, bet, sing, animation, countMarbles. Voi prezenta in continuare rolul si modul de functionare al acestora.

color_leds este responsabila pentru logica celor 4 butoane si celor 4 leduri folosite pentru a inregistra culoare pe care jucatorul doreste sa parieze. Deoarece o singura culoare poate fi pariata la un moment de timp, apasarea unui buton este inregistrata doar pe frontul descrescator (HIGH → LOW) si va “sterge” apasarile anterioare. Acest lucru este realizat cu ajutorul a 3 vectori:

int but_state[5] = {HIGH, HIGH, HIGH, HIGH, HIGH};
int but_state_prev[5] = {HIGH, HIGH, HIGH, HIGH, HIGH};
int led_state[4] = {LOW, LOW, LOW, LOW};

Pentru a exclude din circuit necesitatea unor rezistente pentru butoane am folosit INPUT_PULLUP.

pinMode(but_pins[i], INPUT_PULLUP);

Butoanele, aveau tendinta sa genereze “tranzitii false” dupa o apasare. Pentru a evita acest lucru am folosit tehnica de debounce, astfel verificare unei apasari are loc o data la 100 ms, timp in care tensiunile parazite sunt disipate.

if(millis() - color_time > 100) {
   color_leds();
   color_time = millis();
}

bet este responsabila pentru logica pariului propriu zis. Pariul are loc atunci cand butonul rosu este apasat. Un numar random intre 1 si 15 este ales, seadul pentru random fiind generat de citirea analogica a pinului 6.

randomSeed(analogRead(6));
int random_nr = random(ring_nr_leds);

In cazul in care pariul este castigator, servomotorul elibereaza un numar de bile de 3 ori mai mare decat cel introdus. Controlul motorului este realizat cu ajutorul bibliotecii PWMServo.h. La finalul oricarui pariu numarul de bile introduse este resetat la 0.

animation este functia care genereaza animatia pentru inelul de leduri. Aceasta primeste numarul random ales in momentul pariului si simuleaza o rotire de ruleta. Pentru a controla inelul de leduri am folosit biblioteca Adafruit_NeoPixel.h

countMarbles numara bilele introduse de jucator. Este activata prin intrerupere externa pe pinul 3 generata de frontul crescator al unui senzor de atingere.

attachInterrupt(digitalPinToInterrupt(sensor_pin), countMarbles, RISING);

Si in cadrul acestei functii am folosit technica de debounce pentru a nu inregistra intreruperi false.

sing reproduce theme song-ul Super Mario cu ajoturlui unui buzzer. Pentru a putea interpreta notele muzicale am folosit biblioteca pitches.h care poate fi gasita la adresa https://github.com/hibit-dev/buzzer/tree/master/lib. De asemenea, notele si durata lor au fost preluate de la adresa https://github.com/hibit-dev/buzzer/blob/master/src/games/mario_bros/mario_bros.ino

Probleme intampinate

Au fost atat de multe incat nici nu stiu de unde sa incep.

  • Initial planul era sa folosesc poze cu fructe, in loc de culori, ca tematica a slot machine-ului. Ca atare am comandat un inel de leduri cu diametrul de 5.5 cm, insa din pacate am avut surpriza ca acesta sa nu aiba decat 3 cm. Drept urmare ledurile de pe inel sunt atat de mici si de apropiate incat nu s-ar fi inteles nimic daca as fi folosit poze cu fructe.
  • Primul servo motor comandat nu voia sa mearga decat intr-un singur sens. Dupa o ora de incercari la laborator alaturi de Florin, ne-am dat seama ca acesta tragea atat de mult curent din placuta incat aceasta se reseta. Am fost nevoie sa comand alt servo.
  • Initial planul era ca melodia sa fie cantata non stop, indiferent daca sunt folosite delay-uri sau nu. Am incercat sa folosesc o intrerupere cu timer pentru a schimba nota muzicala o data la 200 ms, insa m-am lovit de eroare multiple definition of _vector_11. Dupa ceva cautari pe Google am aflat ca si biblioteca servo.h foloseste timerul 1, drept urmare existau 2 initializari in conflict. Un raspuns de pe stack overflow propune sa folosesti biblioteca PWMServo.h in loc de servo.h. Desi eroarea nu mai apare si programul ruleaza, rezultatul nu este unul satisfacator, servoul si buzzerul se influenteaza reciproc, ducand la un comportament nedefinit. Am zis, asta e, incerc cu timer 0. Surpriza! delay() si milis() folosesc timer 0. Poate timer 2? multiple definition of _vector_7, functia tune() foloseste timer 2. Dupa ore intregi de setat registrii am decis sa renunt la aceasta idee. In momentul actual melodia poate fi cantata cat timp nu se foloseste un delay.

Concluzii

Resurse

truta_robert_cod.zip

Proiectul a fost inspirat dupa acest video https://www.youtube.com/watch?v=Gg9miQgFtiA

pm/prj2023/fstancu/roberttruta.1685347396.txt.gz · Last modified: 2023/05/29 11:03 by robert.truta
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