node.jsarduinoxbeenode-serialportnode-xbee

Understanding Serial Data from XBee using Node-XBee and Node-SerialPort


node-serialport and node-xbee are used in the following code to read incoming XBee frames from a XBee Series 2 in Router AT configuration. A potentiometer is connected to pin 20 AD0 analog input pin of the XBee. All 4 analog pins AD0, AD1, AD2, AD3 are enabled, only AD1 is connected to something.

How do you interpret the data array in the frame_object received? Theres obviously a trend here, when 0V is fed to the XBee, we receive a array data ending with elements 0, 0, 2, 14, 2, 8, 2, 15. When 3.3V is fed to the XBee, the data array ends with elements 3, 255, 3, 255, 3, 255, 3, 255.

How do you convert these raw values to something more meaningful? 3, 255 looks like a pair of values that denote 3.3V? But how do we get from 3, 255 to a voltage reading?

Reading serial port data

var SerialPort = require('serialport').SerialPort;
var xbee_api = require('xbee-api');

var C = xbee_api.constants;

var xbeeAPI = new xbee_api.XBeeAPI({
  api_mode: 1
});

var serialport = new SerialPort("/dev/cu.usbserial-A702NY8S", {
  baudrate: 9600,
  parser: xbeeAPI.rawParser()
});

xbeeAPI.on("frame_object", function(frame) {
  console.log("OBJ> "+util.inspect(frame));
});

XBee Frames when XBee pin is fed 0V

OBJ> { type: 145,
  remote64: '0013a20040b19213',
  remote16: '56bc',
  receiveOptions: 232,
  data: [ 232, 0, 146, 193, 5, 1, 1, 0, 0, 15, 0, 0, 2, 14, 2, 8, 2, 15 ] }

OBJ> { type: 145,
  remote64: '0013a20040b19213',
  remote16: '56bc',
  receiveOptions: 232,
  data: [ 232, 0, 146, 193, 5, 1, 1, 0, 0, 15, 0, 0, 2, 16, 2, 14, 2, 14 ] }

OBJ> { type: 145,
  remote64: '0013a20040b19213',
  remote16: '56bc',
  receiveOptions: 232,
  data: [ 232, 0, 146, 193, 5, 1, 1, 0, 0, 15, 0, 0, 2, 17, 2, 11, 2, 9 ] }

XBee Frames when XBee pin is fed 3.3V

OBJ> { type: 145,
  remote64: '0013a20040b19213',
  remote16: '56bc',
  receiveOptions: 232,
  data: [ 232, 0, 146, 193, 5, 1, 1, 0, 0, 15, 3, 255, 3, 255, 3, 255, 3, 255 ] }

OBJ> { type: 145,
  remote64: '0013a20040b19213',
  remote16: '56bc',
  receiveOptions: 232,
  data: [ 232, 0, 146, 193, 5, 1, 1, 0, 0, 15, 3, 255, 3, 255, 3, 255, 3, 255 ] }

OBJ> { type: 145,
  remote64: '0013a20040b19213',
  remote16: '56bc',
  receiveOptions: 232,
  data: [ 232, 0, 146, 193, 5, 1, 1, 0, 0, 15, 3, 255, 3, 255, 3, 255, 3, 255 ] }

Solution

  • Check the documentation for the format of an ATIS response.

    Header bytes include the endpoint (232 = 0xE8) and cluster (193, 5 = 0xC105) for the frame. I'm not sure about the 0, 145 and extra 1 before the input sample. I think the bytes after 5, 1 decode as follows:

    Starts with an 8-bit sample count (0x01).

    Then a 16-bit reading of enabled digital inputs (0x0000).

    Then an 8-bit reading of enabled analog inputs (0x0F).

    If there were any enabled digital inputs, you'd have a 16-bit value for all digital readings.

    The four analog inputs follow (3, 255 = 0x03FF), and they're a scaled 10-bit value.

    reference voltage * reading / 0x03FF
    

    So, in your case, 3.3V * 0x03FF / 0x03FF = 3.3V.