Aarhus Universitets segl

Teknologi: Pulse Sensor Amped + Unity (fra Arduino til Processing til Unity)

Dette er en tutorial på hvordan man kan få puls til at styre en del i et Unity projekt.

For setup af puls sensoren, se her. Arduino koden uploades til Arduino boardet og vi kan nu bevæge os over i Processing.

På en Mac skal man læse på seriel porten fra Processing og man kan derefter sende signalet videre som en OSC besked til Unity. Jeg oplevede problemer ved at læse på serielporten direkte fra Unity, hvilket førnævnte metode løste.

Følgende Processing sketch læser på serielporten på 5001 og sender den læste værdi videre som en OSC besked kaldt “value”.


import processing.serial.*;
import cc.arduino.*;
import oscP5.*;
import netP5.*;

OscP5 oscP5;
NetAddress myRemoteLocation;

Serial myPort;
int value;
String bpm;

void setup ()
{
//Lytter på port 5002
oscP5 = new OscP5(this, 5002);

//sætter remote location til at være local host på port 5001
myRemoteLocation = new NetAddress("127.0.0.1", 5001);

String portName = Serial.list()[2];
myPort = new Serial(this, portName, 115200);
myPort.clear();
bpm = myPort.readString();
bpm = null;
}

void draw ()
{
serialEvent();
}

void serialEvent()
{
while (myPort.available ()>0)
{
bpm = myPort.readString();
if (bpm != null)
{
bpm = trim(bpm);
value = int(bpm);
println(value);

OscMessage myMessage = new OscMessage("/pulsesensor ");
myMessage.add(value);

//send beskeden
oscP5.send(myMessage, myRemoteLocation);
}
}
}


Mike Heavers har skrevet en OSC receiver til Unity, som fungerer godt. Læs mere om det her.

Download UnityOSC pakken her.

De to C# scripts, Unity OSCListener og Unity OSCReceiver, kan f.eks. trækkes over på objektet i Unity som skal manipuleres af pulsen. Unity OSCReceiveren har en variabel for den port vi skal lytte på, så den sættes til det samme som i vores Processing sketch: 5002 (Det virker også med 5001).

Inde i Unity OSCListener-scriptet kan vi se at vores message reference indeholder en adresse og en value. Vi kan erklære en variabel int bpm og deklarere den til at være det første element i vores args ArrayList. I samme script kan vi så lave en metode der returnerer vores bpm. Se nedenstående eksempel:


using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class UnityOSCListener : MonoBehaviour
{
private int bpm;
public void OSCMessageReceived(OSC.NET.OSCMessage message){
string address = message.Address;
ArrayList args = message.Values;

bpm = (int)args[0];

//Debug.Log (bpm);
//Debug.Log(address);

/*foreach( var item in args){
Debug.Log(item);
}*/
}

public int GetBPM()
{
return bpm;
}
}


Fra dit script som indeholder funktionerne der skal manipulere objektet, skal der blot laves en reference til UnityOSCListener, hvorefter vores getmetode kan kaldes på den. På den måde kan vi assigne en variabel til den reference og der kan nu arbejdes med værdien i scriptet. Se eksempel.


//vores reference
var listener : UnityOSCListener;

//Vores variabel som indeholder bpm værdien
var newBPM : int = listener.GetBPM();


OBS: Hvis dine scripts er skrevet i Javascript, skal vi lave en workaround for at få de to typer scripts til at snakke sammen. Dette gøres ved at trække C# scripts’ene ind i Standard Assets mappen. Dette har noget at gøre med i hvilken rækkefølge de forskellige scripts compiles.