Cassius Version 2.0

Due to the success of the Cassius project it has undergone a second development iteration in order to improve stability and usability. After exhibiting Cassius 1.0 in Milan (Salone Satelite), London (Metropolitan Works, Autonomatic), Graz (Assembly) and Linz(ARS Electronica) a number of possibilities for improvement emerged.

  • The first change was to create a more stable electronics. The first version of the arduino based sensor board was made with a bread board and resembled a birds nest. The second generation was soldered on two “europlatinen” and still resembled a birds nest. The Cassius 2.0 board utilised a printed board layed out in Eagle. SMD components were soldered to the board using soldering paste and a mini electric pizza oven.
  • The software was improved to reduce the traffic over the serial port to increase the responsiveness of the visualisation software.
  • The sensors were improved to increase their lifespan.

How did we make the Cassius Punching Bag

The Fluidforms Punching Bag contains a matrix of 9x7 force sensors that measure the force exerted by a blow to the bag. The sensors are plugged into a multiplexed Arduino board called Fluid64. The sensor values are sent over USB to a computer using the MIDI protocol. The computer is runs a OpenFrameworks sketch that receives the MIDI packets and renders the lamp shade. The form of the lamp as a subdivision surface whos control mesh is deformed based on the values of the sensors.

Creating the Sensors

Cassius Sensors Initially we planned to use Strain Gauges from HMB. Although these are great sensors they require an amplifier to get a change in resistance great enough to be useful. Because these sensors were going to be applied to a soft surface and needed to withstand being pounded and bent for a the duration of the 5 day Salone Satellite, they needed to be very durable an flexible. For this reason we decided to make our own sensors. The sensors are now in the Ars Electronica Center and need to survive months on end.

Step 1

Solder the wire to the mesh Take a piece of cable and two pieces of wire mesh. This is available from hardware stores and is used on doors and windows to keep out mosquitoes. Copper is the ideal material since you can solder it but by threading the wire through the holes, looping it back and soldering it to itself you can get away using an aluminium or stainless steal mesh that is likely to be easier to find.

Step 3

Glue the edges To prevent a wire from poking through the foam and short circuiting the sensor, we squirt glue with a glue gun around the edges of the mesh. After the glue cools and before it dries, press it around the edges so that all wire is covered.

Step 3

Roll out the foam The conductive foam that we found to provide the best change in resistance was quite brittle before being squashed. To combat this take any cylindrical object you can find around the office and roll the foam flat. In our case this was bottle of Mount Riley Winemakers Selection Sauvignon Blanc but a Mount Riley Pinot Noir will also do the trick. This foam however proved to be unsuitable to prolonged use. It worked great for the first few days but soon became squashed to a point that it provided very little change in resistance. The foam we now use is ?????? from RS Electronics.

Step 4

Insert the foam Place the piece of conductive foam between the two pieces of wire mesh. Make sure the the two meshes and wires are completely "isolated" by the foam.

Step 5

Surround it all with plastic Now place two pieces of plastic on the outside of the sensor.

Step 6

Tape it all up Tape the whole thing up and place a Fluidforms sticker on it. A Formatory sticker will also do if you don't have a Fluidforms one.

Vuala, you now have your very own force sensor. The resistance of each sensor will vary, but we are going to take account of this in software. I took about 5 hours.

Wiring the sensors to the Arduino board

Because Arduino only has six analogue inputs we need to extend this through the use of multiplexers. The multiplexers we use are MC14067BCP. These have 16 channel and enable you to plug 16 sensors into one analogue input. By setting four digital pins you can tell a multiplexer which of the 16 inputs to read (2 x 2 x 2 x 2 = 16). The multiplexer then sends the value of this channel out of its output pin. This becomes the input for an analogue input on the Arduino board. We can plug six multiplexers into the six analogue inputs of Arduino. The same four digital outputs can be used to set each multiplexer. Since we only need 64 inputs the wiring diagram only contains four multiplexers.

The basic process is that we set the control pins to represent channel 0. We then read the value of sensors 0, 16, 32, 48 from the analogue inputs 0,1,2,3 respectively. We then set the control pins to 1 and repeat the process, but this time reading the values of sensor 1, 17, 33, 49. We repeat this process for 0 - 15.

To wire the Multiplexer we connect the inhibit pin (number 15) to earth turning the inhibiter off. Connect the control pin 10 to the digital output 2, control pin 11 to the digital output 3, control pin 14 to the digital output 4 and control pin 13 to the digital output 5. Connect the ground pin (number 12) to ground and the power pin (number 24) to the 5V output on the Arduino board.

You can see how I wired it all together in the wiring diagram.

Programming Arduino

Creative Commons LicenseArduino Multiplexer Code by Fluidforms ~ Stephen Williams is licensed under a Creative Commons Attribution 3.0 Austria License.

The arduino code can be uploaded to the board with the arduino IDE.

The code contains a buffer that prevents values being sent over the serial port if they have not significantly change.

Arduino Code
/* ReadMultiplexedSensorsAndSendMIDI
 * License: http://creativecommons.org/licenses/by/3.0/at/deed.en
 * ------------
 *
 * Reads 4 16 channel Multiplexers and sends the values
 *
 * Created 12 December 2005
 * Changed 19 December 2008
 *
 * http://fluidforms.eu 
 * http://formatory.com
 *
 */
 
#define LEDpin 1
#define CONTROLpin1 2
#define CONTROLpin2 3
#define CONTROLpin3 4
#define CONTROLpin4 5

int lastValues[64];
unsigned long lastCompleteSend = 0;

// Some error chacking would be good here. 
//If the values exceede 128 the will not fit in one byte.
void sendCommand(char command, char sensorID, char value) {
  serialWrite(command);
  serialWrite(sensorID);
  serialWrite(value);
}


void setup() {
  //  set the states of the I/O pins:
  pinMode(LEDpin, OUTPUT);
  pinMode(CONTROLpin1, OUTPUT);
  pinMode(CONTROLpin2, OUTPUT);
  pinMode(CONTROLpin3, OUTPUT);
  pinMode(CONTROLpin4, OUTPUT);
  
  beginSerial(57600);
  int i = 0;
  for(i=0; i<4; i++){
    lastValues[i] = -100;
  }
  
  lastCompleteSend = millis();
}


void loop() {
  boolean sendAll = false;
  if( abs(millis() - lastCompleteSend)  > 5000 ){
    sendAll = true;
  }

  int i;
  int j;
  for (i=0; i <16; i++) {

    // set control pins on the multiplexers
    digitalWrite(CONTROLpin2, (i&15)>>3);//bit4
    digitalWrite(CONTROLpin1, (i&7)>>2);//bit3
    digitalWrite(CONTROLpin3, (i&3)>>1);//bit2
    digitalWrite(CONTROLpin4, (i&1)   );//bit1

    // read the analogue inputs and send the values of the sensors.
    for(j=0; j<4; j++){
      int sensorValue = analogRead(j) / 5;// make the value fit in one byte
      int index = i+16*j;
      // sends a value every second or when it changes significantly
      if( sendAll || abs(lastValues[index] - sensorValue) > 1){
        lastValues[index] = sensorValue;
        sendCommand(0x90, index, sensorValue);
      }
    }
    // if you uncomment this line you can check the control pins 
    // of the multiplexers with your multimeter. You could change this to 
    // turn on when an digital input is set so you can turn it on without 
    // reloading the software. 
    //delay(500); 
    
  }
  if( sendAll ){
    lastCompleteSend = millis();
  }
}

Programming OpenFrameworks

In the OpenFrameworks sketch we will receive the bytes sent by the Arduino and work out which byte is the command, which is the sensor ID and which is the sensor value. Because each sensor will have a slightly different value we will save an array of zero values when we reset the punching bag. This will enable us to take these values away from the actual values in order to get the maximum change in value since the last reset. This equates to measuring the hardest punch on each sensor.

OpenFrameworks Classes