Arduino – gra w powtarzanie

Ten wpis jest trochę spóźniony przez mój wyjazd, no ale obiecałem zamieścić prosty układ oparty na Arduino, a więc oto i on:

Aby było to coś prostego, a jednocześnie dającego trochę radości postanowiłem stworzyć kopię gry w powtarzanie sekwencji zapalanych światełek. Aby całość była mniej skomplikowana użyję trzech LED’ów, a program będzie sterowany z komputera. Dla chętnych na samym dole dostępna jest wersja na cztery diody oraz guziki, nie wymagająca komputera do zabawy. Jednak bez komputera nie można zobaczyć ilości zdobytych punktów. Oczywiście można i to rozwiązać np. zapisując wyniki do pamięci EEPROM, a następnie podłączyć tylko płytkę do komputera celem odczytania ich, ale to już inna kwestia którą pozostawiam jako ćwiczenie do rozwiązania we własnym zakresie. :)

Na początek schemat podłączenia:

Nie jest on zbyt skomplikowany. Są to po prostu diody podłączone poprzez rezystory do wyjść cyfrowych. Dla programu z guzikami potrzebne oczywiście są też guziki. Jak je podłączyć można zobaczyć choćby tutaj.

No i oczywiście program:

[spoiler show=”Pokaż kod” hide=”Ukryj kod”]

int ledPins[3]={6, 4, 2};
int combination[100];
int progress=0;
bool OK=true;

void setup()
{
  // initialize random seed
  randomSeed(analogRead(0));
  // initialize led pins
  for(int i=0; i<3; ++i)
  {
    pinMode(ledPins[i], OUTPUT);
  }
  Serial.begin(9600);
  delay(100);
  Serial.println("Let the game begin!");
}

void loop()
{
  while(OK)    // while not mistaken
  {
    combination[progress]=random(3);    //create new element

    // blink current combination
    for(int i=0; i< =progress; ++i)
    {
      digitalWrite(ledPins[combination[i]], HIGH);
      delay(750);
      digitalWrite(ledPins[combination[i]], LOW);
      delay(250);
    }

    // time for repeating the combination
    for(int i=0; i<=progress; ++i)
    {
      Serial.flush();
      int temp=4;
      while(temp==4)
      {
        if(Serial.available()>0)
        {
          char x=Serial.read();
          switch(x)
          {
          case 'r':
            temp=0;
            break;
          case 'g':
            temp=1;
            break;
          case 'b':
            temp=2;
            break;
          }
        }
        delay(10);
      }
      // if mistaken
      if(temp!=combination[i])
      {
        OK=false;
        break;
      }
    }
    ++progress;
    delay(500);
  }

  // print score and flash all LEDs at the end
  Serial.println("You lost!");
  Serial.print("Your score was: ");
  Serial.println(progress-1);
  for(int i=0; i<3; ++i)
  {
    for(int j=0; j<3; ++j)
    {
      digitalWrite(ledPins[j], HIGH);
    }
    delay(500);
    for(int k=0; k<3; ++k)
    {
      digitalWrite(ledPins[k], LOW);
    }
    delay(500);
  }

  // set values for next game
  delay(3000);
  OK=true;
  progress=0;
}

[/spoiler]

Ci z Was którzy mieli już kiedykolwiek kontakt z Arduino od razu dostrzegą, że kod przystosowany jest do IDE Arduino. Mimo, że jest to kod w języku C++ nie posiada on charakterystycznej funkcji “main()”. Posiada za to funkcje “setup()” i “loop()”. Wszystko dlatego że pliki z IDE Arduino są najpierw parsowane do normalnej formy, a dopiero następnie kompilowane za pomocą gcc.

Funkcja “setup()” jest uruchamiana za każdym razem kiedy podłączymy zasilanie i służy do ustawienia płytki do funkcjonowania z naszym programem. W tym wypadku ustawiamy w niej początkową wartość dla generatora liczb losowych, ustawiamy piny LED’ów w stan wyjściowy oraz inicjalizujemy połączenie z komputerem z prędkością 9600 bodów.

Funkcja “loop()” natomiast, jest główną częścią naszego programu. Jest wykonywana zaraz po funkcji “setup()” i jest powtarzana w kółko przez cały czas. To w niej wszystko się dzieje, czyli w naszym przypadku:

  1. wylosowanie nowego elementu
  2. wyświetlenie całej dotychczasowej sekwencji
  3. zebranie danych od użytkownika, czyli wciśnięcia klawisza r, g lub b, symbolizującego jeden z kolorów
  4. po wciśnięciu każdego klawisza sprawdzane jest od razu czy jest on prawidłowym elementem sekwencji
    • jeśli nie:
      • wyświetlenie liczby punktów
      • zamruganie wszystkimi diodami na znak przegranej
      • odczekanie trzech sekund przed nową grą oraz ustawienie wartości na początkowe
    • jeśli tak:
      • sczytanie kolejnego elementu sekwencji
  5. zwiększenie ilości punktów, a jednocześnie licznika elementów
  6. po sczytaniu wszystkich elementów całość zaczyna się od początku

Jak widać algorytm nie jest zbyt skomplikowany.

No i to w zasadzie wszystko. Jeśli kogoś interesują poszczególne funkcje języka polecam przejrzeć dokumentację dostępną na stronie projektu. Jest bardzo dobra – przejrzysta i czytelna, z dużą ilością przykładów.

No i oczywiście paczki z kodem. Tym opisanym powyżej i tym dla czterech LED’ów oraz guzików.

Comment are closed.