Wiki

Technical reference for system integrators and engineers.

Modbus RTU

The internal bus of the Smart Lamp Locator, joining the RTLS module to the cap lamp controller — and through it to the gas sensors, buttons and display.

Modbus RTU is the main interface between the Smart Lamp Locator and a cap lamp controller — either the native Smart Lamp controller or a third-party cap lamp controller the module is embedded into. It is the integration contract for both cases: a controller that speaks the register map below works with the module without firmware changes on either side.

Who is master

The cap lamp controller is the master; the RTLS module is a slave. This is the reverse of what the naming might suggest — the module does not poll the lamp, the lamp polls the module.
cap lamp controller — master gas sensors buttons display owns the sensors and everything the wearer sees RTLS module — slave 0x11 BLE scanning, position, WiFi uplink to MQTT owns positioning and everything off-device 0x10 0x03
Readings and events are written into the module; commands and display text are read out of it. Both directions are initiated by the lamp.

Bus parameters

ProtocolModbus RTU, CRC-16
Bit rate1200 baud
Module address0x11
Controller address0x34
Register file48 registers, 16-bit
Maximum frame128 bytes

1200 baud is deliberate. The payload is a handful of registers a second, the cable run is centimetres, and the environment is a mining cap lamp — a slow bit rate buys noise immunity and low emissions where nothing needs speed.

Function codes

CodeFunctionDirectionCarries
0x03Read Holding Registerslamp reads the modulecommands for the lamp, display text
0x10Force Multiple Registerslamp writes to the modulegas readings, button and alarm events
0x08Testloopback
0x11Report Slave IDidentification

Errors use the standard exception mechanism: illegal function, illegal data address, illegal data value, and a CRC failure code.

Register map

RegisterContent
0Alarm acknowledgement state
1Methane concentration
2Methane sensor status word
3CO concentration or temperature — see below
4CO sensor status word
5Methane alarm threshold
6CO alarm threshold
7Battery estimate — methane / CO builds
9, 10Pressure, high and low words
11Battery estimate — methane / pressure / temperature builds
12Command to the controller
13Message text, two characters per register
Two registers move depending on the fitted sensor option. Register 3 carries CO concentration on a CO build and temperature on a methane-pressure-temperature build. The battery estimate is at register 7 on most builds and register 11 on a methane-pressure-temperature build. A decoder must know the SL_CONFIG option before it can read either — see Gas Sensors.

Wire register numbers are offset from these positions — the master's numbering and the module's internal array do not share an origin, and the shift differs between the read and write paths. Work from the function code, not from an assumed one-to-one mapping.

Sensor status words

Registers 2 and 4 are split by byte: the high byte reports sensor health and the low byte reports the threshold state.

High byteSensor health
0OK
1Zero point not set
2Not calibrated
3Low sensitivity
4Malfunction
16Warming up
Low byteThreshold
0Concentration normal
1Concentration exceeded

This is the same word that surfaces as MethaneALM and COALM in MQTT, which is why testing bit 0 works for the alarm and comparing the whole word to 1 does not — a sensor that is warming up or uncalibrated carries a non-zero high byte while its threshold state is perfectly normal.

Commands to the controller

Register 12 is split the same way. The high byte is a command for the lamp:

ValueCommand
0x01No command
0x02Turn the tag off
0x03Turn the gas sensors off
0x04Turn the tag on
0x05Sensor status request
0x06Free the bus
0x07Clear the network icon
0x08Show the network icon

The low byte says what kind of message follows in the text registers:

ValueMessage type
0x00None
0x01Alarm — shown as a banner
0x05Proximity notification
0x80Text message

The network icon commands are how the wearer knows the lamp still has a link: the module owns the WiFi connection, so only it can tell the lamp whether to show the icon.

Events from the controller

Written by the lamp with function 0x10:

CodeEvent
0x0001Text message acknowledged by the wearer
0x0002Alarm acknowledged by the wearer
0x0003Alarm raised
0x0004Alarm cancelled
0x0005RTLS confirmed
0x0006Proximity notification acknowledged
0x0007Switch WiFi to ECO mode
0x0008Turn WiFi off

The acknowledgement codes are what become AckSMS, AckReadSMS, AckALM and AckReadALM on MQTT. A wearer pressing a button on the lamp raises a Modbus write, which the module turns into a receipt on the uplink — the two protocols are ends of one path.

The power-management codes travel the same way. The lamp, not the module, decides when to move WiFi into ECO mode or shut it down, because the lamp is the part that knows about the battery and the shift.

Display messages

Message text occupies the registers from 13 upward, two characters per 16-bit register — first character in the high byte, second in the low. The text budget is 70 bytes.

A message arriving from the server on /InSms is decoded by the module, written into these registers with the appropriate type in the low byte of register 12, and read out by the lamp on its next poll. Proximity warnings are generated on the module itself and travel the same path.

Related

  • Smart Lamp Locator — the device this bus lives inside.
  • Gas Sensors — how these registers surface as readings and alarms.
  • MQTT — the uplink side of the same events.