The Wanderer

TL;DR Found a 30 years old sensor device, figured out how it works, and wrote some fresh code to use it.

Introduction

The Wanderer is a battery-operated portable device, which can record ambient temperature and one-dimensional acceleration as a function of time. It was manufactured around 1990-1992 somewhere in Finland by a company called Extrabit1.

I managed to get my hands on one of these, so I had to investigate if it works and how it works. My goal was to be able to control the Wanderer without the original software. I reverse-engineered the important parts of the serial protocol and implemented a few small Python programs to initiate measurements, read their results, and plot them.

Below I have tried documenting the notable parts of this exploration. As far as I know, this specific unit has been sitting unused for the past 30 years. My main interest in this was historical curiosity: I wasn’t able to find any information about the Wanderer on the Internet.

The original box. “Kulkuri” is Finnish for wanderer.

What was in the box?

The device itself came in a box along with a manual in Finnish, a serial cable, a 3.5 inch floppy disk, and warranty information.

The crucial parts for this effort. Yes, I did have to buy an USB floppy disk drive just for this purpose.

It looks and feels like a solid piece of work. The only thing it really reminds me of is another technology from the 90s, the pager, but a bit larger and heavier. It’s some kind of plastic and feels almost completely solid as there is really no noticeable flex. Probably the whole thing inside is full of epoxy or something similar. It weighs around 180 grams without the 9 V battery.

The Wanderer with its top piece off. Visible: the battery connector, the white string for pulling the battery out, and the DE-9 serial port.

The serial cable is straight through but only pins 1-5 and 7 are connected. Luckily no battery was left inside by whoever owned this before!

The floppy disk contained four files but only one I was really interested in: WANDERER.EXE.

Specifications

Here I’m just listing what the manual says. As also shown in the pictures, the unit I have is type WST-10/3.

Measuring acceleration

model ~sensitivity [mG] ~max acceleration [G]
WST-10/1 4.5 0.8
WST-10/2 9.0 1.6
WST-10/3 55 10
WST-10/4 450 80
WT-10/3

Measuring temperature

Other parameters

What components is it using?

It seems hard to open the device without breaking it so I didn’t try. I have no clue what components it contains.

Browsing the manual

Naturally I played around with my Wanderer for a while before really opening the manual. It is mostly intended as a guide for the Windows experience. Along with the device’s specifications, the 17 pages do contain some very useful nuggets of information. Some of this would be pretty hard to learn just by clicking around the software.

How about the original software?

I don’t remember ever trying to run device control software this old on a modern computer. I was really hopeful that I wouldn’t have to do a bare metal installation of Windows 3.1 to get the software up and running, and I assumed I may have to virtualize something, somehow. I struggled quite a bit initially with a few different USB-RS-232 dongles under Linux and DOSBox, and I wasn’t able to get the software to communicate with the device. Eventually I tried DOSBox under Windows 10 running on a computer old enough to have an actual RS-232 serial port on its motherboard. This was a working combination although the reason is not clear3.

The program’s main view looks like this:

This is the main view of the original Windows software. It’s displaying data from a run where I left the Wanderer in my fridge for some hours and then let it warm up before reading the results. You can see the acceleration peaks around the times I moved the device. Note the Y2K timestamps!

The program has plenty of features in a small package: checking battery status, loading or saving measurement data, initiating a new measurement, reading samples recorded by the device, checking out sample metadata, and changing the plot settings. This was clearly meant to be a self-contained lightweight solution for also the data-handling part, in addition to taking care of device control. Back in those days, free and powerful visualization tools weren’t as good and commonplace as they are nowadays, so this was a decision for a different era and possibly specific customer demands.

Displaying metadata for the currently shown measurement. Again, some amount of Y2K confusion may be seen.

Reversing the protocol

Initially I toyed with the idea of actually trying to statically reverse-engineer WANDERER.EXE. After a few frustrating attempts I decided I don’t know enough about handling old 16-bit Windows binaries and I’m also not gonna learn it at this point. I decided to pursue a hopefully easier route: I could just record the serial protocol when the software is actually reading the device’s battery status, programming a new measurement, and reading the results.

I installed trial versions of a few different software that seemed to make sniffing serial traffic possible under Windows. They seemed to work fairly nicely straight away and I started recording the dialogue. Before this, I already did a simple strings check for the binary, so I was expecting to see simple text-based protocol based on these obvious format strings:

BA %02X
PM %04d
PS %04d
RE %02X%02X
SN %04d
SW %04d
TC %.12s
TC %12s
TL %04d
TS %.12s
TS %12s
VS %02d

The serial port sniffers luckily also recorded the changes in individual pin states, so I was able to see that RTS was actually being asserted throughout the device communications. Perhaps this line is used for drawing additional power? The cable indeed had the RTS wire (7th) connected.

After dumping the serial dialogue, it was time to start making sense of the commands. As most of the commands were just printable characters with some Carriage Returns, just reading the dumps already gave a good clue.

Can we get the device to give us an answer?

Based on serial communication I captured, requesting the current battery level from the Wanderer should be easy:

-> BA
<- BA HH

where H is one uppercase hexadecimal character. There’s a request followed by a response from the device. Based on a few readings reported by the program, it seems clear that level = raw - 100 which is convenient for communication & parsing because the result is always two hexadecimal characters even without zero-prefixing.

At this point, I began trials with pySerial and got stuck for a while: I was unable to get the device to respond to any of my BA requests even though I was sure the connection parameters were exactly as they were supposed to. After exhausting other options, I decided to try writing my commands one character at a time and start inserting some sleeps if it’s necessary – this made an immediate difference and I started getting battery status replies. I guess I was just trying to be too fast with the poor old thing!

Programming a new measurement

After I managed to make the battery level readout work, I was confident that programming new measurements wouldn’t be much harder.

Programming a new measurement with the Wanderer software.

You can notice the parameter values 1, 2, 3, 4, and 5 in the dump. These are intentionally just something unique that should be easy to identify in the serial dialogue. Similarly I set the Start Time one second after the Current Time to separate the two. With these settings, the captured dialogue looks like this:

-> LN
<- LN
-> EQ
<- EQ
-> AP
-> SW 0001
-> TC 221021220840
<- TC
-> TS 221021220841
<- TS
-> TL 0001
<- TL
-> PS 0002
<- PS
-> PM 0003
<- PM
-> RE 0504
<- RE

After RE, the programming exchange is done and the Wanderer will start measuring when it’s time. We used unique values for the parameters, so it’s now trivial to identify the abbreviations:

I don’t know what LN, EQ, and SW mean, but I assumed they just have to be there.

Reading measured data from the device

The following is the exchange between the original software and the device when data is being read out:

-> EQ
<- EQ
-> AP
<- SW 0001
<- TC YYMMDDHHMMSS
<- TS YYMMDDHHMMSS
<- TL NNNN
<- PS NNNN
<- PM NNNN
<- RE NNNN
<- VS 03
<- SN NNNN
<- [a blob of mostly non-printable bytes]

where N is a numeric character.

We can identify most of them on the basis of understanding how the programming went, however I have no idea what EQ and AP stand for – AP seems to trigger the data readout. VS seemed to always be 03. SN stood for the amount of samples stored in the device’s memory.

Again, after some experimenting4, I noticed that the data blob’s length in bytes is five times the amount of samples given by SN. When unpacked as individual bytes, the samples looked like this:

#1  000 000 001 113 000
#2  000 000 002 113 000
#3  000 000 011 112 014
#4  000 000 020 112 000

So what does this mean?

Also, as sort of hinted by the resolution parameters we figured out earlier, the device was indeed recording sensor values only if they had changed as specified thus sparing memory instead of pointlessly recording near-identical samples.

From raw data into friendlier units

The values I read from the device were clearly not in units of °C and G. I took the fridge measurement and looked at the original software’s interpretation of it: minimum temperature is 5.0 °C and maximum is 25.5 °C. Let’s define such that the minimum and maximum temperatures were observed at t0 and t1. I then assumed there exists a linear function such that

T(t)=aTraw(t)+b

where t is the current time. For these two known minimum and maximum temperatures in °C we also have the respective raw values which can be found found from the data by just finding the smallest and greatest raw values Traw(t0) and Traw(t1)6:

T(t=t0)=aTraw(t=t0)+b

T(t=t1)=aTraw(t=t1)+b

We have two equations and two unknowns left: the constants. Now we can solve for a and b. This gives us the temperature function

T(t)=0.5Traw(t)30

As you can see by inserting Traw=0, -30 °C is the lowest temperature the Wanderer was expected to handle. We can see from the specifications that the developers added a small margin just in case.

With the acceleration I was a bit lazier and basically eyeballed from the original software that we’re close enough when

a(t)=araw(t)14.5

What about the timestamps then? You may remember from above that when we program a new measurement, we actually have to set the period for storing new samples. After staring at the values for a while and trying a few different kinds of parameters, I noticed that the raw timestamp value is stored in units of PM which was the Store Period we figured out earlier:

t=t0+tstoretraw

where t is the actual time of sampling, t0 is TS, tstore is PM, and traw is the raw integer from the current sample.

At this stage, we understand enough of the data that we can store it and plot it. I decided to just give my program the option to store the data as CSV, because then I can use whatever to do a scatter plot with some lines. And behold:

Same fridge data as shown in an earlier screenshot except read and plotted using the Python code developed here.

As you can see by comparing the screenshot above with the earlier capture from the original software, it’s a pretty good match, and the only major difference is that the original software in fact wasn’t Y2K ready – I had forgotten these issues even existed!

At this point, we understand enough to operate the device.

What about data stored with the original software?

The format seemed fairly simple but I had no use for it, so I didn’t bother figuring it out. It very much looked like the format was essentially some header, measurement metadata, and actual samples.

Closing words

I didn’t really know what to expect when I started looking into the Wanderer, but I’m pleasantly surprised that the device is still in a working condition after several decades of sitting in a box.

After I got the original software working, the protocol was logical enough that it could be reversed with a fairly small effort. Potential hard blockers were the RS-232 issues related to OS and USB dongles. If I wouldn’t have any hardware with actual RS-232 ports, I might’ve given up before I managed to get any signs of life from the device. It was also nice to see how gracefully DOSBox handled the original software!

Is there use for something like the Wanderer today? Nowadays portable and remote-readable sensors are becoming cheap and commonplace, and we have extremely powerful SoCs in almost every thing imaginable. In contrast, the Wanderer probably contains a very low-power and low-performance microprocessor with 8 or 16 bits of word size, and a meager amount of data storage which is cleared if the battery runs out. The only way to speak to it is to use a serial cable and the RS-232 interface which is nowadays usually accessible only with adapters or otherwise specialized hardware.

Clearly I’m not the target audience for the device7, but I could also see myself using it for, say, verifying that some temperature-controlled location is actually operated correctly. Based on my experimentation, one could easily measure for weeks – possibly even a few months – as long the parameters are realistic and the battery is good.

Lastly, I can’t help but wonder how many similar pieces of past technology are simply forgotten.

The code developed during this work is available here.

Open questions

Changelog


  1. Based on the Wikipedia page, Extrabit was or became a part of Elektrobit which seems to have transformed itself into Bittium nowadays.↩︎

  2. You can see how they made most out of the 6540 sample slots they had available.↩︎

  3. I lost interest in figuring this out after I managed to get it working, but it would be interesting to know the reason! The USB-RS-232 dongles may simply not provide enough current when comparing to traditional RS-232 ports in older PCs. The effect of the OS was a greater mystery to me.↩︎

  4. I made much use of my fridge here, because it was always at a well-controlled 5 °C.↩︎

  5. It could be that it’s the third byte for the time shift. I didn’t try any long enough measurements to actually test this.↩︎

  6. Naturally I didn’t store the raw values in my notes, only the result!↩︎

  7. I experimented mainly with my fridge and washing machines.↩︎