Ticket #1058 (closed: wontfix)

Opened 7 years ago

Last modified 6 years ago

Define and implement a simple modular router-MCU-sensor protocol

Reported by: Musti Owned by: Musti
Priority: normal Milestone: 3.0b
Component: telemetry Version:
Keywords: Cc:
Related nodes: Realization state:
Blocking: 1032, 1050, 1052 Effort: normal
Blocked by: 1067 Security sensitive: no


A simple and effective way of interfacing sensors on the software layer is required for the developed hardware. For the understanding of the system, it is important:

  • sensor is an i2c, spi, 1-wire ... device
  • telemetry and telecontrol platform is bridge from uart to sensor protocols(as specified above), with some on board peripherals. It connects to router via UART or USB(virtual com port).
  • router is running openwrt based firmware and has serial or/and USB

A simple effective modular and as independent as possible system for connecting sensors and controlling devices is required, completely abstracted from hardware layer. Thus I suggest we define a protocol that allows for all above.

Telemetry&Telecontrol for nodewatcher protocol:

  • Modules

modules are processing blocks

  • router Daemon

communicates with the Platform as specified in the config files

  • Platform

supports predefined commands, interfaces on board peripherals and is a communication bridge. Can have standalone functions, such as watchdog.

  • Config files

are used by the Daemon

  • Platform config

defines all supported commands and procedures supported by the Platform, specific to each platform type/version

  • Sensor config

defined the communication procedures for each sensor, for example initialization, reading and setting registers, includes information how often each sensor is read and so on.

Two example procedures are here just for clarification.

  • Initialization
    • Daemon checks which sensor configs are present
    • initializes all sensors with procedures defined
      • sends sequential commands to the sensor
  • Sensor reading
    • Deamon takes the read sensor procedure for all sensors, runs it at predetermined time intervals
    • Measurements are compiled into nodewatcher compatible file

The main question now is how to define the protocol, I havent done that before. Please advise.

Change History

comment:1 Changed 7 years ago by Musti

  • Blocking set to 1032, 1050, 1052

comment:2 Changed 7 years ago by kostko

The sensor config would be probably best described as a script that defines how some common operations (reading data or sending commands) can be performed for a sensor.

I see two things that it would need to describe:

  • Operations that are possible to perform on a sensor. For reading data this should not be a problem, as it should just be a list of keys (types of information) that can be retrieved from a sensor. For sensors/devices that can be written into (telecontrol), this should define a list of commands that can be performed together with a description of parameters for those commands. Both of these should probably be standardized somehow, because they will probably be shared among different classes of sensors (for example, different temperature sensors will all report "temperature").
  • How to perform the operations. This is a sensor-specific script (for example written in Lua) that uses the above mentioned "low-level platform commands" to obtain the wanted data for each of the defined operations. In addition, it would also describe how to perform common maintenance tasks on the device (like initialization).

So consider these "configuration scripts" as some kind of drivers written for a common platform.

Last edited 7 years ago by kostko (previous) (diff)

comment:3 Changed 7 years ago by kostko

As far as the protocol is concerned I suggest the following:

  • Protocol is a simple RPC interface, where the client sends commands to the platform module via the serial port and the platform module returns responses. Commands and responses are represented as messages and we must decide on a wire format for serializing these messages. It can be anything from a simple ASCII serialization to some binary format. In case a binary protocol is chosen, fields should all be big-endian.
  • Whatever we decide, the protocol must be designed with evolution in mind. This means that when a time comes that we need to change something in the protocol (this will happen), that we can modify the message structure in this protocol in a backward-compatible way. This could simply be a version number field before anything else is parsed.
  • An important consideration is whether the serial interface is reliable or not. In case it is not, we need to also consider checksums in the protocol and perform retransmisions on both ends.

A simple protocol message would contain the following fields:

  • Protocol version. A single byte representing the protocol version starting at 0x01.
  • Message type. Currently command or response, a byte should probably suffice.
  • Payload. Contents of the message, depending on message type. This could also be size-prefixed in case payloads are variable in length.

Each command will probably be composed of two main things:

  • A command identifier. There are again multiple options on how we identify commands:
    • The most extensible one is if we make the identifier of string type. In this case it should have some kind of structure (for example some commands could be grouped under sys for example like sys.reboot, those that implement specific bus functionality under the respective name like i2c.read and i2c.write etc.).
    • Another approach is to use a numeric identifier for the individual commands and perform a mapping in the platform driver.
  • Command arguments. This is of a command-specific type so the wire protocol must support serialization of common types (NULL-terminated strings, integers of different widths and signs, floating point numbers).

Similarly each response will contain a command-specific structure for its payload. The same serialization requirements apply.

If there are always only command-response interactions and there is no way for the platform module to initiate communications first, this will suffice. Otherwise, we would need to add other message types in addition to commands and responses.

comment:4 Changed 7 years ago by Musti

A kind of a similar thing, at least from hardware point of view: http://www.robot-electronics.co.uk/htm/usb_i2c_tech.htm

comment:5 Changed 7 years ago by domen

For current MCU->router communications see telemetry/blob/master/msp430-telemetry/main.c#L55.

Yes, MCU can just send a message, which isn't a reply (INTERRUPT is an example).

As for router software, yes, some scripting language would be suitable for fastest development (I can't imagine config files covering all possible i2c devices, and it really is development not configuration). Current proof of concept C-only daemon is telemetry/blob/master/daemon/telemetryd.c.

Last edited 7 years ago by mitar (previous) (diff)

comment:6 Changed 7 years ago by mitar

Is there any existing standard protocol for this?

comment:7 Changed 7 years ago by Musti

Not that I am aware of, but this should be looked at. If not existing, this is the time to implement it.

comment:8 Changed 7 years ago by mitar

Yes. So we could use any general serial RPC protocol with low codebase requirements.

comment:9 Changed 7 years ago by domen


Any experience with something similar?

comment:10 Changed 7 years ago by mitar

No idea. Just writing in general. This is not really my field. We might want to ask around.

comment:11 Changed 6 years ago by Musti

  • Blocked by set to 1067

comment:12 Changed 6 years ago by Musti

  • Status changed from new to closed
  • Resolution set to wontfix

Ticket #1067 implements all these functions.

Note: See TracTickets for help on using tickets.