Xideco Is Moving Forward

What I Am Working On Now

I am currently working on two Xideco features, one to improve xirt, the Xideco router, and the other is to provide i2c support in a universal and unconstrained manner.

Xideco Router Improvements

The current router implementation is somewhat "brittle". Each time a new message topic is introduced into the network, the router needs to modified to accommodate the new message.

I am looking to change the current implementation so that the router becomes a totally stable component that will need no modification as new components and message topics are added or removed. It will transparently forward all published messages without regard to message topic. The ZeroMQ Forwarder Device provides that functionality. A Forwarder is a ZeroMQ networking pattern that subscribes to all messages, and transparently publishes them with original topics intact.

The new Xideco Router will consist of 2 Forwarders so that messages can flow and be routed in 2 independent directions, one in the upstream direction towards a user application from the hardware devices, and the other in the downstream direction, towards the hardware actuators.

Universal i2c Support

At the board level, Xideco takes advantage of existing GPIO APIs. For Arduino, pymata-aio is being used, for Raspberry Pi, pigpio is being used and for the BeagleBone Black the adafruit bbio library is being used. If you look at the  three i2c library APIs, each is markedly different, but in essence results in the same low level i2c functionality.

The goal of Universal i2c Support is to have the control and operation of an i2c device described in a single universal file.  What this results in, is having one set of commands describing the device operation across all of the boards in a consistent manner, and when any changes or additions to functionality occur,  all modifications are limited to that one file. When a control message is received by a board translator it simply executes the i2c request by translating the message into board level i2c API calls, without having to have knowledge of the logic behind the request. All "intelligence" remains as close to the application as possible, and execution of that intelligence occurs as close to the target board as possible.

To understand what I am striving for,  let's look at a proposed implementation supporting the ADXL345 accelerometer.

Xideco will be using a JSON formatted file to describe the control and maintenance of i2c devices. The reason for JSON is that Xideco uses MessagePack to serialize its messages and MessagePack formatting is very JSON-like.

The JSON descriptions reside in the Xideco i2c Library, and TinyDB will be used to build the library file. In the future, a Tkinter GUI will be provided so that adding new i2c devices will be simplified.

Let's look at a sample JSON descriptor file supporting two i2c devices, the ADXL345 and the TMP102 temperature device. We will be concentrating on the ADXL345 for the sake of this discussion.

   "adxl345": {
      "device_address": 83,
      "commands": {
         "init": [{
            "cmd": "write_byte",
            "register": 45,
            "value": 0         }, {
            "cmd": "write_byte",
            "register": 45,
            "value": 8         }, {
            "cmd": "write_byte",
            "register": 49,
            "value": 0         }, {
            "cmd": "write_byte",
            "register": 49,
            "value": 3         }],
         "read": [{
            "cmd": "read_block",
            "register": 50,
            "num_bytes": 6         }]
   "tmp102": {
      "device_address": 72,
      "commands": {
         "read": [{
            "cmd": "read_block",
            "register": 50,
            "num_bytes": 2         }]

The full operational description for a given device begins with its name.

Below that is the default i2c address of the device. The user will be able to modify that address value if necessary as part of an API call and will not have to modify the library to change the address.

Next comes the commands that are supported for the device. In the case of the ADXL345, there are 2 commands, "init" and "read".

Below the command is a list of Xideco primitives that describe the i2c instructions used to accomplish the command. A command could be as simple as writing a single byte to a device register, or a list of primitives that must be performed in sequence to accomplish the command.

So for example, to "init" the ADLX345, a sequence of 4 primitives are necessary to be executed in order to initialize the device for operation:
  • Writing a value of 0 to  register 45.
  • Writing a value of 8 to register 45
  • Writing a value of 0 to register 49
  • Writing a value of 3 to register 49
Dereferencing the JSON description will result in the following Python dictionaries:
{'value': 0, 'cmd': 'write_byte', 'register': 45}
{'value': 8, 'cmd': 'write_byte', 'register': 45}
{'value': 0, 'cmd': 'write_byte', 'register': 49}
{'value': 3, 'cmd': 'write_byte', 'register': 49}
The device address will also be dereferenced separately  and added to the MessagePack message published messages.

The i2c translators will translate these Xideco primitive message into  specific native board i2c API calls. When data is returned from an i2c device, the translator will translate the data into a Xideco primitive i2c reply message.

Here are the board specific translations for the Xideco primitive "write_byte":

  • pymata-aio
    • i2c_write_request
  • pigpio
    • i2c_write_byte_data
  • bbio
    • write8

i2c For BeagleBone Black

The BBB has posed some unforeseen challenges. The adafuuit BBIO library does not support Python 3 for i2c (it does support Python 3 for GPIO).  As a result, the i2c Translator for the BBB must run in its own process to support Python 2. This is not a problem for Xideco, and will demonstrate that applications of differing languages (in this case Python 2 and Python 3) can and will interact seamlessly. I considered using other languages to support BBB i2c, but i could not find one that actually worked "out of the box", so I decided to stay with the adafruit library.

Want to Keep Up With The Progress?

If you want to keep with the changes, I have created a new Github branch for the i2c and Forwarder changes. Currently there are is not much to see, but you can follow any progress by visiting the branch from time to time. Whenever there is a significant milestone met, I will announce it on this blog.

As always, any comments, questions, or suggestions are always welcome.