Phidgets + Quartz Composer

We’re going to use Phidgets for a university project pretty soon, so I tried to come up with a way to control Quartz Composer with the Phidget sensors. Hiroaki has done Accelerometer and RFID custom patches that you can find here, but I want to use the Interface Kit 8/8/8 and be able to use all the different sensors.

I’m not smart enough to program my own patches for QC, but I was able to build a Cocoa application that sends the data from the sensors to the QC composition. I got a little help from the Phidget Interface Kit -sample code that you can download here and from the instructions found from the Phidgets forum. The code on the forum post didn’t work for me so here’s a small tutorial that shows you how build a Cocoa app that will control your Quartz Composer composition with Phidgets sensors.

What do you need?

– A computer running Mac OSX 10.4 with the developer tools installed
– Phidgets Interface Kit 8/8/8 + some sensors
– Download and install the Mac OSX Framework 21 from Phidgets website. This will also include the source code that you need for this tutorial.


OK. Let’s start

1)
Open the CocoaIFKit Xcode project from the /Examples/Source Code/CocoaIFKit folder.

2)
First we need to modify the project so that we can import and use a Quartz Composer Composition. These next steps are explained with more detail in the Quartz Composer programming guide by Apple and I recommend that you try the tutorials first, but I’ll go through the important stuff quickly.

– First, choose Project > Add to Project.
– Navigate to System/Library/Frameworks/Quartz.framework and add it to the project.
– Drag the Quartz.Framework to your Frameworks folder in the Groups & Files list
– Double click the MainMenu.nib file and Interface Builder launches.
– If you haven’t done this before, you have to install the Quart Composer palette to Interface Builder. Choose Tools > Palettes > Palette Preferences and click add.
– Navigate to /Developer/Extras/Palettes/ and add QuartzComposer.palette.
– Now your palette window should show the Quartz Composer palette. The blue thing is QCView and the green thing is QCPatchController.

– Drag the QCPatchController from the Palette window to the Instances tab in the MainMenu.nib window
– Go to the Cocoa Windows tab in the Palette window and drag a window to the Instances tab also. A new window appears.
– Your MainMenu.nib window should look something like this

– Select the new window and go to Tools > Show Inspector. In the Attributes section, make sure that the “Visible at launch time” is checked for the new window
– Now drag a QCView from the palette to the new window and resize the QCView the way you like it.
– Select the QCView and then open the Bindings pane of the Inspector window. Click the small triangle where it says patch.
– Choose QCPatchController from the “Bind to” pop-up menu. Enter patch in the Controller Key text field.

3)
OK. Now we need a QC Composition to use with our app. I won’t go to any details about using Quartz Composer. There’s plenty of info for that available and this tutorial is already becoming too long.

What you need to do is to create any kind of composition that has a published input with the name of sensorZero. I just used an Image With String connected to a Sprite and published the String input with the name sensorZero. Save the .qtz file to the CocoaIFKit folder. I used the name phidgets.qtz.

Back in Xcode, drag phidgets.qtz to the Resources folder in the Groups & Files list. In Interface Builder, select the QCPatchCotroller from the MainMenu.nib window and select the Attributes pane of the Inspector and click “Load from Composition File…” Navigate to your phidgets.qtz file. Choose File > Test Interface. You should see your composition in the window. The sensors won’t work in the testing mode.

4)
Now the application shows our composition, but we want to change the published value with the sensors. Read on and I’ll tell you how to do just that.

– Select the blue PhidgetInterfaceKitController from the instances tab. Then select the classes tab.
– Choose Classes > Add Outlet to PhidgetInterfaceKitController.
– Name the new outlet theController
– In the Instances tab, ctrl-click and drag from the PhidgetInterfaceKitController to the QCPatchController

– Choose Connect to connect the outlet.
– Save and go to Xcode again.

5)
Now we need to change the code so that the data goes from the sensors to the QC composition

– Double-click the PhidgetInterfaceKitController.h file.
– Add this to the list of outlets:

IBOutlet id theController;

– Close the window and double-click the Phi
dgetInterfaceKitController.m file.
– Find the SensorChange section and add this code there:

// sensors to Quartz Composer
if(Index==0){
[theController setValue:[NSNumber numberWithInt:(int)Value] forKeyPath:@”patch.sensorZero.value”];
}else if(Index==1){
[theController setValue:[NSNumber numberWithInt:(int)Value] forKeyPath:@”patch.sensorOne.value”];
}else if(Index==2){
[theController setValue:[NSNumber numberWithInt:(int)Value] forKeyPath:@”patch.sensorTwo.value”];
}else if(Index==3){
[theController setValue:[NSNumber numberWithInt:(int)Value] forKeyPath:@”patch.sensorThree.value”];
}else if(Index==4){
[theController setValue:[NSNumber numberWithInt:(int)Value] forKeyPath:@”patch.sensorFour.value”];
}else if(Index==5){
[theController setValue:[NSNumber numberWithInt:(int)Value] forKeyPath:@”patch.sensorFive.value”];
}else if(Index==6){
[theController setValue:[NSNumber numberWithInt:(int)Value] forKeyPath:@”patch.sensorSix.value”];
}else if(Index==7){
[theController setValue:[NSNumber numberWithInt:(int)Value] forKeyPath:@”patch.sensorSeven.value”];
}

– We only published the sensorZero from QC, but this code works with all the 8 analog inputs in the Interface Kit (Index numbers 0-7). So you can publish more values from QC. Just name them correctly: sensorZero, sensorOne, sensorTwo…
Note! I’m a total amateur when it comes to Cocoa, so this code might not be the best way to do this but it works.

6)
That’s it. Save. Then choose Build and Go to see if it works.

If you want to change the QC composition, you need to reload the composition to the QCPatchController in Interface Builder and rebuild the app.

Pheew! This is the first tutorial I’ve ever written. I hope it’s useful to someone.

Tags: , ,


6 Responses to “Phidgets + Quartz Composer”

  1. yourbartender says:

    mahtavaa upeaa hienoa. Minäkin melkein pääsin yhtä pitkälle! Mutta tämä auttaa maailman kodittomia ja muitakin!

  2. Stormbuster says:

    Hi Waxtastic,

    Sorry to hear my code sample did not work for you. After my initial success I put the project on hold for a bit (I discovered the world of Arduino and cocoa is still not really my cup of tea).

    My intent is however still to finish what I started; a drag and drop Quartz Composer player application that works with the Phidget interfacekit. Your post has motivated me again to get this one nailed so I’ll probably spend some time over the weekend trying to fix it. I’ll post the source on the Phidget forum for anyone interested to give it go.

    Thanks for sharing this!

    Cheers,

    Robert

  3. yourbartender says:

    some further comments after testing it out: you don’t really add the Quartz.framework to targets, do you? just add existing framework, and put it to the correct place like you described.

    second note is about the values: the sensors give values from 0 to 999 right? and in quartz composer a lot of things happen between 0 and 1… so you’ll have to do some math operations in QC…

    just my 2 c.

  4. yourbartender says:

    ok I have to admit I was wrong and then I just don’t know what to do 🙂 – yes there is a text Add as Target. But there is also a possibility: Add New Target…you want to add a framework and not a target.

    Dealing with turning sensor readings to correct readings for QC seems more tricky. with cocoa interface you can define the range within what the sliders should work (between 0.0 and 1.0 for example) but how about here? adding math operator, publishing its input port and dividing it with 1000 doesn’t seem to do the trick…or let me refresh my stuff…

  5. Waxtastic says:

    Yeah, the part about adding the framework was a little bit confusing. I fixed it. You use the add to project not the add a new target. I recommend for everyone to check out the Apple tutorials where this stuff is explained with more detail.

    I recommend using math operators for the published inputs. Publish the initial values as sensorZero, sensorOne etc.

    You can get values from 0 to 1 by dividing with 1000

    If you want values from -1 to 1 subtract by 500 then divide by 500.

    But everytime you change the QC composition you have to save it, reload it in Interface Builder and then rebuild the app in Xcode.

  6. ian says:

    Hi you can avoid reloading the patch in IB by programmatically loading the composition in your init or awakeFromNIB method. This saves time if you are tweaking your QC composition. You just need to recompile.

    //load QC
    NSString* path = [[NSBundle mainBundle] pathForResource:@”MyQCPatch” ofType:@”qtz”];

    //We assume the “patch” parameter of the “QCView” QCView instance has been bound to the
    //”patch” property of the QCPatchController in Interface Builder

    if([qcView loadCompositionFromFile:path]) {

    //The composition has been successfully replaced on the QCPatchController and its QCView
    //and the bindings have been updated

    } else {
    NSLog(@”Could not load QC resource.”);
    }

    Regards,

    Ian

Leave a Reply