You are here: Home Documentation How-tos Talk to the Make Controller with Ruby
Document Actions

Talk to the Make Controller with Ruby


This How-to is intended for: Desktop Developers

Use the rosc (Ruby-OSC) library to communicate with the Make Controller via Ethernet.

Problem

You'd like to extend your Ruby app into the physical world with the Make Controller, or you just plain like ruby hacking.

 

Solution

This solution only covers communication with the Make Controller over Ethernet, not USB, but is pretty straightforward.  We'll cover:

You may also want to have a look at the rosc documentation at http://hans.fugal.net/src/rosc/docs to get a sense for how the library works.

 

Prerequisites

This how-to assumes:

  • you have Ruby set up on your system and are somewhat familiar with it
  • you can communicate with your Make Controller over Ethernet

 

 

Installation

First we need to install the rosc library, which can be found at http://hans.fugal.net/src/rosc.  Grab the latest archived version - it was 0.1.2 at the time of this writing, so I grabbed rosc-0.1.2.tar.gz.  Unpack it, navigate into the directory, and run the setup script

sudo ruby setup.rb

to install and you're all set.  Have a look at readme.rb in the examples directory for a brief overview and hello world experience.

You should also make sure your Make Controller is connected via Ethernet and that you can see it in mchelper.  This will confirm that the network interface is working, and it will also get you the board's IP address which we'll need for the examples.

 

Blink the LEDs

So, first we'll just blink the LEDs on the Make Controller Kit.  In order to do this, we actually don't even need to set up a UDP server since we're not receiving any messages, just sending them. We're just going to create a socket, and send messages to it to turn the LEDs on and off.  Grab the the appled.rb file here and have a look.  Let's take a look at the important part of the code...

10.times do |i|
  state = i % 2 # alternate between one and zero
  m = OSC::Message.new('/appled/*/state', 'i', state )
  c.send m, 0, Host, Port
  sleep 1
end

Explanation
Most of this is pretty self-explanatory, aside from creating the OSC message.  The Osc::Message.new() method takes for its first argument the address pattern that the message is being sent to. 

Second is the type tag - the letters i, f, s, b correspond to the OSC types int, float, string and blob.  Your type tag should indicate the order and length of the argument data in the message.  In this example we're just sending one int, so our typetag is 'i'.  If we were sending an int and a string, it would look like 'is'

The third argument (which can actually be a number of arguments) is the actual value of the arguments as indicated in the typetag.  If we wanted to send 2 values in our message, it might look like

m = OSC::Message.new('/appled/*/state', 'ii', 1, 678 )

Not too bad.  Really all you need to do is substitute the IP address and port of your board if they're different, but otherwise you can run this by typing

ruby appled.rb

and kick back and watch a little light show on your Make Controller!

 

Read the Analog Inputs

There are 2 strategies for reading values back from the board:

  • Send a request message to the board, and it will send a response back to you
  • Configure the board to constantly monitor its inputs and automatically send a message when they change.  See this how-to for a guide to setting that up.

In the example code we manually send the request messages, but you can omit that part if you've configured autosend on your board.  To deal with the messages coming back from the board, there are basically 2 steps:

  1. Create an Osc::UDPServer that listens for messages.
  2. Register with that server to get notified any time a message comes back that we care about.

Grab the analogin.rb file here, and let's have a look at the relevant code:

s = OSC::UDPServer.new
# bind to '', which means we're listening for messages from any address
s.bind '', MakeControllerPort

s.add_method '/analogin/*/value', 'i' do |msg|
domain, port, host, ip = msg.source
puts "#{msg.address} -> #{msg.args.inspect} from #{host}:#{port}"
end

Explanation
First, we tell the server to listen for messages from any address by passing an empty string to the bind method.  The constant MakeControllerPort should correspond to the port that your Make Controller is configured to send messages on (10000 by default).

Then, we call the server's add_method method to be notified any time a message that looks like /analogin/*/value comes back, with a single int argument.  Notice that the wildcard (*) means the server will match any value in that part of the address string, which is very convenient since we'll be getting messages from analog ins 0-7, and we can use this single method to deal with all of them.  If we wanted, we could match any messages with 3 elements in the address string by registering for /*/*/* instead. 

The 'i' represents the type tag of the messages we want to be notified of - in this case, we're just looking for messages with a single int argument.  You can use the wildcard * in the type tag as well to be notified of messages with any kind of argument, but note that you need to use a wildcard for each of the elements in the type tag.  A single * would match messages with one argument of any type, while ** would match messages with 2 arguments of any type.

 

Further information

That's it!  Of course, you'll want to send other messages to the board, but the concepts for reading and writing will be the same as in the examples above.

To recap, the relevant reference pages are:

Attached files