Which protocol to implement on a home brewed diving computer ?

Linus Torvalds torvalds at linux-foundation.org
Mon Mar 16 10:15:09 PDT 2015


On Mon, Mar 16, 2015 at 6:29 AM, Thomas Schrein (mailinglists)
<tsx508 at schrein.de> wrote:
>
>        Because serial is running already we prefer to use a
> already available protocol like the "SeaBear", you've mentioned.

So while SeaBear is fairly simple (it's just a comma-separated file),
I don't think you really want to try to be compatible with it.  You
still need a command protocol etc, and you want something that is more
extensible than just plain csv.

I hope/assume that the STM32F4 could easily do something that is
fairly high-speed serial (ie something equivalent to 115kbps), and
then the trick to get good performance is *not* to try to minimize the
amount of data moved, but to minimize the ping-pong packets
back-and-forth.

A lot of dive computers not only do a fairly slow serial line, they
tend to be about some "smallish packet" formar, where "smallish" is
8-64 bytes. That almost inevitably makes anything really slow.

So I'd suggest trying to make as much of the protocol be "streaming",
with as little "packet back-and-forth" as humanly possible. Don't ask
for small things, as for a stream of data.

And I don't think it matters too much to be "compatible" with somebody
else, unless you actually aim for being a 100% clone. Which would be
very hard, honestly. So not being 100% compatible, I personally don't
think you should worry about compatibility at ALL, but instead make
sure that the protocol is really obvious and easy to understand.
That's often better than "documented".

So what I mean by that is that you could be 100% "documented", but if
you send binary structures with things like "the first word contains
the depth in bits 0-15 in cm", that may be perfectly well documented,
but it's the kind of thing that is really easy to screw up, and that
it hard to extend later when you notice that you did something wrong.

And if you don't really have any other divelog you can work with than
subsurface, don't worry too much about getting it perfectly rigth the
first time - both sides can change, and I suspect you learn more from
experimenting with a simple and easy-to-understand protocol than you
would with something clever.

Also, I think you need to think a lot about "bringup" and "testing",
and you'll want to do both of those *without* having to have
subsurface itself understand everything perfectly (or even
_anything_).

So here's what *I* would suggest. This is just a raw suggestion, but
it is fairly simple:

 - make everything ASCII-based, and make it about lines of text that
have a really simple format

 - make it so that you can literally do bringup testing from just a
terminal emulator, with *nothing* else. No fancy need for
test-programs, just a human typing into a terminal.

 - if you're familiar with the old "AT" modem command set, _that_ is
the kind of completely brainless and very simple command set you want.
Or if you are comfortable with DOS or Unix, make it literally look
like a command shell.

So I would suggest some really really simple model, where you type a
command like "LIST", and the dive computer responds with a simple list
of dives - one dive per line, just giving date (in some *sane* and
simple hard-coded format, but still as ascii, and due to debuggability
I would suggest still "fairly human-readable", so not the usual
"number of seconds since 1970". So something like

    > LIST

    461   2014-01-11-Sat-08:47:37   61:10 min
    462   2014-01-11-Sat-11:03:53   59:10 min
    463   2014-01-12-Sun-08:38:00   59:55 min
    464   2014-01-12-Sun-10:55:00   59:40 min
    465   2014-01-12-Sun-13:38:00   61:30 min
    466   2014-01-13-Mon-08:24:00   60:30 min
    467   2014-01-13-Mon-12:38:00   62:00 min
    468   2014-01-13-Mon-15:04:00   64:00 min
    469   2014-01-14-Tue-08:36:00   57:05 min
    470   2014-01-14-Tue-10:59:00   60:20 min
    471   2014-01-14-Tue-13:30:00   59:40 min
    472   2014-01-14-Tue-15:44:00   64:10 min
    473   2014-01-15-Wed-08:54:00   63:05 min
    474   2014-01-15-Wed-11:12:00   62:05 min
    END

    > GET 473

    model "Odico dive computer"
    serial "A-00016"
    firmware "v0.12-23"
    algorithm "Bühlmann-16 35/70"
    date "2014-01-15"
    time "08:54:00"
    duration "63:05 min"
    gps -10.447069 105.561344
    gas 34.0 0.0
    maxdepth 26.0m
    meandepth 13.355m
    watertemp 28.2°C
    surfacepressure 1.0bar
    sample   0:05 4.1m 28.2°C
    sample   0:10 4.4m
    sample   0:15 4.4m 28.3°C
    sample   0:20 4.3m 218.1bar
    sample   0:25 4.4m
    sample   0:30 4.4m 28.4°C
    sample   0:35 4.6m 28.5°C
    sample   0:40 4.6m 28.6°C 217.8bar
    sample   0:45 4.5m
    sample   0:50 4.4m 28.7°C
    sample   0:55 4.2m 28.8°C
    sample   1:00 4.2m 28.9°C 216.4bar
    ,,, 700+ sample lines ..
    END

    > ...

(the above format is completely made up, but it's somewhat real data
from my dives, so it's not *entirely* unrealistic as a format - it's
close to how subsurface saves things in the git save format).

Now, if this was a *real* serial line, you'd have to worry about data
corruption etc, which is one reason why a lot of traditional dive
computers do that whole packetized format (so that they can do
checksums and retry etc). But USB should be reliable, so I think
you're actually better off making it as streaming as possible (ie
don't ask for one sample at a time - just ask for the whole dive data,
and then stream the whole dive in one go), and making it something
that you can test and at least get some early version going with just
that terminal and typing. And make the output obvious enough that even
*without* documentation you can guess what it is.

Obviously, add documentation too, but seriously - add a HELP command
that just lists all the commands you support. Make it so obvious that
you feel that people could understand what to do even if they lost the
documentation.

Because even *with* documentation, you'll find that it's better if the
protocol is simple enough and obvious enough that you don't really
need the documentation.  And if it turns out that you messed up the
documentation, or people messed up implementing it, if the protocol is
simple and human-understandable, then hopefully it's also simple and
obvious when something was wrong.

I dunno. The above is just a suggestion. I think something like the
above would be fairly easy for us to download from, but I haven't
though a *lot* about it.

And yes, the above format is fairly verbose (despite not having
temperatures and cylinder pressures repeated if they don't change). A
single dive would easily be 16kB of data. So on a real serial line at
115kbps, that would be a second and a half at *best*, assuming your
CPU is even fast enough to generate it that quickly.  But that's ok
download speeds: if you can get it to be in the range of "one or two
seconds per dive", you're fine. Sure, faster would be better, and
maybe you'd go for a slightly more compressed format (sample data is
the only thing that is big enough to be worth compressing), but I
really do think that tryin gto be "streaming" is more important from a
performance angle than trying to be very dense.

There are lots of dive computers that are *much* slower than a second
or two per dive. And there's a orecious few that are faster. Aim for
"good enough", if it makes things simpler.

                             Linus


More information about the subsurface mailing list