I’m working on a hardware project at the moment that’s more complex than a basic microcontroller-build that I could have implemented with an Arduino. So I’ve been using a Raspberry Pi as the centre of the project, and writing my code in the high-level languages I’m most proficient in. (In this case, Ruby).

As the project nears completion, it’s really important that the device doesn’t manifest as a computer in any way: it’s just a physical object. To that end, I’d like all the software inside the miniature computer to run at startup without any manual intervention.

My Pi is running Raspbian – the Pi-focused version of Debian – so, fortunately, there’s a tool easily available to do that for us: upstart.

We’ll write an upstart configuration for our script, which will turn our script into an upstart service, which we can then start at login.

First, let’s install upstart:

sudo apt-get install upstart

This will issue some warnings, because – on my install – it was replacing the traditional init.d setup. Don’t worry; everything will continue to work.

Once you’ve installed upstart, reboot your Pi, either from the command line or with a power-cycle.

Let’s now make an upstart config file. Here’s a very basic one:

Put this code into /etc/init/myscript.conf. You should then be able to run the script by typing sudo start myscript, and kill it with sudo stop myscript. And, of course, you’ll discover it’ll start automatically on startup.

That’s a very simple example, with no dependencies. But that won’t work for the script I’d like to use. In this example, I’m running a Ruby script (using the Pi Piper library) that blinks an LED attached to GPIO Pin 17. That script needs to be run as root to get access to the GPIO pins, and it needs to reference the directory’s Gemfile. Upstart scripts are run as root, so that’s not an issue – but we need to set up the environment correctly. That’s not so hard:

As you can see, we just have to export the BUNDLE_GEMFILE variable so that Bundler will know where the Gemfile is located.

Also, you’re going to have to make sure that all references to files in your code are done with absolute paths. That wasn’t a problem with the simple shell script example, but becomes an issue with more real-world type code – especially the program I’m ultimately running, which has various includes, dependencies, and data files to load. An obvious place you’ll run into this with Ruby is when setting up the $LOAD_PATH.

Rather than starting my Ruby script

$LOAD_PATH << 'lib'

I had to do this:

$LOAD_PATH << File.expand_path(File.dirname(__FILE__)) + '/lib'

And similarly, any other references to file loading will need to be absolute – and, ideally, derived using tricks like File.dirname(__FILE__) rather than through hardcoded paths.

Anyhow: it took me a while to piece together, but now that I have, it felt worth writing down – because I’ve now got reasonable complex computation-backed hardware working in an entirely headless enclosure – and one that’s resilient to power-cycling.

  • "x-OSC is a wireless I/O board that provides just about any software with access to 32 high-performance analogue/digital channels via OSC messages over WiFi. There is no user programmable firmware and no software or drivers to install making x-OSC immediately compatible with any WiFi-enabled platform. All internal settings can be adjusted using any web browser." Small, simple, wireless OSC-transmitting board; really nice idea, simply implemented, and noted down as a way of simplifying certain kinds of projects in future…
  • "What did The Hustle™ accomplish? I gained weight. I wasn’t spending enough time with my (now) wife. I felt like shit. I began to resent my work, and the work I was producing clearly wasn’t my best. I started cutting corners. I went from a mindset of shipping with quality and integrity to “when is this going to be over?”" I've almost never worked like this – but every time I have, it's always been as terrible as I've suggested it will be beforehand. Mainly on the software end of things, but not always. And the hustle is short-term thinking: the long-term damage is usually so much worse, including, but not limited to: technical debt, RSI, ill health, weight gains, emotional exhaustion, damage to relationships, friendships, and family. I am not only convinced that nothing is worth that; I know it.
  • Really excellent technical article on the development of Novation's Launchpad S. It's not that remarkable a product in many ways, but this is a super-detailed post about some of the thought and improvements that have gone into what looks, on the surface, like a most incremental upgrade – but is in fact surprisingly comprehensive and affects many things at low levels. Really clear, well explained – as is the rest of Focusrite's engineering blog.
  • "Dam-Drum is a handheld drum machine and sequencer with four unique sounds selected by Dam-Funk. This is a collaboration with Dam and Bleep Labs, who designed and built the drum in Austin, Texas." And that right there is your future of music merch: support your favourite artist by purchasing custom hardware with their sounds in. They only made 100, because exclusivity (or is it because longer runs would be painful to make), but it's got lovely packaging, and is surprisingly functional.
  • "I think one of the most gut-wrenching realizations that small companies have to make is that they aren’t Apple. Apple spends over a billion dollars a year on tooling. An injection molding tool may cost around $40k and 2-3 months to make; Apple is known to build five or six simultaneously and then scrap all but one so they can evaluate multiple design approaches. But for them, tossing $200k in tooling to save 2 months time to market is peanuts. But for a startup that raised a million bucks, it’s unthinkable. Apple also has hundreds of staff; a startup has just a few members to do everything. The precision and refinement of Apple’s products come at an enormous cost that is just out of the reach of startups.

    I don’t mean to say that design isn’t important — it still is an absolutely critical element to a product, and good design and attention to detail will enable a startup to charge more for a product and differentiate themselves from competitors. Apple has raised the bar very high for design and user experience, and users will judge your product accordingly. But it’s important to keep in mind that your true bar for comparison is other startups, and not Apple; and if your chief competitor is Apple, you either need your own billion dollars of cash to invest in product design, or you need to rethink your strategy."