Work at SourceForge, help us to make it a better place! We have an immediate need for a Support Technician in our San Francisco or Denver office.

Close

getRegisterValue(n) return a int Unsigned???

Help
raf
2013-04-04
2013-05-29
  • raf
    raf
    2013-04-04

    Hello,
    I just saw in the source file ReadInputRegistersResponse that the method getRegisterValue(n) return a UnisgnedShort
    But I have a slave (nanosense E4000) which must send me a signed 16-bits temperature.
    So, how can I see the sign of the temperature sent by the slave?

    Thank you

      public int getRegisterValue(int index)
          throws IndexOutOfBoundsException {

        if (index >= getWordCount()) {
          throw new IndexOutOfBoundsException();
        } else {
          return m_Registers.toUnsignedShort();
        }
      }//getRegisterValue

     
  • raf
    raf
    2013-04-05

    Ok, thank you
    So If I use public short toShort() with public InputRegister getRegister(int index), The data  will not be modify, and if the data was signed, I will get a shot with the good sign? But if the data was not signed, the value of the short will be wrong (if the bit 15 = 1)?
    And, If I use public int getValue() with public InputRegister getRegister(int index), The data will not be modify, and if the data was not signed, I will get a int with the good value, but if the data was signed and if data was negative so the value of the int will be wrong (because the two's complement with 32 bits is different that with 16 bits)?

    So if I want a int from a data no signed, I must use getValue(), but if I want a int from a data signed, I must use (int)getShort()

    Is it right?And Is my description matches the classes work?
    Thank you

     
  • jamod will actually work as follows
    ( http://jamod.svn.sourceforge.net/viewvc/jamod/trunk/src/main/java/net/wimpi/modbus/procimg/SynchronizedAbstractRegister.java?revision=1&view=markup):

    public int getValue() {
        return ((m_Register[0] & 0xff) << 8 | (m_Register[1] & 0xff));
      }//getValue
      public final int toUnsignedShort() {
        return ((m_Register[0] & 0xff) << 8 | (m_Register[1] & 0xff));
      }//toUnsignedShort
    

    and

    public final short toShort() {
        return (short) ((m_Register[0] << 8) | (m_Register[1] & 0xff));
      }//toShort
    

    You need to make sure with the device manual how the two bytes are actually translated to a value, so you can retrieve it in Java. This might or might not be achieved with the shifting and masking as you see above :)

    If not, then you can access the raw data (the two bytes) as received from the device and apply the right masking and shifting so that you get the correct value in Java.

    Hope that helps,
    Dieter

     
  • raf
    raf
    2013-04-17

    Thank you,  but what is the difference because & 0xFF allows all bits of a byte?
    And why there is a "final" for  toUnsignedShort() and toShort() but not for getValue()?
    And a last question, if I receive a number of 16 bits in one complement, how can I obtain a int with the good signe (I think in two's complement)?
    Thank you

     
  • Julie Haugh
    Julie Haugh
    2013-05-29

    raf,

    All Java integral types are signed by default. If you have an unsigned short you must use an (int) so that the twos-compliment representation isn't interpreted as a negative value. So, if you have 0x8765, as a Java short that has the value -30,875, but as an unsigned short "stored" in an (int), it has an unsigned value of 34,661. If you have 0x8765 stored in an (int) and you want it convert back to a signed (short), you first cast to (short) --

    ((short) 0x8765)

    then cast that BACK to an (int)

    ((int) ((short) 0x8765))

    and Java will perform the sign-extension for you.

    Bit masking a byte is performed to avoid the sign extension which would automatically happen when a (byte) value is operated on. Going back to the 0x8765 example, assuming it is stored big-endian (most significant byte first), the expression

    (((byte) 0x87) << 8) | 0x65

    would result in 0xFFFF8765 because 0x87 would be sign-extended to 0xFFFFFF87 prior to being left-shifted by 8. To see how dangerous that can be, if the value were 0x6789, the 0x89 byte would be sign-extended to 0xFFFFFF89, then or'd with 0x6700 to yield 0xFFFFFF89 rather than 0x6780. What would happen instead is (0xFFFFFF89 & 0xFF) yields 0x89, which is what you want.

    This should be covered in any introduction to the Java programming language text you might pick up, though the when's and why's of bit manipulation tends to be learned by experience.