Computing stuff tied to the physical world

JeeMon device discovery

In Software on Oct 12, 2010 at 00:01

Ok, I must admit that JeeMon has been a bit too ambitious in its original inception. It works quite nicely here at Jee Labs, but there are just too many hoops you have to jump through to make it happen on your own.

I’ll first explain why things are the way they are, and how that is supposed to work, and then I’ll present a different setup for the OOK Scope which jettisons all that machinery and lets you use the OOK Scope with nothing but a single source file and JeeMon.

The idea behind the “Serial” and “JeeSketch” rigs (code modules) in JeeMon, is that it should be possible to respond to changes in interfaces dynamically. So there’s a way to scan for USB interfaces periodically:

Serial periodicScan <cmd>

This will compare the list of USB devices it sees with the list it saw last time (once every 5 seconds by default). And then call the specified <cmd> whenever an interface is added or has gone away. Only FTDI interfaces are detected, by the way.

The next step is to decide what to do when a new USB device is attached. I’ve been using a convention for some time now, whereby every sketch starts by sending out its own name, with optional version and configuration details. For example, RF12demo will send out a string like this to the USB connection when it starts up:

[RF12demo.6] A i1 g5 @ 868 MHz

The trick is to wait for such a string when JeeMon detects the device and opens it. This is handled by the “JeeSketch” rig. Once the sketch type is known, JeeMon then tries to locate a “host.tcl” driver for it. It does this by looking in a directory, as configured at start up. I’ve been placing all my drivers in a directory called “sketches”, so my startup includes the following line:

JeeSketch register ./sketches

When RF12demo connects, JeeMon checks whether “./sketches/RF12demo/host.tcl” exists, and runs it.

Similarly, when plugging in a JeeNode running the OOK Scope sketch, it announces itself as:

[ookScope]

The script “./sketches/ookScope/host.tcl” then gets started, it creates a GUI window, takes over the communication link to process all incoming (binary) data bytes, and does its pulse histogram thing.

So far so good. It’s a nicely modular mechanism. I can add a new sketch, i.e. a “blah.pde” file for use in a JeeNode, and add a matching “host.tcl” script alongside to deal with the communication in any way it likes. Then, all I need to do is plug the device in and everything starts up. With a bit of care, everything is also shut down and cleaned up again when the device is removed.

Unfortunately, that’s not the end of the story. One of the important devices I want to support is a JeeNode or JeeLink running RF12demo. But how can JeeMon deal with remote nodes? After all, all they do is send packets to the central device. Each of these nodes will be running a sketch, and not all of them are necessarily the same. So we either need some sort of auto-discovery or some central configuration file. For a first implementation, I decided to use a configuration file to try and keep things, eh, simple. Which is why my startup code also contains these two commands:

set appDir [file dir [dict get [info frame 0] file]]
Config setup $appDir/config.txt

That’s a tricky way of making sure that the “config.txt” file will be picked up from the same directory as the source code, i.e. the “application.tcl” file.

I’ll refrain from describing the config.txt file in full detail. Let me just include an example which I’ve been using around here:


Screen Shot 2010 10 11 at 22.52.15


As with any such type of “registry”, you can see lots of little config details, for use in different modules and parts of the code. Even some obsolete stuff, in fact.

Does it work? Oh, sure, it works great and it’s very easy to extend for new modules and usage scenarios. Even node discovery works nicely, both coming on-line and dropping off-line, as seen in the voltmeter demo.

But there’s a problem with what I’ve described so far…

… there’s too much rope – to hang yourself. It’s brittle, it needs lots of documentation to use this stuff (unless you’re willing to dive into the JeeMon Tcl code), and it’s just too much trouble if you want to do something simple with JeeMon, like run the OOK Scope and nothing else. The entry curve is way too steep.

I can’t say I’ve figured out an alternative. There is a lot of ground to cover, and it is fairly hard to implement a system which dynamically adapts to interfaces getting plugged in and nodes coming (wirelessly) online.

But at the end of the day, all that extra bagage is unnecessary for simple cases.

Fortunately, JeeMon is flexible enough to adapt in any way I want. I don’t have to use any of the above machinery. So here’s the OOK Scope logic as a single “application.tcl” file. No scanning, no config, nothing:

Screen Shot 2010 10 11 at 23.05.06

The full code is available here. To run this version of the OOK Scope, download that file, make sure it is called “application.tcl”, and place it next to your JeeMon executable. Then launch JeeMon. Just make sure to have the JeeNode running ookScope.pde plugged in.

If more than one FTDI interface is found, you will be asked to pick one:

Screen Shot 2010 10 11 at 23.22.45

That’s it: ookScope.pde, application.tcl, plus JeeMon – should work on Windows, Mac OS X, and Linux.

  1. Configuration is always a problem with powerful and flexible software.

    I must admit I haven’t used JeeMon, but would it be possible to write a “wizard” which could ask a few questions and create the config file for you?

    I would offer to write one for you, but as I said, I don’t have any experience with JeeMon, plus I’d end up using some weird and wonderful language to make it cross-platform, probably FPC+Lazarus aka, open Delphi :)

  2. I must also admit not being a user — it says something about your site that you have followers that are just curious :) — but would you consider the “Tcl way” to handle the diversity? I mean every received packet would be, in fact, a procedure call to a secure interpreter run by the Jeemon.

    • That is already the case… on a USB serial links, sketches send “ROOM …”, “BARO …”, etc.

      The challenge is to create a simple plugin mechanism which allows me to keep JeeMon running at all times, while adapting to interfaces being plugged in and removed, and driver logic being updated with new versions. Not there yet, but a scripted language such as Tcl should definitely be up to such a task. I’m not too worried by the fact that the first attempt got stuck a bit – it’s simply a way to learn from experience ;)

  3. Would you consider a switch to Python? Speaking for myself, I resisted learning Python for years, and finally gave it a try about a year ago- wonderful stuff. I don’t want to go back to Tcl. In 30+ years of programming, I’ve encountered a lot of programming languages and development environments. Python is truly worth a look-see. If you do, I recommend Beazley’s Python 4th Ed, and Summerfield’s Rapid GUI programming – python interface to QT.

    • I’ve worked with Python for a few years – not intensely, but enough to get a good look at the landscape, I think. I’ve also worked with Ruby, Lua, Perl, Icon, Lisp, to name a few other dynamic languages (all of them at least several months).

      It’s not the surface of these languages that keeps me from adopting one (many of them have gone way beyond what Tcl offers in all sorts of ways), it’s the core decisions. Tcl fits my needs (a lot) better. The trouble is that the generality I’m after needs to be built up – and that’s a lot of error-prone work…

  4. Hmm, seems like a trade-off to me — something like Python or even Processing(.org) would seem to match the ‘needs’ of typical Jeenode developers much better than Tcl. I used Tcl for a year or so, but I’d never do it again unless it was mandatory.

    • You might also want to check out http://processingjs.org/ – it’s pretty impressive stuff.

      To paraphrase Andrew Tanenbaum: the beauty of standards is that there are so many to choose from. And IMO, the beauty of open source is that implementation choices no longer prevent anyone from going off in a different direction. Just re-use and re-purpose the parts you like, and replace the rest. This used to be totally out of the question with software.

      Your choice seems to be Python. Others want Ruby, or Lua, or PHP, or Java, or C#, or Delphi, or Basic. But I’m not designing an application, I’m designing an infra-structure. The trade-offs are considerably more involved than notation, libraries, or language semantics.

      Given that where I’m going is heavily geared towards web apps, what I do will be based on the combination of C++ (embedded), Tcl (server), and JavaScript (browser). There are 7 ways to disagree with these choices. And there would be even more if had limited myself to a specific platform or OS.

      What can I say? I didn’t create the language mess we’re in, I just want to find a way forward.

Comments are closed.