BANNER_SLIDESHOW_DESTAQUEBLOG_DESKTOP_ Pouso Lunar no ardino

Pouso Lunar no Arduino Deixe um comentário

Pouso Lunar foi um dos mais populares jogos em BASIC para microcomputadores (você pode ver uma versão clássica aqui). Esta versão do Pouso Lunar no Arduino, em tempo real, utiliza o Shield Arduino Multifunções Nível Intermediário para a interface com o operador.

Shield usado para o pouso lunar

O Jogo

Quando o jogo começa, você está no módulo lunar, a 1000 metros da superfície da Lua, caindo com uma velocidade de 50 m/s e uma aceleração de  5m/s2 (a gravidade da Lua simulada). Para pousar suavemente você precisa acionar o seu retrofoguete, tomando o cuidado para não ficar sem combustível (você tem inicialmente 150 unidades de combustível).

O display do shield apresenta alternadamente a distância e a velocidade do módulo Lunar. Os quatro LEDs do shield indicam quanto combustível você tem. Para acionar o retrofoguete você precisa apertar um dos três botões do shield, a quantidade de combustível queimada (e a freagem obtida) é crescente da esquerda para a direita:

  • Botão S1 queima 7 unidades de combustível
  • Botão S2 queima 14 unidades de combustível
  • Botão S3 queima 21 unidades de combustível

Ao acabar o combustível os botões deixarão de fazer efeito e o módulo descera em queda livre. O jogo termina quando o módulo chegar à superfície da Lua, a velocidade do impacto fica piscando no display. Para iniciar um novo jogo pressione o botão de reset.

Material Necessário

Preparação

A montagem consiste apenas de encaixar o shield Multifunções no Arduino. Para evitar o risco dos pinos do display no shield encostarem no conector USB do Arduino recomendamos colar uma fita isolante no shield (embaixo do display).

Partes de trás do shield usado para fazer o pouso lunar

O código utiliza a biblioteca <MultiFuncShield.h>, descrita no post “Projetos com o Shield Arduino Multifunções Nível Intermediário“.  Para instalá-la, baixe o zip do link e o expanda no diretório “libraries” da pasta onde a IDE armazena os sketches:

Código

#include <TimerOne.h>
#include <Wire.h>
#include <MultiFuncShield.h>

// Vamos tratar nós mesmos os botões
const int pinBotao1 = A1;  
const int pinBotao2 = A2;  
const int pinBotao3 = A3;

// Parâmetros da nossa simulação
const float distanciaInicial = 1000.0;
const int velocidadeInicial = 50.0;
const int combustivelInicial = 150;
const int gravidadeLunar = 5;

// Variáveis da nossa simulação
float distancia;
int velocidade;
int combustivel;

// Iniciacao do programa
void setup() {

  // Iniciações para o Shield
  Timer1.initialize();
  MFS.initialize(&Timer1);

  // Descomente a linha abaixo se o buzzer do seu shield
  // tocar continuamente
  //digitalWrite(BEEPER_PIN, LOW);

  // Situacao inicial da simulação
  distancia = distanciaInicial;
  velocidade = velocidadeInicial;
  combustivel = combustivelInicial;

  // Indica tanque cheio
  MFS.writeLeds(LED_ALL, ON);
}

// Laco principal
// Cada passada corresponde a 1 segundo de simulação
void loop() {
  if (distancia <= 0) {
    // Chegou a superficie
    // Mostrar a velocidade piscando
    MFS.write(velocidade);
    MFS.blinkDisplay (DIGIT_1 | DIGIT_2 | DIGIT_3 | DIGIT_4, ON);
    // Aguardar reset
    for (;;)
      delay(100);
  } else {
    // Atualiza indicação do combustivel
    if (combustivel < 3*combustivelInicial/4) {
      MFS.writeLeds(LED_1, OFF);
    }
    if (combustivel < combustivelInicial/2) {
      MFS.writeLeds(LED_2, OFF);
    }
    if (combustivel < combustivelInicial/4) {
      MFS.writeLeds(LED_3, OFF);
    }
    if (combustivel <= 0) {
      MFS.writeLeds(LED_4, OFF);
    }
    // Mostra distancia e velocidade
    MFS.write((int) distancia);
    delay(500);
    MFS.write(velocidade);
    delay(500);
    // Determina a aceleração
    int acel = gravidadeLunar;
    int queima = 0;
    if (digitalRead(pinBotao3) == LOW) {
      queima = 21;
    } else if (digitalRead(pinBotao2) == LOW) {
      queima = 14;
    } else if (digitalRead(pinBotao1) == LOW) {
      queima = 7;
    }
    if (queima > combustivel) {
      queima = combustivel;
    }
    combustivel = combustivel - queima;
    acel = acel - queima;
    // Calcula a velocidade final no período
    int velocidadeFinal = velocidade + acel;
    if (velocidadeFinal < 0) {
      velocidadeFinal = 0;
    }
    // Atualiza distância
    distancia -= (velocidade + velocidadeFinal)/2;
    if (distancia < 0) {
      distancia = 0;
    }
    // Atualiza velocidade
    velocidade = velocidadeFinal;
  }  
}

Distância e velocidade são atualizados incrementalmente em intervalos de 1 segundo:

  • A aceleração do módulo é a gravidade menos a queima do retrofoguete (aceleração negativa faz a velocidade diminuir)
  • A velocidade ao final do intervalo é igual à velocidade inicial mais a aceleração
  • A distância final é igual à distância inicial menos a média entre a velocidade inicial e a final

O código é uma adaptação de uma demonstração da linguagem Eleven.

Conclusão

Neste jogo temos uma simulação (bem simplificada) de um sistema real. Algumas sugestões de melhorias:

  • Apresentar o combustível restante no display (você pode usar os LEDs para indicar qual valor está sendo mostrado)
  • Permitir velocidade negativa (isto é, com o módulo se afastando da Lua)
  • Considerar que o módulo fica mais leve à medida que o combustível é queimado
  • Acrescentar efeitos sonoros usando o buzzer do shield

Gostou de ver o Pouso Lunar no Arduino? Ajude-nos a melhorar o blog comentando abaixo sobre este tutorial.

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *