Arduino: Simon Says
O Arduino é uma plataforma de prototipagem eletrônica que, por ser facilmente customizável e programável, é popular entre hobistas e profissionais, sendo utilizado principalmente para prototipagem de instalações multimídia.
Para a atividade da aula do dia 08 de maio, resolvi construir, utilizando algumas das peças disponíveis no Laboratório de Computação Física, um jogo simples de Simon Says, que consiste em apertar os botões correspondentes às luzes que acendem em uma sequência que se amplia a cada acerto do jogador. Esta aplicação foi baseada no trabalho que pode ser visualizado aqui.
Para esta aplicação, foi utilizado 4 botões, 4 resistores de 100 ohm, jumpers (que são fios que conectam o Arduino à Protoboard) 4 LEDs e um speaker, além do Arduino Uno. utilizei a IDE do Arduino versão 1.8.2 no Windows 10.
Para as conexões dos fios e disposições corretas dos componentes, utilizei a ilustração deixada no guia como orientação.
Para a atividade da aula do dia 08 de maio, resolvi construir, utilizando algumas das peças disponíveis no Laboratório de Computação Física, um jogo simples de Simon Says, que consiste em apertar os botões correspondentes às luzes que acendem em uma sequência que se amplia a cada acerto do jogador. Esta aplicação foi baseada no trabalho que pode ser visualizado aqui.

Para as conexões dos fios e disposições corretas dos componentes, utilizei a ilustração deixada no guia como orientação.

Depois de deixar as placas devidamente conectadas e prontas, o resultado obtido foi este aqui:
Em seguida, utilizei o código fornecido pelo autor original do projeto, entretanto, havia uma série de problemas no código em si. Primeiro, por algum motivo, ele não reconhecia a biblioteca que estava sendo utilizada para a produção de sons no speaker, mesmo depois de fazer a importação desta biblioteca para o projeto. Depois de reescrever parte do código que utilizava esta biblioteca, o erro sumiu.
Havia também outro erro no código, em que um vetor do tipo "boolean" recebia valores do tipo "int", causando um erro que foi facilmente resolvido depois de ser corrigido o código, fazendo com que este vetor fosse agora do tipo "int".
Segue o código:
#include <Tone.h>
/*Simon Says game. Now with sound effects.
Originaly made by Robert Spann
Code trimmed and sound effects added by digimike
Buttons are to be set on there designated pins without pull down resistors
and connected to ground rather then +5.
*/
Tone speakerpin;
int starttune[] = {NOTE_C4, NOTE_F4, NOTE_C4, NOTE_F4, NOTE_C4, NOTE_F4, NOTE_C4, NOTE_F4, NOTE_G4, NOTE_F4, NOTE_E4, NOTE_F4, NOTE_G4};
int duration2[] = {100, 200, 100, 200, 100, 400, 100, 100, 100, 100, 200, 100, 500};
int note[] = {NOTE_C4, NOTE_C4, NOTE_G4, NOTE_C5, NOTE_G4, NOTE_C5};
int duration[] = {100, 100, 100, 300, 100, 300};
int button[] = {2, 3, 4, 5}; //The four button input pins
int ledpin[] = {8, 9, 10, 11}; // LED pins
int turn = 0; // turn counter
int buttonstate = 0; // button state checker
int randomArray[100]; //Intentionally long to store up to 100 inputs (doubtful anyone will get this far)
int inputArray[100];
void setup()
{
Serial.begin(9600);
speakerpin.begin(12); // speaker is on pin 12
for(int x=0; x<4; x++) // LED pins are outputs
{
pinMode(ledpin[x], OUTPUT);
}
for(int x=0; x<4; x++)
{
pinMode(button[x], INPUT); // button pins are inputs
digitalWrite(button[x], HIGH); // enable internal pullup; buttons start in high position; logic reversed
}
randomSeed(analogRead(0)); //Added to generate "more randomness" with the randomArray for the output function
for (int thisNote = 0; thisNote < 13; thisNote ++) {
// play the next note:
speakerpin.play(starttune[thisNote]);
// hold the note:
if (thisNote==0 || thisNote==2 || thisNote==4 || thisNote== 6)
{
digitalWrite(ledpin[0], HIGH);
}
if (thisNote==1 || thisNote==3 || thisNote==5 || thisNote== 7 || thisNote==9 || thisNote==11)
{
digitalWrite(ledpin[1], HIGH);
}
if (thisNote==8 || thisNote==12)
{
digitalWrite(ledpin[2], HIGH);
}
if (thisNote==10)
{
digitalWrite(ledpin[3], HIGH);
}
delay(duration2[thisNote]);
// stop for the next note:
speakerpin.stop();
digitalWrite(ledpin[0], LOW);
digitalWrite(ledpin[1], LOW);
digitalWrite(ledpin[2], LOW);
digitalWrite(ledpin[3], LOW);
delay(25);
}
delay(1000);
}
void loop()
{
for (int y=0; y<=99; y++)
{
//function for generating the array to be matched by the player
digitalWrite(ledpin[0], HIGH);
digitalWrite(ledpin[1], HIGH);
digitalWrite(ledpin[2], HIGH);
digitalWrite(ledpin[3], HIGH);
for (int thisNote = 0; thisNote < 6; thisNote ++) {
// play the next note:
speakerpin.play(note[thisNote]);
// hold the note:
delay(duration[thisNote]);
// stop for the next note:
speakerpin.stop();
delay(25);
}
digitalWrite(ledpin[0], LOW);
digitalWrite(ledpin[1], LOW);
digitalWrite(ledpin[2], LOW);
digitalWrite(ledpin[3], LOW);
delay(1000);
for (int y=turn; y <= turn; y++)
{ //Limited by the turn variable
Serial.println(""); //Some serial output to follow along
Serial.print("Turn: ");
Serial.print(y);
Serial.println("");
randomArray[y] = random(1, 5); //Assigning a random number (1-4) to the randomArray[y], y being the turn count
for (int x=0; x <= turn; x++)
{
Serial.print(randomArray[x]);
for(int y=0; y<4; y++)
{
if (randomArray[x] == 1 && ledpin[y] == 8)
{ //if statements to display the stored values in the array
digitalWrite(ledpin[y], HIGH);
speakerpin.play(NOTE_G3, 100);
delay(400);
digitalWrite(ledpin[y], LOW);
delay(100);
}
if (randomArray[x] == 2 && ledpin[y] == 9)
{
digitalWrite(ledpin[y], HIGH);
speakerpin.play(NOTE_A3, 100);
delay(400);
digitalWrite(ledpin[y], LOW);
delay(100);
}
if (randomArray[x] == 3 && ledpin[y] == 10)
{
digitalWrite(ledpin[y], HIGH);
speakerpin.play(NOTE_B3, 100);
delay(400);
digitalWrite(ledpin[y], LOW);
delay(100);
}
if (randomArray[x] == 4 && ledpin[y] == 11)
{
digitalWrite(ledpin[y], HIGH);
speakerpin.play(NOTE_C4, 100);
delay(400);
digitalWrite(ledpin[y], LOW);
delay(100);
}
}
}
}
input();
}
}
void input() { //Function for allowing user input and checking input against the generated array
for (int x=0; x <= turn;)
{ //Statement controlled by turn count
for(int y=0; y<4; y++)
{
buttonstate = digitalRead(button[y]);
if (buttonstate == LOW && button[y] == 2)
{ //Checking for button push
digitalWrite(ledpin[0], HIGH);
speakerpin.play(NOTE_G3, 100);
delay(200);
digitalWrite(ledpin[0], LOW);
inputArray[x] = 1;
delay(250);
Serial.print(" ");
Serial.print(1);
if (inputArray[x] != randomArray[x]) { //Checks value input by user and checks it against
fail(); //the value in the same spot on the generated array
} //The fail function is called if it does not match
x++;
}
if (buttonstate == LOW && button[y] == 3)
{
digitalWrite(ledpin[1], HIGH);
speakerpin.play(NOTE_A3, 100);
delay(200);
digitalWrite(ledpin[1], LOW);
inputArray[x] = 2;
delay(250);
Serial.print(" ");
Serial.print(2);
if (inputArray[x] != randomArray[x]) {
fail();
}
x++;
}
if (buttonstate == LOW && button[y] == 4)
{
digitalWrite(ledpin[2], HIGH);
speakerpin.play(NOTE_B3, 100);
delay(200);
digitalWrite(ledpin[2], LOW);
inputArray[x] = 3;
delay(250);
Serial.print(" ");
Serial.print(3);
if (inputArray[x] != randomArray[x]) {
fail();
}
x++;
}
if (buttonstate == LOW && button[y] == 5)
{
digitalWrite(ledpin[3], HIGH);
speakerpin.play(NOTE_C4, 100);
delay(200);
digitalWrite(ledpin[3], LOW);
inputArray[x] = 4;
delay(250);
Serial.print(" ");
Serial.print(4);
if (inputArray[x] != randomArray[x])
{
fail();
}
x++;
}
}
}
delay(500);
turn++; //Increments the turn count, also the last action before starting the output function over again
}
void fail() { //Function used if the player fails to match the sequence
for (int y=0; y<=2; y++)
{ //Flashes lights for failure
digitalWrite(ledpin[0], HIGH);
digitalWrite(ledpin[1], HIGH);
digitalWrite(ledpin[2], HIGH);
digitalWrite(ledpin[3], HIGH);
speakerpin.play(NOTE_G3, 300);
delay(200);
digitalWrite(ledpin[0], LOW);
digitalWrite(ledpin[1], LOW);
digitalWrite(ledpin[2], LOW);
digitalWrite(ledpin[3], LOW);
speakerpin.play(NOTE_C3, 300);
delay(200);
}
delay(500);
turn = -1; //Resets turn value so the game starts over without need for a reset button
}
Depois de arrumado o código e executado, a aplicação funcionou como esperado. Abaixo, um vídeo demonstrando a aplicação funcionando:
Este jogo pode ser adaptado para diferentes aplicações mais elaboradas utilizando o mesmo princípio básico. Como o jogo em si é focado na memorização de padrões, podemos construir aplicações que utilizem desta característica para engajarem os usuários em diferentes atividades. Um exemplo disso seria a construção de um jogo de basquete em que teríamos diferentes cestas com lâmpadas que piscariam na ordem determinada pelo jogo e, para o jogador poder vencer, ele precisaria fazer arremessos na cestas que correspondessem à ordem feita.
Isto, é claro, apenas um exemplo dentre vários outros que um jogo simples pode ter como aplicação de uma instalação multimídia.
Este jogo pode ser adaptado para diferentes aplicações mais elaboradas utilizando o mesmo princípio básico. Como o jogo em si é focado na memorização de padrões, podemos construir aplicações que utilizem desta característica para engajarem os usuários em diferentes atividades. Um exemplo disso seria a construção de um jogo de basquete em que teríamos diferentes cestas com lâmpadas que piscariam na ordem determinada pelo jogo e, para o jogador poder vencer, ele precisaria fazer arremessos na cestas que correspondessem à ordem feita.
Isto, é claro, apenas um exemplo dentre vários outros que um jogo simples pode ter como aplicação de uma instalação multimídia.
Comentários
Postar um comentário