# Read-Only Memory – Read Command (04)

{% hint style="info" %}
When reading large values using different data formats (e.g., **Float32** or **Int64**) and performing conversions, **very small differences** may occur due to internal calculation methods. These differences are typically **less than 1/10,000** and are considered **normal**.
{% endhint %}

#### **Function Code 04**

**Purpose:** This memory area is specifically used to store the device’s **real-time status**, **measurement results**, and **flow-related memory**.

**Characteristics:** The data is **read-only** and can only be accessed via the **Read command**. Values **cannot be modified** using write commands.

#### Read-Only Memory – Read Command (04) Format

![](https://3404778090-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fi4ECt41Kyy9211OWazj4%2Fuploads%2Freb9w1HVRJuNuDjmVmj9%2Fmodbus-04-TX-diagram-en.png?alt=media\&token=990793a9-39e3-4390-82e6-e153c0d4fbfe)

![](https://3404778090-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fi4ECt41Kyy9211OWazj4%2Fuploads%2FTahA1LkITMgPQGZSw2JP%2Fmodbus-04-RX-diagram-en.png?alt=media\&token=ed407c1e-596c-4860-ac37-b54f67294de8)

#### Modbus RTU – Example of Read-Only Memory Read Command (04)

Using the **Read-Only Memory Read Command (04)** as an example, this section explains how to send a command and parse the returned data into a decimal value when the **totalized flow** is **20,000.5 liters**.

**Master Sends Read Command (TX Frame)**

According to device specifications, the accumulated flow is stored in **Float32 format**, occupying **2 registers (4 bytes)**; therefore, the quantity to read should be set to **00 02**. The master must send Modbus function code 04 (Read Input Registers) to read 2 registers starting from address 0000.

```
TX: 01 04 00 00 00 02 71 CB
```

* Slave Address = 01
* Function Code = 04
* Starting Register Address = 00 00
* Quantity to Read = 00 02 (2 registers)
* CRC Checksum = 71 CB

**Slave Response Data (RX Frame)**

After receiving the read request, the slave returns the internally stored **20,000.5 liters (Float32)** data, packaged as **4 bytes** according to **Modbus Register Big Endian** (high byte first) and **IEEE 754 Float32** format.

```
RX: 01 04 04 45 9C 40 00 E2 56
```

* Slave Address = 01
* Function Code = 04
* Byte Count (Number of Data Bytes) = 04 (4 Bytes)
* Data (Data Field) = 45 9C 40 00
* CRC Checksum = E2 56

**Data Parsing and Conversion (Back to Decimal)**

**Step A: Arrange the Data**\
Since the device uses **Big Endian** format, the most significant byte comes first. Therefore, the 4 bytes are kept in the received order and combined as:\
`459C4000₁₆`

**Step B: Decode the Float32 Structure (SEM: S = Sign, E = Exponent, M = Mantissa)**\
Convert `459C4000₁₆` into a 32-bit binary number for IEEE 754 Float32 interpretation.

![](https://content.gitbook.com/content/i4ECt41Kyy9211OWazj4/blobs/0xkomQ8TDrwjQi11vUhZ/image)

**Partial Binary Value Explanation**

* **S (Sign bit)** = 0 (1 bit) → 0 means a positive number
* **E (Exponent bits)** = `10001011` (8 bits) → 139₁₀\
  Actual exponent = 139 − 127 = **12**
* **M (Mantissa bits)** = `001110001...` (23 bits) → the significand is **1.M**

**Step C: Calculate the Value**

According to the IEEE 754 Float32 format, the calculation is as follows.\
The exponent bits `10001011₂` equal 139₁₀, so the actual exponent is 139 − 127 = 12.

* The mantissa bits are 0011100100000000000000，, giving a significand of 1.001110001...

After shifting the binary point 12 places to the right and converting to decimal:

Value = 2¹⁴ + 2¹¹ + 2¹⁰ + 2⁹ + 2⁵ + 2⁻¹\
\= 16384 + 2048 + 1024 + 512 + 32 + 0.5\
\= 20000.5

Therefore, the Modbus RX response data `01 04 04 45 9C 40 00 E2 56` represents a cumulative flow value of **20000.5 liters**.

{% embed url="<https://codepen.io/philo_lorric/embed/BagqoRj>?" %}

另見 CodePen 作者個人頁面： <https://codepen.io/philo\\_lorric>
