Skip to content

These module docs are in beta and may be incomplete.

modm:communication:sab: Sensor Actuator Bus (SAB)

The SAB (**S**ensor **A**ctuator **B**us) is a simple master-slave bus system. It is primarily used to query simple sensors and control actuators inside our robots.

One master can communicate with up to 32 slaves. The slaves are only allowed to transmit after a direct request by the master. They may signal an event by an extra IO line, but this depends on the slave.


Features: - Baudrate is 115200 Baud. - Maximum payload length is 32 byte. - CRC8 (1-Wire)


  • SYNC - Synchronization byte (always 0x54)
  • LENGTH - Length of the payload (without header, command and CRC byte)
  • HEADER - Address of the slave and two flag bits
  • COMMAND - Command code
  • DATA - Up to 32 byte of payload
  • CRC - CRC-8 checksum (iButton)
  7   6   5   4   3   2   1   0
| Flags |      ADDRESS          |

  Flags | Meaning
  0   0 | request by the master
  0   1 | reserved
  1   0 | negative response from the slave (NACK)
  1   1 | positive response from the slave (ACK)

The second bit is always false when the master is transmitting. In the other direction, when the slaves are responding, the second bit has to following meaning:

  • true - Message is an positive response and may contain a payload
  • false - Message signals an error condition and carries only one byte of payload. This byte is an error code.

Electrical characteristics

Between different boards CAN transceivers are used. Compared to RS485 the CAN transceivers have the advantage to work without a separate direction input. You can just connected the transceiver directly to the UART of your microcontroller.

Within a single PCB, standard digital levels are used (either 0-3,3V or 0-5V) in a multi-drop configuration. Meaning it does not allow multiple drivers but multiple receivers. The idle state of a UART transmission line is high, so standard TTL-AND gates have to be used for bundling transmission lines from multiple slaves.

Both approaches can be combined to reduce the number of needed CAN transceivers on a single board. Between two boards you should always use transceivers and therefore differential signaling to improve noise immunity.

The signal lines to indicate events by the slave are strict optional, you may or may not use them (if the slave provides them).


// Class
class modm::sab2::Interface< typename Device , std::size_t N=maxPayloadLength >;
class modm::sab::Interface< typename Device  >;
class modm::sab::Master< typename Interface  >;
class modm::sab::Response;
class modm::sab::Slave< typename Interface  >;
class modm::sab::Transmitter;

// Struct
struct modm::sab::Action;
struct modm::sab::Callable;

// Function
uint16_t modm::sab2::crcUpdate(uint16_t crc, uint8_t data);
uint8_t modm::sab::crcUpdate(uint8_t crc, uint8_t data);

// Enum
enum Error;
enum Error;
enum Flags;

// Variable
const uint16_t modm::sab2::crcInitialValue = 0xffff;
const uint8_t modm::sab2::controlEscapeByte = 0x7d;
const uint8_t modm::sab2::frameBounderyByte = 0x7e;
const uint8_t modm::sab2::maxPayloadLength = 32;
const uint8_t modm::sab::crcInitialValue = 0x00;
const uint8_t modm::sab::maxPayloadLength = 32;
const uint8_t modm::sab::syncByte = 0x54;

// Define
#define SAB_ACTION(command, object, function, length)


modm:communication:sab modm_communication_sab modm: communication: sab modm_architecture_accessor modm: architecture: accessor modm_communication_sab->modm_architecture_accessor modm_communication modm: communication modm_communication_sab->modm_communication modm_debug modm: debug modm_communication_sab->modm_debug modm_processing_timer modm: processing: timer modm_communication_sab->modm_processing_timer modm_communication_sab2 modm: communication: sab2 modm_communication_sab2->modm_communication_sab