# Smart Roulette - Patrasc Andrea - Eduardo , 336CAb ## Flow program * In *loop()* avem 2 functii principale: * *print_welcome_message()* care afiseaza mesajul de Welcome pe LCD * *handle_button_actions()* functia care controleaza tot flow-ul programului in functie de apasarea pe cele 3 butoane. * In *handle_button_actions()* tinem cont de cele 4 stari in care se poate afla programul, sau mai exact, afisajul LCD-ul: * *BET_MODE* (ecran in care userul alege suma de pariat) * *COLOR_MODE*(ecran in care userul alege culoarea de pariat) * *SPIN_MODE* (ecran in care userul poate actiona accelerometrul pentru a "invarti" ruleta) * *WIN_LOSE_MODE* (ecran in care este afisat daca userul a castigat/pierdut si suma castigata aduna la balance-ul curent daca e cazul). * Flow-ul pentru a ajunge din ecran in ecran este urmatorul: * User asteapta sa treaca ecranul de Welcome si se trece in BET_MODE * In BET_MODE incrementeaza (btn albastru) sau decrementeaza (btn negru) suma de pariat si confirma print btn galben si se trece in COLOR_MODE. * In COLOR_MODE se apasa unul dintre butoane pentru a paria pe o culoare: * YELLOW = RED * BLACK = BLACK * ALBAASTRU = GREEN * Acum ecranul o sa se afle in SPIN_MODE unde userul actioneaza acceloremetrul care este captat si tratat in *read_accelerometer_data_handle_spin()* unde: * Programul capteaza vibratia accelerometrului si salveaza valoarea. In functie de aceasta valoarea controlam rapiditatea cu care se aprind led-urile (velocitatea rotii).Rotatia ruletei (aprindere led-ur, declansare buzzer, calculare profit si resetare ecran/mod joc) este tratata in functia *spin_roulette(float avg_spin_power)*: * La sfarsit rotatiei, se intra pe ecranul de WIN_LOSE si se afiseaza informatiile corespunzatoare. * La sfarsit, ecranul ramane in stand-by in ecranul *WIN_LOSE_MODE* unde userul va putea sa apese din nou pe butonul Galben pentru a reincepe jocul. (suma adunata din castiguri se pastreaza). ### Detalii implemetare functii: * *handle_buttons_actions()* : * Functii clasice de tratare apasare *singulara* pe un buton pe baza algoritmului de *state change*. * Afisarea pe LCD se face cu functiile clasice : * lcd.print() in combinatie cu lcd.clear(), lcd.setCursor()... * *read_accelerometer_data_handle_spin()* : * Citesc valorile x, y, z ale accelerometrului prin urmatorul cod: ```c Wire.beginTransmission(ADXL345); Wire.write(0x32); // Start with register 0x32 (ACCEL_XOUT_H) Wire.endTransmission(false); Wire.requestFrom(ADXL345, 6, true); // Read 6 registers total, each axis value is stored in 2 registers X_out = (Wire.read() | Wire.read() << 8); // X-axis value X_out = X_out / 256; // For a range of +-2g, we need to divide the raw values by 256, according to the datasheet Y_out = (Wire.read() | Wire.read() << 8); // Y-axis value Y_out = Y_out / 256; Z_out = (Wire.read() | Wire.read() << 8); // Z-axis value Z_out = Z_out / 256; ``` * Retin modulul acestor valori si modulul valorilor rularii anterioare. * Daca roata nu este in modul de rotatie si daca diferenta intre valorile coordonatelor inregistrate acum si valorile inregistrate in masuratoarea anterioara este mai mare decat un *spin_treshold* de 0.35 (ales mai mult sau mai putin random), atunci calculam o velocitate a rotatiei prin media aritmetica a celor 3 diferenta. In functie de aceasta valoarea (*avg_spin_power* in cod) controlam cat de "rapid de invarte ruleta". ```c float avg_spin_power = (diff_x + diff_y + diff_z) / 3; ``` * De mentionat aici este ca nu vrem sa citim fix primele 3 rezultate/coordonate masurate de accelerometru deoarece ele nu au o valoarea anterioare de comparatie prin care putem face diferenta si, logic, mereu o sa se depaseasca acel mic *spin_treshold* de 0.35. * *spin_roulette(float avg_spiin_power)* : * Calculam numar random de rotiri si index led random la care o sa se opreasca roata * In functie de *avg_spin_power()* setam delay-ul intre care se aprind led-urile pentru a simular practic invartirea rotii. Aprinderea unui led se face prin setare pe "1" unui bit din shift register. Totdata, cand setam un bit, ne asiguram sa declansam si un mic sunet din partea buzzerului. * La sfarsit, daca led-ul pe care s-a oprit roata corespunde cu culoarea pariata calculam profitul si setam pe 1 starea *WIN_LOSE_MODE* pentru a anunta LCD sa intre in ecranul de afisare a profit/pierdere.