Also from Andrew Faraday

Where else can you find me?

Sunday, 23 August 2015

Reading USB controllers in Ruby (or What to do when you don't know what to do)

Disclaimer: I'm writing a blog on this subject because I couldn't find a more useful tutorial online. The truth is that I have twice worked out how to read a USB device in ruby, but I do not have a good understanding of the USB standard. I am sharing both how I reached a working code-base and the code I wrote, but there will be people out there who understand this better. If you're one of them, please write a simpler tutorial so this one won't be needed any more.

Our story starts at the Brighton Ruby conference in 2015, where I presented a technology-themed version of the popular panel game, Just A Minute. I had put together a simple system in Pure Data to keep track of the scores, topics and the timer. Long story short, this system let me down, it crashed half way through the session and I had to re-construct the scores on the fly.

In retrospect, I found that Pure Data was not the right tool for the job, so I set about rebuilding the same system in Ruby, with the Gosu library.

One of the reasons I had chosen Pd in the first place was the simplicity of using USB HID devices (you can learn about that in my earlier tutorial). So half way through this process, I ran up against the fact that is is not quite so simple in Ruby.

Firstly, I started with libusb, a standard library for reading USB.

I'm using the controllers from the trivia game Buzz, which look like they should be a particularly simple USB device, no output, no continuous controllers, just 20 buttons, should be simple, right?

First order of business was to find out what the USB device was. There's none of the PD index-based HID identifiers, instead I had to use the linux command 'lsusb' to find them. And the output from this includes my laptops keyboard and mouse, as well as what appears to be some internal USB hubs. It looks a little like this:

ajfaraday@ajf-samsung:~$ lsusb
Bus 002 Device 005: ID 0cf3:3004 Atheros Communications, Inc. 
Bus 002 Device 003: ID 054c:0002 Sony Corp. Standard HUB
Bus 002 Device 002: ID 8087:0024 Intel Corp. Integrated Rate Matching Hub
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 003: ID 2232:1029  
Bus 001 Device 002: ID 8087:0024 Intel Corp. Integrated Rate Matching Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

To this day, I have no idea what bus 1, device 3 is.

Okay, so we can't see the word Buzz, or playstation, or HID. The only clue is that it's made by Sony. The only way I can see to confirm this is to un-plug the USB and re-run lsusb. Sure enough, the Sony Corp. Standard HUB does not appear now. So I know this is the device I'm looking for.

Bus 002 Device 006: ID 054c:0002 Sony Corp. Standard HUB
It looks like this isn't enough information to actually use it, tho. I'm going to need more. The help page for lsusb tells us we can use the -s flag to choose a specific device, and the -v device to get verbose information.

ajfaraday@ajf-samsung:~$ lsusb -h
Usage: lsusb [options]...
List USB devices
  -v, --verbose
      Increase verbosity (show descriptors)
  -s [[bus]:][devnum]
      Show only devices with specified device and/or
      bus numbers (in decimal)
So we need to get the bus, and devnum (device) from our previous lsusb command. Here's the full information from my Buzz controllers.
ajfaraday@ajf-samsung:~$ lsusb -s 002:006 -v

Bus 002 Device 006: ID 054c:0002 Sony Corp. Standard HUB
Couldn't open device, some information will be missing
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.00
  bDeviceClass            0 (Defined at Interface level)
  bDeviceSubClass         0 
  bDeviceProtocol         0 
  bMaxPacketSize0         8
  idVendor           0x054c Sony Corp.
  idProduct          0x0002 Standard HUB
  bcdDevice           11.01
  iManufacturer           3 
  iProduct                1 
  iSerial                 0 
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength           34
    bNumInterfaces          1
    bConfigurationValue     1
    iConfiguration          0 
    bmAttributes         0x80
      (Bus Powered)
    MaxPower              100mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass         3 Human Interface Device
      bInterfaceSubClass      0 No Subclass
      bInterfaceProtocol      0 None
      iInterface              0 
        HID Device Descriptor:
          bLength                 9
          bDescriptorType        33
          bcdHID               1.11
          bCountryCode           33 US
          bNumDescriptors         1
          bDescriptorType        34 Report
          wDescriptorLength      78
         Report Descriptors: 
           ** UNAVAILABLE **
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0008  1x 8 bytes
        bInterval              10

Okay, there's a load of extra information here that we don't need. Just to cut a bit of this out, we're going to need idVendor, idProduct and the Endpoint Descriptor.

Back to libusb, the README for the library quickly gives me a bit of example code, which I've changed to include the information for my Buzz controllers.
require "libusb"

usb =
device = usb.devices(:idVendor => 0x054c, :idProduct => 0x0002).first
device.open_interface(0) do |handle|
  handle.control_transfer(:bmRequestType => 0x40, :bRequest => 0xa0, :wValue => 0xe600, :wIndex => 0x0000, :dataOut => 1.chr)
But as soon as I try running this code I see this error.
/var/lib/gems/1.9.1/gems/libusb-0.5.0/lib/libusb/constants.rb:62:in `raise_error': 
LIBUSB::ERROR_BUSY in libusb_claim_interface (LIBUSB::ERROR_BUSY)
The stack trace points us at line 5, 'device.open_interface'. I did a lot of googling on this subject, and got a lot of confusing answers. I'm skipping a lot of trial and error here, but the answer here seems to be that something else, possibly the operating system, is reading the USB port already. So to use it with my Ruby app, I need to use detach_kernel_driver. Which looks a little like this:
  def reset_device_access
    usb_context =
    device = usb_context.devices(
      idVendor: 0x054c, idProduct: 0x0002
    handle =
  rescue => er
    puts er.message
    # nothing needs doing here

There's a couple of things here, firstly, I'm finding the usb context, then finding the device by as in the example. I then need to open a device handle, run detach_kernel_driver, then close the handle. Only, if there is no kernel driver to detach, this throws an error. The rescue block here is something of a hack, I can't find out how to detect if I need to run detach_kernel_driver or not, so I simply catch the error, but don't halt the code. If it throws an error, then it didn't need to be done. This shows my ignorance of the deeper, darker parts of libusb, but it works.

I don't like this, but some times this is something we need to do, pending a better understanding of what we're working with.

So, I can actually get to my device, that's a start. Although, I want to use my device in and amongst some other code, I didn't want it to be limited to a single code block. I had to go digging around in the libusb API documentation and found that instead of using 'open_interface', which opens the interface, uses it within a block, and then closes it at the end of the block, I could instead use the 'open' method. My new code looks a bit like this:

class Controller
  def initialize
    @usb_context =
    @device = @usb_context.devices(
      idVendor: 0x054c, idProduct: 0x0002
    @handle =

So, I've wrapped it in a class, run my reset method to ensure it's free, and saved the device handle as an instance variable, @handle. The next thing we need is a method to read that handle. For this we need the endpoint data from back in our lsusb data, specifically the attributes named bEndpointAddress, bLength and bInterval. Again, after a lot of trial and error, I found it easier to use interrupt_transfer, which is specific to input endpoints (the information coming back from a USB device). So this is also in the Controller class

  def raw_data
    data = @handle.interrupt_transfer(
      :endpoint => 0x81,
      :dataIn => 0x0005,
      :timeout => 10
Again, I had a great deal of difficulty reading the result of interrupt_transfer, and the code shows where I wound up after it. The data variable is a string, but it's not human readable, the result looks a little bit like this.





Each line of this is a single output from the raw_data method, while I'm pushing some buttons on the Buzz controllers. There's no understanding this. A lot of trial and error later, I discovered that this is actually an array of numbers, each one is a byte (a number made up of 8 binary bits, which translates to a number between 0 and 255. So, with the method defined above, I wrote a script to watch what happens when I push the buttons...
require 'libusb'
require './controller.rb'

c =

loop do
    puts c.raw_data.inspect
  sleep 0.01 

Oops, there's another one of those unhandled rescue blocks. This is bad practise! Usually you would either stop the program completely on an error, and guard earlier on in the code against situations which will cause an error to be thrown. Only I can't find out if it'll work or not without just trying it. So this will have to do for now.

What I've found by probing in this way, is that when a button is pushed between one call of the raw_data method and the next, there is no error, but when no buttons are pushed, it throws the error 'error TRANSFER_TIMED_OUT'. So I just ignore the timeouts, and use the data from when there is a change. So I can now see the output from the raw data method, only when buttons are pushed. Here's what happens when I push a button at random:
[127, 127, 0, 0, 240]
[127, 127, 0, 4, 240]
[127, 127, 0, 0, 240]
[127, 127, 0, 4, 240]
[127, 127, 0, 0, 240]
Okay, so the first thing I've noticed is that the first two numbers (bytes 0 and 1) don't seem to change at all. I have no idea why, but I can easily isolate the input I was looking for. The fourth item in the list (byte 2) goes up by 4 when it is pushed.

Now, 4 is a binary number, and a quick check of the other buttons proved a definite pattern. Pushing any button on the controllers will increment byte 2 or byte 3 by a binary number (1, 2, 4, 8, 16, 32, 64 or 128). The long and the short of it is this, as I mentioned before, these numbers are made up of 8 binary bits, each representing one of the numbers listed above. The number each active bit represents is added up to make that number.

If I select the index of a number in Ruby, it gives me that indexed bit of the number. For instance:
# bit 0 represents 1, so for number 1, this is active.
# => 1
# but if the number will not contain a 1 in it's binary makeup, this is 0.
# => 0
# This means that if we add up some binary numbers, the bits for these numbers is a 1:
n = 4 + 32
n[2] # the bit for 4
# => 1
n[5] the bit for 32
# => 1

So, applying this to the data to
c =

loop do
    puts c.raw_data[3][0] == 1
  sleep 0.01 
So, raw_data[3] is byte 3 of our raw data and raw_data[3][0] is bit 0 of byte 3. If this bit is a 1 instead of a 0, that button is pushed. By pushing each of the buzzer buttons (the ones I'm interested in), I found this information out.

# buzzer | byte  | value | bit
# 1      |  2    |  1    |  0
# 2      |  2    |  32   |  5
# 3      |  3    |  4    |  2
# 4      |  3    |  128  |  7
That is, for buzzer 1 we see byte 2 increment by 1, which is bit 0 (the one on the far right) etc. So to check all 4 buttons, I narrowed this down to an array with which byte and bit to look for for each button. Which I've stored as a constant on my Controller class.

class Controller

    [2, 0],
    [2, 5],
    [3, 2],
    [3, 7]

  def check
    data = raw_data
    BUZZ_BITS.each_with_index do |lookup, i|
      if data[lookup[0]][lookup[1]] == 1
        puts "buzzer #{i + 1} pushed"
    # no input, just ignore the error

This is really the end-point for this tutorial. What I've done in the end is store which bit I'm looking for for each button and at each call of the check method, I grab the raw data. Then I iterate through the bits I'm looking for, and print the index of that bit (with a + 1 so people aren't confused by the zero index).

Okay, so this is pretty confusing, but it works, honest. You can see the full example code at and see it in the wild at

Thanks for bearing with me on this one, I really hope you found it helpful. Any comments, questions? Feel free to get me on twitter at @MarmiteJunction

Monday, 16 March 2015

An open letter to recruitment consultants, on their relationship with developers.

To: The incumbents of the IT recruitment industry

Recruitment consultants are a reality, it can be difficult for companies to find the right candidate, and for developers, particularly those who decide to work a series of short term contracts to find their next position. In this climate recruiters are regularly in contact with tech companies and programmers both searching for jobs and employees and attempting to find matches for them.

But it's not always a match made in heaven, often developers are not looking for work, and many happily hold a single job for a number of years. However my skills as a Ruby on Rails developer are currently in a lot of demand, so sometimes as many as five different agents, often more than one from the same agent, will get in contact and take up some of my valuable time attempting to tempt me into a new position.

Many people in the computer industry share the experience of being frustrated by over-zealous recruitment agents, often getting in touch during working hours, advertising unrelated jobs and using hyperbole to exaggerate the desirability of positions. In more extreme cases, recruiters can be patronising, unduly persistent or completely dishonest to both potential employers and employees.

I appreciate that recruitment is a goal-driven sector, and there is pressure to perform, but making more contact is not, necessarily, the best way to fill jobs, or find them.


Allow me to give one example of the mistakes which recruiters make:

My boss works hard, he is a director of the company, and has worked hard to make it the success it is. He's a rails developer, but also handles database and system administration, as well as liaising with customers, regularly working to capacity.

One of my colleagues walks through the door with the phone, someone, giving their name, but not the reason for their call, has asked to speak to the head of Rails development. The boss answers, politely, and quickly becomes annoyed "No, I'm a director of the company, I can't just leave to do another job."

The recruiter has learned the piece of information they phoned to ask about, taking around 30 seconds of the time they are uniquely placed to know the value of. They've also told a director of the company that they want to poach developers from what is a small, tight-knit team, of course he's annoyed.

The correct response would be to give it up as a bad job, politely withdraw and cross his name off the list, permanently.

The next thing I hear is a raised voice "No, we are not currently hiring. Good bye!". It's hard to slam a cordless phone, but my boss had a jolly good try at pushing the red button with attitude.

Having phoned the office phone number in the hope of getting to a senior developer, told the boss that they're attempting to poach developers and persisting in a conversation which is clearly over. This recruiter decided to switch modes from "we need developers" to "we've got developers for you" without missing a beat. Besides a devious method of getting in touch, they're must be an untruth in there somewhere, or at least speculation. They're either lying to the developer in him, or to the director.

This having taken place, is it any surprise the boss didn't want to enter in to a business relationship with the individual on the phone?


Here's another example, in which a lengthy and complicated bug fix was interrupted with a 30 second phone call which put my own thought processes back by at least half an hour.

The phone rings, undisclosed number, I step out of the room and answer, already expecting recruitment, PPI claims or some form of "get rich quick" scheme.

The voice comes through, "Hello I'm (name) from (company name, it was an acronym, unhelpful)"

I reply, "Sorry, I don't know that company, what do you do?"

"We're a company of IT specialists."

"But what do you do?"

"I'm looking for a developer for a job in..."

Enough of my time has been wasted, I raise the tone of my voice a little "I'm not looking for work at the moment, thanks."

Again, the conversation has clearly ended, but the killer instinct which recruitment agents all seem to develop kicked in, but uncertainly...

"But what if we could..." he pauses, "Offer you more money". There was a noticeable rising, uncertain tone to this last word. As if he'd only just realised that the word money might not be a magic bullet in his fight.

"No thanks", and I make another spirited attempt at slamming my mobile phone.

I couldn't stop thinking about the fact that this total stranger, who wants to start an actual business relationship with me, seriously thought he was going to tempt me away from my current position with a pay cut.

This fact, on it's own, was enough to distract me for some time, but in truth any interruption is disruptive.


I don't just want to shout in the direction of recruiters, but to offer some genuine constructive advice on how to avoid alienating developers who aren't interested.

There are three principles I'd like to suggest you bear in mind when contacting developers.


Recruiters will often provide a lot of extraneous information about a position, for instance, that it has investment, inflated perks (office furniture and powerful work computers are not perks, they're necessities), or who their clients are. Developers are busy, we don't have a lot of time to read emails in detail, especially when we haven't decided to change jobs at all.

We are not likely to be tempted away by the fact you've taken more time to fill out some of the unimportant details of a job, and to exaggerate the benefits, and quite possibly hide some negaitve points.

Mostly, we'd like to find out who the job is for, so we can do our own research, and bypass all this text.

Okay, so there's a business case for keeping that piece of information secret. Although it does try to start a real business relationship by openly showing a lack of trust in potential clients.

Here's what developers actually want to know:
  • What's the job, don't just say "may be relevant to you", what does the successful applicant have to do? 
  • Where is it?
  • Is it a contract? (this isn't always a good thing), how long will it last?
  • How much is it? We're not completely money obsessed, but it's a good guide for the level a job is at, if we can go for it, and if it's worth the considerable disruption of changing a job. 
How about a bullet point list of this information, instead of paragraphs and paragraphs of nebulous, imprecise information?


A javascript developer will rarely be interested in a java position.

A new developer will not be interested in a highly responsible job which doesn't provide some amount of training and employee development. (Senior developers don't happen without being juniors first).

If a CV has not been updated for years, this is probably because it's owner is not looking for work.

Recruiters tend towards a scatter-shot approach to recruitment, the theory being that recruitment emails have a hit rate, so a higher volume of emails lead to the same proportion of a higher number of people. Keywords don't always result in candidates who fit the bill.

I have personally blocked a number of recruiters from contacting my email address when I get more than one email from them a week. I have been known to reply tersely when I get multiple emails concerning the same position from multiple recruiters belonging to the same agency.

Try to gain a little more understanding of the industry you are working in, be a little quicker to take names off the list, or at the very least wait a year before getting back in touch.

Remove hyperbole and patronisation

Developers are intelligent, hard-working people who understand our work affects the public image, productivity and stress levels of our clients. We are professionals, we've worked hard to develop our skills and persist in improving skills to the benefit of our employers.

We do not need to have our egos stroked in order to begin a serious business relationship with an agent. We do not need to be called ninjas, rockstars or jedi to pique our interest. In around half a decade, there will be many programmers who are actually twelve years old, presently, however very few are.

Please don't tell me the job you're representing is an exciting opportunity. Near enough every email from a recruiter starts this way. It's a job, I can decide for myself whether or not it's an exciting prospect for me.

Any other hyperbole says so much more about the author than the subject, facts really are more important.


So how would I like to be contacted?

Dear Mr Faraday

I'm currently looking for a Ruby developer for my client, a digital advertising agency based in Rotherham. It's a 6 month, contract, which may become permanent, and a £150 day rate.

Let me know if you're interested and I'll send over a job spec.

Kind Regards

Ms Joan Q Recruiter - Doohickey IT

As a prospect, that's really all I want to know. It's not hard to ask for more, and initiate a dialogue, but it's very off-putting to be fed lots of information outright.

Just let me know who you are and what you're representing to me.

Oh, and you'll rarely get a good response by phoning my mobile during work hours. Interrupting my job to try and take me away from it is not a considerate thing to do. It's like an estate agent saying "It looks like you have a home, would you like a home".


In conclusion, think about who you're talking to, and how this unsolicited contact will be received.


Andrew Faraday

Wednesday, 5 February 2014

Making music with Ruby and Beep (Linux only)

I've not posted in a long time, I know. This is mostly because I've explained most of what I know about Pure Data which can be explained in a blog post without relying 100% on prior knowledge. So this is a little about Ruby, and a little about Linux. A nice, short topic which can get you writing a little bit of code in a short time. 

Firstly, you will need two applications, Ruby and Beep, these are easily installed with a simple command. On Ubuntu distributions you can use apt-get, like so. 

If you are using a Redhat variation of Linux, such as CentOS you might need to use yum instead. 

Now, beep is an application for controlling the internal speaker in most computers (towers), although for laptops it will usually work through the sound card, with the in-built speakers. So, to use it in it's simplest form, use this command:

Unsurprisingly, your computer will make a beeping sound. It's not very interesting, or very musical, but it beeps. 

There are two problems you may well run into at this stage, firstly, it might not beep at all. If this is the case, I suggest you check out this forum topic, for some linux jiggery pokery on fixing that issue. You may also find that it comes through VERY LOUDLY, if this happens, try alsamixer, which usually has a volume level entitled beep, which you can navigate to and lower using the arrow keys.

Back to beep, a single beep, on it's own, or a few one after another, still don't really sound musical, but we can take a little more control. As with most command line applications, you can bring up a help page by using the -h command, like so.

 Okay, so this may be a little baffling if you're not used to using the command line, but basically there's a list of flags, preceded by a hyphen(-), which you can add to the command while calling beep, to change change the result in one way or another. Some of these would be followed by an attribute (after the flag but within the same brackets) to control this more directly. 

Now, the first two options on a beep are frequency, and length. These two options are, really, the minimum you need to start producing musical sequences. The frequency is in Herz (as I've covered before, this means it's roughly between 20 and 20,000 and increases the pitch by an octave every time it is doubled), so we can try a simple sequence by typing these commands one after another...

Now, you'll notice a couple of things here. Firstly, those three tones sound quite nice in sequence. More importantly, however, you'll notice that you can't type quickly enough to hear them as any kind of tune. Clearly this is not something you can easily control directly from the command line. 

But, again as I've mentioned before, the beauty of programming computers is that when you don't want to (or aren't able to) keep controlling a computer directly, you can give it some rules and let the computer follow these. So, the first thing we need to do is use a programming language capable of running terminal commands for us. I'm using my main programming language, Ruby. 

We'll use irb (or instant ruby) for now, which just runs ruby commands line-by-line, instead of reading through a file.

You'll notice the start of the line has changed, but you're still being prompted to type. 

We're going to use a standard Ruby method, system, with a single argument which is a string of text. So we'll make our argument, that last beep command, for now.

This returned true, which basically says, yes, this worked. You'll also hear the beep. You may also notice that you typed a longer, slightly more complicated line for exactly the same result. This part is just a primer, however, to show you ruby running the terminal command. Next we're going to use a single variable, which we'll substitute for the frequency number. 

First let's take a step back, a variable is a single piece of named information within Ruby (and most other programming languages). You can think of it a little bit like doing algebra at school, if we set a variable called f (say, f = 440) we can then do some actions on f, which would be the same as doing those on the original number. For instance...

You can see that we've done some maths with f, the results are worked out for us, and if we define f again as something different, the answers to the other lines would change. Although in this case, f doesn't change unless we use f = something again. 

We can define f as the result of some of this maths, like so...

You'll see that this time f has changed with each line. So the result of the each bit of maths is based on the one before. 

For these maths functions, we can usually shortcut this by putting the = and the operator together (like *= to multiply and set the variable...

 Notice how the results are the same as the method I used before. 

So what has this got to do with making music with beep? Well, once we have our variable we can do a string substitution to put it into the beep command, then send it to the terminal with system. 

So if we change f, and then run the beep command again, the pitch will change. 

String substitutions in Ruby can be done on double quotes ("") and are a hash followed by curly brackets. That might not make sense but they look like this: "Solid string: #{variable}" For instance: 

What this substitution (#{}) does is evaluate the ruby code within, and then put it in that place in the string, so we could put one of our *= commands in there, so f would be multiplied by the same figure whenever we run that line...

To help you do this, in irb (and in the terminal) you can re-run lines by pressing up until you see the previous line you want to run, then pressing enter. 

This may look the same, but you'll hear that the pitch has increased by an octave each time and see at the end that our variable f has been doubled four times. 

So, we've established that we can make the frequency change by running the same line of code a few times over, hearing the beep each time. The next step is to run that line a few times over without having to run each one manually. For this we're going to use a ruby times loop, this does the thing which is in curly brackets ({}) after it a given number of times. like:

4.times {system("beep")}

Lets try that last sequence, but in just 2 lines of Ruby:

This will sound the same, but a lot more fluent than the previous example, the four beeps sounding one after another. 

When using a times loop, we can also set a variable which comes from times to use inside the loop, which is defined within pipe characters (|) at the start of the loop. For instance:

This uses the Ruby puts method (which simply puts it's argument down in the terminal) to show you what i is each time this loop is run, you can clearly see it's the numbers from 0 to 7. It's basically the number of times that loop has been run so far. 

So if we use this alongside our f variable, we listen to the pitch changing based on algorithm which changes in the same way each time, based on how many times the loop has been run. 

Lets apply some pure data knowledge here, way back in June last year in Algorithms of the Street: Part 3 - Additive Synthesis I told you that when you multiply a frequency by whole numbers, you get what is known as the harmonic series, which is a set of frequencies which go together, often they are present together when you hear musical notes, and strings tuned to the first of these will vibrate in sympathy when a tone is played at one of the other frequencies in the list. 

So frequencies which are multiples of the same note go together. 

So lets try that times loop, but multiplying f by i each time. I'm going to start a little lower down and run this line 8 times (although because i starts at 0, I'm putting a little bit of ruby in brackets to use i + 1, so we actually get the numbers 1 to 8):

You'll now hear beep running through the harmonic series, from that initial frequency of 220 hertz.

Let's try a different approach, let's use a method called rand, which generates a random number. When we give it an argument, it will generate a random number between 0 and 1 less than that number (the same as pure data's random object). 

This time you'll hear a sequence of 8 beeps at random pitches, and if you run it again you'll hear different random sequence. 

Incidentally, you could substitute 8.times with loop, which is an infinite loop in Ruby (followed by the curly brackets in the same way). However, you will have to press ctrl + c to stop this running. 

Lets try combining the last two approaches, a loop which randomly chooses a value for f, then runs up the first 8 partials in it's harmonic series.

Sounds complicated? Well it is, and if you do any coding, you'll wind up doing some complicated things, that's just the way it is. So let's start by making it simpler. Firstly, this shouldn't be done on just one line. And because we're relying on a few lines, it's probably best to use a ruby file (a text file who's name ends in .rb). 

Also, because we are working across multiple lines we'll replace those surrounding curly brackets with the words do to start and end to end. The convention to make these more readable is to indent the lines between these two words by two spaces, so you can scan down the left hand side of the file and see that those which are indented are inside that block. 

So, in your favourite text editor (but not word processor, just a simple text editor. I'm using vim) put this in a file and save it as beeps.rb in your home directory. 

(notice that I've replaced system with back-ticks(`), which do the same thing, only they wait for the command to finish, if you use system here you might get a shock when you try to stop the ruby file from running)

I've added a -l flag of 100 milliseconds to make this slightly faster. So you see the { and } have been replaced with do and end and the lines between are indented, so you can scan down from the do line to the end line without any interruption. You don't have to understand this at first, but please do it. This makes code readable! 

You can now run this in the terminal, in your home folder, with this command:

ruby beeps.rb

press ctrl and c to stop this script

You'll hear the same kind of random melody. 

Now we're going to put a times block inside our loop block. Again, replacing curly brackets with do and end, and the line within will be indented a further 2 spaces. 

I'm also going to add a puts line so you can see the frequency as the script runs.

Now when you run ruby beeps.rb, you'll hear a random note, beeps running up it's harmonic series, then a new random note and it's harmonic series, and so on. 

And that is some algorithmic music made in Ruby and Beep, no pure data at all this time. 

I realise it will be very heavy for people who haven't written any code before, but it's quite rewarding. Remember that code is, above all else, very logical, you can often work out problems as you are writing it with a few rules:

  • Finish everything you start
  • Read error messages carefully, they may be talking about something you're not currently thinking about.
  • If stuck, ask google
  • If stuck, ask someone who knows about it. 
That last rule is important, the internet is full of well-meaning techies who will often help beginners with a little leg-up in the world of code. I'm amongst them (feel free to grab me on twitter, @MarmiteJunction). 

I hope you found this little tutorial interesting, informative, or even fun. By all means tell me what parts of it make no sense to you. 

God bless and have fun coding

- Andrew F

Monday, 14 October 2013

USB controllers in PD

Todays blog post is about a deceptively simple subject which can instantly expand your capabilities in Pure Data, Human Interface Devices or HID.

This was one of the things to excite me about Pd usage in the early days because it introduces what could be termed the 'alchemy' of  computer programming. Simply termed, we can turn a kind of thing with a specific purpose, such as a joypad, into the same thing, with a very different purpose, a musical instrument.

So today I'm working with this rather simple setup:

Now, that's a nice, cheap, third-party USB joypad, I bought for £15, but if you fish around online you can find cheaper, still. Now, almost all game controllers for computers use a set of standards known as HID (Human Interface Device). Which strangely enough is also the name of the object which we can use to get this information into Pd.

Try this patch (remember to plug in a USB controller before opening Pd):

Step 1: Finding your HID device

This is a simple patch to start with, because hid is quite complicated there's a few different messages you can feed into the top. The message 'print' when you haven't told it which device to listen to yet will print out a list of available hid devices in your Pd terminal, looking something like this...

Now, we can see a list of devices, and that hte USB joystick (curiously named MY-POWER when the name ORB is printed on the pad itself) is Device 12. You may also see keyboards, mice, graphics pads etc on this list.

Note that next time you plug in your joypad (or other kind of controller) it may not have the same device number, so you might have to go through this process again when you open a saved patch.

The next step is to open this device and see what information Pd can read from it...

Step 2: Look at the device, having found it

Now, clicking on 'open 12' will tell hid to read the device we found in the previous step, and then the purpose of 'print' has changed. Instead of listing devices Pd can see, it will tell you what parameters it can read from that device. So clicking 'print' will result in a readout like this one...

Now, you can see that we have messages which Pd can get from the controller, 12 btn messages (which will send 1 when a button is pushed, and 0 when it is released) and 7 absolute axes, which are sliding-scale type messages. If, having opened a hid device, we feed hid a 1 (usually from a toggle, but you could feed it in from a message, too) it will start polling (basically, listening to) these events from the controller.

Let's try setting this to poll, then feeding the results out to the terminal via an object called print (not to be confused with print from the message, mentioned above.

Step 3: have a look at what's available 

All we've done here is pipe the output of hid into print, which puts everything it sees onto the terminal, so when I push some buttons on my controller we see something a little bit like this...

Now, this is just a list of messages, but we can see that there's a certain structure there. Firstly there's three things separated by a space, which Pd reads as a list. Firstly the contents of the TYPE column we saw above, then the name of that parameter, then a value of 0 or 1.

There's also a miscellaneous scan parameter, which seems to identify the button being used. I don't really know what this is for, but I know we can safely ignore it.

You'll also notice that every message (1 for on, 0 for off) is sent twice. This is a problem known as 'debouncing' which some controllers are prone to. There are ways around this, but for everything we're going to do here, it won't matter.

The next thing we need to know in order to make this information useful is how to just get the last part of the list, for just one button. For this we're going to use route. All route does is list (without that first item), and everything else out of it's right-hand outlet.

If route has more than one argument, it will gain additional outlets, if the first item in an incoming list matches the first argument, it'll be output via the first outlet. The second argument, the second outlet, and so on...

Step 4: Use route to focus on the controls you're interested in.

So all I've done here is route the lists starting with 'key' to the second route, where it takes the messages btn_0, btn_1, btn_2 and btn_3 and outputs them to four toggles. When I took this screenshot I was holding one of those buttons, so you can see that one toggle is selected.

And that's basically all you need to know about getting (or Mapping) inputs from a hid device into Pd. But we don't want to stop there, what about those joysticks? and the d-pad? Well, with the same process we can route their inputs into our patch, too.

Step 5: A few more mappings...

So there you have it, both of the joysticks output two axes, and moving them around I can easily learn that they range from 0 (at the top, or far left of it's range of motion) to 255 (at the bottom, or far right) and the resting position has both at 128.

The d-pad (direction control on the left hand side of the pad) also outputs two axes of motion, although these are only ever -1 (up and left), 0 (resting) or 1 (down and right).

In the snapshot above I was holding one stick to the bottom-right and also the d-pad.

I think it's time for a little alchemy, let's hide the patch so far in a sub-patch (see Putting Pure Data in a Box) and use some of these controls to make music.

Step 6: Mapping controllers to a simple synth

Now there's a few things here from previous patches, firstly the object 'pd controller' contains the hid patch we've been working on, only I've added a few sends to it (named b1 for button 1 etc. lx for the left stick's x axis etc.). As you can see here:

The patch outside it contains a few things from previous tutorials, an array with 15 numbers (representing two octaves of the major scale), a maxlib/scale which converts the 0 to 255 we have to the 0 to 15 we want. This goes through i to make sure it's an integer (whole number) and to tabread, which reads a number from the array, scale. we add 50 then smooth out the edges with a line~. This is converted to a frequency with mtof~ and feeds an oscillator.

I've then brought in one of my buttons (b1) to turn the volume on or off for the oscillator, multiplied it down a little and fed it to the sound card with dac~

Once again I've described each part of a Pd chain to tell you it's function, but if you haven't read all my other blog posts, this basically turns the left-right motion of the left joystick into a pitch control, in a given scale, and one of our buttons into an on-off switch. This is a simple musical instrument. With a little practise you can play a tune on this.

Now, just for fun, I'm going to use the up-down motion as a volume control and lengthen the envelope on the button control...

So the left stick is taking on the duties of a bit more expression. This also opens the patch up to something of a money shot. Why not have a synth on each of these 4 buttons, an octave apart? One of the strengths of Pd is to quickly duplicate and modify code, so let's try it...

Step 7: A modified joypad quartet

Now, I've done a few things here. Firstly I've moved that volume control to the top of the patch, and sent it to the bottom part of the patch with an audio send (s~ vol), then I've duplicated the bottom part of my patch 4 times. I added 12 to each successive midi note (making it an octave higher), then I used a different button send to turn each one on and off. Hey presto, I can play at a different octave by pressing each of the four buttons.

I also changed all the osc~ objects to phasor~ for a different tone, and lowered the initial + to make the lowest tone a bit lower.

Now is probably the time for a little demo, but first, I should warn of some of the pitfalls of working with cheap and cheerful gaming controllers.

Firstly, you'll find the range of motion on joypads is much narrower than you think. That is, the range which isn't the extreme top or bottom end, or dead centre only takes up a small amount of the space you can move the joystick.

Also, you'll probably trip up over the fact that the top of a stick's motion is 0, and not the bottom.

Well, that range of motion issue has made it a little limited, and it is a very simple instrument, but here it is. My custom joypad instrument and a little exploration of the sounds it's making...


Monday, 30 September 2013

Using Midi, and Pure Data, and mashing up sound

It's been too long, readers, since I posted anything to blogger. I've been busy, and sadly the blog is one of the first things to go, even when I'd just reached the point of putting gifs on a post

Well, this time round I thought we'd have some fun with audio, so let's start with a short clip of sound like this one. I'd download it, it's only two seconds long.

For those interested, this is from the Teabot and it regularly does a good job of informing me and my colleagues that there's a cuppa ready for the drinking.

Let's try analysing the sound the sound a little, it's short, contains three distinct notes, two of which are part of the same syllable, and has quite a hard 'st' sound in the middle of it.

There isn't much more to say about what we're hearing, but what about how the computer makes the sound. As I've said before digital audio is actually a long stream of numbers, each between 1 and -1, which are played at a rate of thousands per second (44.1 thousand, usually). These are interpreted as how far a speaker membrane is pushed or pulled (either side of 0, the resting position) which produces the same pattern as a pressure wave in the air, which you can then hear as sound.

I've also said before that an array in Pure Data holds a list of numbers, which you can then feed into your sound card, to control your speakers.

You can probably see where I'm going with this, if we feed all of the numbers (known as samples) from this sound file into an array in Pure Data, we can then control that sound in a similar way to how we control synthesizers. So, first things first, how do we get it into an array? Try This.

Part 1: Loading sounds in to a Pd array

So, there's an array, named tea, containing my tea sample, but how did it get there?

Once again, let's follow the Pd chain from the top. First is a bang, a button which outputs an activation message, which goes to openpanel. This brings up your usual file opening dialog, when you choose a file in there, it outputs the path to that file (e.g. /home/ajfaraday/Downloads/tea.wav), which is then being passed to a message. As discussed earlier, message boxes send a message down the line, and substitute placeholders (marked with $1, $2, etc.) with whatever is placed in the top, so $1 here will be replaced with the file path. The message itself is fairly simple.

read... resize... the file... the name of the array

this will read the named file, and put it in the array, tea, and re-size it to the size of the file. But only when it is passed to the next object, soundfiler. That's pretty much what soundfiler does, dump sound files into arrays.

So, after clicking the bang and choosing the file, we have it all in an array, it even looks a bit like the waveform you can see on soundcloud (above). Now, what can we do with it?

Step 2: Simply playing a sound

Pure Data can be very simple some times, when we want to play the contents of an array (or table), we can use tabplay~ (as ever, the tilde, ~, means this is an audio object). This, with the name of the array as an argument, plays the sound when it is given a bang. I'm then feeding it into a volume control (*~) and out to my sound card with dac~.

This is very simple, and offers very little control of how the sound is being played, only when.

As I discussed way back in Pure Data and BACON (Part 1), you don't have to keep hitting bangs manually, you can automate them with a metro object and control how regularly that outputs its bang with a number.

Part 3: Automating audio triggers, a simple stutter effect

You'll find what this start's to have an incessant, droning quality, mostly because you're hearing that first (not very well produced) note over and over again. You can have fun with moving that number down to make a very quick repeat (if it's low enough it won't even reach the start of the word), and then moving it back up, in what's known as the 'bouncing ball' effect. This kind of fast audio re-triggering is used by quite a few DJ's, if you listen out for it.

However, this all the time, with no changes, gets difficult to listen to. Let's try taking control of what's going on here with two simple facts, tabread~ can accept a number, which tells it which sample to start on, and any number you can get into Pd, such as MIDI controls, can control anything.

Part 4: Adding position to our stutter

So what're we doing here? Well, I've got the data from the midi keyboard coming in via notein, which gives me the most recently pressed key as a number between 1 and 127. On the two octaves of my small midi keyboard, these are between 48 and 72.

In MIDI Controllers in Pure Data I used spigot to filter out the note-off signals from the keyboard, on this occasion I'm using stripnote, which does the same thing, it's just a little lazier for me to do it that way.

I'm then using maxlib/scale (as I did in How To Make A Musical Instrument in 10 Minutes) to change that range to between 0 and 88,200. Which seems a large, scary, and quite specific number. You might wonder where it's come from. Well, back to the idea of digital audio as a stream of numbers. CD quality audio is usually at 44.1 kHz. Meaning that 44.1 thousand of these numbers are in every second of audio. So, for a two second clip, we need 88.2 thousand, or 88200.

That's a bit of a cheat, not every clip of audio is 2 seconds long. You can find the exact length of our resized array by right-clicking on it and selecting properties. Or, within your patch using arraysize, like so (you may want to do this in future to avoid having to type the length of an array manually):

So we've now taken the range of our keyboards midi numbers and transformed it into the range of samples in the array (give or take a few).

Now, float boxes (f) simply store a number, and if a bang is placed in the left-hand inlet, it will output that number, time and time again. So when we press a key, it changes the number it's storing to a position within the array and whenever the metro fires, the tea sound is played from that point.

When you start the metro, you can press keys and effectively play the different parts of the sound on your keyboard! Like so:


Okay, so it's not the best video, and the screen flickers (this is to do with frame rates, but don't worry about it, just don't, usually, point a camera at a tv or computer screen), but you get the idea. I'm taking direct control of the position of playback from my keyboard.

Well, this is a little limited. But I we can use some of my earlier teaching in Pure Data to take control of other parts of the sound, how loud it's playing, how fast the metro is and when to start and stop the metro direct from the keyboard. Take a look at this...

Part 5: Some more direct controls

I've added comments for which midi controls are entering via which ctlin box (if you don't know what these are, have a look at my earlier post on MIDI) so, from the top-left, lets look at what they're doing.

The first control, labelled 'button', is a button, when it's pushed it alternately outputs 0 or 127, which I've fed into a bang, so every push will be treated the same way. That then feeds a toggle, which will turn the metro on and off. (I may have said before, turning it off is a very valuable feature).

The rotary control is turned, producing figures from 0 to 127, which I've scaled to 0 to 600 which control the speed of the metro re-triggering in milliseconds. Then there's the keys, which I've described in the last part.

Then the mod wheel has been used (via line~ to smooth out the rough edges) to control the volume.

So I can start and stop the sound, control how fast it triggers, where in the sound it starts and how loud it is, all with tactile controls on the keyboard, and I don't have to touch my computer. The only major flaw so far is that the sound won't start when you press a key, as you might expect.

To do this, I'm going to take a send (s) from the key input and send it to the float (f).

Part 6: Triggering with the keys as well...

There's a lot in there, now. It's just starting to get to the point where Pure Data patches get a little difficult to follow. But we should reflect on what's been done here. We've turned a fairly boring sound clip into an instrument we can use to manually control three attributes of sound (the position of playback, a speed we've enforced on it and volume) to make sounds we might not expect to be able to hear from the initial sound.

Again, please excuse some low-quality video, but I think it would be a shame to make this tea-board and not use it to make a little 'teamix'.


I'm exploring some of the sounds it can make here, and not, necessarily attempting to make sounds which are 'commercial', or even musical. But you can see that this is really quite powerful. The important factors here are that every sound I make is repeatable with the same physical actions, every key will always be the same part of the sound.

Next time, I feel, we can probably take this further, notably we haven't changed the speed of playback so far, or tried any effects. There is more we can do with this instrument, but that's for another blog post, I think.

There's a few unfamiliar concepts in this post, and I may not have explained everything very well. If you're confused, feel free to drop me a line at @MarmiteJunction and ask any questions you like. I'm always up for a bit of audio-chatter.

So, until next time, take care, God bless and keep coding.

P.S. As a little extra bonus, here's my second attempt at the 'teamix'


Monday, 12 August 2013

MIDI controllers in Pure Data

Well, it's been ages since I wrote any blogs on Pure Data, and I thought it was time we really got to grips with phyiscal, tactile controllers. For this, we're going to look at a very common way to control music software, MIDI.

MIDI stands for Musical Instrument Digital Interface is a standard for controlling synthesisers and other sound equipment which was invented in the 80's and has been used since with most music technology, in one form or another. Simply put, MIDI is a set of digital signals which are the same coming from any device, and which any synthesizer responds to in the same way. So any MIDI controller can work with any MIDI synth.

Now, MIDI has mostly worked through MIDI cables, but in the last decade or so it's been possible to get USB midi controllers, which use the same system of signals but can be plugged in to a computer, to control music software. Here's an example:

As you an see, it's a keyboard, plugged into a laptop, it's very simple. And now that we have our controller hooked up, it's time to look at the signals we're getting in pure data. Now, different operating systems do this differently, but under the Media menu in Pd, you'll find some midi settings, (in Linux this is either 'default-midi' or 'alsa-midi'. Select this and you'll see a window like this.

Make sure you select a MIDI device as the input device. If you don't see anything here, it might be because you opened Pd before plugging in your midi device, try restarting Pd.

Now, let's see what kind of signals we're getting out of this. First, we're going to try a MIDI object, notein, which, unsurprisingly, takes the signal from a note into your computer. Now, just so we can get a look at it, lets just hook it up with some number boxes.

Simple enough so far, lets see what happens when we press a note on the keyboard.

Incidentally, this is my first attempt at using an animated visual aid.

So, when I press a key, the first number changes depending which key I press. Now, I have explained earlier that midi notes range from 0 to 127 and are one semitone apart. So when I move from a C to an E, the numbers are 4 semitones apart (from 60 to 64).

The second number is what's known as velocity, or how fast the key is pressed. That's a little harder to show with a GIF, so you'll have to take my word for it, or try it yourself. This, too ranges from 0 to 127. And you'll notice that when you take your finger off the key, the velocity is 0, the end of that note.

The third is a little more difficult to explain. It's what's called the midi channel, which is used for when a keyboard or sequencer are sending out notes for more than one instrument, these will be sent on different channels. There are 16 of these. Usually your keyboard will always send signals on channel 1, so for now we're going to ignore this.

Now, besides notes, midi also includes control signals, to get these into Pd we shorten 'control' to 'ctl' and use the object, ctlin.

Now, almost any control which isn't a note will come in via this object. My keyboard has a few rotary controls (otherwise known as knobs), so lets see what happens when we move some of these:

Now, this is simple enough, turning the knob to the right increases the first number from ctlin, turning it to the left reduces this number.

The last number is once again the midi channel, once again we're only using channel 1.

The middle number is very simple, it's which control is the source of the number, there's up to 128 of these (from 0 to 127, sound familiar). And I'll tell you now that there's no real logic to how these are arranged, you just have to move one of the controllers and see which number it is. So the next challenge is to get just the number from one control. Lets try that right hand knob, labelled B4 and on MIDI control number 73.

We're going to use the object called spigot, which has two inlets. If the right hand one is one or higher, whatever goes into the left inlet is passed through, and when the right inlet gets 0, nothing passes through.

We're also going to use an operator, borrowed from the world of mathematics, ==, or double equals. So when the left inlet is equal to it's argument it outputs a 1, for true, and otherwise, it's a 0. So when we connect one to the other...

So, when the control number is 73, the resulting number gets through to the number below it. So that's just the result of that one knob will get to the lowest number, others will not.

Now, we can do the same with our note numbers. So lets replace double equals with more than (>), this follows the same rules. so we can filter just pressing the keys (the 'note on' signal) by filtering it with more than 0.

So this is just a simplified version of midi notes, the number which gets through is just the last key which was pressed.

So, that's about it, getting midi controls into Pure Data as numbers, and as I've said before, any number you can get into pure data can be used to control pretty much anything. So let's try applying it to an earlier pure data post. In Pure Data and Bacon (Part 2), I made this simple synthesiser which uses a random number to make some simple music.

So, I'm just going to build the same chain, only replacing the random number generator with our simple key controller. And I'm going to set the volume (with *~) from that knob.

So, this is a very simple keyboard synthesizer. There are problems with it, firstly the note won't dissipate when you take your finger off the key, you'll have to turn your notes on and off with the midi control. But the important fact here is that you've made it from scratch, and by playing with a physical object (the keyboard) you can make music directly.

This is only to demonstrate how we can use this simple method of getting input to take direct control of just about anything we've done so far in Pure Data. Also, next I'll tell you how to use a keyboard to make boring sounds into interesting sounds with a patch that's similar to the one which saw me looking like this...

Although that's rather a long story. Feel free to get in touch on @MarmiteJunction and ask me about it.

Or for any other reason. So enjoy playing with Pure Data and MIDI, and stay tuned for some audio manipulation.

Wednesday, 26 June 2013

Introducing: The Teabot

Regular readers may notice that I've not written much in my blog recently. Meaning my Pure Data tutorials have dropped off slightly. I've been a little busy with a side-project of mine which has take n a lot of my spare time and thought to produce, and is mostly pointless. Anyway, here's a post telling you all about it, and hopefully I'll manage to explain some programming concepts while I'm at it...

Basically it started with the office teapot, which reflects some basic courtesy in hot beverages at my office. When you make a brew, make one for everyone, and alert folks to the fact that it's there. It's a simple workflow, but there's a few too many variables. I have a few basic issues with it, the teapot readily changes location, people forget (or "forget") to let you know it's there, and there's frankly not enough technology involved. 

This mild daily frustration, and, frankly, the fact that I quite like to play with technology, lead me to produce one of the more useful side-projects in my recent life. The Teabot, the idea was simply this:
  • Read a scale with a computer
  • Show the result on a web page
  • Let people know when the tea's ready to drink
This plan, being quite simple, lead me to explore methods of producing web pages with Ruby (my main programming language) which use much less processing power, memory and hard-drive space than Ruby on Rails (my main web framework). The result I settled on was Sinatra, which does just about nothing as standard except output the result of methods you write over http, the web standard for data transfer.

Then all I had to do was add in the RoR library for embedding ruby to generate files (erb, or embedded ruby) and I could create a front-end to the Teabot that didn't take too much out of the computer. That's exactly what I did, long before I got my hands on some USB readable scales to test it out on. I actually completed a first draft of the application entirely without it. The result looks something like this:

During development (as programmers often do, in the absence of hardware or software they are developing something to integrate with), I used a 'pretend' scale, or mock, which works like this. I know what a scale does, the computer asks it what the weight it's measuring is, and it passes the number back to the computer. This is what's known as a contract, describing how something will work, from the point of view of another application. So as far as my Teabot program's concerned:

  • A request goes to the scale 
  • The scale returns a number
So as long as the mock fulfils the same contract, the Teabot doesn't care whether or not it's a real scale. So I wrote a script that keeps asking me to type a number in, and the Teabot responds to that number in the same way (by saving the number to a file, which is read in various places in the application).

The next thing I had to think about is use cases which is, simply put, the ways in which a program will be used, you can think of these as the success conditions, when you can perform all your use cases the application is finished. Okay, this is a part-truth, but it's usually the right way to go about it. The Teabot is a very simple application, so I can think of around 4 simple use cases (using the standard software personalities, Alice and Bob):
  1. Alice wonders if there is tea, she opens the teabot page to see how much is in the pot, and how long it's been there.
  2. Bob makes a pot of tea, when it's brewed, Alice wants to know about it without constantly checking the page.
  3.  Alice makes a pot of tea, she would like Bob, and other co-workers (lets call them Charles and Deirdre), to know she made it, and what type of tea it is (she made Earl Grey this time).
  4. There are two teapots (used depending on how many people are in the office that day), if the teapot says full, it should mean the pot is full, whichever is being used. 
You can easily expand on these, for instance, a new teapot could be bought for formal occasions, a new 
co-worker could be added to the list, but these are essentially what should be possible. 

Use case one is simple, you can see the result in the screenshot above, users can't see the scale reading and refill-detection algorithm I created with my mocks, but they can see the level indicator in the teapot, and the time since the last refill was detected. 

Use case two means it has to provide users with similar information but in real-time. Now this presents a problem with a basic web interface. HTTP (protocol used to bring websites to your computer, there's loads to read about it online, if you wat to) works like this: Your computer sends a request, asking another computer (identified by a URL) for a particular page, the page is sent back to your browser which then displays it. Most of the time, you have to take some action to make the request, either typing in the address of a site and page, or clicking a link

To fix this, I've introduced polling, in which the Teabot main page automatically sends a request every 10 seconds, the Teabot app then sends back a response containing information about the teapot's current level and whether the other information on the page changes. 

But wait a second, all these people (Alice, Bob, Charles, Deirdre and perhaps someone beginning with E) have the Teabot open, and every ten seconds they're all sending a request, and only a small amount of the information on the page has changed (the headers, links, and footer are the same as well as the teapot image), so why should we re-load all of these?

Actually, the teapot doesn't reload everything every ten seconds, the polling request only returns the working data (who made the current pot, how full it is (in percent), what tea it is, when it was last made, and a few other odds and ends). This is then read (as JSON) and used to update relevant parts of the page are updated. 

There's an opportunity here for some stone soup, I could go in to the story of this term, but instead I could tell you what I mean by it. Stone soup refers to something which doesn't actually serve the purpose of the application, but which intrigues people and makes it seem interesting. In turn the interest generated makes it easier, politically or financially, to continue making it into a better application. 

The stone soup in the Teabot takes the form of an animated teapot! It's actually fairly simple, the outside of the teapot is an image with a transparent space in the centre of it (the outside of this image is the same colour as the background), there's a white space behind it, and a darker brown block between the two which changes it's size to indicate the level of the tea. Using the jQuery 'animate' method the tea moves up and down when the amount of tea in the pot on the scale changes. 

So far, everyone who's seen it working has been fascinated to see this happen, and this has helped me to discuss the future direction of the Teabot with my co-workers, and helped me to spend a little time at work on the Teabot. The little bit of interest generated in it allowed me a little extra resources to make it better, stone soup!

One of the pieces of data returned every ten seconds is whether or not to notify users that tea's ready. This gave me the opportunity to explore the HTML5 audio tag. I'm not going in to detail here, but 5 minutes after a new pot is detected, teabot plays a sample of my own dulcet tones declaring "There's tea!". 

This sounds like stone soup, but it's very directly meeting the conditions for our second use case. When the tea's had time to brew, it only takes one computer open and audible in each room of our office and everyone knows it's ready. In the second day of testing this in my office, there's an almost Pavlovian response, within a minute of this sound the brew-wanting masses descend on the teapot. Usually, a conversation ensues. 

Use cases 3 and 4 are fairly simple, there's a form to add pourers and teas, and a simple page called the "Teapot Station Interface" where, most of the time, users can simply click their name and/or the name of the tea, and change which one's currently in use.

Hidden under the Show List Manager link, there's a simple way to add to these lists.

You'll also notice a list of teapots there, which hints at the fourth use-case. You'll see at the top the button 'Calibrate Scale', this leads to a simple Wizard (multi-step form) which gathers three pieces of data about a teapot...

  • How heavy it is with nothing in
  • How heavy it is when it's got one cup of water in
  • How heavy it is when it's completely full
You can then give it a name, and it' on the list. This allows us to find the percentage of the teapot that's currently full of tea, and also, you guessed it, about how many cupfuls are left. 

That's pretty much what it does, and hopefully I've explained a bit about how I go about making web applications. I've not gone into much detail here, but there is one thing I had HUGE problems with that I've not talked about here. 

I could find nothing at all online which told me how to go about reading data from USB (from the scale) and how to go about interpreting this in ruby. So, mark my words, there will be a post giving you a step-by-step rundown of how I went about making the teabot happen. 

Oh, very last thing, here's what it actually looks like, in development at my flat, and at the office.

Oh, and the scale with my prototype hardware branding...

Also, if you're au fait with github, you can go there and take a look at the Code for the Teabot there. And as ever, I'm always up for discussing my fun coding, so feel free to get in touch on twitter (@MarmiteJunction) and have a chat, ask any questions, look into how to get your own teabot, whatever you fancy. Or just leave me a comment here.