JavaScript API

IDE Setup

Download and install the text editor of your choice:

Core Sphero Commands

ping(callback)

orb.ping(function(err, data) {
  console.log(err || "data: " + data);
}

The Ping command verifies the Sphero is awake and receiving commands.

Params:

  • callback (Function) triggered when Sphero has been pinged

version(callback)

orb.version(function(err, data) {
  if (err) {
    console.log("error: ", err);
  } else {
    console.log("data:");
    console.log("  recv:", data.recv);
    console.log("  mdl:", data.mdl);
    console.log("  hw:", data.hw);
    console.log("  msaVer:", data.msaVer);
    console.log("  msaRev:", data.msaRev);
    console.log("  bl:", data.bl);
    console.log("  bas:", data.bas);
    console.log("  macro:", data.macro);
    console.log("  apiMaj:", data.apiMaj);
    console.log("  apiMin:", data.apiMin);
  }
}

The Version command returns a batch of software and hardware information about Sphero.

Params:

  • callback (Function) triggered with version information

controlUartTx(callback)

orb.controlUartTx(function(err, data) {
  console.log(err || "data: " + data);
}

The Control UART Tx command enables or disables the CPU's UART transmit line so another client can configure the Bluetooth module.

Params:

  • callback (Function) function to be triggered after write

setDeviceName(name, callback)

orb.setDeviceName("rollingOrb", function(err, data) {
  console.log(err || "data: " + data);
}

The Set Device Name command assigns Sphero an internal name. This value is then produced as part of the Get Bluetooth Info command.

Names are clipped at 48 characters to support UTF-8 sequences. Any extra characters will be discarded.

This field defaults to the Bluetooth advertising name of Sphero.

Params:

  • name (String) what name to give to the Sphero
  • callback (Function) function to be triggered when the name is set

getBluetoothInfo(callback)

orb.getBluetoothInfo(function(err, data) {
  if (err) {
    console.log("error: ", err);
  } else {
    console.log("data:");
    console.log("  name:", data.name);
    console.log("  btAddress:", data.btAddress);
    console.log("  separator:", data.separator);
    console.log("  colors:", data.colors);
  }
}

Triggers the callback with a structure containing

  • Sphero's ASCII name
  • Sphero's Bluetooth address (ASCII)
  • Sphero's ID colors

Params:

  • callback (Function) function to be triggered with Bluetooth info

setAutoReconnect(flag, time, callback)

orb.setAutoReconnect(1, 20, function(err, data) {
  console.log(err || "data: " + data);
}

The Set Auto Reconnect command tells Sphero's BT module whether or not it should automatically reconnect to the previously-connected Apple mobile device.

Params:

  • flag (Number) whether or not to reconnect (0 - no, 1 - yes)
  • time (Number) how many seconds after start to enable auto reconnect
  • callback (Function) function to be triggered after write

getAutoReconnect(callback)

orb.getAutoReconnect(function(err, data) {
  if (err) {
    console.log("error: ", err);
  } else {
    console.log("data:");
    console.log("  flag:", data.flag);
    console.log("  time:", data.time);
  }
}

The Get Auto Reconnect command returns the Bluetooth auto reconnect values as defined above in the Set Auto Reconnect command.

Params:

  • callback (Function) function to be triggered with reconnect data

getPowerState(callback)

orb.getPowerState(function(err, data) {
  if (err) {
    console.log("error: ", err);
  } else {
    console.log("data:");
    console.log("  recVer:", data.recVer);
    console.log("  batteryState:", data.batteryState);
    console.log("  batteryVoltage:", data.batteryVoltage);
    console.log("  chargeCount:", data.chargeCount);
    console.log("  secondsSinceCharge:", data.secondsSinceCharge);
  }
}

The Get Power State command returns Sphero's current power state, and some additional parameters:

  • RecVer: record version code (following is for 0x01)
  • Power State: high-level state of the power system
  • BattVoltage: current battery voltage, scaled in 100ths of a volt (e.g. 0x02EF would be 7.51 volts)
  • NumCharges: Number of battery recharges in the life of this Sphero
  • TimeSinceChg: Seconds awake since last recharge

Possible power states:

  • 0x01 - Battery Charging
  • 0x02 - Battery OK
  • 0x03 - Battery Low
  • 0x04 - Battery Critical

Params:

  • callback (Function) function to be triggered with power state data

setPowerNotification(flag, callback)

orb.setPowerNotification(1, function(err, data) {
  console.log(err || "data: " + data);
}

The Set Power Notification command enables sphero to asynchronously notify the user of power state periodically (or immediately, when a change occurs)

Timed notifications are sent every 10 seconds, until they're disabled or Sphero is unpaired.

Params:

  • flag (Number) whether or not to send notifications (0 - no, 1 - yes)
  • callback (Function) function to be triggered when done writing

sleep(wakeup, macro, orbBasic, callback)

orb.sleep(10, 0, 0, function(err, data) {
  console.log(err || "data: " + data);
}

The Sleep command puts Sphero to sleep immediately.

Params:

  • wakeup (Number) the number of seconds for Sphero to re-awaken after. 0x00 tells Sphero to sleep forever, 0xFFFF attemps to put Sphero into deep sleep.
  • macro (Number) if non-zero, Sphero will attempt to run this macro ID when it wakes up
  • orbBasic (Number) if non-zero, Sphero will attempt to run an orbBasic program from this line number
  • callback (Function) function to be triggered when done writing

getVoltageTripPoints(callback)

orb.getVoltageTripPoints(function(err, data) {
  if (err) {
    console.log("error: ", err);
  } else {
    console.log("data:");
    console.log("  vLow:", data.vLow);
    console.log("  vCrit:", data.vCrit);
  }
}

The Get Voltage Trip Points command returns the trip points Sphero uses to determine Low battery and Critical battery.

The values are expressed in 100ths of a volt, so defaults of 7V and 6.5V respectively are returned as 700 and 650.

Params:

  • callback (Function) function to be triggered with trip point data

setVoltageTripPoints(vLow, vCrit, callback)

orb.setVoltageTripPoints(675, 650, function(err, data) {
  console.log(err || "data: " + data);
}

The Set Voltage Trip Points command assigns the voltage trip points for Low and Critical battery voltages.

Values are specified in 100ths of a volt, and there are limitations on adjusting these from their defaults:

  • vLow must be in the range 675-725
  • vCrit must be in the range 625-675

There must be 0.25v of separation between the values.

Shifting these values too low can result in very little warning before Sphero forces itself to sleep, depending on the battery pack. Be careful.

Params:

  • vLow (Number) new voltage trigger for Low battery
  • vCrit (Number) new voltage trigger for Crit battery
  • callback (Function) function to be triggered when done writing

setInactivityTimeout(time, callback)

orb.setInactivityTimeout(120, function(err, data) {
  console.log(err || "data: " + data);
}

The Set Inactivity Timeout command sets the timeout delay before Sphero goes to sleep automatically.

By default, the value is 600 seconds (10 minutes), but this command can alter it to any value of 60 seconds or greater.

Params:

  • time (Number) new delay before sleeping
  • callback (Function) function to be triggered when done writing

jumpToBootloader(callback)

orb.jumpToBootLoader(function(err, data) {
  console.log(err || "data: " + data);
}

The Jump To Bootloader command requests a jump into the Bootloader to prepare for a firmware download.

All commands after this one must comply with the Bootloader Protocol Specification.

Params:

  • callback (Function) function to be triggered when done writing

runL1Diags(callback)

orb.runL1Diags(function(err, data) {
  console.log(err || "data: " + data);
}

The Perform Level 1 Diagnostics command is a developer-level command to help diagnose aberrant behaviour in Sphero.

Most process flags, system counters, and system states are decoded to human-readable ASCII.

For more details, see the Sphero API documentation.

Params:

  • callback (Function) function to be triggered with diagnostic data

runL2Diags(callback)

orb.runL2Diags(function(err, data) {
  if (err) {
    console.log("error: ", err);
  } else {
    console.log("data:");
    console.log("  recVer:", data.recVer);
    console.log("  rxGood:", data.rxGood);
    console.log("  rxBadId:", data.rxBadId);
    console.log("  rxBadDlen:", data.rxBadDlen);
    console.log("  rxBadCID:", data.rxBadCID);
    console.log("  rxBadCheck:", data.rxBadCheck);
    console.log("  rxBufferOvr:", data.rxBufferOvr);
    console.log("  txMsg:", data.txMsg);
    console.log("  txBufferOvr:", data.txBufferOvr);
    console.log("  lastBootReason:", data.lastBootReason);
    console.log("  bootCounters:", data.bootCounters);
    console.log("  chargeCount:", data.chargeCount);
    console.log("  secondsSinceCharge:", data.secondsSinceCharge);
    console.log("  secondsOn:", data.secondsOn);
    console.log("  distancedRolled:", data.distancedRolled);
    console.log("  sensorFailures:", data.sensorFailures);
    console.log("  gyroAdjustCount:", data.gyroAdjustCount);
  }
}

The Perform Level 2 Diagnostics command is a developer-level command to help diagnose aberrant behaviour in Sphero.

It's much less informative than the Level 1 command, but is in binary format and easier to parse.

For more details, see the Sphero API documentation.

Params:

  • callback (Function) function to be triggered with diagnostic data

assignTime(time, callback)

orb.assignTime(0x00ffff00, function(err, data) {
  console.log(err || "data: " + data);
}

The Assign Time command sets a specific value to Sphero's internal 32-bit relative time counter.

Params:

  • time (Number) the new value to set
  • callback (Function) function to be triggered when done writing

pollPacketTimes(time, callback)

orb.assignTime(0x00ffff, function(err, data) {
  if (err) {
    console.log("error: ", err);
  } else {
    console.log("data:");
    console.log("  t1:", data.t1);
    console.log("  t2:", data.t2);
    console.log("  t3:", data.t3);
  }
}

The Poll Packet Times command helps users profile the transmission and processing latencies in Sphero.

For more details, see the Sphero API documentation.

Params:

  • time (Number) a timestamp to use for profiling
  • callback (Function) function to be triggered when done writing

Sphero Commands

sphero(address, [opts])

var orb = sphero("/dev/rfcomm0");

var orb = sphero("/dev/tty.Sphero-OGB-AMP-SPP", { timeout: 300 });

Creates a new Sphero instance with the provided options.

Params:

  • address (String) port/UUID/address of the connected Sphero
  • [opts] (Object) options for sphero setup
  • [opts.adaptor] (Object) if provided, a custom adaptor used for Sphero communication
  • [opts.sop2=0xFD] (Number) SOP2 value to be passed to commands
  • [opts.timeout=500] (Number) delay before a command is considered dead

connect(callback)

orb.connect(function() {
  // Sphero is connected, tell it to do stuff!
  orb.color("magenta");
});

Establishes a connection to Sphero.

Once connected, commands can be sent to Sphero.

Params:

  • callback (Function) function to be triggered once connected

disconnect(callback)

orb.disconnect(function() {
  console.log("Now disconnected from Sphero");
});

Ends the connection to Sphero.

After this is complete, no further commands can be sent to Sphero.

Params:

  • callback (Function) function to be triggered once disconnected

Custom Commands

color(color, [luminance], callback)

orb.color("#00ff00", function(err, data) {
  console.log(err || "Color Changed!");
});

orb.color(0xff0000, function(err, data) {
  console.log(err || "Color Changed!");
});

orb.color({ red: 0, green: 0, blue: 255 }, function(err, data) {
  console.log(err || "Color Changed!");
});

The Color command wraps Sphero's built-in setRgb command, allowing for a greater range of possible inputs.

Params:

  • color (Number|String|Object) what color to change Sphero to
  • [luminance] (string) - percentage of luminance to apply to RGB color
  • callback (Function) function to be triggered with response

randomColor(callback)

orb.randomColor(function(err, data) {
  console.log(err || "Random Color!");
});

The Random Color command sets Sphero to a randomly-generated color.

Params:

  • callback (Function) (err, data) to be triggered with response

getColor(callback)

orb.getColor(function(err, data) {
  if (err) {
    console.log("error: ", err);
  } else {
    console.log("data:");
    console.log("  color:", data.color);
    console.log("  red:", data.red);
    console.log("  green:", data.green);
    console.log("  blue:", data.blue);
  }
});

Passes the color of the sphero Rgb LED to the callback (err, data)

Params:

  • callback (Function) function to be triggered with response

detectCollisions(opts, callback)

orb.detectCollisions();

orb.on("collision", function(data) {
  console.log("data:");
  console.log("  x:", data.x);
  console.log("  y:", data.y);
  console.log("  z:", data.z);
  console.log("  axis:", data.axis);
  console.log("  xMagnitud:", data.xMagnitud);
  console.log("  yMagnitud:", data.yMagnitud);
  console.log("  speed:", data.timeStamp);
  console.log("  timeStamp:", data.timeStamp);
});

The Detect Collisions command sets up Sphero's collision detection system, and automatically parses asynchronous packets to re-emit collision events to 'collision' event listeners.

Params:

  • opts (Object) device
  • callback (Function) (err, data) to be triggered with response

detectFreefall(callback)

orb.detectFreefall();

orb.on("freefall", function(data) {
  console.log("freefall:");
  console.log("  value:", data.value);
});
orb.on("landing", function(data) {
  console.log("landing:");
  console.log("  value:", data.value);
});

The Detect Freefall command sets up Sphero's freefall detection system, and automatically listens to data events to emit freefall/landing events to 'freefall' or 'landing' event listeners.

Params:

  • callback (Function) (err, data) to be triggered with response

startCalibration(callback)

orb.startCalibration();

The Start Calibration command sets up Sphero for manual heading calibration.

It does this by turning on the tail light (so you can tell where it's facing) and disabling stabilization (so you can adjust the heading).

When done, call #finishCalibration to set the new heading, and re-enable stabilization.

Params:

  • callback (Function) (err, data) to be triggered with response

finishCalibration(callback)

orb.finishCalibration();

The Finish Calibration command ends Sphero's calibration mode, by setting the new heading as current, and re-enabling normal defaults

Params:

  • callback (Function) function to be triggered with response

setDefaultSettings(callback)

orb.setDefaultSettings();

The setDefaultSettings command sets Sphero's settings back to sensible defaults, such as turning off the back LED, and re-enabling stabilization.

Params:

  • callback (Function) function to be triggered with response

streamOdometer([sps=5], [remove=false])

orb.streamOdometer();

orb.on("odometer", function(data) {
  console.log("data:");
  console.log("  xOdomoter:", data.xOdomoter);
  console.log("  yOdomoter:", data.yOdomoter);
});

Starts streaming of odometer data

It uses sphero's data streaming command. User needs to listen for the dataStreaming or odometer event to get the data.

Params:

  • [sps=5] (Number) samples per second
  • [remove=false] (Boolean) forces velocity streaming to stop

streamVelocity([sps=5], [remove=false])

orb.streamVelocity();

orb.on("velocity", function(data) {
  console.log("data:");
  console.log("  xVelocity:", data.xVelocity);
  console.log("  yVelocity:", data.yVelocity);
});

Starts streaming of velocity data

It uses sphero's data streaming command. User needs to listen for the dataStreaming or velocity event to get the velocity values.

Params:

  • [sps=5] (Number) samples per second
  • [remove=false] (Boolean) forces velocity streaming to stop

streamAccelOne([sps=5], [remove=false])

orb.streamAccelOne();

orb.on("accelOne", function(data) {
  console.log("data:");
  console.log("  accelOne:", data.accelOne);
});

Starts streaming of accelOne data

It uses sphero's data streaming command. User needs to listen for the dataStreaming or accelOne event to get the data.

Params:

  • [sps=5] (Number) samples per second
  • [remove=false] (Boolean) forces velocity streaming to stop

streamImuAngles([sps=5], [remove=false])

orb.streamImuAngles();

orb.on("imuAngles", function(data) {
  console.log("data:");
  console.log("  pitchAngle:", data.pitchAngle);
  console.log("  rollAngle:", data.rollAngle);
  console.log("  yawAngle:", data.yawAngle);
});

Starts streaming of IMU angles data

It uses sphero's data streaming command. User needs to listen for the dataStreaming or imuAngles event to get the data.

Params:

  • [sps=5] (Number) samples per second
  • [remove=false] (Boolean) forces velocity streaming to stop

streamAccelerometer([sps=5], [remove=false])

orb.streamAccelerometer();

orb.on("accelerometer", function(data) {
  console.log("data:");
  console.log("  xAccel:", data.xAccel);
  console.log("  yAccel:", data.yAccel);
  console.log("  zAccel:", data.zAccel);
});

Starts streaming of accelerometer data

It uses sphero's data streaming command. User needs to listen for the dataStreaming or accelerometer event to get the data.

Params:

  • [sps=5] (Number) samples per second
  • [remove=false] (Boolean) forces velocity streaming to stop

streamGyroscope([sps=5], [remove=false])

orb.streamGyroscope();

orb.on("gyroscope", function(data) {
  console.log("data:");
  console.log("  xGyro:", data.xGyro);
  console.log("  yGyro:", data.yGyro);
  console.log("  zGyro:", data.zGyro);
});

Starts streaming of gyroscope data

It uses sphero's data streaming command. User needs to listen for the dataStreaming or gyroscope event to get the data.

Params:

  • [sps=5] (Number) samples per second
  • [remove=false] (Boolean) forces velocity streaming to stop

streamMotorsBackEmf([sps=5], [remove=false])

orb.streamMotorsBackEmf();

orb.on("motorsBackEmf", function(data) {
  console.log("data:");
  console.log("  rMotorBackEmf:", data.rMotorBackEmf);
  console.log("  lMotorBackEmf:", data.lMotorBackEmf);
});

Starts streaming of motor back EMF data

It uses sphero's data streaming command. User needs to listen for the dataStreaming or motorsBackEmf event to get the data.

Params:

  • [sps=5] (Number) samples per second
  • [remove=false] (Boolean) forces velocity streaming to stop

stopOnDisconnect([remove=false], callback)

orb.stopOnDisconnect(function(err, data) {
  console.log(err || "data" + data);
});

The Stop On Disconnect command sends a flag to Sphero. This flag tells Sphero whether or not it should automatically stop when it detects that it's disconnected.

Params:

  • [remove=false] (Boolean) whether or not to stop on disconnect
  • callback (Function) triggered on complete

stop(callback)

sphero.stop(function(err, data) {
  console.log(err || "data" + data);
});

Stops sphero the optimal way by setting flag 'go' to 0 and speed to a very low value.

Params:

  • callback (Function) triggered on complete

Examples

Bluetooth Info

  "use strict";

var sphero = require("../");
var orb = sphero(process.env.PORT);

orb.connect(function() {
  orb.color("FF00FF");

  orb.getBluetoothInfo(function(err, data) {
    if (err) { console.error("err:", err); }
    else {
      console.log("bluetoothInfo:");
      console.log("  name:", data.name);
      console.log("  btAddress:", data.btAddress);
      console.log("  separator:", data.separator);
      console.log("  colors:", data.colors);
    }
  });
});

Calibration

  "use strict";

var sphero = require("../");
var orb = sphero(process.env.PORT);

orb.connect(function() {
  console.log("::START CALIBRATION::");
  orb.startCalibration();
  setTimeout(function() {
    console.log("::FINISH CALIBRATION::");
    orb.finishCalibration();
  }, 5000);
});

Collision Detection

  "use strict";

var sphero = require("../");
var orb = sphero(process.env.PORT);

orb.connect(function() {
  orb.detectCollisions();
  orb.color("green");

  orb.on("collision", function(data) {
    console.log("collision detected");
    console.log("  data:", data);

    orb.color("red");

    setTimeout(function() {
      orb.color("green");
    }, 1000);
  });

  orb.roll(155, 0);
});

Color

  "use strict";

var sphero = require("../");
var orb = sphero(process.env.PORT);

orb.connect(function() {
  // sets color to the provided r/g/b values
  orb.color({ red: 255, green: 0, blue: 255 });

  setTimeout(function() {
    console.log("color 1");
    // sets color to the provided hex value
    orb.color(0xff0000);
  }, 1000);

  setTimeout(function() {
    console.log("color 2");
    // hex numbers can also be passed in strings
    orb.color("00ff00");
  }, 2000);

  setTimeout(function() {
    console.log("color 3");
    // sets color to the provided color name
    orb.color("magenta");
  }, 3000);
});

Get Color

  "use strict";

var sphero = require("../");
var orb = sphero(process.env.PORT);

orb.connect(function() {
  // sets color to the provided r/g/b values
  orb.getColor(function(err, data) {
    if (err) {
      console.log(err);
    } else {
      console.log("Color is:", data.color);
    }
  });
});

Conway's Game

  "use strict";

/* eslint key-spacing: 0, no-use-before-define: 0 */

var sphero = require("../");

var spheros = {
  Thelma : sphero(process.env.PORT),
  Louise : sphero("/dev/rfcomm1"),
  Grace  : sphero("/dev/rfcomm2"),
  Ada    : sphero("/dev/rfcomm3")
};

function main() {
  connect(spheros, function() {
    console.log("Spheros are connected, starting game.");
    for (var name in spheros) { start(name); }
  });
}

// connects all spheros, triggering callback when done
function connect(orbs, callback) {
  var total = Object.keys(orbs).length,
      finished = 0;

  function done() {
    finished++;
    if (finished >= total) { callback(); }
  }

  for (var name in orbs) {
    orbs[name].connect(done);
  }
}

// tells each Sphero what to do
function start(name) {
  var orb = spheros[name],
      contacts = 0,
      age = 0,
      alive = false;

  orb.detectCollisions();

  born();

  orb.on("collision", function() { contacts += 1; });

  setInterval(function() { if (alive) { move(); } }, 3000);
  setInterval(birthday, 10000);

  // roll Sphero in a random direction
  function move() {
    orb.roll(60, Math.floor(Math.random() * 360));
  }

  // stop Sphero
  function stop() {
    orb.stop();
  }

  // set Sphero's color
  function color(str) {
    orb.color(str);
  }

  function born() {
    contacts = 0;
    age = 0;
    life();
    move();
  }

  function life() {
    alive = true;
    color("green");
  }

  function death() {
    alive = false;
    color("red");
    stop();
  }

  function enoughContacts() {
    return contacts >= 2 && contacts < 7;
  }

  function birthday() {
    age += 1;

    if (alive) {
      console.log("Happy birthday,", name);
      console.log("You are", age, "and had", contacts, "contacts.");
    }

    if (enoughContacts()) {
      if (!alive) { born(); }
    } else {
      death();
    }
  }
}

main();

Data Streaming

  "use strict";

var sphero = require("../");
var orb = sphero(process.env.PORT);

orb.connect(function() {
  // options for streaming data
  var opts = {
    n: 200,
    m: 1,
    mask1: 0x00000000,
    pcnt: 0,
    mask2: 0x0D800000
  };

  orb.setDataStreaming(opts);

  orb.on("dataStreaming", function(data) {
    console.log("streaming data packet recieved");
    console.log("  data:", data);
  });

  orb.roll(150, 0);
});

Keyboard

  "use strict";

var sphero = require("../");
var orb = sphero(process.env.PORT);

orb.connect(function() {
  // roll orb in a random direction, changing direction every second
  setInterval(function() {
    var direction = Math.floor(Math.random() * 360);
    orb.roll(150, direction);
  }, 1000);
});

Roll

  "use strict";

var sphero = require("../");
var orb = sphero(process.env.PORT);

orb.connect(function() {
  // roll orb in a random direction, changing direction every second
  setInterval(function() {
    var direction = Math.floor(Math.random() * 360);
    orb.roll(150, direction);
  }, 1000);
});

Shakeometer

  "use strict";

var sphero = require("../");
var orb = sphero(process.env.PORT);

orb.connect(function() {
  var max = 0,
      updating = false;

  // enable streaming of velocity data
  orb.setDataStreaming({
    mask1: 0x00000000,
    mask2: 0x01800000,
    n: 40,
    m: 1,
    pcnt: 0
  });

  orb.on("dataStreaming", function(data) {
    if (updating) { return; }

    var x = Math.abs(data.xVelocity.value),
        y = Math.abs(data.yVelocity.value);

    var localmax = Math.max(x, y);

    if (localmax > max) { max = localmax; }
  });

  function update() {
    updating = true;

    if (max < 10) {
      orb.color("white");
    } else if (max < 100) {
      orb.color("lightyellow");
    } else if (max < 150) {
      orb.color("yellow");
    } else if (max < 250) {
      orb.color("orange");
    } else if (max < 350) {
      orb.color("orangered");
    } else if (max < 450) {
      orb.color("red");
    } else {
      orb.color("darkred");
    }

    max = 0;
    updating = false;
  }

  setInterval(update, 600);
});

Stream Accel-one

  "use strict";

var sphero = require("../");
var orb = sphero(process.env.PORT);

orb.connect(function() {
  orb.streamAccelOne();

  orb.on("accelOne", function(data) {
    console.log("accelOne:");
    console.log("  sensor:", data.accelOne.sensor);
    console.log("  range:", data.accelOne.range);
    console.log("  units:", data.accelOne.units);
    console.log("  value:", data.accelOne.value[0]);
  });

  orb.roll(180, 0);
});

Stream Accelerometer

  "use strict";

var sphero = require("../");
var orb = sphero(process.env.PORT);

orb.connect(function() {
  orb.streamAccelerometer();

  orb.on("accelerometer", function(data) {
    console.log("accelerometer:");
    console.log("  sensor:", data.xAccel.sensor);
    console.log("    range:", data.xAccel.range);
    console.log("    units:", data.xAccel.units);
    console.log("    value:", data.xAccel.value[0]);

    console.log("  sensor:", data.yAccel.sensor);
    console.log("    range:", data.yAccel.range);
    console.log("    units:", data.yAccel.units);
    console.log("    value:", data.yAccel.value[0]);

    console.log("  sensor:", data.zAccel.sensor);
    console.log("    range:", data.zAccel.range);
    console.log("    units:", data.zAccel.units);
    console.log("    value:", data.zAccel.value[0]);
  });

  orb.roll(180, 0);
});

Stream Gyroscope

  "use strict";

var sphero = require("../");
var orb = sphero(process.env.PORT);

orb.connect(function() {
  orb.streamGyroscope();

  orb.on("gyroscope", function(data) {
    console.log("gyroscope:");
    console.log("  sensor:", data.xGyro.sensor);
    console.log("    range:", data.xGyro.range);
    console.log("    units:", data.xGyro.units);
    console.log("    value:", data.xGyro.value[0]);

    console.log("  sensor:", data.yGyro.sensor);
    console.log("    range:", data.yGyro.range);
    console.log("    units:", data.yGyro.units);
    console.log("    value:", data.yGyro.value[0]);

    console.log("  sensor:", data.zGyro.sensor);
    console.log("    range:", data.zGyro.range);
    console.log("    units:", data.zGyro.units);
    console.log("    value:", data.zGyro.value[0]);
  });

  orb.roll(180, 0);
});

Stream IMU-Angles

  "use strict";

var sphero = require("../");
var orb = sphero(process.env.PORT);

orb.connect(function() {
  orb.streamImuAngles();

  orb.on("imuAngles", function(data) {
    console.log("imuAngles:");
    console.log("  sensor:", data.pitchAngle.sensor);
    console.log("    range:", data.pitchAngle.range);
    console.log("    units:", data.pitchAngle.units);
    console.log("    value:", data.pitchAngle.value[0]);

    console.log("  sensor:", data.rollAngle.sensor);
    console.log("    range:", data.rollAngle.range);
    console.log("    units:", data.rollAngle.units);
    console.log("    value:", data.rollAngle.value[0]);

    console.log("  sensor:", data.yawAngle.sensor);
    console.log("    range:", data.yawAngle.range);
    console.log("    units:", data.yawAngle.units);
    console.log("    value:", data.yawAngle.value[0]);
  });

  orb.roll(180, 0);
});

Stream Odometer

  "use strict";

var sphero = require("../");
var orb = sphero(process.env.PORT);

orb.connect(function() {
  orb.streamImuAngles();

  orb.on("imuAngles", function(data) {
    console.log("imuAngles:");
    console.log("  sensor:", data.pitchAngle.sensor);
    console.log("    range:", data.pitchAngle.range);
    console.log("    units:", data.pitchAngle.units);
    console.log("    value:", data.pitchAngle.value[0]);

    console.log("  sensor:", data.rollAngle.sensor);
    console.log("    range:", data.rollAngle.range);
    console.log("    units:", data.rollAngle.units);
    console.log("    value:", data.rollAngle.value[0]);

    console.log("  sensor:", data.yawAngle.sensor);
    console.log("    range:", data.yawAngle.range);
    console.log("    units:", data.yawAngle.units);
    console.log("    value:", data.yawAngle.value[0]);
  });

  orb.roll(180, 0);
});

Stream Velocity

  "use strict";

var sphero = require("../");
var orb = sphero(process.env.PORT);

orb.connect(function() {
  orb.streamVelocity();

  orb.on("velocity", function(data) {
    console.log("velocity:");
    console.log("  sensor:", data.xVelocity.sensor);
    console.log("    range:", data.xVelocity.range);
    console.log("    units:", data.xVelocity.units);
    console.log("    value:", data.xVelocity.value[0]);

    console.log("  sensor:", data.yVelocity.sensor);
    console.log("    range:", data.yVelocity.range);
    console.log("    units:", data.yVelocity.units);
    console.log("    value:", data.yVelocity.value[0]);
  });

  orb.roll(180, 0);
});