Negative Temperature

Hi,
i am using Dragino with Arduino Uno, OTAA. I have Problem with negative numbers. Positive numbers works fine. Its a basic mistake for sure, but i just cant see it.
Arduino code:

temperature=-10;
static int8_t payloadA[4];
      mydata[0] = highByte(ID);
      mydata[1] = lowByte(ID);
      mydata[2] = highByte(temperature);
      mydata[3] = lowByte(temperature);

TNN Code:

function Decoder(bytes) {
    var decoded_tsbid = (bytes[0]<<8) | bytes[1] ;
    var temp_operator = (bytes[2]<<24>>16) ;
    var temp_value = (bytes[3]) ;
    var temp = temp_operator + temp_value ; 
    return {
      Id: decoded_tsbid ,
      Temperature: temp ,
    };
    }

Output:
grafik

I already read the article: Decrypting messages for dummies
but that didnt solve my problem, maybe you can you help me finde the solution

1 Like

(bytes[0] & 0x80 ? 0xFFFF<<16 : 0) | bytes[0]<<8 | bytes[1]

1 Like

What’s the type of the variable temperature? The function highByte is documented as:

Extracts the high-order (leftmost) byte of a word (or the second lowest byte of a larger data type).

Now, if temperature has a size of more than 2 bytes (1 word), you’ll be missing information, and will also show wrong results for large positive values then. It’s safer to be more explicit about the specific byte you’re including then. Also, it needs to be defined as some signed integer value, so something like int_16t temperature.

With the signed integer -10 being stored in memory as 0xFFF6 or 0xFFFF FFF6 (when showing as hexadecimal), and assuming mydata is defined as byte[] or uint8_t[]:

int_16t temperature = -10;
uint8_t mydata[4];

// Handle high byte (MSB) first; 0xFF for -10
// 0xFFF6 >> 8 shifts the 0xF6 out of memory, leaving 0x00FF
// 0x00FF does not fit in a single byte, so only 0xFF is stored in mydata[2]:
mydata[2] = temperature >> 8;
// Handle low byte (LSB) next; 0xF6 for -10
// 0xFFF6 does not fit in a single byte, so only 0xF6 is stored in mydata[3]:
mydata[3] = temperature;

This should work, but is confusing: bytes[2] is not only the sign, but is really part of the value. Also, using the bitwise OR rather than the mathematical addition, saves the need for some parentheses. So, I’d use a single line:

// Sign-extend to 32 bits to support negative values, by shifting 24 bits
// (16 too far) to the left, followed by a sign-propagating right shift:
var temp = bytes[2]<<24>>16 | bytes[3];

This is the same as:

bytes[0]<<24>>16 | bytes[1]
1 Like

awesome, it worked.
Ty very much.
Little mistake: It has to be mydata[2] = temperature >> 8 instead of mydata[2] = temperature << 8;
(For people if they have the same problem).

2 Likes

Oops, yes, I’ve fixed that now for future reference.