LightStone to Processing

Several years ago, my friend Justin gave me a Journey to Wild Divine set he had found at a good price. I have finally gotten around to getting the data from its biofeedback device (which measures heart rate variability and skin conductance) into Processing so I can use it for weird projects (such as sorcerous robots that respond to fear — MWAHAHAHA!).

I am using Processing 2.0.1 (should also work with 2.2), oscP5 0.9.8, and GlovePIE 0.45. GlovePIE (Programmable Input Emulator) is a Windows program that can read data from many old and new video-game peripherals, including the LightStone device for JtWD (since replaced by the iOM). GlovePIE’s docu says that OSC messages are broken in versions >= 0.40, but I had no problem on a machine running Windows XP SP3 and the latest DirectX update.

The GlovePIE script could not be any simpler: = "" // host IP address
var.port = 7400 // host port number

SendOsc(, var.port, "/ls_hrv", LightStone.HeartRateVariance)
SendOSC(, var.port, "/ls_scl", LightStone.SkinConductanceLevel)

The processing code is a little longer, so I have placed it at the end of this article. For the example, I just read the data into two variables, then draw bar graphs from those values — here is an image of the output:

One of the cool things about this sketch is you can watch the graph for skin conductance level go up and down with your pulse (I should upload a video). I mapped the values based on those given in the GlovePIE docu and what I observed in Processing. I will tweak them as I play more with this and get a better idea of my actual ranges.

The OSC messages from GlovePie look like this:

received from /
addrpattern /ls_hrv
typetag f
[0] 0.261

Here is the Processing code:

 * LightStone to Processing
 * by Joshua Madara,
 * This sketch reads and graphs heart rate variability and
 * skin conductance level data from the LightStone device
 * via OSC messages from GlovePIE.

import oscP5.*;
import netP5.*;

OscP5 oscP5;

float hrv = 0.0; // heart rate variability
float scl = 0.0; // skin conductance level

void setup() {
  size(200, 200);
  // create OSC listener
  oscP5 = new OscP5(this, 7400);
  // plug the input values to functions defined at end of sketch
  oscP5.plug(this, "updateHrv", "/ls_hrv");
  oscP5.plug(this, "updateScl", "/ls_scl");

void draw() {
  background(#012232); // fill background with dark blue
  // draw bar graph for HRV
  fill(#ff0000); // set fill color to red
  float mHrv = map(hrv, 0.0, 0.4, 0, 100); // map hrv to bar height
  rect(50, 150, 25, -mHrv); // draw bar
  // draw bar graph for SCL
  fill(#00f149); // set fill color to green
  float mScl = map(scl, 0.0, 20.0, 0, 100); // map scl to bar height
  rect(125, 150, 25, -mScl); // draw bar

// update hrv value
void updateHrv(float val) {
  hrv = val;
  println("hrv: " + hrv);

// update scl value
void updateScl(float val) {
  scl = val;
  println("scl: " + scl);

Leave a Reply