Harvestree Modbus Register Table

Modbus RTU register reference for operating Harvestree LoRaWAN from a Modbus master.

← Communication

This document covers only what is needed by a Modbus master in MODBUSSLV mode:

  • usable holding-register map,
  • data encoding on the wire,
  • read/write rules relevant for polling and configuration.

Register map (holding registers)

Start address Size (regs) Access Description
0x0000 2 R Serial number (uint32, LSW then MSW)
0x0002 2 R Firmware version (uint32, LSW then MSW)
0x0004 1 R Storage voltage
0x0005 1 R Board temperature
0x0006 1 R Base temperature
0x0007 1 R TEG voltage
0x0008 2 R Measurement counter (uint32, LSW then MSW)
0x000A 1 R Port 1 configured type (PortType_t, see below)
0x000B 1 R Port 2 configured type (PortType_t, see below)
0x000C 1 R Port 3 configured type (PortType_t, see below)
0x000D 1 R Port 4 configured type (PortType_t, see below)
0x0020 1 R/W Delay before standby (seconds)
0x0021 2 R/W Measurement period (milliseconds, uint32, LSW then MSW)
0x0100 64 R (dynamic) Port 1 measurement data window
0x0140 64 R (dynamic) Port 2 measurement data window
0x0180 64 R (dynamic) Port 3 measurement data window
0x01C0 64 R (dynamic) Port 4 measurement data window

Encoding and ordering

  • Register payload unit is uint16.
  • For uint32 / float32, words are ordered LSW first (offset 0), then MSW (offset 1).
  • For port windows (0x0100, 0x0140, 0x0180, 0x01C0), the valid offset range is not fixed at 64 registers: it depends on the active measurement type read from 0x000A0x000D (see Port configured type and dynamic window layout).

Port configured type and dynamic window layout

Each port exposes its active measurement type at 0x000A0x000D (ports 1–4). The value is a PortType_t code (uint16 in one holding register): the same code used in LoRaWAN uplink metadata (bytes 1–4) and in Toolbox / remote configuration.

Port measurement windows are allocated 64 registers each, but the device exposes only the offsets that match the configured type. Any read beyond that valid range returns illegal address — even inside the 64-register block.

Integrator workflow (dynamic table)

A Modbus master can build its polling map at runtime without hard-coding port wiring:

  1. Discover — read 0x000A + (port − 1) for each port (0x000A0x000D).
  2. Resolve layout — look up the code in the table below and open the matching row in Port measurement windows.
  3. Poll — read only the valid offsets from that port’s window base (0x0100, 0x0140, 0x0180, 0x01C0). Global address = window base + offset.
  4. Reconcile on change — if a port is reconfigured (Toolbox or downlink), the type register and valid offsets update; window bases stay fixed.

Example: port 2 reads 0x000B = 0x0F (WEATHER_A) → valid offsets 02 → poll holding 0x01400x0142 only.

PortType_t lookup

Codes 0x11, 0x15, and 0x17 are reserved and are not used in production configurations.

Code Measurement Valid window offsets Layout section
0x00 Port disabled (none — all reads illegal)
0x01 PT1000 0 Temperature → PT1000
0x020x09 Thermocouple (K, J, T, N, S, E, B, R) 01 Temperature → Thermocouple
0x0A Infrared (ref A) 0 Temperature → Infrared
0x0B DC differential voltage 0 Voltage → DC differential voltage
0x0C AC differential voltage (RMS) 01 Voltage → AC differential voltage
0x0D DC voltage 0 Voltage → DC voltage
0x0E AC voltage (RMS) 01 Voltage → AC voltage
0x0F Temperature and humidity 02 Environmental
0x10 Potentiometer 01 Industrial analog → Potentiometer
0x12 4–20 mA loop 01 Industrial analog → 4–20 mA
0x13 Analog 1-axis vibration 06 Vibration
0x14 Dry contact (synchronous) 0 Dry contact → synchronous
0x16 Digital temperature probe (ref A) 0 Temperature → Digital temperature probe
0x18 DC magnetic sensor 01 Magnetic field → DC magnetic sensor
0x19 AC magnetic sensor (RMS) 03 Magnetic field → AC magnetic sensor
0x1A DC current (voltage difference) 01 Current → DC current (voltage difference)
0x1B DC current (magnetic sensor) 01 Current → DC current (magnetic sensor)
0x1C AC current (voltage difference, RMS) 03 Current → AC current (voltage difference)
0x1D AC current (magnetic sensor, RMS) 03 Current → AC current (magnetic sensor)
0x1E DC differential + external amplifier 01 Voltage → DC differential + external amplifier
0x1F AC differential + external amplifier (RMS) 03 Voltage → AC differential + external amplifier
0xFF Asynchronous dry contact (Alarm mode) 0 Dry contact → asynchronous

Write behavior

  • Writable holding registers: 0x0020 (delay before standby — one uint16, seconds) and 0x00210x0022 (measurement period — uint32 in milliseconds).
  • For the measurement period, write LSW at 0x0021 first, then MSW at 0x0022, to apply the full value.

Port measurement windows (0x0100 / 0x0140 / 0x0180 / 0x01C0)

Each port has a 64-register window. Offset below is relative to that port’s window base (not the global holding address). Which rows apply is determined by the port’s configured type at 0x000A0x000D — see Port configured type and dynamic window layout.

Port Window base
Port 1 0x0100
Port 2 0x0140
Port 3 0x0180
Port 4 0x01C0

Register encoding in the window

Wire type Registers Decoding
int16 1 Signed value in one uint16 register (two’s complement)
uint8 1 Low byte valid
float32 2 IEEE-754, LSW at offset n, MSW at offset n+1

Physical scaling matches Harvestree LoRaWAN Payload Decoding where the same quantity is transmitted on LoRaWAN. Reads beyond the valid offset range for the active port type return illegal address.

Temperature

Measurement Offsets Fields Decoding
PT1000 0 Temperature int16, × 0.1 → °C
Thermocouple (types K, J, T, N, S, E, B, R) 0, 1 Cold junction, hot junction int16 each, × 0.1 → °C
Digital temperature probe (ref A) 0 Temperature int16, × 0.1 → °C
Infrared (ref A) 0 Object temperature int16, × 0.1 → °C

Environmental

Measurement Offsets Fields Decoding
Temperature and humidity 0, 1, 2 Air temperature, humidity, frost index int16 × 0.1 → °C; int16 × 0.1 → %RH; uint8 frost byte

Voltage

Measurement Offsets Fields Decoding
DC voltage 0 Voltage int16, × 0.1 → mV
AC voltage (RMS) 0, 1 RMS, frequency int16 × 0.1 → mV RMS; int16 × 0.1 → Hz
DC differential voltage 0 Voltage int16, × 0.1 → mV
AC differential voltage (RMS) 0, 1 RMS, frequency int16 × 0.1 → mV RMS; int16 × 0.1 → Hz
DC differential + external amplifier 01 Voltage float32 (project-defined unit)
AC differential + external amplifier (RMS) 01, 23 RMS, frequency float32 each

Magnetic field

Measurement Offsets Fields Decoding
DC magnetic sensor 01 Magnetic quantity float32 (project-defined unit)
AC magnetic sensor (RMS) 01, 23 RMS, frequency float32 each

Current

Measurement Offsets Fields Decoding
DC current (voltage difference) 01 Current float32 (project-defined unit)
AC current (voltage difference, RMS) 01, 23 RMS, frequency float32 each
DC current (magnetic sensor) 01 Current float32 (project-defined unit)
AC current (magnetic sensor, RMS) 01, 23 RMS, frequency float32 each

Industrial analog

Measurement Offsets Fields Decoding
4–20 mA loop 01 Loop quantity float32 (project-defined unit)
Potentiometer 01 Position / calibrated quantity float32 (project-defined unit)

Vibration

Measurement Offsets Fields Decoding
Analog 1-axis vibration 0 LF RMS int16, × 0.01
1 HF RMS int16, × 0.01
24 LF sub-band ratios 0–2 uint8 in register, ÷ 255
56 HF sub-band ratios 0–1 uint8 in register, ÷ 255

Dry contact

Measurement Offsets Fields Decoding
Dry contact (synchronous) 0 State uint8 in register (0 open, 1 closed)
Asynchronous dry contact (Alarm mode) 0 State uint8 in register (0 open, 1 closed)

Document Version: 1.2
Last Updated: 2026-06-02