Mini-Game für das rapidM2M Developer Board

Das rapidM2M Developer Board kann sich nicht nur mit anderen Geräten im Internet of Things unterhalten, es kann auch zu Ihrer Unterhaltung beitragen. Wir haben ein kleines Mini-Game entwickelt, dass Ihre Reaktionsgeschwindigkeit fordert. Dazu werden nur die 6 GPIOs (General-Purpose Input/Output), die mit den darüber liegenden LEDs verbunden sind, benötigt. GPIO bedeutet, man kann die Taster/LEDs entweder als Eingänge (Ändern des Zustands durch Tastendruck) oder als Ausgänge (Ändern des Zustands durch das Skript und Signalisierung dessen durch die dazugehörige LED) benutzen. Das Spiel demonstriert auf einfache Weise, wie dies praktisch umgesetzt werden kann. Damit es auch tatsächlich funktioniert, müssen zuvor jedoch noch die Dip-Switches am Board richtig eingestellt werden (bevor Sie es an den Strom anschließen):

Dip-Switch S207: Aktiviert die LEDs für die jeweiligen GPIOs, daher müssen Schalter 3 -8 auf ON gestellt werden. Zu beachten ist hierbei, dass Schalter 1 und 2 der Ansteuerung des Buzzers dienen. Sie sollten also auf OFF bleiben, da der Buzzer sonst einen ziemlich lauten Ton von sich gibt, wenn GPIO1 gedrückt wird.

Dip-Switch S206: Aktiviert die Pull-up bzw. Pull-down Widerstände. Wird ein GPIO als Ausgang verwendet, so muss der Widerstand deaktiviert werden (mittlere Schalterstellung). Soll ein GPIO grundsätzlich LOW sein, so muss der dazugehörige Schalter auf DOWN gestellt werden. In unserem Beispiel verwenden wir GPIO1 – GPIO3 als Ausgänge und GPIO4 – GPIO6 als Eingänge. Folglich müssen Schalter 1-3 deaktivert und Schalter 4-6 auf DOWN gestellt werden.

Dip-Switch S208: Gibt an, ob die LED des jeweiligen GPIOs beim Drücken desselben ein- oder ausgeschaltet wird. In unserem Fall wollen wir GPIO4 – GPIO6 durch einem Tastendruck leuchten lassen, daher müssen Schalter 4-6 auf HIGH gestellt werden.

Haben Sie alle Einstellungen vorgenommen und das Board angeschlossen, sollten nun die ersten 3 LEDs aufleuchten.

Für das Spiel werden, wie bereits erwähnt, GPIO1 -3 als Ausgänge verwendet, während GPIO4 – 6 als Eingänge verwendet werden. Dazu müssen Sie in der Main-Methode entsprechend konfiguriert werden:


main()
{
  new iIdx, iResult;

  /* set gpio #0, #1, #2  as signalling output */
  rM2M_GpioDir(0, RM2M_GPIO_OUTPUT);
  rM2M_GpioDir(1, RM2M_GPIO_OUTPUT);
  rM2M_GpioDir(2, RM2M_GPIO_OUTPUT);

  /* set gpio #3, #4, #5 as input */
  rM2M_GpioDir(3, RM2M_GPIO_INPUT);
  rM2M_GpioDir(4, RM2M_GPIO_INPUT);
  rM2M_GpioDir(5, RM2M_GPIO_INPUT);

  /* initialize random generator */
  rand_mwc(true);

  /* init 30ms Timer, used for general game flow */
  iIdx = funcidx("Timer30ms");
  iResult = rM2M_TimerAddExt(iIdx, true, 30);
  printf("rM2M_TimerAddExt(%d) = %d\r\n", iIdx, iResult);
}

Zusätzlich wird noch ein Timer gesetzt, wodurch die Funktion „Timer30ms()“ alle 30ms durchlaufen wird. In dieser wird der eigentliche Spielablauf gesteuert:


public Timer30ms()
{
  switch(iState)
    {
    case STATE_START:   stateStart();
    case STATE_RUNNING: stateRunning();
    case STATE_FINISH:  stateFinish();
    }
}

 

stateStart() wartet darauf, dass GPIO4 und 6 gleichzeitig gedrückt werden und das Spiel somit beginnen kann. stateRunning() lässt mittels eines Zufallsgenerators GPIO1, 2 oder 3 leuchten, und zwar solange bis die entsprechende Taste GPIO4, 5 oder 6 gedrückt wurde. Das heißt: Leuchtet z. B. LED 2, dann muss so schnell wie möglich GPIO5 gedrückt werden. Leuchtet danach LED1, so muss GPIO4 gedrückt werden usw. Dabei wird ein Zähler hochgezählt, um Ihre Reaktionszeit zu erfassen. Nachdem eine konstanten Anzahl von LEDs aufgeleuchtet ist und der jeweils richtige Taster gedrückt wurde, ist das Spiel beendet. stateFinish() lässt nun kurzzeitig alle 3 Ausgänge blinken, um das Ende des Spiels zu signalisieren. Die insgesamt benötigte Reaktionszeit in Sekunden wird auf der Konsole des Toolsets ausgegeben.


/* game in start mode */
stock stateStart()
{
  /* light up all three lights */
  rM2M_GpioSet(0, 1);
  rM2M_GpioSet(1, 1);
  rM2M_GpioSet(2, 1);
 
  /* check if gpio 4 and 6 is pressed */
  if(rM2M_GpioGet(3) && rM2M_GpioGet(4)==0 && rM2M_GpioGet(5))
  {
    /* start game */
    iPattern = 0;
    iTime = 0;
    iState = STATE_RUNNING;
    generatePattern();
  }
}

/* game running */
stock stateRunning()
{
  iTime++;

  if(!iPressed)
  {
    /* check if the right button is pressed */
    if(rM2M_GpioGet(3)==rM2M_GpioGet(0) &&
       rM2M_GpioGet(4)==rM2M_GpioGet(1) &&
       rM2M_GpioGet(5)==rM2M_GpioGet(2)   )
    {
      rM2M_GpioSet(0, 0);
      rM2M_GpioSet(1, 0);
      rM2M_GpioSet(2, 0);

      iPressed = 1;
    }
  }
  else
  {
    /* check if the button was released */
    if(rM2M_GpioGet(3)==0 &&
       rM2M_GpioGet(4)==0 &&
       rM2M_GpioGet(5)==0   )
    {
      iPressed = 0;
      iPattern ++;

      /* game finished if MAX_PATTERNS reached */
      if(iPattern == MAX_PATTERNS)
      {
        iFinish = 0;
        iState = STATE_FINISH;
      }
      else
      {
        generatePattern();
      }
    }
  }
}

/* game finished */
stock stateFinish()
{
  if(!iFinish)
    printf("time: %.2fs", iTime/100.0);

  /* flash all three lights some time */
  if(iFinish & 1)
  {
    rM2M_GpioSet(0, 0);
    rM2M_GpioSet(1, 0);
    rM2M_GpioSet(2, 0);
  }
  else
  {
    rM2M_GpioSet(0, 1);
    rM2M_GpioSet(1, 1);
    rM2M_GpioSet(2, 1);
  }

  iFinish ++;

  if(iFinish == 300)
  {
    iFinish = 0;
    iState = STATE_START;
  }
}
 

Hier gibt’s das gesamte Mini-Game inklusive Zufallsgenerator zum Download: Mini-Game

Viel Spass beim Testen!

 

 

Katharina

Als Mitglied des Microtronics Support Teams kennt Katharina Ihre Fragen zum Thema Programmierung ganz genau. Im Microtronics Blog bringt die Wirtschaftsinformatikerin regelmäßig spannende und hilfreiche Programmierbeispiele. Nachmachen ausdrücklich erlaubt.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.