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.

Link demo: https://www.youtube.com/watch?v=2sDv7H4uAIs

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. Breadbord-ul este folosit doar pentru a alimenta piesele la 5V, inclusiv rezistentele, fiind lipite in serie direct de led-uri. 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 culoarea 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 verificarea 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, sead-ul 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, servomotor-ul 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 ajutorul 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 nevoit 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 eroarea 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 StackOverflow propune sa folosesti biblioteca PWMServo.h in loc de servo.h. Desi eroarea nu mai apare si programul ruleaza, rezultatul nu este unul satisfacator, servo-ul si buzzer-ul se influenteaza reciproc, ducand la un comportament nedefinit. Am zis, asta e, incerc cu timer 0. Surpriza! delay() si millis() 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.
  • La propunerea lui Florin am vrut sa folosesc o melodie cu ritmuri orientale pentru slot machine. Buzzerul are nevoie de o frecventa ca input, iar dupa ceva cautari am gasit un script de python care converteste notele muzicale in frecvente. Pentru a obtine notele unei melodii am gasit un program https://www.lunaverus.com/ care foloseste AI pentru a realiza acest lucru. Programul genereaza un fisier midi (.mid) si am folosit chatGPT pentru a extragele notele si durata lor. Desi parea ca detin toate piesele puzzle-ului rezultatul nu a fost unul de succes. Sunetul reprodus de buzzer era doar foarte vag asemanator cu originalul. Din ce am putut analiza, rezultatul prost se datoreaza faptului ca unele note sunt suprapuse in timp iar buzzerul poate reproduce doar una dintre ele. Dupa ce am renuntat si la aceasta tentativa, am folosit o melodie gata partitionata de pe github.
  • La acestea se mai adauga si probleme de tensiuni parazite care insa au fost rezolvate usor cu tehnica de debounce si probleme de “infrastructura” cum ar fi: eu cu ce dau gauri? sau: de ce nu vrea sa se lipeasca superglue-ul?

Concluzii

  • Pot sa spun ca mi-a facut placere sa lucrez la acesta tema. Era si pacat ca dupa 4 ani de facultate sa nu raman macar cu un proiect palpabil, fizic.
  • Materia de laborator am inteles-o cu adevarat doar dupa ce am inceput sa lucrez la proiect.
  • Arduino UNO este destul de limitat, doar 3 timere, doar 2 pini de intrerupere directa, memorie putina.
  • Volumul de munca a fost cu MULT peste cel estimat.
  • Socoteala de acasa nu bate cu cea din targ
  • Nu recomand Optimus Digital

Resurse

pm/prj2023/fstancu/roberttruta.txt · Last modified: 2023/05/29 13:07 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