Operácie

Simon's Game: Rozdiel medzi revíziami

Z SensorWiki

Riadok 19: Riadok 19:
 
Tento program som vytvoril na ovládanie štyroch LEDiek pomocou joysticku. Najprv sa navrhlo samotné ovládanie LEDiek joystickom. Následne som dokódoval aby sa najprv LEDky rozsvietili v náhodnej sekvencii. Nakoniec som dokódoval aby po doznení danej sekvencie uživateľ danú sekvenciu zopakoval a program vyhodnotí, či sa sekvencia rovná alebo nerovná roszvietením LEDiek. Joystick sa taktiež využil na zresetovanie a opakované spustenie novej sekvencie aby sa nemusel využívať reset button na doske Arduino.
 
Tento program som vytvoril na ovládanie štyroch LEDiek pomocou joysticku. Najprv sa navrhlo samotné ovládanie LEDiek joystickom. Následne som dokódoval aby sa najprv LEDky rozsvietili v náhodnej sekvencii. Nakoniec som dokódoval aby po doznení danej sekvencie uživateľ danú sekvenciu zopakoval a program vyhodnotí, či sa sekvencia rovná alebo nerovná roszvietením LEDiek. Joystick sa taktiež využil na zresetovanie a opakované spustenie novej sekvencie aby sa nemusel využívať reset button na doske Arduino.
  
[[Súbor:ledRGB.jpg|400px|thumb|center|RGB LED.]]
+
[[Súbor:Schemasimon.png|400px|thumb|center|RGB LED.]]
  
 
Nezabudnite doplniť schému zapojenia!
 
Nezabudnite doplniť schému zapojenia!
  
[[Súbor:Diagramfinal.png|400px|thumb|center|Schéma zapojenia joysticku a LEDiek.]]
+
[[Súbor:Diagramfinalfinal.png|400px|thumb|center|Schéma zapojenia joysticku a LEDiek.]]
  
  

Verzia zo dňa a času 18:15, 5. jún 2024

Záverečný projekt predmetu MIPS / LS2024 - Ondrej Tarcal


Zadanie

Cieľom zadania bolo naprogramovať Simon's game. V skratke hra by mala fungovať tak, že doska generuje náhodnú sekvenciu a my ju musíme následne zopakovať.

Doska Arduino UNO R3.

Literatúra:


Analýza a opis riešenia

Tento program som vytvoril na ovládanie štyroch LEDiek pomocou joysticku. Najprv sa navrhlo samotné ovládanie LEDiek joystickom. Následne som dokódoval aby sa najprv LEDky rozsvietili v náhodnej sekvencii. Nakoniec som dokódoval aby po doznení danej sekvencie uživateľ danú sekvenciu zopakoval a program vyhodnotí, či sa sekvencia rovná alebo nerovná roszvietením LEDiek. Joystick sa taktiež využil na zresetovanie a opakované spustenie novej sekvencie aby sa nemusel využívať reset button na doske Arduino.

RGB LED.

Nezabudnite doplniť schému zapojenia!

Schéma zapojenia joysticku a LEDiek.


Program

1. Definície a Inicializácie

Naprv sa preddefinovali makrá pre LEDky a ich polohy a mŕtve zóny joysticka. Inicializácia ADC prevodníka, čítanie z ADC, inicializacia LEDiek, tlačidla na joysticku a kontrola stlačenia tlačidla

2. Funkcie pre samotnú hru

zobrazenie LEDiek, generovanie náhodných sekvencií a následne zobrazenie sekvencií cez LEDky. Získanie sekvencie od uživateľa cez joystick, kontrola sekvencie a indikácia úspechu alebo neúspechu


#include <avr/io.h>

#include <avr/io.h>
#include <util/delay.h>
#include <stdlib.h>
#include <stdbool.h>

#define F_CPU 16000000UL

#define LED_LEFT    PD2
#define LED_RIGHT   PD3
#define LED_DOWN    PD4
#define LED_UP      PD5

#define BUTTON_PIN  PD6

#define THRESHOLD_X_MIN 300
#define THRESHOLD_X_MAX 700
#define THRESHOLD_Y_MIN 300
#define THRESHOLD_Y_MAX 700

void ADC_Init() {
    ADMUX = (1 << REFS0); // Set ADC reference to AVCC
    ADCSRA = (1 << ADEN) | (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0); // Zapne ADC a nastavi predelicku na 128
}

uint16_t ADC_Read(uint8_t channel) {
    ADMUX = (ADMUX & 0xF0) | (channel & 0x0F); // Select ADC channel
    ADCSRA |= (1 << ADSC); // zacne jednotkovu konverziu
    while (ADCSRA & (1 << ADSC)); // caka na dokoncenie konverzie
    return ADC; // vrati ADC hodnotu
}

void LED_Init() {
    DDRD |= (1 << LED_LEFT) | (1 << LED_RIGHT) | (1 << LED_DOWN) | (1 << LED_UP);
    PORTD &= ~((1 << LED_LEFT) | (1 << LED_RIGHT) | (1 << LED_DOWN) | (1 << LED_UP));
}

void Button_Init() {
    DDRD &= ~(1 << BUTTON_PIN); // tlacitko na joysticku input bude
    PORTD |= (1 << BUTTON_PIN); //  pull-up resistor 
}

bool isButtonPressed() {
    return !(PIND & (1 << BUTTON_PIN)); // Return true if button is pressed
}

void displayLED(int ledIndex) {
    PORTD &= ~((1 << LED_LEFT) | (1 << LED_RIGHT) | (1 << LED_DOWN) | (1 << LED_UP));

    switch (ledIndex) {
        case 1:
            PORTD |= (1 << LED_LEFT);
            break;
        case 2:
            PORTD |= (1 << LED_RIGHT);
            break;
        case 3:
            PORTD |= (1 << LED_DOWN);
            break;
        case 4:
            PORTD |= (1 << LED_UP);
            break;
        default:
            break;
    }
}

void generateRandomSequence(int sequence[], int length) {
    for (int i = 0; i < length; i++) {
        sequence[i] = (rand() % 4) + 1; // Random cislo medzi 1 az 4
    }
}

void displayLEDSequence(int sequence[], int length) {
    for (int i = 0; i < length; i++) {
        displayLED(sequence[i]);
        _delay_ms(5000); // kazdu led vysvieti na dany cas
        displayLED(0); // vypne vsetky ledky
        _delay_ms(2000); // medzera pred dalsou ledkou vysvietenou
    }
}

void getUserInputSequence(int userSequence[], int length) {
    for (int i = 0; i < length; i++) {
        bool inputReceived = false;

        // Wait for a valid input from the joystick
        while (!inputReceived) {
            if (isButtonPressed()) return; // zresetuje sekvenciu ak sa zatlaci joystick

            uint16_t xAxisValue = ADC_Read(0);
            uint16_t yAxisValue = ADC_Read(1);

            if (xAxisValue < THRESHOLD_X_MIN) {
                userSequence[i] = 1; // Left
                inputReceived = true;
            } else if (xAxisValue > THRESHOLD_X_MAX) {
                userSequence[i] = 2; // Right
                inputReceived = true;
            } else if (yAxisValue < THRESHOLD_Y_MIN) {
                userSequence[i] = 3; // Down
                inputReceived = true;
            } else if (yAxisValue > THRESHOLD_Y_MAX) {
                userSequence[i] = 4; // Up
                inputReceived = true;
            }

            // rozsvieti tu LEDku ktoru ma podla inputu
            if (inputReceived) {
                displayLED(userSequence[i]);
                _delay_ms(2000); // Small delay to show the LED
                displayLED(0); // Turn off the LED
            }
        }
    }
}

bool checkUserInput(int sequence[], int userSequence[], int length) {
    for (int i = 0; i < length; i++) {
        if (sequence[i] != userSequence[i]) {
            return false; // nespravny input
        }
    }
    return true; // sekvencie sa zhoduju
}

void indicateSuccess() {
    // ak sedi sekvencia rozsvieti ledky
    PORTD |= ((1 << LED_LEFT) | (1 << LED_RIGHT) | (1 << LED_DOWN) | (1 << LED_UP));
    _delay_ms(1000);
    PORTD &= ~((1 << LED_LEFT) | (1 << LED_RIGHT) | (1 << LED_DOWN) | (1 << LED_UP));
}

void indicateFailure() {
    // ak nesedi sekvencia rozsvieti inak rozsvieti ledky
    for (int i = 0; i < 3; i++) {
        PORTD |= ((1 << LED_LEFT) | (1 << LED_DOWN));
        _delay_ms(200);
        PORTD &= ~((1 << LED_LEFT) | (1 << LED_DOWN));
        _delay_ms(200);
    }
}

int main(void) {
    ADC_Init();
    LED_Init();
    Button_Init();

    srand(42); // Initialize random number generator

    int sequenceLength = 4;
    int sequence[sequenceLength];
    int userSequence[sequenceLength];

    while (1) {
        generateRandomSequence(sequence, sequenceLength);
        displayLEDSequence(sequence, sequenceLength);

        getUserInputSequence(userSequence, sequenceLength);

        if (isButtonPressed()) {
            // zresetuje sekvenciu ak je stlaceny joystick
            continue;
        }

        bool sequenceMatched = checkUserInput(sequence, userSequence, sequenceLength);

        if (sequenceMatched) {
            indicateSuccess();
        } else {
            indicateFailure();
        }

        // caka na resetu tlacitko pred zacatim novej sekvencie
        while (!isButtonPressed()) {
            _delay_ms(100);
        }
        
        // Small delay to debounce the button press
        _delay_ms(200);
    }

    return 0;
}
#include <avr/io.h>

void adc_init(void);                                   // A/D converter initialization

unsigned int adc_read(char a_pin);

Pridajte sem aj zbalený kompletný projekt, napríklad takto (použite jednoznačné pomenovanie, nemôžeme mať na serveri 10x zdrojaky.zip:

Zdrojový kód: OndrejTarcal_Simons_game


Overenie

Na používanie našej aplikácie stačia dve tlačítka a postup používania je opísaný v sekcii popis riešenia. Na konci uvádzame fotku záverečnej obrazovky pred resetom. Vypísaný je tu priemerný čas a najlepší čas.

Aplikácia.

Video:

Kľúčové slová 'Category', ktoré sú na konci stránky nemeňte.