Utilizando Joystick com Arduino

Joystick-com-Arduino
Font Size

Olá, tudo bem? Hoje vamos utilizar o Joystick com Arduino e criar um projeto bem bacana. Certamente você já utilizou ele em seus projetos ou já tenha utilizado ele e nem sabia.

Então, vamos agora conhecer um pouco melhor o seu funcionamento, além de criar um super projeto, vamos nessa?

Funcionamento Joystick

Quando falamos sobre Joystick, a primeira ideia que vem é de jogos, mais especificamente um controlador de jogo. Inegavelmente, é exatamente isso. Então, este joystick não é nada além de uma combinação de dois potenciômetros para o plano X e Y, respectivamente.

Dessa forma, ele realiza a leitura da tensão através dos potenciômetros e envia valores analógicos ao Arduino. Assim, é esperado que o valor analógico mude à medida que movemos o eixo do joystick (que é simplesmente o ponteiro do potenciômetro).

Módulo Joystick

Agora falando mais sobre o nosso módulo e da utilização do joystick com Arduino, ele normalmente fornece saídas do tipo analógicas e as suas tensões de saída são alteradas de acordo com a direção em que nós o movemos. 

Por fim, para obtermos as direções do movimento, temos que interpretar a mudanças de tensão seguindo os valores da imagem abaixo.

Valor de tensão do Joystick

Display Nokia 5110

A escolha do display Nokia se baseou muito na forma que iremos apresentar o nosso projeto e no espaço que ele ocupa no circuito. Pois, comparando ele com o famoso Display LCD, notamos que ele possui maior largura o que facilita na parte gráfica.

Hardware do Display Nokia 5110

Outro ponto importante é o fato dele aceitar imagens no formato bitmap. Esse e outros pontos sobre o Display Nokia, eu expliquei no post sobre a sua utilização. Confere lá clicando no botão abaixo.

Explicando o Projeto Joystick com Arduino

Mas o que iremos fazer hoje? No post de hoje vamos desenvolver um jogo no display Nokia. Para tal jogo, será importante a prática do conhecimento de Joystick que expliquei até o momento sobre a leitura dos valores de tensão. Combinado?

Basicamente, vamos utilizar o espaço que nosso display dispõe. Utilizaremos a resolução de 84*48 para alocar toda a parte gráfica do jogo. A qual consiste em um placar e naves do nosso jogo espacial.

Serão três ruas onde duas sempre terão naves alienígenas e o jogador com sua nave deverá ir para a pista vazia sem poder chocar com as naves inimigas. Beleza? Simples assim!

Componentes do Projeto Joystick com Arduino

Vamos então a nossa lista de componentes de hoje. Separe todos eles e realize a ligação do joystick no arduino seguindo o circuito na imagem logo abaixo.

Montagem do Circuito com Joystick

Esquema de ligação no Arduino

Código do Projeto Comentado

<code>/* ==================================================================================================

Projeto: Jogo Espacial com Joystick e Display 5110
Autor: Danilo Nogueira
Data: 04/08/2019

**Código Modificado de Circuit Digest**

// ==================================================================================================*/
// --- Declaração Bibliotecas ---

#include &lt;SPI.h&gt;               // Biblioteca para realizar a comunicação
#include &lt;Adafruit_GFX.h&gt;      // Bibliteca Gráfica para usar no Display
#include &lt;Adafruit_PCD8544.h&gt;  // Biblioteca do Display 5110

// ==================================================================================================
// --- Declaração das Variáveis ---

// Imagem em Bitmap da Nave Espacial
static const unsigned char PROGMEM ship[] =
{
B00000000,B00000000,
B00000001,B00000000,
B00000011,B10000000,
B00000010,B10000000,
B00000010,B11000000,
B00000111,B11000000,
B00001101,B11100000,
B00011111,B11110000,
B00111111,B11111000,
B01111111,B11111100,
B01111111,B11111100,
B01111111,B11111100,
B00011111,B11110000,
B00000111,B11100000,
B00000000,B00000000,
};

// Imagem em Bitmap da Nave Inimiga
static const unsigned char PROGMEM enemy[] =
{
B00000101,B11000000,
B00001011,B11100000,
B00000011,B11100000,
B00110011,B11111000,
B01111111,B11111100,
B10111111,B11111010,
B01110111,B11011100,
B01111110,B11111100,
B00111111,B11111100,
B11101111,B11101110,
B11000001,B00000110,
B10000001,B00000010,
B10000000,B00000010,
B00000000,B00000000,
};

// Passando a pinagem de ligação do Display no Arduino
Adafruit_PCD8544 display = Adafruit_PCD8544(8, 9, 10, 11, 12);      // Criando o construtor e passando a pinagem dele

int  enemy_0_pos, enemy_1_pos, enemy_phase;
int  Joy_X;
int  game_speed = 0;
int  pontuacao = 0;
char POS = 2;
boolean enemy_dead = true;
boolean control = true;

// ==================================================================================================
// --- Configurando o void setup() ---
void setup()   {
  Serial.begin(9600); // Velocidade de Comunicação da Seial

  display.begin();          // Iniciando a comunicação do Display
  display.setContrast(55);  // Configurando o contraste do Display
  display.clearDisplay();   // Limpando o Display
}

// ==================================================================================================
// --- Configurando o void loop() ---
void loop() {
  display.clearDisplay();

  TelaJogo(); // Chamando a função para desenhar o jogo na tela.

  // Coletando os dados do Joystick  
  Joy_X = analogRead(A1); // Realizando a leitura do eixo X
  
  if (Joy_X &gt; 800 &amp;&amp; POS!=1 &amp;&amp; control==true) // Caso o Joystick mova p/ ---&gt;
  { 
    POS--;    // Vai trocar de pista (decrementar sua posição)
    control = false;
  }
  
  if (Joy_X &lt; 312 &amp;&amp; POS!=3 &amp;&amp; control==true) // Caso mova-se novamente para &lt;--
  {
    POS++;
    control = false;
  }
  
  if (Joy_X &gt; 490 &amp;&amp; Joy_X &lt; 522) // Se o joystick voltar ao estado parado
  control = true;

  player_car(POS); // Posição da nave na tela de acordo com a posição do joystick

  delay(100);
  if (enemy_dead) // Verifica se a nave inimiga morreu (não teve choque das naves)
  {
    enemy_0_pos = POS;           // Cria uma nave inimiga na mesma pista que a nossa nave
    enemy_1_pos = random(0,4);   // Cria a segunda nave numa posição sorteada aleatoriamente
    enemy_phase = 0;             // As naves inimigas iniciam no topo da tela
    enemy_dead = false;
  }

  // Função para desenhar a nave inimiga na pista indicada e no topo da tela
  enemy_ship (enemy_0_pos,enemy_phase); enemy_phase++; 
  enemy_ship (enemy_1_pos,enemy_phase); enemy_phase++; 

  // Caso a nossa nave toque em alguma nave inimiga é GAME OVER!
  if (enemy_phase&gt;22 &amp;&amp; ((enemy_0_pos == POS) || (enemy_1_pos == POS))) 
    game_over(); // Mostra no Display a mensagem 'game over'
  
  // Caso não ocorra nenhuma batida, o jogador ganha 1 ponto
  if (enemy_phase&gt;40)
  {
    enemy_dead = true;  // O inimigo é morto e novos inimigos são criados
    pontuacao++;
  }

  // Função para aumentar a velocidade de acordo com a pontuacao
  Controle_Veloc();

  display.display();  // Atualiza o display com as alterações
}

void  Controle_Veloc() 
{ 
  if (pontuacao&gt;=0 &amp;&amp; pontuacao&lt;=10) 
  {
    game_speed = 0; delay(100);
  }
    if (pontuacao&gt;10 &amp;&amp; pontuacao&lt;=20) 
  {
    game_speed = 1; delay(80);
  }
    if (pontuacao&gt;20 &amp;&amp; pontuacao&lt;=30)  
  {
    game_speed = 2; delay(75);
  }
    if (pontuacao&gt;30 &amp;&amp; pontuacao&lt;=40)
  {
    game_speed = 3; delay(55);
  }
}

void enemy_ship(int place, int phase)
{
  if (place==1)
  display.drawBitmap(2, phase, enemy, 15, 15, BLACK);

  if (place==2)
  display.drawBitmap(18, phase, enemy, 15, 15, BLACK);

  if (place==3)
  display.drawBitmap(34, phase, enemy, 15, 15, BLACK);
}

void game_over()
{
  while(1)
  {
    delay(100);
  display.clearDisplay();  
  display.setCursor(16,20);
  display.println("SE FUDEO!");
  
  display.display();  
  }
}

void TelaJogo()
{
  // Desenha a linha que separa jogo | pontuacao
  display.drawLine(0, 0, 0, 47, BLACK);
  display.drawLine(50, 0, 50, 47, BLACK);
  display.drawLine(0, 47, 50, 47, BLACK);

  display.setTextSize(1);
  display.setTextColor(BLACK);
  
  display.setCursor(52,2);
  display.println("Km/h");
  display.setCursor(54,12);
  display.println(game_speed);
  
  display.setCursor(52,25);
  display.println("Pont.");
  display.setCursor(54,35);
  display.println(pontuacao);
}

void player_car(char pos)
{
  if (pos==1)
  display.drawBitmap(2, 32, ship, 15, 15, BLACK);

  if (pos==2)
  display.drawBitmap(18, 32, ship, 15, 15, BLACK);

  if (pos==3)
  display.drawBitmap(34, 32, ship, 15, 15, BLACK);
}
// =========================== FIM ===============================</code>

Explicação do Código

O nosso código inicia com a declaração das bibliotecas que iremos utilizar. Que seria a parte gráfica do display fora a comunicação entre os módulos.

<code>#include &lt;SPI.h&gt;               // Biblioteca para realizar a comunicação
#include &lt;Adafruit_GFX.h&gt;      // Bibliteca Gráfica para usar no Display
#include &lt;Adafruit_PCD8544.h&gt;  // Biblioteca do Display 5110</code>

Em seguida, temos a declaração das variáveis que iremos utilizar. Vamos começar com a criação das naves, PROGMEM ship e PROGMEM enemy.

Logo após, definimos a pinagem dos módulos e as variáveis para pontuação e deslocamento na tela.

<code>// Passando a pinagem de ligação do Display no Arduino
Adafruit_PCD8544 display = Adafruit_PCD8544(8, 9, 10, 11, 12);

int  enemy_0_pos, enemy_1_pos, enemy_phase;
int  Joy_X;
int  game_speed = 0;
int  pontuacao = 0;
char POS = 2;
boolean enemy_dead = true;
boolean control = true;</code>

Já no void setup(), iniciamos a comunicação serial e setamos o display definindo um valor inicial do contraste.

<code>void setup()   {
  Serial.begin(9600); // Velocidade de Comunicação da Seial

  display.begin();          // Iniciando a comunicação do Display
  display.setContrast(30);  // Configurando o contraste do Display
  display.clearDisplay();   // Limpando o Display
}</code>

Por fim, entramos no void loop() onde toda a parte lógica é executada onde chamamos as funções para executar os comandos.

Ao entrar nos if, vamos analisar o valor da tensão enviado pelo joystick e realizar o movimento necessário.

<code>// Coletando os dados do Joystick  
  Joy_X = analogRead(A1); // Realizando a leitura do eixo X
  
  if (Joy_X &lt; 312 &amp;&amp; POS!=1 &amp;&amp; control==true) // Caso o Joystick mova p/ ---&gt;
  { 
    POS--;    // Vai trocar de pista (decrementar sua posição)
    control = false;
  }
  
  else if (Joy_X &gt; 712 &amp;&amp; POS!=3 &amp;&amp; control==true) // Caso mova-se novamente para ---&gt;
  {
    POS++;
    control = false;
  } //???
  
  else if (Joy_X &gt;502 &amp;&amp; Joy_X&lt;522) // Se o joystick voltar ao estado parado
  control = true;</code>

Resultado do Projeto

Mas e ai? Gostou do post? Caso tenha ficado algo incompleto para você, comenta abaixo 📝

Dicas? 😄 Dúvidas? 👀 Críticas? 😱 Só comentar abaixo!

Forte abraço e compartilha se gostou! 🤘

Posts relacionados

Utilizando Módulo Bluetooth no Arduino

por Danilo Nogueira
5 anos ago

Utilizando o sensor de presença com Arduino

por autocore
8 anos ago

Como expandir as Saídas do Arduino?

por Danilo Nogueira
6 anos ago
Sair da versão mobile