Konzept für einen Spiele-Controller mit besonderen Funktionen

February 23, 2019 Mario Zeller, Miriam Widhalm and Sandra Szeliga

IMG_20190220_134059

von Sandra Szeliga (mt171067), Miriam Widhalm (mt171075) und Mario Zeller (mt171093)

Der Spiele-Controller von vorne

Dieses Projekt stellt ein Konzept für einen Spielkontroller mit einigen Zusatzfunktionen dar. So kann unser Gerät neben Temperatur- bzw. Luftfeuchtigkeit auch Alkoholwerte messen. Diese Funktionen werden für unser in Unity entwickeltes Spiel benötigt. Beispielsweise muss man Feuer ausblasen oder kann erst mit einem Schluck Alkohol intus Hindernisse überwinden, da wir unser Projekt auch als Gemeinschaftsaktivität bereitstellen wollen. Angebrachte LEDs geben hierbei die Informationen, ob die Luftfeuchtigkeit nach dem Reinpusten ausreichend ist, um das Feuer zu löschen, oder ob der Alkoholwert hoch genug ist, um weiterspielen zu dürfen. Über zwei Buttons wird das Spiel gesteuert, einer lenkt nach rechts, der andere nach links.

Der Controller im Test

Angefangen hat unser Projekt mit einem ESP32 Board, einem Steckbrett, einigen Kabeln und LEDs. Nachdem diese verbaut und funktionsfähig waren, haben wir uns um den Luftfeuchtigkeitsensor gekümmert. Nach anfänglichen Schwierigkeiten, die unter anderem damit zu tun hatten, dass der Sensor nicht funktionierte und wir einen neuen beschaffen mussten, gelang es uns, die Werte im Serial Port von Arduino auszugeben. Im nächsten Schritt haben wir einen Grenzwert festgelegt, bei dessen Überschreitung die grüne LED zu leuchten beginnt und in weiterer Folge das Feuer im Spiel verschwindet.

Anschließend beschäftigten wir uns mit dem Alkoholsensor. Es stellte sich heraus, dass wir am besten einen mit montierter Platine benötigen, also suchten wir nach einem Ersatz für unseren ursprünglichen, der keine Platine hatte. Nachdem alles richtig verkabelt war, haben wir es nach einigem Probieren geschafft, die Alkoholwerte auszugeben und wieder einen Grenzwert zu definieren. Wenn dieser Wert überschritten wird, leuchtet eine blaue LED auf und der Spieler kann sich weiterbewegen.

Zu guter Letzt haben wir zwei Buttons auf einem zweiten Steckbrett montiert und verkabelt, debounced und wieder mittels Serial Port überprüft. Der Schaltungsaufbau ist in folgender Grafik zu sehen.

Schaltungsaufbau ESP32 für Spiel-Controller (+Temp/Humidity-Sensor, +Alkohol-Sensor)

Als wir uns während der Projektarbeit Gedanken über die Zusammensetzung der Einzelteile zu einem handlichen Kontroller gemacht haben, sind uns mehrere Materialien in den Sinn gekommen. Schlussendlich haben wir uns für einen Steckschwamm entschieden, da dieser leicht bearbeitbar ist. Mit einem Messer haben wir Rechtecke ausgeschnitten und in diese Steckbretter hineingedrückt. Zuvor haben wir die Kabel auf diesen noch mit einer Heißklebepistole festmontiert, damit sie nicht verrutschen oder hinausfallen können.

Die Art und Weise, wie der ESP32 Werte an Unity schicken und Unity diese auslesen kann, ist folgende: Die zwei Programme (am ESP32 und Unity) kommunizieren über den SerialPort. Unity hat somit Zugriff auf die ausgegebenen Werte, also die Luftfeuchtigkeit, den Alkoholwert, die LEDs und welcher der Buttons gedrückt wird und kann so die richtigen Aktionen im Spiel (und theoretisch auch am Controller) ausführen.

Dies wird über eine Instanz der Klasse SerialPort realisiert, der der Name des COM, an dem der Microcontroller angeschlossen ist, und die Baud-Rate, mit der über den Serial-Port kommuniziert wird, übergeben wird. Dieser SerialPort muss in der Start-Funktion eines Objekts im Spiel geöffnet werden. In einer Methode des Typs IEnumerator wird der SerialPort in festgelegten Intervallen mit der Methode ReadLine() ausgelesen und per Split(,) bei jedem Beistrich getrennt und in ein Array gespeichert. Dieses Array enthält nun nur noch Werte, die Unity benötigt, um zum richtigen Zeitpunkt die richtige Entscheidung zu treffen. Dies ist im folgenden Code-Beispiel zu sehen.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO.Ports;

public class SerialPortReader : MonoBehaviour {

    SerialPort serial = new SerialPort("COM3", 9600);

    public int leftButton;
    public int rightButton;
    public int button = 0;
    public float luftfeuchtigkeit;
    public float alkohol;
    public int led1 = 0;
    public int led2 = 0;
    public int led3 = 0;

	// Use this for initialization
	void Start () {

        serial.Open();
        StartCoroutine(ReadDataFromSerialPort());
        StartCoroutine(WriteDataToSerialPort());
	}
	
    IEnumerator ReadDataFromSerialPort()
    {
        while (true)
        {
            string[] values = serial.ReadLine().Split(',');
            rightButton = (int.Parse(values[0]));
            leftButton = (int.Parse(values[1]));
            luftfeuchtigkeit = (float.Parse(values[2]));
            alkohol = (int.Parse(values[3]));
            if (rightButton == 1)
            {
                button += 1;
            }
            else if (leftButton == 1)
            {
                button -= 1;
            } else
            {
                button = 0;
            }

            yield return new WaitForSeconds(.5f);
        }
    }
}

Auf den ESP32-Microcontroller wurde ein Script geladen, welches die jeweiligen Sensoren und Buttons, angeschlossen an den jeweiligen digitalen bzw. analogen Pins des Controllers, ausliest, die LEDs ab einem gewissen Schwellenwert leuchten lässt und die Werte an den SerialPort schickt. Dies ist im folgenden Code-Beispiel zu sehen.

#include <ButtonDebounce.h>

#include "DHT.h"        // including the library of DHT11 temperature and humidity sensor
#define DHTTYPE DHT22   // DHT 11

int ButtonPinR=21;
int ButtonPinL=23;
ButtonDebounce debouncerR = ButtonDebounce(ButtonPinR,250);
ButtonDebounce debouncerL = ButtonDebounce(ButtonPinL,250);

int Analog = 14; //Alkotester
int Wert;

#define dht_dpin 13 //Luftsensor
DHT dht(dht_dpin, DHTTYPE); 
void setup(void)
{ 
  dht.begin();
  Serial.begin(9600);
  
  pinMode(25,OUTPUT);//rote LED1
  pinMode(26,OUTPUT);//rote LED2
   pinMode(27,OUTPUT);//rote LED3
   pinMode(15,OUTPUT);//grüne LED (Luftfeuchtigkeit)
   pinMode(4,OUTPUT);//blaue LED (Alkohol)

   pinMode(21, INPUT_PULLUP);
   pinMode(23, INPUT_PULLUP);
  
}

void loop() {
 
debouncerR.update();
debouncerL.update();
 
  if(debouncerR.state() == HIGH){
    Serial.print("0"); //R
    Serial.print(",");
    }
    
  if(debouncerR.state() == LOW){
     
    Serial.print("1");//R
    Serial.print(",");}


    
  if(debouncerL.state() == HIGH){
    Serial.print("0");//L
    Serial.print(",");
   }
    
  if(debouncerL.state() == LOW){
    Serial.print("1");//L
    Serial.print(",");
   }

 
   //Rote LED's (Status LEDs)

    digitalWrite(26,HIGH);
    digitalWrite(27,HIGH);
    digitalWrite(25,HIGH);  
   
     Wert = analogRead(Analog); // Der analoge Sensorwert wird ausgelesen.

     if(Wert>1000){
      digitalWrite(4,HIGH); //blaue LED
      
     }else{
      digitalWrite(4,LOW);
     }
  
    float h = (int)dht.readHumidity();
    float t = (int)dht.readTemperature();  

   if (h>45){
   digitalWrite(15,HIGH); //grüne LED
   }else{
   digitalWrite(15,LOW); }
    Serial.print(h);
    Serial.print(",");

Serial.println(Wert); 
delay(500);
}

, , electronics, games, interaction, interactive