Programming the Fio

The Fio (or Funnel IO) is an Arduino derivative and can be programmed the same way. There are many tutorials on how to do that and I will not give detailed information on this page. If you are not familiar with any Arduino board, I suggest you read this Getting Started page.

You need to upload this code to the Arduino:

  Read 8 analog inputs and 10 digital inputs.

  Send data over serial.  3 bytes for each analog input and 3 bytes the 10
  digital inputs.
  Total: 27 bytes in each loop.

  The format is somewhat inspired by MIDI: in each group of 3 bytes, the first
  byte is a status byte and the two others are data bytes.  The MSBit
  indicates if the byte is status(0) or data(1).  Only the last four bits are
  used in a status byte.  The data bytes start with a one and contain seven
  (MSB) or three (LSB) bits of data.

  The structure is like this:
  | status byte     | 0000xxxx |
  | data byte (MSB) | 1xxxxxxx |
  | data byte (LSB) | 10000xxx |

  For example, if the analog input one reads the value 765 (1011111101), the
  following three bytes will be sent:
  | status byte     | 00000000 |
  | data byte (MSB) | 11011111 |
  | data byte (LSB) | 10000101 |

  For the Sponge version 3.0 (2012 with 10 buttons).
  Martin Marier 2012-03-02

const int butPins[10] = { 2,3,4,5,6,7,8,9,10,11 }; // pins on which the buttons are connected
const int gSelPins[2] = { 12,13 };  // pins connected to g selection pin on accelerometers.
int butVal[10]; // values of buttons
int analVal[8]; // values of analog sensors

void setup() {
  for (int i=0; i < 10; i++){
    pinMode(butPins[i], INPUT);
  for (int i=0; i < 2; i++){
    pinMode(gSelPins[i], OUTPUT);
    digitalWrite(gSelPins[i], LOW);

void loop() {
  int compButVal=0; // compound value of buttons

  // read and print the analog inputs
  for (int i=0; i < 8; i ++){
    analVal[i] = analogRead(i);
    Serial.print((0<<7) + (i), BYTE); // print the analog pin number to serial.
    Serial.print((1<<7) + (analVal[i] >> 3 ), BYTE); // print the 7 MSBits.
    Serial.print((1<<7) + (analVal[i] % 8 ), BYTE); // print the 3 LSBits.

  //read and print the digital inputs
  for (int i=0; i < 10; i ++){
    butVal[i] = digitalRead(butPins[i]);
    compButVal |= (butVal[i] << (9-i));

  Serial.print((0<<7) + (8), BYTE); // print a <8> to
  Serial.print((1<<7) + (compButVal >> 3 ), BYTE); // print the 7 first buttons.
  Serial.print((1<<7) + (compButVal % 8 ), BYTE); // print the 3 last buttons.

/* Max throughtput of xBee modules is 35 kbps.  This means sending all the 27
  bytes should take 6.2 ms.  At 57600 (baud rate of fio), it takes 3.75 ms.
  Here, we wait three extra ms to make sure we do not overflow the xBee
  transfer.  This way, sending the 27 bytes takes 3.75 + 3 = 6.75 ms.

  Maybe this logic is flawed somehow... I am no expert in this matter.  But,
  nevertheless, the serial connection to SuperCollider gets unstable when
  waiting less than 2 ms.  I have not yet tested thoroughly, but so far, a
  wait time of 3 ms works well.



What this code does

There are many comments in there but here is, in a nut shell, what this code does. It makes the Fio read the digital and analog pins and send the values to a serial port. Each continuous sensor has a 10 bit value encoded on 3 bytes:

Byte Values Name Explanation
1 0000xxxx Status Byte This is the sensor number (from 0 to 7).
The status byte 8 (00001000) is for the buttons.
The Status Byte always starts with a 0.
2 1xxxxxxx Data Byte (MSB) Value of the sensor (MSB).
Data Bytes always start with a 1.
3 10000xxx Data Byte (LSB)) Value of the sensor (LSB).

The last status byte (00001000) is reserved for the buttons. The 10 buttons are represented as a 10 bit value, just like the analog sensors.

I then use my Sponge Object in the SuperCollider environment to receive, process and map the sponge’s data to musical parameters.

Leave a Reply

Your email address will not be published. Required fields are marked *