Demonstration of Use of Radiant Enterprise's Commonsense CNX Controller from Macromedia's Director

Stephen Wilson, Professor, Conceptual Information Arts Program, SFSU

The CommonSense interface box allows creation of events that read sensors and control devices.  Unfortunately the company that made this device is out of business and no more can be bought.  The box contained several interface options for the Macintosh including the following:
4 Analog Inputs,  8 digital input/output ports, 4 Relay outputs, 1 analog output, a timer, and built in macros
Since the device is no longer supported, it is not entirely compatible with current hardware and software.  Originally it was controlled from HyperCard which is also not supported.  Nonetheless with proper care, it can still be used to great advantage.  I explain the constraints below.  Care must be taken in the electronics of hooking up sensors and devices or the box and computer can be damaged.  We can't get any more!!!

Link to Wilson sample CNX director movie  (binhex,44K)      Link to Cnx XCMD's (binhex 48K)

1. Hardware compatibility and constraints: LocalTalk:  The device connected to the Macintosh via LocalTalk interface boxes.  Localtalk used to be the method of connecting Macintoshes with each other and printers before Ethernet.  It requires a special adaptor box and Operating System protocols.  Apple stopped supporting all of this with OS 8.1. and PowerMacs.  The CNX will not work fully with contemporary PowerMacs. I have found the following compatibility constraints:

Quadras with System 7.5.5.  - works fully ( true with earlier hardware and software)
Power Mac 8500 with System 8.1  -  the analog inputs work and maybe digital i/o but nothing else
G3's with system 8.1 or 9 -  ?? not tested.  need USB to Serial Converter.  Not sure about OS.
2.  Local Talk Connection:  The lab provides LocalTalk boxes.  Both the computer and the device need one.  The computer's end must be connected to the printer serial port.  The appletalk control panel should be set for appletalk connection via printer port.  The chooser must be activated to turn on appletalk.  The two boxes connect with telephone wire.  Each one needs a special terminator (a small resistor plugged into one of the two telephone jacks.)

3 Electronic connections:  The CNX box provides two screw terminal strips for connecting external sensors and devices.  The map is provided in the manual.    Extreme care must be used in connecting electronics to the controller. Connecting the CNX to the wrong polarities or levels of current will damage it.   When in doubt, DON'T DO IT.  ASK.  More information is provided later in this guide.

4. Software drivers - XCMD:  Director cannot communicate with localTalk and the CNX without special software drivers.  The box comes with a set of Hypercard XCMDs (X-commands). Luckily  Director was built in with the ability to use XCMDs, but they must be specially loaded by your movie.  You must place the XCMD resource where Director can find them.

In Director these supplementary pieces of software are called X-tras, Xobjects, or XCMDs (X-commands).  These are called an "Xlibrary" in Director.   The special software must be placed in the X-tras folder near the Director application or in the same folder as the Director movies you create. My samples assume they are in the same folder as your movie.  Make sure to put them in or nothing will work..  You can get the file from the lab.  You must install it on the computer you are working with or no acccess to the interface box will be possible.

5  Open Xlib:  In your Director movie you must open the Xlibrary before you use it.  Typically this script is placed in the StartMovie handler.  The  example below shows the script.  Note the name in the script must exactly match the name of the XCMD file name.  When the movie is over, it is customary to close the X-library in the StopMovie handler.  Typing "showXlib" in the message window will list all the Xtras Director knows about.  CNX XCMD's should show up if it has been successfully loaded. Also the Xlibrary needs to be in the right folder or the openXlib command won't work.

On StartMovie
 -- "OpenXLib" is needed for the XCMD
 -- The whole pathName is needed if the XCMD file is not in
 --  the same folder as the movie.
--  actual loading is in routine loadXlib
--  the findCnx routine intializes the box address
-- (you could substitute other routines for other itnerface boxes)
--open adbio -- (this would be the active one if you were using adbio box - see adbio sample for details)
end openMovie

on StopMovie
   global cnxpath
  closeXlib cnxpath
--- close adbio -- you would switch to this routine if you wre using adbio box
end StopMovie

on loadcnxXlib
    global theZone, nodeName, theNode,cnxpath
    -- the moviepath is a function that will find address on any computer
      set cnxpath=the moviepath&"commonsense.xcmd"
     openXlib cnxpath
  end loadXlib

on findCnx
  -- assumes only simple connection no extended appletalk
  -- default is *
  -- each box has its own address that is dynamically configured when you start up

  set theZone = "*"

  -- assumes only one device
  -- comes back with every device hooked up
  -- otherwise would need to pick from list

  set nodeName =  CNXLIst("*")

-- CNXAddress function will get the address
-- you will need the address in every routine that calls the box
   set theNode =  CNXAddress(TheZone,nodeName)
   if TheNode = "Can't find CNX node" then
     put TheNode into field "zone"
     if TheNode = "Many CNX nodes with this name" then
        put TheNode into field "zone"
        put theNode into field "zone"
    end if
  end if


6  Find the CNX address:  LocalTalk dynamically sets addresses of devices each time it is powered up.  All the xcmds need that address to work.  The XCMDs provide some special functions to determine the address.  A variable arbitraily called theZone is set to "*".  This is the default when only one appletalk zone is involved.  The function CNXLIst("*")  returns all the nodes that are in any given zone.  In our situation there will only be one,  The function CNXAddress(TheZone,nodeName) returns the actual CNX address all the routines will need.  The varibale the Node is set = to what the function returns.  It is also put into a field called "zone".  Be sure the CNX box is connected to the computer when it it powered up so it will determine its address correctly.

7  Read the analog inputs:  The 4 analog inputs read the voltage at their terminals.  You can change the voltage by using switches or any component that changes it resistance (such as a photocell.)  The XCMD   CNXData (theNode,"AtoD") will put a comma separated list of the 4 analog readings.  The variable theNode is the address determined in initialization.  They will assume values from 0 to 255.   The one function CNXData (address,kindofdata) is used to get all the various pieces of data from the CNX box.  The "AtoD" tells it to get the Analog to Digital information.  The XCMDs are very finicky so key parts of the your syntax must match the samples exactly.

on mouseUp
  global  theNode, ana, a1, a2, a3, a4
  set ana =  CNXData (theNode,"AtoD")
  put  ana into field "report"
  set a1 = item 1 of ana
 ---   returns a list such as 255,0,0,0

8  Set up to use the analog input values in a movie:   You could use one shot commands such as mouseclicks to get the values or you can set up to have the movie constantly read the values so they can be used at any time.  The sample above shows the one shot way. .  Remember you will need to extract the reading of each sensor from the comma list of four. The following sample shows a way to have Director constantly update the values by using the idle message.  Director constantly sends idle messages. The handler checks whether a flag variable called analogflag is set to 1.  If it = 1 it sends out to the routine arbitraily called readcnxAnalog.   I put the flag in just to have a way to turn off the updating. Separating the analog reading routine means that a different routine could be substituted if you were using a different interface box.  The routine gets the list of 4 values and extracts the value of each one to set global variables a1,a2,a3,a4.  These can then be used any where in the movie.

Simiulator:  If no interface box is available you can still design the movie by using simulators.  In the example, there are four text boxes representing eacy of the analog input values.  You type any value from 0-255 into each value.  If you switch the readAnalog to readSimulator routine then the global values a1,a2,a3,a4 follow the simulator rather than the interface box. You could do similar things with the digital input values.

on idle
  global analogflag
  if analogflag = 1 then
    --readSimulator   --- use this if not really attached
    --readadbioAnalog  -- use this if using adbio box -- deactivate the cnxanalog
  end if
end idle

On readcnxAnalog
  -- assumes you have gotten the address via initialization
  -- and put it into variable theNode
  -- extracts each value and puts it into variables a1,a2,a3,a4
  -- that can be used anywhere in the Director movie
  global theNode, ana
  global a1,a2.a3.a4
  set ana =  CNXData (theNode,"AtoD")
  put  ana into field "report"
  set a1 = item 1 of ana
  set a2 = item 2 of ana
  set a3 = item 3 of ana
  set a4 = item 4 of ana
end readcnxAnalog

on readSimulator
global a1,a2,a3,a4
 set a1 = field "a1sim"
  set a2 = field "a2sim"
  set a3 = field "a3sim"
  set a4 =field "a4sim"
end readSimulator

8  Set up to read and use the digital input values in a movie:  The same function CNXData (theNode,"DioPorts") will return the value of the digital I/O ports if the function is changed to "DioPorts".  It returns one number with a value from 0-255 that indicates the values of all the ports.   The tricky part here is that you must understand the translation from decimal to binary.  The binary pattern is the indication.  Consult any resource on binary math to refresh your memory about the patterns.  The following examples clarify.
Decimal Binary Meaning
0 00000000 all ports low
255 11111111 all ports high
7 00000111 ports 1,2,3 high; all others low
16 00010000 port 5 high; all others low
65 01000001 port 7 and port 1 high; all others low

Here is a director routine to convert a input value into a comma separted list of 1's and 0's to indicate which ports are high and low.  It assumes that you have read in the port values using the CNX command.  It then creates a director list of the high and low values of each digital port.  **Note for convenience it reverses the usual binary pattern - the lowest port 1 is the first number not the last.  Thus, if the value returned was 15 (binary 00001111)  the routine would create a list dlist that looked like this:  [1, 1, 1, 1, 0, 0, 0, 0]. This would mean that ports 1-4 had positive voltages.   It is very easy in Director to retrieve each of the values in a list using the getAt(dlist,2) command.  the example means get item 2 in the list called dlist.  You could arrange your scripts to set each of these values to a global variable and they would be avaible everywhere in the movie.

The routine uses the method of subtracting decreasing powers of 2.  It tries to subtract 128 (2 to the 7th power).  If it can it knows that binary position 8 is a 1 and then subtracts it and tries with the remainder - eg subtracting 64 (2 to the 6th power - binary position 7).  The binary position numbers don't match the powers because 0 is a valid binary number.)

on converttolist
  global digval, dlist,d1,d2,d3,d4,d5,d6,d7,d8, theNode
 set digval =  CNXData (theNode,"DioPorts")
  set digvaltemp = digval
  set dlist = [0,0,0,0,0,0,0,0]

--- test each level of binary, subtract if present
  repeat with n = 8 down to 1

    set t  = digvaltemp - power(2,n-1)
    if t < 0 then
      setAt (dlist,n,0)
      set digvaltemp =  t
      setAt (dlist,n,1)
    end if
  end repeat
  -- set global variables
  set d1 = getAt (dlist,1)
  set d2 = getAt (dlist,2)
  set d3 = getAt (dlist,3)
  set d4 = getAt (dlist,4)
  set d5 = getAt (dlist,5)
  set d6 = getAt (dlist,6)
  set d7 = getAt (dlist,7)
  set d8 = getAt (dlist,8)

Digtial Ports are electronically very sensitive.  The can't handle anything more than 25 miliamps so be very careful about connections.

9  Set up to control the relay outputs in a movie:  The CNX has 4 relay outputs.  These are electronic switches that can turn DC, AC, and speaker lines on and off.  The XCMDs provide a command called ControlCNX.  For example the command line  ControlCNX "0,186","Relay",1,"On" would turn relay 1 on.  The similar command ControlCNX "0,186","Relay",1,"Off" woud turn it off.  Note the syntax.  For some reason Director cannot use a variable the the address such as theNode used in other examples.  You must actually substitute the address in quotes.  In this example the addres was "0,186".  You can get the address because our initialization rotuine findCNX places it in a field called "zone".   Note the syntax must follow exactly with quotes, etc in the right places.  It took quite a while to figure out this syntax. Here is an example of a script that would turn relay 4 on when entered and turn it off when leaving.

on mouseEnter
  ControlCNX "0,186","Relay",4,"On"

on mouseLeave
  ControlCNX "0,186","Relay",4,"Off"

The relays are medium duty and can handle even 110AC loads up to 5 amperes.  Also the relays have 2 outputs.  One is normally open (NO) which means it is an open circuit until the relay is turned on.  The other output is normally closed (NC) which means it is a complete closed circuit until the relay is turned on at which time if becomes open.

10  Set up to control the digital outputs in a movie:  The same ports that function as digital inputs and also funciton as digital outputs. You again must be very careful about your electornic connections.  The ControlCNX command can control each port separately or all of them together with a single number representing the binary pattern of the 8 ports.  The example shows the control of one port.  Note the syntax must be exact as explained in item 9.  the term "OnePort" indicates that one port is to be controlled.  It is followed by the digital port number and the level.  Level must be either "High" or "Low".  The example shows port 2 being set to high.

On MouseUp
  ControlCNX "0,186","OnePort",2,"High"
You could also output one value to represent all the ports using the decimal number to represent a binary pattern.  For example 15 represents 0001111.  It would turn on ports 1,2,3,4 and off ports 5,6,7,8.  It is indicated by the term
on mouseUp
  ControlCNX "0,186","AllDioPorts",15
Here are some example binary equivalents and their results on the channels.
4 = 00000100 = channel 3 high, all others low        15 = 00001111 = all channels high
10=00001010 = channel 4/2 high, others low           9  = 00001001 = channel 4/1 high, others low
11 An example of Using Analog Inputs
This example shows how colored balls on the screen could respond in real time to changing light levels out in the world.  The physical setup requires the CNX  nterface box to be connected to 2 inexpensive photocells.  The photocells are electronic devices that read the light shining on them and change their electrical resistance.  The CNX  box is electronically built to report the levels of voltage at its inputs which are affected by the changing resistance. With appropriate physical arrangements of lights and sensors, the photocell could read movement of hands or persons.

This example assumes the basic CNX  XCMDs have been loaded   It also assumes that you have created the on Idle handler and readAnalog routine that constantly reads the values  These routines are placed in the movie script so they are constantly active and available to routines throughout your Director movie.  The  routine puts the values of sensor channel 1 into a global variable I arbitraily named a1 and the values of sensor channel 2 into global variable called a2

The example script is put in each of the frame scripts of every frame in the relevant section of the movie.  a1 and a2 are constantly updated to reflect light levels by the constantUpdate routine.  This routine sets the vertical level of the red ball (sprite 3) to correspond to the light level of sensor 1 by using the line set the locv of sprite 3 = a1+50. It sets the vertical level of the blue ball (sprite 4) to correspond to the light level of sensor 2 by using the line set the locv of sprite 4 = a1+50.   The +50 is introduced so that even when there is 0 light level the ball will only go up to the beginning of the black line which was arbitraily set at vertical position 50.  The next lines of the script illustrate how sound levels could also be mapped to light levels.  For example the line set the volume of sound 3 = a1 will make the volume of sound 3 change with light levels at sensor 1. 

The if statements using the soundbusy(3) and soundbusy(4) are necessary to make Director keep repeating the sounds when they are done.  It assumes you have created a sound file called "redsound.aiff" and "bluesound.aiff" to be assoicated with the movement of the balls and that you have chosen to play them in sound channels 3 and 4.  See the tutorials elsewhere on this site if you need background in Lingo.

on exitframe 
  global a1,a2
  set the locv of sprite 3 = a1+50 
  set the locv of sprite 4  = a2+50 
  set the volume of sound 3 = a1 
  set the volume of sound 4 = a2 
  put a1 into member "a1indicator" 
  put a2 into member "a2indicator" 

  if soundbusy(3) = false then 
    soundplay file "redsound.aiff" 
  end if 

  if soundbusy(4) = false then 
    soundplay file "bluesound.aiff" 
  end if 


(**note this not active example because of hardware)
If your light levels did not move the full range between 0 and 255 you would need to build in a conversion rotuine to covert the sensor values a1 and a2 into more relevant screen location values- for example, if the sensors only returned values from 40 to 160 but you wanted to move more than location pixels 40 to 160.  This line would accomplish the expansion of the 120 sensor value change range to 480 screen pixel range. Each a1 value would be multiplied by the ratio of the full screen range to the sensor possible range.  In this example, a sensor reading of 100 would be multibplied by 4 and place the ball at screen location 400 instead of the 100 position if the sensor value would be used directly.

set newredloc = 480/(160-40) * a1


12  Example 2:  Turning virtual and physical lights on and off
In this example, moving a mouse into each of the images of a light bulbs makes the screen image of that light appear to go on.  It also turns on the physical relay controlling a real light controlled through the CNX interface box.  Moving a mouse out of the light bulb image on the screen appears to turn off the screen light and the physical light by turning off the relay. 

To use this script, one must have loaded the xcmd and configured the interface box for digital output as described in items 1,2, and 3 above.  There are 2 cast members - one showing a light off (called member "lightoff") and the other showing a light on (called member "lighton").  There are 4 sprites - each controlling a different light.  There are sprite behavior scripts attached to each of them. 

When the mouse enters the sprite, a mouseEnter script changes the cast member to member "lighton" - giving the appearance of illumination.  It also beeps and sends the command to turn on the CNX relay.  When the mouse leaves the sprite a mouseLeave script changes the cast member to member "lightoff" - giving the appearance of turning off.  It also sends the command to turn off the CNX relay.  (The Script is slightly different for each sprite - the 3rd parameter for the relay CNX command changes to refer to channel 2,3,or 4 as is appropriate.

on mouseEnter me
  set the member of sprite the spriteNum of me = 
member "lighton"  (really on 1 continuous line) 
   ControlCNX "0,186","Relay",1,"On"
end mouseEnter

on mouseLeave me
  set the member of sprite the spriteNum of me = member "lightoff"
   ControlCNX "0,186","Relay",1,"Off"
end mouseLeave

(**note this not active example because of hardware)


More information about the course exploring the artisitic use of these capabilities is available at the description of the Trio of Experimental Technologies Course Description.
Stephen Wilson, Professor, Art, Conceptual/Information Arts Program, San Francisco State University
Information about the Conceptual/Information Arts program    (415) 338-2291   swilson@sfsu.eduWilson web page
Copyright, Stephen Wilson, 1999 - You are free to use the text as long as you attribute source and do not use them commercially.