MRBus Specification Section 4 - Component-Level Integration

MRBus Specification Section 4 - Component-Level Integration
MRBus Spec Table of Contents
  1. Section 1 - Introduction
  2. Section 2 - Hardware Implementation
  3. Section 3 - Software and Logical Implementation
  4. Section 4 - Component-Level Integration
Section 4 - Component-Level Integration

As would be expected, individual components spewing data are not, by themselves, very useful. Since MRBus is initially designed to replace signal systems with literally dozens of individual logic lines connecting nodes, a sensible starting point is the ability to build "virtual logic connections" between nodes.

For example, take the following ABS signaling setup: (insert picture here)

Nodes 0x71-0x73 clearly need logical inputs from block detectors 0x11 and 0x12 in order to determine the correct aspects on the signals. For simple R-Y-G signaling, at least two inputs are needed for each signal – immediate block occupancy (the block the signal is guarding), and adjacent block occupancy (the block beyond the immediate block). We'll call these inputs IMD and ADJ for brevity. So, for the westbound signal (right-facing) on 0x73, it needs the occupancy of Block N for its IMD input, and Block O for its ADJ input.

Block detector 0x11 is transmitting Data ('D') packets that are as follows: [0x11][0xFF][CRC (16b)][0x07][0x44][b0000(-)(-)(P)(O)] Block detector 0x12 is transmitting Data ('D') packets that are as follows: [0x12][0xFF][CRC (16b)][0x07][0x44][b0000(-)(M)(N)(-)]

In both cases, the last byte is a bitmap of occupancy statuses, where (*) represents the occupancy of block *, or (-) means unknown or not relevant.

A fundamental recommended practice with MRBus is to make all possibly needed outputs a bit. That way virtual logic connections are possible by just selecting bits out of incoming packets. This input selection process, known as "building virtual logic connections", should allow the user to specify by source address, packet type, and bit/byte position the desired input. For complex logic, a combination of inputs may be used, but as in most cases simplicity is to be valued.

Source and packet type are fairly straightforward – if you want the input from a 'D' packet sent by a detector at 0x12, your source is 0x12 and your type is 0x44 ('D' in ASCII). Bit/byte are more complex, as they can be bitpacked into a single byte to save configuration memory space.

It's recommended they be assembled as follows: @@Bit/byte = XXXYYYYY XXX = Bit number, 0-7 YYYYY = Byte number, from start of packet. Source address is byte 0@@

So, signal node 0x73 has, in its configuration values (CV), positions for source address, packet type, and byte/bit to use as the IMD and ADJ virtual logic connections. Let's say these are CV10, CV20, and CV30 for IMD and CV11, CV21, and CV31 for ADJ.

So, to configure the Westbound IMD input to read block N: @@CV10 (IMD Source Addr)= 0x12 (Block N's detector address) CV20 (IMD Packet Type)= 0x44 ('D') CV30 (IMD Byte/Bit) = 0x26 (Bit 1 (XXX=b001) and byte 6 (YYYYY=b00110)@@

Likewise, the Westbound ADJ input for Block O would be configured as: @@CV11 (ADJ Source Addr)= 0x11 (Block O's detector address) CV21 (ADJ Packet Type)= 0x44 ('D') CV31 (ADJ Byte/Bit) = 0x06 (Bit 0 (XXX=b000) and byte 6 (YYYYY=b00110)@@

The virtual logic connections for the eastbound signal would have similar configurations, except being set up to read Block M and the unnamed (and not shown) block to the right of that.

So, the example conversation on the bus would look like: @@[0x11][0xFF][CRC16][0x07][0x44][b00000000] -- 00:00:00 Regular update on 0x11 [0x12][0xFF][CRC16][0x07][0x44][b00000000] -- 00:00:00 Regular update on 0x12 [0x72][0xFF][CRC16][0x07][0x53][0x11] -- 00:00:00 Two greens on 0x72 [0x71][0xFF][CRC16][0x07][0x53][0x11] -- 00:00:00 Two greens on 0x71 [0x73][0xFF][CRC16][0x07][0x53][0x11] -- 00:00:00 Two greens on 0x73


Next Second ----

[0x12][0xFF][CRC16][0x07][0x44][b00000000] -- 00:00:01 Regular update on 0x12 [0x11][0xFF][CRC16][0x07][0x44][b00000000] -- 00:00:01 Regular update on 0x11 [0x12][0xFF][CRC16][0x07][0x44][b00000100] -- 00:00:01 Train enters Block M [0x73][0xFF][CRC16][0x07][0x53][0x41] -- 00:00:01 Eastbound drops to red [0x72][0xFF][CRC16][0x07][0x53][0x21] -- 00:00:01 Eastbound drops to yellow


Next Second ----

[0x12][0xFF][CRC16][0x07][0x44][b00000100] -- 00:00:02 Regular update on 0x12 [0x11][0xFF][CRC16][0x07][0x44][b00000000] -- 00:00:02 Regular update on 0x11 [0x71][0xFF][CRC16][0x07][0x53][0x11] -- 00:00:02 Two greens on 0x71 [0x73][0xFF][CRC16][0x07][0x53][0x41] -- 00:00:02 E=Red, W=Grn on 0x73 [0x72][0xFF][CRC16][0x07][0x53][0x21] -- 00:00:02 E=Ylw, W=Grn on 0x72 ... Time elapses ... [0x12][0xFF][CRC16][0x07][0x44][b00000110] -- 00:00:33 Train enters Block N [0x71][0xFF][CRC16][0x07][0x53][0x21] -- 00:00:33 E=Ylw, W=Grn on 0x71 [0x72][0xFF][CRC16][0x07][0x53][0x41] -- 00:00:33 E=Red, W=Grn on 0x72 [0x73][0xFF][CRC16][0x07][0x53][0x41] -- 00:00:33 E=Red, W=Grn on 0x73 [0x12][0xFF][CRC16][0x07][0x44][b00000100] -- 00:00:33 Regular update on 0x12 [0x11][0xFF][CRC16][0x07][0x44][b00000000] -- 00:00:33 Regular update on 0x11


Next Second ----

[0x12][0xFF][CRC16][0x07][0x44][b00000110] -- 00:00:34 Regular update on 0x12 [0x11][0xFF][CRC16][0x07][0x44][b00000000] -- 00:00:34 Regular update on 0x11


Next Second ----

[0x11][0xFF][CRC16][0x07][0x44][b00000000] -- 00:00:35 Regular update on 0x11 [0x12][0xFF][CRC16][0x07][0x44][b00000010] -- 00:00:35 Block M clears [0x71][0xFF][CRC16][0x07][0x53][0x21] -- 00:00:35 E=Ylw, W=Grn on 0x71 [0x73][0xFF][CRC16][0x07][0x53][0x11] -- 00:00:35 E=Grn, W=Grn on 0x73 [0x72][0xFF][CRC16][0x07][0x53][0x41] -- 00:00:35 E=Red, W=Grn on 0x72@@

...and so it goes. This bus example should give you some idea of how devices communicate on a simple, basic level using the example ABS system pictured above. In addition, it should be noted that CV0-9 are reserved for standardized uses. At the moment, only CV1 is used, however.

@@CV0 = Undefined CV1 = Device Address (should initialize to 0x00) CV2 = Undefined CV3 = Undefined CV4 = Undefined CV5 = Undefined CV6 = Undefined CV7 = Undefined CV8 = Undefined CV9 = Undefined@@

A special set of commands, packet types 'R' and 'W', have been reserved to read and write the CV registers. The format of these packets should be as follows, and universal across devices: @@[SRC][DEST][0x07][CRC16]['R'][CV_ADDR] [SRC][DEST][0x08][CRC16]['W'][CV_ADDR][VAL]@@

SRC = Source of packet – device doing the programming, usually a computer interface DEST = Device being programmed, 0x00 if the device has not been set to its own address yet, since all programmed devices will ignore a destination of 0x00 (*nobody*). LEN = Length of packet – 7 for 'R' commands, 8 for 'W' commands CRC16 = Packet checksum, computed when sent CV_ADDR = Address of the configuration value to be manipulated (0 -???) VAL = For writing CVs, the value to be written.

  Questions? Email Nathan Holmes
© NDHolmes, but freely usable under a Creative Commons Attribution-NonCommercial-ShareAlike 2.5 License.
Last modified on January 12, 2006, at 05:56 PM
Edit Page | Page History