Chances are your project with Phidgets is going to involve more than one Phidget channel. Luckily, making a program that deals with multiple Phidgets is done in much the same way as making a program that only deals with one.
This video explains the process of using multiple Phidgets in your program:
The Basics
To use more than one Phidget channel in you program, simply repeat the Create, Address, and, Open process for each channel, and remember to Close them all when done.
Addressing Channels
When you are using more than one Phidget channel in your program, you are going to have to specify some addressing parameters to ensure each software channel connects to the right Phidget.
Full descriptions of all the addressing parameters can be found on the Addressing Phidgets page.
Example
For example, to open two Phidgets, the code might be:
#Set up the first channel as normalch=TemperatureSensor()ch.setDeviceSerialNumber(12345)ch.setHubPort(4)ch.setChannel(0)ch.openWaitForAttachment(5000)#For a second channel, simply repeat the process with different addressing informationch1=TemperatureSensor()ch1.setDeviceSerialNumber(12345)ch1.setHubPort(3)ch1.setChannel(0)ch1.openWaitForAttachment(5000)#Do stuff with your Phidgets here...#Remember to close the channels when donech.close()ch1.close()
//Set up the first channel as normalTemperatureSensorch=newTemperatureSensor();ch.setDeviceSerialNumber(12345);ch.setHubPort(4);ch.setChannel(0);ch.open(5000);//For a second channel, simply repeat the process with different addressing informationTemperatureSensorch1=newTemperatureSensor();ch1.setDeviceSerialNumber(12345);ch1.setHubPort(3);ch1.setChannel(0);ch1.open(5000);//Do stuff with your Phidgets here...//Remember to close the channels when donech.close();ch1.close();
//Set up the first channel as normalTemperatureSensorch=newTemperatureSensor();ch.DeviceSerialNumber=12345;ch.HubPort=4;ch.Channel=0;ch.Open(5000);//For a second channel, simply repeat the process with different addressing informationTemperatureSensorch1=newTemperatureSensor();ch1.DeviceSerialNumber=12345;ch1.HubPort=3;ch1.Channel=0;ch1.Open(5000);//Do stuff with your Phidgets here...//Remember to close the channels when donech.Close();ch1.Close();
//Set up the first channel as normalPhidgetTemperatureSensorHandlech;PhidgetTemperatureSensor_create(&ch);Phidget_setDeviceSerialNumber((PhidgetHandle)ch,12345);Phidget_setHubPort((PhidgetHandle)ch,4);Phidget_setChannel((PhidgetHandle)ch,0);Phidget_openWaitForAttachment((PhidgetHandle)ch,5000);//For a second channel, simply repeat the process with different addressing informationPhidgetTemperatureSensorHandlech1;PhidgetTemperatureSensor_create(&ch1);Phidget_setDeviceSerialNumber((PhidgetHandle)ch1,12345);Phidget_setHubPort((PhidgetHandle)ch1,4);Phidget_setChannel((PhidgetHandle)ch1,0);Phidget_openWaitForAttachment((PhidgetHandle)ch1,5000);//Do stuff with your Phidgets here...//Remember to close the channels when donePhidget_close((PhidgetHandle)ch);Phidget_close((PhidgetHandle)ch1);PhidgetTemperatureSensor_delete(&ch);PhidgetTemperatureSensor_delete(&ch1);
Similar Phidgets
If you have a large number of the same Phidget channel and want an easier way to keep track of them all, consider using an array to keep them all together.
#Create the array of Phidget channelsch=[DigitalOutput()foriinrange(0,8)]foriinrange(0,8):#Address, then open the channelsch[i].openWaitForAttachment(5000)#Now you can access each channel by its position in the array ch[0].setState(True)ch[1].setState(False)ch[2].setState(False)ch[3].setState(True)foriinrange(0,8):ch[i].close()
//Create an array for your Phidget channelsDigitalOutput[]ch=newDigitalOutput[8];for(inti=0;i<8;i++){//Create the channelsch[i]=newDigitalOutput();//Address, then open the channelsch[i].open(5000);}//Now you can access each channel by its position in the array ch[0].setState(true);ch[1].setState(false);ch[2].setState(false);ch[3].setState(true);//Close all channels when donefor(inti=0;i<8;i++){ch[i].close();}
//Create an array for your Phidget channelsDigitalOutput[]ch=newDigitalOutput[8];//Open the channelsfor(inti=0;i<8;i++){//Create the channelsch[i]=newDigitalOutput();//Address, then open the channelsch[i].Open(5000);}//Now you can access each channel by its position in the array ch[0].State=true;ch[1].State=false;ch[2].State=false;ch[3].State=true;//Close the channels when donefor(inti=0;i<8;i++){ch[i].Close();}
//Create an array for your Phidget channelsPhidgetDigitalOutputHandlech[8];for(inti=0;i<8;i++){//Create the channelsPhidgetDigitalOutput_create(&ch[i]);//Address, then open the channelsPhidget_openWaitForAttachment((PhidgetHandle)ch[i],5000);}PhidgetDigitalOutput_setState(ch[0],true);PhidgetDigitalOutput_setState(ch[1],false);PhidgetDigitalOutput_setState(ch[2],false);PhidgetDigitalOutput_setState(ch[3],true);//Close the channels when donefor(inti=0;i<8;i++){Phidget_close((PhidgetHandle)ch[i]);}
Distinguishing Events
When using events, you can either create separate events for each device, or handle multiple devices with the same event (or some combination of both). If multiple devices use the same event handler, you can use the addressing properties of the channel to determine which Phidget channel caused the event.
For example, for an Attach Event handler:
In Python, the channel that fired the event can be accessed from the event handler using the self parameter (the first parameter in the list).
#Declare the event handlerdefonAttachHandler(self):#You can access the Phidget that fired the event using the "self" parameterph=selfdeviceSerialNumber=ph.getDeviceSerialNumber()...#Declare your object. Replace "DigitalInput" with the object for your Phidgetch=DigitalInput()...#Assign the handler that will be called when the event occursch.setOnAttachHandler(onAttachHandler)
In Java, you can call getSource() on the event parameter to get the Phidget that caused the event.
//Declare the event listenerpublicstaticDigitalInputAttachListeneronAttach=newDigitalInputAttachListener(){@OverridepublicvoidonAttach(AttachEvente){//You can access the Phidget that fired the event by calling "getSource()"//on the event parameter.//Replace "DigitalInput" with the object for your Phidget.DigitalInputph=(DigitalInput)e.getSource();intdeviceSerialNumber=ph.getDeviceSerialNumber();}};...//Declare your object. Replace "DigitalInput" with the object for your Phidget.DigitalInputch;...//Assign the event listener that will be called when the event occursch.addAttachListener(onAttach);
In C#, you can access the Phidget that fired the event by typecasting the sender parameter to the appropriate Phidget object type.
//Declare the event handlervoidattach(objectsender,Phidget22.Events.AttachEventArgse){//You can access the Phidget that fired the event by typecasting "sender"//to the appropriate Phidget object type.//Replace "DigitalInput" with the object for your Phidget.DigitalInputph=((DigitalInput)sender);intdeviceSerial=ph.DeviceSerialNumber;}...//Declare your object. Replace "DigitalInput" with the object for your Phidget.DigitalInputch;...//Assign the handler that will be called when the event occursch.Attach+=attach;
In C, you can access the Phidget that fired the event using the first parameter of the event handler.
//Declare the event handlerstaticvoidCCONVonAttachHandler(PhidgetHandleph,void*ctx){//You can access the Phidget that fired the event by using the first parameter//of the event handlerintdeviceSerialNumber;Phidget_getDeviceSerialNumber(ph,&deviceSerialNumber);}...//Declare your object. Replace "PhidgetDigitalInputHandle" with the handle for your Phidget object.PhidgetDigitalInputHandlech;...//Assign the handler that will be called when the event occursPhidget_setOnAttachHandler((PhidgetHandle)ch,onAttachHandler,NULL);
Referencing Other Phidgets from Events
When using multiple Phidgets in the same program, you may want to access one Phidget from the within an event caused by another. There are simple ways of doing this for all languages, though the specifics depend on the programming language you are using:
Python is dynamically interpreted, and objects follow a less rigid structure than in other languages. To access another Phidget from an event handler, you can add the second Phidget's handle as an attribute of the Phidget object that will be triggering the event. Then, you can access the second Phidget using the corresponding attribute from the self parameter of the event.
For example, if we wanted to make a Digital Output channel follow the state of a button:
defonStateChangeHandler(self,state):#Be sure the other Phidget you are trying to access is attached before using itif(self.linkedOutput.getAttached()):self.linkedOutput.setState(state)button=DigitalInput()output=DigitalOutput()#Addressing info here#Here we create an attribute of input called "linkedOutput", and assign it the handle for outputbutton.linkedOutput=outputbutton.setOnStateChangeHandler(onStateChangeHandler)#Be sure to open any channels you are using within events before the channels#that cause the events.#This gives them a chance to be attached before the event tries to use them.output.openWaitForAttachment(5000)button.openWaitForAttachment(5000)# The rest of your code here....
In Java, chances are your event handlers are defined in the same class as the Phidget handles. In this case, you can simply reference Phidgets in the event handlers the same way as you would in the rest of your code.
For example, if we wanted to make a Digital Output channel follow the state of a button:
publicclassMultiPhidgetExample{privatestaticDigitalInputbutton=null;privatestaticDigitalOutputoutput=null;publicstaticDigitalInputStateChangeListeneronStateChange=newDigitalInputStateChangeListener(){@OverridepublicvoidonStateChange(DigitalInputStateChangeEvente){//Be sure the other Phidget you are trying to access is attached before using itif(output.getAttached()==true)output.setState(e.getState());}};publicstaticvoidmain(String[]args)throwsException{try{button=newDigitalInput();output=newDigitalOutput();//Set Any Addressing Parameters Herebutton.addStateChangeListener(onStateChange);//Be sure to open any channels you are using within events before the channels//that cause the events.//This gives them a chance to be attached before the event tries to use them.output.open(5000);button.open(5000);// The rest of your code here...}catch(PhidgetExceptionex){System.out.println(ex.getDescription());}}}
In C#, chances are your event handlers are defined in the same class as the Phidget handles. In this case, you can simply reference Phidgets in the event handlers the same way as you would in the rest of your code.
For example, if we wanted to make a Digital Output channel follow the state of a button:
namespaceConsoleApplication{classProgram{privatestaticDigitalInputbutton=null;privatestaticDigitalOutputoutput=null;privatestaticvoidonStateChange(objectsender,DigitalInputStateChangeEventArgse){//Be sure the other Phidget you are trying to access is attached before using itif(output.Attached==true)output.State=e.State;}staticvoidMain(string[]args){button=newDigitalInput();output=newDigitalOutput();//Set Any Addressing Parameters Herebutton.StateChange+=onStateChange;//Be sure to open any channels you are using within events before the channels//that cause the events.//This gives them a chance to be attached before the event tries to use them.output.Open(5000);button.Open(5000);//The rest of your code here...}}}
In C, all event handler declarations have a context pointer that can be pointed at any object you choose. This can be a set of relevant data, or even a Phidget handle. If you pass a Phidget handle as the context pointer for an event, you can access the passed Phidget from the event as follows:
For example, if we wanted to make a Digital Output channel follow the state of a button:
staticvoidCCONVonStateChangeHandler(PhidgetDigitalInputHandlepdih,void*ctx,intstate){intattached;//Extract our output handle from the context pointerPhidgetDigitalOutputHandlelinkedOutput=(PhidgetDigitalOutputHandle)ctx;//Be sure the other Phidget you are trying to access is attached before using itPhidget_getAttached((PhidgetHandle)linkedOutput,&attached);if(attached)PhidgetDigitalOutput_setState(linkedOutput,state);}intmain(){PhidgetDigitalInputHandlebutton=NULL;PhidgetDigitalOutputHandleoutput=NULL;PhidgetDigitalInput_create(&button);PhidgetDigitalOutput_create(&output);//Addressing info here//Here we pass the handle for "output" as the context pointer so we can access it from the eventPhidgetDigitalInput_setOnStateChangeHandler(ch,onStateChangeHandler,output);//Be sure to open any channels you are using within events before the channels//that cause the events.//This gives them a chance to be attached before the event tries to use them.Phidget_openWaitForAttachment((PhidgetHandle)output,5000);Phidget_openWaitForAttachment((PhidgetHandle)button,5000);//The rest of your code here...}
JavaScript is dynamically interpreted, and objects follow a less rigid structure than in other languages. To access another Phidget from an event handler, you can add the second Phidget's handle as a property of the Phidget object that will be triggering the event. Then, you can access the second Phidget using the corresponding property from the this parameter of the event.
For example, if we wanted to make a Digital Output channel follow the state of a button:
functionstateChange(state){//Be sure the other Phidget you are trying to access is attached before using itif(this.linkedOutput.getAttached())this.linkedOutput.setState(state);}...varbutton=newphidget22.DigitalInput();varoutput=newphidget22.DigitalOutput();...//Here we create an attribute of input called "linkedOutput", and assign it the handle for outputbutton.linkedOutput=output;button.onStateChange=stateChange;output.open();button.open();//The rest of your code here...
What's Next?
Now that you know how to use multiple Phidgets in your program, we should discuss how to find the features available to you by using the Phidget22 API.