4

I need to build a NodeJS server-based prototype that reads industrial modbus data.

I am reading two consecutive 16bit decimal registers that provide me an array with two entries:
// eg transaction = [ 17007, -2621 ] or // eg transaction = [ 17007, 0000 ]

This value should translate to electrical frequency, approx = ~60.00 (hz) (at least it should if the data I'm given is right)

I am aware that I need to combine the two registers values in the array and convert the data either to 32-bit float .. but how:

a) how to combine them without casting them as something they aren't
b) how to covert them to 32 bit float

I think I need to use some type of parseInt() and then toString(10) - one suggestion was to convert each to hex using parseInt(num, 10).toString(16) and then convert that joined hex to a string or possibly float using parseFloat() but again how to join the two separate parts first.

I've not found solutions to this, surprisingly.

Jeremy
  • 1
  • 85
  • 340
  • 366
Tremendus Apps
  • 1,497
  • 12
  • 20
  • (I'm not familiar with modbus; pardon if this should be evident from context.) It's not quite clear to me how you want the values to be combined. The original values are signed 16-bit integers, and you want to basically concatenate their bits and get the resulting 32-bit signed integer? If they were unsigned than that would probably be something like `(firstValue << 16) | secondValue`; ideally any conversion to/from strings could be avoided. Could you provide an example of a desired input/output pair? – Jeremy Feb 20 '16 at 01:02
  • I'm actually looking for the float of the concat. I am expecting 60.00... or something very close to that. (Frequency doesn't change by more than one or two decimal places) – Tremendus Apps Feb 20 '16 at 13:01
  • Does it really provide you with an `Array`? File a bug that they should use a `Uint16Array`. – Bergi Apr 01 '17 at 16:16

1 Answers1

3

You can use a DataView of an ArrayBuffer to manipulate the binary data directly, using defined types and endianness. By writing the register values as consecutive 16-bit integers and interpreting the result as a big-endian (false) 32-bit float, we get the result you're looking for:

var buffer = new ArrayBuffer(4);
var view = new DataView(buffer);

view.setInt16(0, 17007, false);
view.setInt16(2, -2621, false);

document.body.textContent = view.getFloat32(0, false);
Jeremy
  • 1
  • 85
  • 340
  • 366