PLC registers to real numbers

I am trying to combine two consecutive 16 bit (uint16) registers read from a plc into a double and also in reverse I need to turn a real number into two 16 bit integers and write to regitsers in PLC. Help much appreciated

A Double is 8 bytes though, so I think you want a Single?

Go through a MemoryBlock, but make sure the LittleEndian setting matches what you’re reading so the bytes are written in the correct order.

Note that creating and destroying MemoryBlocks is “expensive” so reuse them where you can.

(On my phone or I’d post example code.)

@Kem_Tekinay - would you please expand on that “expensive” a little bit? I am heading into my code to make sure Im reusing the blocks i have now but…

Creating and tearing down any object takes time as the memory has to be allocated and deallocated. If you are only doing this a few times, you won’t notice, but after a few dozen reps, it will take a toll, especially when you are trying to squeeze out speed. Sometimes it’s unavoidable, but where an operation needs the same-sized MemoryBlock several times, you can save those cycles by creating it once and reusing it.

1 Like

Hello Bruce,

Here is one of a few possible methods to convert 2 UInt16 values to a double:

As Kem mentioned, there are speed differences in calculations. Possibly try this method and see if it does what you want, and at the speed that you want.

Happy to help. :slight_smile:

Edit: Sorry, this was meant for Bruce, not for Sean.

Here is a method which converts a double to two UInt16 values:

@Eugene_Dakin You’re coverting singles, not doubles, right? I think the OP misspoke as well.

ahh…ok

yes - apologies - I am trying to convert to a 32bit real number so single - thanks for suggestions Conversion from single to 2 x uint 16 will be infrequent but conversion fro 2 x uint16 to real will be a few a second so I don;t think processor time to much of an issue.

Hi Bruce, here’s a function I use to accomplish what I think you’re after. I’m constantly taking values from registers and converting them back and forth - no guarantee this is the best way, but it does work :slight_smile:

Public Function convert_32bitFloat_toUint16s(the32bitFloat as Double) As Uint16()
  
  var theResults() as UInt16
  var myMB as New MemoryBlock(4)
  var UInt16_1, Uint16_2 as UInt16
   
  myMB.LittleEndian = False
  
  myMB.SingleValue(0) = the32bitFloat
  
  UInt16_1 = myMB.Int16Value(0)
  
  UInt16_2 = myMB.Int16Value(2)
  
  theResults.AddRow(UInt16_1)
  
  theResults.AddRow(UInt16_2)
  
  return(theResults())
  
End Function

thanks much appreciated