0

I'm using Cylon.js and Node.js to work with a Sphero, and I'm not sure how I am supposed to reconstruct the 16 bit values from the data returned from a collision event.

The docs imply that they should be signed 16-bit integers, and that the numbers come in (MSB, LSB) byte order, but I get oddball values when I attempt to convert two bytes into what should be negative power ratings (such as impacts from behind or from the left).

The Javascript code I am using to convert a two-btye Sphero value is this:

  function convertToSignedInt(msb, lsb) {
    var negative = msb > 128;
    if (negative) {
      msb -= 128;
    }
    var value = msb*256 + lsb;
    if (negative) {
      value = 0 - value;
    }
    return value;
  }

Given raw collision data like the following:

{"SOP1":255,"SOP2":254,"ID_CODE":7,"DLEN":17,"DATA":[18,31,255,104,0,0,1,0,67,0,6,0,0,9,1,95],"CHK":156}

I then attempt to convert the DATA property to a more readable object using this:

  function convertCollisionData(data) {
    var obj = {};
    obj.xPower = convertToSignedInt(data[0], data[1]);
    obj.yPower = convertToSignedInt(data[2], data[3]);
    obj.zPower = convertToSignedInt(data[4], data[5]);
    obj.impactAxis = data[6];
    obj.xImpact = convertToSignedInt(data[7], data[8]);
    obj.yImpact = convertToSignedInt(data[9], data[10]);
    obj.speed = data[11];

    return obj;
  }

To come up with this:

{"xPower":4639,"yPower":-32616,"zPower":0
    ,"impactAxis":1,"xImpact":67,"yImpact":6,"speed":0}

It's obvious that the yPower is completely wrong, since this was a right-side (positive X) collision. Since the xImpact and yImpact values are positive, they appear to be converting correctly.

So the short version of the question is, what is the proper way to convert the two bytes to a signed integer?

Michael Oryl
  • 20,856
  • 14
  • 77
  • 117
  • Are you sure they are in big-endian order? If they are, `yPower` should be negative if I'm not wrong (but not the value in your code). – Qantas 94 Heavy May 10 '15 at 13:42
  • Instead of the code you've got, I'd just combine the bytes (in the proper order, as @Qantas94Heavy points out), left-shift by 16, and then right-shift by 16. The right-shift operator does sign extension. If `[255, 104]` is really a big-endian pair, the value is `-152`. – Pointy May 10 '15 at 13:44
  • 1
    Also, is "DATA" an array or a buffer? If it's a buffer, you could just use `readInt16BE`. I ask this as some of the issues on Github show them as buffers, but I'm not too familiar with the project itself. – Qantas 94 Heavy May 10 '15 at 13:47
  • @Qantas94Heavy Thanks for the tips. yPower is not negative because it is a raw rating of power, not direction. It's supposed to be positive in all cases, to the best of my understanding. – Michael Oryl May 10 '15 at 15:09
  • 1
    Well if the values *are* big-endian, then `255, 104` must be negative. If they're little-endian, then the value is `26879`, which seems big (but maybe not?). – Pointy May 10 '15 at 15:13

0 Answers0