Modbus Scaling & Data Conversion Guide

How to convert raw Modbus register values to engineering units — integer scaling, multipliers and divisors, floating-point registers, temperature conversion, and configuring scaling in protocol conversion gateways.

Categories:

Overview

Modbus registers are 16-bit integers. They don’t inherently carry unit information, decimal points, or scaling factors. A register value of 2500 could mean 25.00°C, 250.0 PSI, 2500 RPM, or just the number 2500 — the register map documentation defines the interpretation.

Converting raw register values to meaningful engineering units is one of the most error-prone steps in Modbus integration. This guide covers the common scaling methods, how to identify them in device documentation, and how to configure them in gateway devices.

Modbus scaling pipeline — raw register value through scale factor and offset to engineering units

Common Scaling Methods

Method 1: Fixed Multiplier / Divisor (Most Common)

The raw register value is divided (or multiplied) by a fixed factor to produce the engineering value:

Engineering Value = Raw Value × Multiplier

or equivalently:

Engineering Value = Raw Value ÷ Divisor
Raw ValueDivisorScale FactorEngineering ValueUnit
2500100×0.0125.00°C
250010×0.1250.0PSI
25001×12500RPM
123410×0.1123.4kW
456100×0.014.56pH

[!TIP] The most common divisors in building automation are 10 and 100. When a register map says “resolution: 0.1” or “decimal places: 1,” divide by 10. When it says “resolution: 0.01” or “decimal places: 2,” divide by 100.

How to Identify the Scale Factor

Look for these clues in the device register map documentation:

Documentation SaysScale FactorExample
”Resolution: 0.1”÷10Raw 250 → 25.0
”Resolution: 0.01”÷100Raw 2500 → 25.00
”×10” or “Multiplier: 10”÷10 (to get back to real value)Raw 250 → 25.0
”Scaled by 100”÷100Raw 2500 → 25.00
”Integer, no decimal”÷1 (no scaling)Raw 72 → 72
”Units: 0.1°F”÷10, value is in °FRaw 720 → 72.0°F

Writing Scaled Values

When writing setpoints back to a device with scaling, apply the inverse operation:

Raw Value = Engineering Value × Divisor

Example: To set a temperature setpoint of 23.5°C on a device with divisor 10:

Raw Value = 23.5 × 10 = 235

Write 235 (0x00EB) to the setpoint register via FC06 or FC16.

[!CAUTION] Always verify the acceptable range before writing. If the register accepts 0–500 (representing 0.0–50.0°C), writing a raw value of 1000 (100.0°C) may cause exception code 03 (Illegal Data Value) or damage the controlled equipment.

Method 2: IEEE 754 Floating Point (32-Bit)

Some devices store values as 32-bit IEEE 754 floating-point numbers, spread across two consecutive 16-bit holding registers:

ByteContent
Bits 31–23Sign (1 bit) + Exponent (8 bits)
Bits 22–0Mantissa (23 bits)

A 32-bit float spans 2 Modbus registers. The register order varies by manufacturer — see Modbus Data Types & Byte Order Reference for byte/word order details.

Register OrderDescriptionAlso Called
Big-endian (AB CD)High word first, high byte first”Normal”
Little-endian (CD AB)Low word first, high byte first”Word-swapped”
Byte-swapped (BA DC)High word first, low byte firstUncommon
Fully reversed (DC BA)Low word first, low byte firstSome Asian manufacturers

Example: 25.5°C as IEEE 754 Float

25.5 in IEEE 754 = 0x41CC0000

Register OrderRegister NRegister N+1
Big-endian (AB CD)0x41CC0x0000
Little-endian (CD AB)0x00000x41CC

[!WARNING] If you read two registers and the resulting float is an impossibly large or small number (like 1.2e+38 or 3.4e-43), the register order is almost certainly wrong. Try swapping the two register values.

Method 3: Signed Integer (Two’s Complement)

Modbus registers are unsigned by default (0–65,535). For negative values (e.g., below-zero temperatures), devices use two’s complement signed representation:

Raw Value (unsigned)Raw Value (hex)Signed Interpretation
00x00000
1000x0064100
32,7670x7FFF32,767 (maximum positive)
32,7680x8000-32,768 (minimum negative)
65,4350xFFAB-85
65,5350xFFFF-1

How to Detect Signed Values

If a register represents temperature, pressure, position, or any value that can be negative, it’s likely signed. If you read a value around 65,500 when expecting a small negative number, the value needs signed interpretation.

Conversion: If the unsigned value is > 32,767, subtract 65,536 to get the signed value.

Signed = Unsigned - 65536  (when Unsigned > 32767)

Example: Raw register = 0xFFAB (65,451 unsigned)

65451 - 65536 = -85  →  with divisor 10  →  -8.5°C ✅

Method 4: 32-Bit Integer (Long)

Energy meters, flow meters, and counters frequently use 32-bit unsigned or signed integers across two registers for values that exceed the 16-bit range (0–65,535):

FormatRangeUse Case
32-bit unsigned0 to 4,294,967,295Energy totals (kWh), flow totals, runtime hours
32-bit signed-2,147,483,648 to 2,147,483,647Bidirectional totals (import/export energy)

Like floats, the register order (high word first vs low word first) varies by manufacturer. See Modbus Data Types & Byte Order Reference.

Temperature Conversion

Building automation frequently requires temperature conversion between °C and °F:

ConversionFormula
°C to °F°F = (°C × 9/5) + 32
°F to °C°C = (°F - 32) × 5/9

Common Temperature Scaling Table

Device ReportsRaw ValueDivisorEngineering Value
Temperature in 0.1°C2351023.5°C
Temperature in 0.01°C235010023.50°C
Temperature in 0.1°F7451074.5°F
Temperature in 0.1°C, signed6550110(65501-65536)/10 = -3.5°C

[!NOTE] Some devices report temperature in °F while the BACnet side expects °C (or vice versa). When configuring a protocol conversion gateway, apply both the scaling divisor AND the unit conversion in the point map.

Scaling in Gateway Configuration

QuickServer Scaling

When configuring a QuickServer point map:

Mapping StepParameterExample
1. Read raw registerSource address, FCFC03, Register 0
2. Apply data typeSigned/unsigned, 16/32-bitSigned 16-bit
3. Apply scale factorMultiplier or divisor÷10
4. Apply unit conversion°F→°C, PSI→kPa, etc.(°F-32)×5/9
5. Write to destinationTarget BACnet object, register, etc.BACnet AV, Present Value

Common Pitfalls

MistakeResultFix
Forgot to apply divisorValue is 10× or 100× too largeCheck register map for scale factor
Applied wrong divisorValue is close but off by a factorVerify divisor against a known reading
Wrong sign interpretationNegative values appear as ~65,000Configure as signed 16-bit
Wrong register order for 32-bitValue is impossibly large or garbageSwap register order
Scaling applied twiceValue is 100× or 10,000× too smallCheck if the device already provides scaled values

Verifying Scaling

Sanity-Check Workflow

  1. Read the raw register value using CAS Modbus Scanner or equivalent tool
  2. Compare against a known reference — read the device’s display panel, check with a handheld meter, or compare to a known setpoint
  3. Apply the documented scaling and verify the math: Raw ÷ Divisor = Expected Value ± tolerance
  4. Test extremes — verify scaling holds at both high and low ends of the range (not just midrange)
  5. Test negative values (if applicable) — confirm signed interpretation works for below-zero readings

Example Verification

Device documentation: “Register 100 = Room Temperature, 0.1°C resolution”

TestRaw ValueCalculationExpectedVerified?
Normal range235235 ÷ 10 = 23.5°C~23.5°C on display
Cold room5555 ÷ 10 = 5.5°C~5.5°C on display
Below zero65516(65516-65536) ÷ 10 = -2.0°C~-2.0°C on display

Chipkin Tools

Need more help?

If this page does not resolve the issue, contact Chipkin support with the product model, protocol details, and any diagnostics you have already captured.

Open Chipkin Support