Simon's Game: Rozdiel medzi revíziami
Zo stránky SensorWiki
Bez shrnutí editace |
Bez shrnutí editace |
||
Riadok 35: | Riadok 35: | ||
#include <avr/io.h> | #include <avr/io.h> | ||
#include <avr/io.h> | |||
#include <util/delay.h> | |||
#include <stdlib.h> | |||
#include <stdbool.h> | |||
#define F_CPU 16000000UL | |||
return(0); | #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; | |||
} | |||
</source></tab> | </source></tab> |
Verzia z 17:38, 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ť.
Literatúra:
Analýza a opis riešenia
Opíšte sem čo a ako ste spravili, ak treba, doplňte obrázkami...
Nezabudnite doplniť schému zapojenia!
Algoritmus a program
Algoritmus programu je....
#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: zdrojaky.zip
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.
Video:
Kľúčové slová 'Category', ktoré sú na konci stránky nemeňte.