Saturday, 13 October 2018

It Bleeps

(Originally posted on Google+, Jul 18 2018.)

Old school bleep with Moog Werkstatt, LittleBits and Ableton. Testing the gate input modification (blue wire), courtesy of

The Case of the Flaky TV Remote

(Originally posted on Google+, Apr 5 2016.)

Been quite annoyed lately with the crap digital TV box we have. Or, in particular with the remote control. It was glitching a lot, only reacting to about 20% of keypresses - felt like the keys were giving up or the IR circuit was flaky. To switch channel, you had to press it repeatedly and swear a lot. Well, technically, the swearing was optional. And actually, it was my wife who was most affected by the problem, since she's the one who watches TV in this house. I was mainly being annoyed by proxy and because I'm the one who has to try to fix the problem.

Today, I tried again. I checked with the camera on my phone that the IR lamp seemed to work - and I noted no glitching. It reacted immediately to all keypresses. So I cleaned the front of the TV box to make sure the receiver wasn't being blocked. Then I tried it out - and it worked surprisingly well. No problems at all in fact. It behaved just as when new (still a crap box, but a working one).

So she got ready to sit in front of the TV, and turned on a couple of smaller ambience lamps. I was still fiddling with the remote, and said "No, I was wrong, it still glitches". Then I had a thought: "Wait - turn off that lamp again." Remote worked. "Turn it on." Glitching again. Facepalm. For the better part of a year, we'd been trolled by interference from a cheap low-energy light bulb. A quick googling confirmed that this was indeed a well known problem, but not one that I had heard about before.

Department of Death, Sutter Street, SF

(Originally posted on Google+, Mar 24 2016.)

If you've played the classic point-and-click adventure Grim Fandango, you probably remember the Department of Death building where the game starts out. But did you know that it was based on a real building? The place is 450 Sutter Street, San Francisco, and it is covered in Aztec Art Deco, for real. On my recent trip to SF, I had the opportunity to check it out. Was not disappointed. Would have been nice to be able to go up to a skybar or similar though. Preferably with the option to go onto the roof and feed the pigeons while carrying a balloon animal looking like Robert Frost.

For more details, see

Also, I always thought that the hidden elevator (spoiler warning) in the pavement in the alley behind the DoD was a contrived idea that someone made up just for the game. But these are actually common in San Francisco - see the last picture. They are used to bring stuff in from delivery trucks in the street directly to the basement level of buildings (e.g. hotels), take out garbage, etc.

Now go play the game again. What are you waiting for?

And while you're at it, go get Day Of The Tentacle (Remastered) as well!

Mug shot

(Originally posted on Google+, Oct 15 2015.)

Got myself a new mug to match that keyboard.

Recreated ZX Spectrum (Bluetooth Keyboard)

(Originally posted on Google+, Sep 30 2015.)

So I got myself what has to be the nerdiest bluetooth keyboard in the world:

Quite expensive too, for a bluetooth keyboard. But build-wise, it's a perfect replica of the ZX Spectrum we know and love. Feels exactly right and has the correct key labels. Which means that used with a decent emulator, it recreates the feeling of typing on a real Speccy (without resorting to blind hunt-and-peck which is generally the case if you use a PC keyboard).

And after some fiddling with figuring out how to unlock the full bluetooth QWERTY mode as well as the Speccy-specific mapping, I can confirm that it works as advertised as a generic keyboard for Android, iOS or Windows.

I only had to ask myself, "can I think of anyone who's a more suitable target for this product" to realize that I really had to get it.

It's certainly not for fast touch typing, but programming on a Speccy was more like playing chords on a weird instrument. You didn't need to type e.g. "RESTORE", you'd just press a combination of shifts and an S and then on to the next word. I could throw together long lines of Basic way faster than anyone with a Commodore. As a bonus, you could use it as an eraser just by turning it over...

(2018 update: In the end I was pretty disappointed with the unpolished final state of the Android app, and I never really used it for Speccy gaming. On the other hand, I've used it as a keyboard for my PS3 and my Raspberry Pi RetroPi Emulation Station, and that gives me a warm fuzzy - and rubbery - feeling.)

Speccylator video

(Originally posted on Google+, Sep 30 2015.)

Wow, someone put up a video of running my old Speccy emulator on an Amiga. :-)

Lego Zombie Holocaust

(Originally posted on Google+, Jun 22 2015.)


Floating on a sea of mud

(Originally posted on Google+, May 10 2014.)

Did I mention that this town is built on clay? A lot of clay. Over 80 meters deep, around where we live. And you only have to dig about 2 meters down to find it - pure clay, looking like you could just scoop it up and start making pots. As seen on these pictures from just across the road where they're making foundations for a couple of new buildings.

(2018 update: We're now in fact living in the building that got built on this site.)

Tuesday, 13 March 2018

Erlang slave nodes and ssh login shells

The Erlang runtime environment is more similar to an operating system than to a traditional language runtime library. An Erlang "node" is an Erlang instance started with the flag -name (or -sname, for "short names" if your network does not rely on DNS). For example:
$ erl -sname foo
will give you an interactive Erlang shell with a prompt like this:
Eshell V9.2.1  (abort with ^G)
and you can see from the prompt that this is running as a "node" with the node name foo@rocka. In practice, this means that networking is enabled, allowing Erlang processes on this node to communicate with processes on other nodes, either on the same host machine or on other machines, through the ordinary Erlang message passing mechanism.

Working with multiple nodes

If I open a separate console and start another node bar@rocka in the same way, I can then connect these two and start doing interesting multi-node stuff:
(foo@rocka)1> net_adm:ping(bar@rocka).
(foo@rocka)2> nodes().                                         
For instance, if I have implemented a module mysrv that runs a simple counter server, I can load the code onto the other node like this - even if the nodes do not share a file system - and start it on that node.
(foo@rocka)3> BeamFile = code:which(mysrv).
(foo@rocka)4> {ok, BeamBin} = file:read_file(BeamFile).
(foo@rocka)5> rpc:call(bar@rocka, code, load_binary, [mysrv, "", BeamBin]).
(foo@rocka)6> Pid = spawn(bar@rocka, mysrv, run, []).
The last command should print something like <8112.88.0> where the non-zero leftmost number in the Pid indicates that it runs on another node than the local one. We can try to request numbers from the server to check that it is running:
(foo@rocka)7> mysrv:next(Pid).
(foo@rocka)8> mysrv:next(Pid).
(foo@rocka)9> mysrv:next(Pid).
That's cool and all, but it requires that you first do the orchestration of starting the nodes on the various machines (and making sure they get restarted if need be). In some situations, it would be much nicer if one Erlang node could simply start another one, on demand. For example:
  • Having a node on one machine coordinate a number of worker nodes on a cluster of machines
  • Writing test suites for code that cooperates across two or more nodes
  • Protecting the main node from failure when running less dependable native code (NIFs or C drivers, or a WX-based GUI)
  • Not running certain operations in the same OS process context as the main Erlang node
And of course, you want to get notified if one of these nodes crashes, and you want them to disappear automatically if the main node dies.

Running slave nodes

Erlang has standard library support for starting and supervising such slave nodes, and it looks straightforward enough:
  slave:start(Hostname, Nodeame, ErlangArgs)
for example:
  slave:start("rocka", "baz", "-s io write hello")
For this to work, you need help from your operating system to actually get the new nodes running, and by default it is assumed that the command for doing this is rsh. (The original Unix rsh command is deprecated these days, but on many machines nowadays, the rsh name is simply a link to ssh.) Edit: the patch to switch to using ssh by default was merged upstream in February 2019 and should be included in the following major release, Erlang/OTP 22.

You can however pass a flag to Erlang to tell it to use any other command, like this:
$ erl -sname foo -rsh /usr/bin/ssh
Easy! But there is a snag: the way this is implemented, you cannot pass additional flags to the command, and the default behaviour for ssh is to create a non-interactive non-login shell, if a command is specified.

This means that your attempt to start a node on a remote machine will probably fail because the command erl could not be found in the path, for a non-login shell (at least if you have standard .profile/.bashrc files). And -rsh "/usr/bin/ssh -l" does not work either, because the given string is treated by Erlang as a single path (which is allowed to contain spaces).

You may also be mystified by why the following might work:
(foo@rocka)1> slave:start("rocka","baz", "").
while this might not:
(foo@rocka)1> slave:start("localhost","baz", "").
bash: erl: command not found
and the reason is that if the given hostname matches the hostname of the local node, the use of the rsh command is bypassed, and the new node is simply launched as erl ... <UserArgs> instead of "<Rsh>" <Hostname> erl ... <UserArgs> - and you probably had erl in your current path already, so it just worked. Also note that there is no way of specifying an absolute path to the erl command - it has to be in the path.

To get around this, you could set up a specific environment on all the remote machines, either by customizing their ssh configurations, or by creating custom user accounts for running the nodes. But if you want it to "just work", using a regular user account with no special modifications, how can you get around these limitations?

Starting the nodes in a login shell

The answer is to use a simple wrapper script like this one, for rearranging the arguments and passing them on to ssh along with the -l flag:
    exec /usr/bin/ssh "$host" "/bin/bash -l -c '$@'"
Put the above in a file myrsh, make it executable with chmod a+x myrsh, and then start Erlang as follows:
$ erl -sname foo -rsh myrsh
That's all! Now it should work, both for "localhost" and for any remote machine that you can log in to (only assuming you have Erlang installed):
(foo@rocka)1> slave:start("localhost","baz", "").
You could augment the script as you please - for example, adding logging of the arguments being passed to the command, which was something I used quite a lot while debugging this stuff. The only tricky part of all of this was to figure out what was actually happening in the different cases, how the actual command line was constructed, whether there are any straightforward alternatives for getting ssh to behave like you want (not really), and whether your shell really should set up your user path only if it is a login shell (as far as I can tell, yes).

I hope this can be of help to anyone else who wants to try out the slave node feature, which understandably has been rather underused.