RTU Modbus problem with negative temperature

Hello to the Arduino community...
I control my heating system via RTU Modbus. This has been working for a year without any glitches or other problems.

Now I would like to expand the control to include the outside temperature.
The problem is that if the temperature is equal to or less than 0 degrees Celsius, the calculation is incorrect.

I suspect that the registers have to be read differently to display the negative temperatures.

Has anyone here had a similar problem and can offer me a solution? I would be very, very grateful...

Here is my script with all the additional information.
It works 100% as configured here.

/*
------------------------------------------------------------------------------------------
Problem description!

The following program works perfectly and is running here 
with my heat pump!

Now the heat pump's output should be controlled according
to the outside temperature. But that's the problem!

The problem with this script is that at outside temperatures
equal to or below 0 degrees Celsius, the measured values ​​are
output incorrectly. 

65533
65530
65626
65519
65516

Therefore, the registers must be read in reverse.
I only need this function for the temperature on port D6 (outside temperature)
I don't have a solution for this at the moment, or the problem is beyond my expertise.

If you're the specialist or someone has a solution, I'd be happy!

Please help me!!!

--------------------------------------------------------------------------------------------

(NOTE! Temperature sensor functions compatible with the heat pump)
T1 = THW1
T2 = THW2
T3 = THW6
T4 = THW7
T5 = room thermostat
T6 = outside temperature
T7 = THW10
T8 = ext. TWW

---------- NECESSARY HARDWARE FOR THE PROJECT ---------------------------------------------

1pcs
Arduino Mega Rev 3 
( SKU A000067 - https://store.arduino.cc/products/arduino-mega-2560-rev3 )

1pcs
Professional RS422/RS485 Shield for Arduino
( https://www.hwhardsoft.de/english/webshop/shields )

1pcs
RTU-modbus R4DCB08 Shield eletechsup (CN) (temperature sensor assembly)
( various dealers )

8pcs
Digital temperature sensor DALLAS DS18B20
( various dealers )

---------- THE NECESSARY PROGRAM LIBRARIES ------------------------------------------------

  Library : ModbusMaster
  Author  : Doc Walker <4-20ma@wvfans.net>
  Version : 2.0.1
  Download: https://github.com/4-20ma/ModbusMaster

---------- THE ARDUINO SOFTWARE USED ------------------------------------------------------

  ARDUINO IDE
  Version: 2.3.4
  Datum: 2024-12-03T10:03:03.490Z
  CLI Version: 1.1.1
  Copyright © 2025 Arduino SA
  https://www.arduino.cc/en/software

---------- PREPARING THE MODBUS SHIELD ----------------------------------------------------

RS485 module settings

S1: OFF -  ON - OFF -  ON
S2: OFF - OFF -  ON -  ON
S3:  ON - OFF - OFF - OFF

Arduino Mega 2560 R3, only with Jumper (* note see below)
RX <-> Port (Serial RX0) 
TX <-> Port (Serial TX1)

TRX control Pin - Jumper to 1st row: pin 6

---------- THE CONNECTION OF THE MASTER WITH THE SLAVES IN RTU-MODBUS ---------------------

Connection between RS485 module(0) to R4DCB08(1) 

(0)          (1)  
A o--------o A+  o---o (here a resistor 120R
B o--------o B-  o---o  from A+ to B- )
Shield o---o GND 

-------------------------------------------------------------------------------------------

(*) IMPORTANT NOTE only for Modbus communication via serial port (RX pin0, TX pin1)!

If you want to upload the program over serial to your Arduino, remove the RX jumper 
on RS485 module first! Otherwise you will get an error message...   

avrdude: stk500_getsync() __________

After successful upload, put the jumper back on the RX-pin (0)!

-------------------------------------------------------------------------------------------
---------- Modbus master functions of the library -----------------------------------------
-------------------------------------------------------------------------------------------

Modbus function 0x03 Read Holding Registers.
uint8_t ModbusMaster::readHoldingRegisters ( uint16_t u16ReadAddress, uint16_t u16ReadQty )

-------------------------------------------------------------------------------------------
---------- START OF THE PROGRAM -----------------------------------------------------------
-----------------------------------------------------------------------------------------*/

// Integrates the library ModbusMaster into the program 

#include <ModbusMaster.h>

// ---------- SETTING THE VARIABLES FOR TEMPERATURE MEASUREMENT ---------------------------

float T1, T2, T3, T4, T5, T6, T7, T8;  // sets the variable for the array

// ------- SETTING THE COMMUNICATION PARAMETERS FOR YOUR ARDUINO(R) AND THE SERIAL MONITOR ---

#define SERIAL_BAUD 9600              // baud rate is 9600 for serial monitor communication with a UNO R3 (default: 19200 bps)

// ---------- SETTING THE COMMUNICATION PARAMETERS FOR RTU MODBUS  ------------------------

#define MAX485_DE      6               // control of transceiver/receiver via pin 6 (or pin 7)

// ---------- Setting the Slave ID --------------------------------------------------------

#define MODBUS_ID     6                // slave ID 6 for temperatures heating system (default: on R4DCB08 Shield is 1!)

// ---------- INITIALIZE MODBUS-MASTER OBJECT ---------------------------------------------

ModbusMaster node;

// ---------- TRANSMISSION CONTROL --------------------------------------------------------

void preTransmission()
{
  digitalWrite(MAX485_DE, 1);    // DE, RE controll TX
}

void postTransmission()
{
  digitalWrite(MAX485_DE, 0);    // DE, RE controll RX
}

// ----------------------------------------------------------------------------------------
// ---------- SETUP -----------------------------------------------------------------------
// ----------------------------------------------------------------------------------------

void setup()
{

// DE, RE controll-pin as output

  pinMode(MAX485_DE, OUTPUT);

// DE, RE controll RX
  
  digitalWrite(MAX485_DE, 0);

// initialize serial monitor communication

  Serial.begin(SERIAL_BAUD);

// communicate with Modbus over Serial

node.begin(MODBUS_ID, Serial);

// Callbacks allow us to configure the RS485 transceiver correctly

  node.preTransmission(preTransmission);
  node.postTransmission(postTransmission);

}  // end setup

// ----------------------------------------------------------------------------------------
// -------- THE PROGRAM LOOP --------------------------------------------------------------
//-----------------------------------------------------------------------------------------

void loop()
{  
//------------------- starts the slave, read T1-T8 ------------------------------------

       uint16_t result;
       
       result = node.readHoldingRegisters(0x0000, 0x0008);  //  Read 8 registers starting at 0x0000)

     if (result == node.ku8MBSuccess)
     {
       T1 = (node.getResponseBuffer(0x0000)/10.0f);
       T2 = (node.getResponseBuffer(0x0001)/10.0f);
       T3 = (node.getResponseBuffer(0x0002)/10.0f); 
       T4 = (node.getResponseBuffer(0x0003)/10.0f);
       T5 = (node.getResponseBuffer(0x0004)/10.0f);
       T6 = (node.getResponseBuffer(0x0005)/10.0f);
       T7 = (node.getResponseBuffer(0x0006)/10.0f);
       T8 = (node.getResponseBuffer(0x0007)/10.0f);
       delay(150);

             node.clearResponseBuffer();
      }

              Serial.print("---> Temp5: ");
              Serial.print(T5);              // Room temperature its okay
              Serial.print("°C | ");

              Serial.print("Temp6: ");
              Serial.print(T6);              // The Outside temperature is not okay 
              Serial.println("°C");          // if temp <= 0 grad C ERROR 65434 !!!

}
// ---------- THE PROGRAM END -------------------------------------------------------------

Negative values can be presented many different ways on modbus protocols.
Looks that yours just simply outputs X-65535 (the highest value in hex, FFFF).

It's mostly likely 2's complement representation.

You could try:

Hello and thanks!
I'm getting a reading of -3276.80!
This value doesn't change with temperature changes.

Hello kmin thanks, Yes, that's my problem. There isn't much data.

Here is the data sheet...
https://485io.com/eletechsup/R4DCB08-1.rar

If that is what you get, you need to subtract 65536 from the result like I already suggested....

It is specified on page 2:

The return of the temperature data is two bytes,High-bit in the former and low-bit in the post,convert it to decimal and divided by 10, is the current temperature value;The highest bit 1 indicates a negative value, this value directly subtracting 65536,is the current temperature value.

For example: Read CH2 temperature value:

Send data(RS485 address is 1):01 03 00 01 00 01 D5 CA

Returns data:01 03 02 FF 90 F9 D8

FF90 is the temperature value, the highest bit is 1, so the temperature is negative, it is converted to decimal = 65424, (65424-65536)/10=-11.2 is the current temperature value

Also note

When the data is 0X8000(32768),
it indicates no sensor or error

If you read the document "R4DCB08 modbus rtu protocol.docx", you will see the following explanation:

The return of the temperature data is two bytes,High-bit in the former and low-bit in the post,convert it to decimal and divided by 10, is the current temperature value;The highest bit 1 indicates a negative value, this value directly subtracting 65536,is the current temperature value.

For example: Read CH1 temperature value:
Send data(RS485 address is 1):01 03 00 00 00 01 84 0A
Returns data:01 03 02 00 DB F8 1F
01 RS485 address,03 Function,02 length,F8 1F crc16
00DB is the temperature value, the highest bit is 0, so the temperature is positive, it is converted to decimal = 219, 219/10=21.9 is the current temperature value;

For example: Read CH2 temperature value:
Send data(RS485 address is 1):01 03 00 01 00 01 D5 CA
Returns data:01 03 02 FF 90 F9 D8
FF90 is the temperature value, the highest bit is 1, so the temperature is negative, it is converted to decimal = 65424, (65424-65536)/10=-11.2 is the current temperature value

Hello everyone... Thank you, thank you! I completely missed that, that's the solution!

Sorry again, that was a stupid question! I'm ashamed...

Kind regrads