Using Multiple Phidgets: Difference between revisions
No edit summary |
|||
(40 intermediate revisions by 5 users not shown) | |||
Line 1: | Line 1: | ||
[[Category:Programming]]{{Recommended_Flow_Links|{{Flow Page Number|{{PAGENAME}} }} }} | |||
__NOTOC__ | |||
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: | |||
<center>{{#ev:youtube|17VQNQlrxxU|||||rel=0}}</center> | |||
== | ==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. | |||
For example, | ===Addressing Channels=== | ||
< | |||
<syntaxhighlight lang= | 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: | |||
<tabber> | |||
Python=<syntaxhighlight lang=python> | |||
#Set up the first channel as normal | |||
ch = TemperatureSensor() | |||
ch.setDeviceSerialNumber(12345) | |||
ch.setHubPort(4) | |||
ch.setChannel(0) | |||
ch.openWaitForAttachment(5000) | |||
#For a second channel, simply repeat the process with different addressing information | |||
ch1 = 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 done | |||
ch.close() | |||
ch1.close() | |||
</syntaxhighlight> | </syntaxhighlight> | ||
</ | |-| | ||
Java=<syntaxhighlight lang=java> | |||
//Set up the first channel as normal | |||
TemperatureSensor ch = new TemperatureSensor(); | |||
ch.setDeviceSerialNumber(12345); | |||
ch.setHubPort(4); | |||
ch.setChannel(0); | |||
ch.open(5000); | |||
//For a second channel, simply repeat the process with different addressing information | |||
TemperatureSensor ch1 = new TemperatureSensor(); | |||
ch1.setDeviceSerialNumber(12345); | |||
ch1.setHubPort(3); | |||
ch1.setChannel(0); | |||
ch1.open(5000); | |||
//Do stuff with your Phidgets here... | |||
//Remember to close the channels when done | |||
ch.close(); | |||
ch1.close(); | |||
</syntaxhighlight> | </syntaxhighlight> | ||
</ | |-| | ||
C#=<syntaxhighlight lang=cSharp> | |||
//Set up the first channel as normal | |||
TemperatureSensor ch = new TemperatureSensor(); | |||
ch.DeviceSerialNumber = 12345; | |||
ch.HubPort = 4; | |||
ch.Channel = 0; | |||
ch.Open(5000); | |||
//For a second channel, simply repeat the process with different addressing information | |||
TemperatureSensor ch1 = new TemperatureSensor(); | |||
ch1.DeviceSerialNumber = 12345; | |||
ch1.HubPort = 3; | |||
ch1.Channel = 0; | |||
ch1.Open(5000); | |||
//Do stuff with your Phidgets here... | |||
//Remember to close the channels when done | |||
ch.Close(); | |||
ch1.Close(); | |||
</syntaxhighlight> | |||
|-| | |||
C=<syntaxhighlight lang=c> | |||
//Set up the first channel as normal | |||
PhidgetTemperatureSensorHandle ch; | |||
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 information | |||
PhidgetTemperatureSensorHandle ch1; | |||
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 done | |||
Phidget_close((PhidgetHandle)ch); | |||
Phidget_close((PhidgetHandle)ch1); | |||
PhidgetTemperatureSensor_delete(&ch); | |||
PhidgetTemperatureSensor_delete(&ch1); | |||
</syntaxhighlight> | |||
|-| | |||
JavaScript=<syntaxhighlight lang=javascript> | |||
// Set up the first channel as normal | |||
const ch = new phidget22.TemperatureSensor() | |||
ch.deviceSerialNumber = 12345 | |||
ch.hubPort = 4 | |||
ch.channel = 0 | |||
await ch.open(5000) | |||
// For a second channel, simply repeat the process with different addressing information | |||
const ch1 = new phidget22.TemperatureSensor() | |||
ch1.deviceSerialNumber = 12345 | |||
ch1.hubPort = 3 | |||
ch1.channel = 0 | |||
await ch1.open(5000) | |||
// Do stuff with your Phidgets here... | |||
// Remember to close the channels when done | |||
await ch.close() | |||
await ch1.close() | |||
</syntaxhighlight> | |||
</tabber> | |||
==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. | |||
< | <tabber> | ||
<syntaxhighlight lang= | Python=<syntaxhighlight lang=python> | ||
#Create the array of Phidget channels | |||
ch = [DigitalOutput() for i in range (0, 8)] | |||
for i in range (0, 8): | |||
#Address, then open the channels | |||
ch[i].setChannel(i) | |||
ch[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) | |||
for i in range (0, 8): | |||
ch[i].close() | |||
</syntaxhighlight> | |||
|-| | |||
Java=<syntaxhighlight lang=java> | |||
//Create an array for your Phidget channels | |||
DigitalOutput[] ch = new DigitalOutput[8]; | |||
for(int i = 0; i < 8; i++) { | |||
//Create the channels | |||
ch[i] = new DigitalOutput(); | |||
//Address, then open the channels | |||
ch[i].setChannel(i); | |||
ch[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 done | |||
for(int i=0; i<8; i++) { | |||
ch[i].close(); | |||
} | |||
</syntaxhighlight> | |||
|-| | |||
C#=<syntaxhighlight lang=cSharp> | |||
//Create an array for your Phidget channels | |||
DigitalOutput[] ch = new DigitalOutput[8]; | |||
//Open the channels | |||
for(int i=0; i<8; i++) | |||
{ | |||
//Create the channels | |||
ch[i] = new DigitalOutput(); | |||
//Address, then open the channels | |||
ch[i].Channel = i; | |||
ch[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 done | |||
for(int i=0; i<8; i++) | |||
{ | |||
ch[i].Close(); | |||
} | |||
</syntaxhighlight> | </syntaxhighlight> | ||
</ | |-| | ||
C=<syntaxhighlight lang=c> | |||
//Create an array for your Phidget channels | |||
PhidgetDigitalOutputHandle ch[8]; | |||
for (int i = 0; i < 8; i++) { | |||
//Create the channels | |||
PhidgetDigitalOutput_create(&ch[i]); | |||
//Address, then open the channels | |||
Phidget_setChannel((PhidgetHandle)ch[i], i); | |||
Phidget_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 done | |||
for (int i = 0; i < 8; i++) { | |||
Phidget_close((PhidgetHandle)ch[i]); | |||
} | |||
</syntaxhighlight> | |||
|-| | |||
JavaScript=<syntaxhighlight lang=javascript> | |||
// Create the array of Phidget channels | |||
var ch = [] | |||
for(i = 0; i < 8; i++) { | |||
< | |||
// Create, address, then open the channels | |||
var tmp = new phidget22.DigitalInput() | |||
tmp.channel = i | |||
await tmp.open(5000) | |||
ch.push(tmp) | |||
} | } | ||
// 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 | |||
for(i = 0; i < 8; i++) { | |||
await ch[i].close() | |||
} | } | ||
</syntaxhighlight> | |||
</tabber> | |||
==Distinguishing Events== | |||
When using [[Polling vs. Events|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: | |||
<tabber> | |||
Python= | |||
In Python, the channel that fired the event can be accessed from the event handler using the {{code|self}} parameter (the first parameter in the list). | |||
<syntaxhighlight lang=python> | |||
#Declare the event handler | |||
def onAttachHandler(self): | |||
#You can access the Phidget that fired the event using the "self" parameter | |||
ph = self | |||
deviceSerialNumber = ph.getDeviceSerialNumber() | |||
... | |||
#Declare your object. Replace "DigitalInput" with the object for your Phidget | |||
ch = DigitalInput() | |||
... | |||
#Assign the handler that will be called when the event occurs | |||
ch.setOnAttachHandler(onAttachHandler) | |||
</syntaxhighlight> | |||
|-| | |||
Java= | |||
In Java, you can call {{code|getSource()}} on the event parameter to get the Phidget that caused the event. | |||
<syntaxhighlight lang=java> | |||
//Declare the event listener | |||
public static AttachListener onAttach = new AttachListener() { | |||
@Override | |||
public void onAttach(AttachEvent e) { | |||
//You can access the Phidget that fired the event by calling "getSource()" | |||
//on the event parameter. | |||
//Replace "DigitalInput" with the object for your Phidget. | |||
DigitalInput ph = (DigitalInput) e.getSource(); | |||
int deviceSerialNumber = ph.getDeviceSerialNumber(); | |||
} | |||
}; | |||
... | |||
//Declare your object. Replace "DigitalInput" with the object for your Phidget. | |||
DigitalInput ch; | |||
... | |||
//Assign the event listener that will be called when the event occurs | |||
ch.addAttachListener(onAttach); | |||
</syntaxhighlight> | |||
|-| | |||
C#= | |||
In C#, you can access the Phidget that fired the event by typecasting the {{code|sender}} parameter to the appropriate Phidget object type. | |||
<syntaxhighlight lang=cSharp> | |||
//Declare the event handler | |||
void attach(object sender, Phidget22.Events.AttachEventArgs e) { | |||
//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. | |||
DigitalInput ph = ((DigitalInput)sender); | |||
int deviceSerial = ph.DeviceSerialNumber; | |||
} | |||
... | |||
//Declare your object. Replace "DigitalInput" with the object for your Phidget. | |||
DigitalInput ch; | |||
... | |||
//Assign the handler that will be called when the event occurs | |||
ch.Attach += attach; | |||
</syntaxhighlight> | |||
|-| | |||
C= | |||
In C, you can access the Phidget that fired the event using the first parameter of the event handler. | |||
<syntaxhighlight lang=c> | |||
//Declare the event handler | |||
static void CCONV onAttachHandler(PhidgetHandle ph, void *ctx) { | |||
//You can access the Phidget that fired the event by using the first parameter | |||
//of the event handler | |||
int deviceSerialNumber; | |||
Phidget_getDeviceSerialNumber(ph, &deviceSerialNumber); | |||
} | } | ||
... | |||
//Declare your object. Replace "PhidgetDigitalInputHandle" with the handle for your Phidget object. | |||
PhidgetDigitalInputHandle ch; | |||
... | |||
//Assign the handler that will be called when the event occurs | |||
Phidget_setOnAttachHandler((PhidgetHandle)ch, onAttachHandler, NULL); | |||
</syntaxhighlight> | |||
|-| | |||
JavaScript= | |||
In JavaScript, you can access the Phidget that fired the event using the 'this' property. | |||
<syntaxhighlight lang=c> | |||
// Declare your object. Replace "DigitalInput" with the object for your Phidget | |||
const ch = new phidget22.DigitalInput() | |||
// Assign the handler that will be called when the event occurs | |||
ch.onAttach = function { | |||
// You can access the Phidget that fired the event using the "this" parameter | |||
let deviceSerial = this.deviceSerialNumber | |||
} | |||
</syntaxhighlight> | </syntaxhighlight> | ||
</ | </tabber> | ||
==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: | |||
<tabber> | |||
Python= | |||
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 {{code|self}} parameter of the event. | |||
For example, | For example, if we wanted to make a Digital Output channel follow the state of a button: | ||
<syntaxhighlight lang=python> | |||
def onStateChangeHandler(self, state): | |||
#Be sure the other Phidget you are trying to access is attached before using it | |||
if(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 output | |||
button.linkedOutput = output | |||
button.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.... | |||
</syntaxhighlight> | |||
|-| | |||
Java= | |||
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: | |||
<syntaxhighlight lang=java> | <syntaxhighlight lang=java> | ||
public class MultiPhidgetExample { | |||
public void | |||
private static DigitalInput button = null; | |||
// | private static DigitalOutput output = null; | ||
} | |||
public static DigitalInputStateChangeListener onStateChange = | |||
new DigitalInputStateChangeListener() { | |||
@Override | |||
public void onStateChange(DigitalInputStateChangeEvent e) { | |||
//Be sure the other Phidget you are trying to access is attached before using it | |||
if(output.getAttached() == true) | |||
output.setState(e.getState()); | |||
} | |||
}; | |||
public static void main(String[] args) throws Exception { | |||
try { | |||
button = new DigitalInput(); | |||
output = new DigitalOutput(); | |||
//Set Any Addressing Parameters Here | |||
button.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 (PhidgetException ex) { | |||
System.out.println(ex.getDescription()); | |||
} | |||
} | |||
} | |||
</syntaxhighlight> | </syntaxhighlight> | ||
|-| | |||
C#= | |||
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: | |||
<syntaxhighlight lang=cSharp> | |||
namespace ConsoleApplication | |||
{ | |||
class Program | |||
{ | |||
private static DigitalInput button = null; | |||
private static DigitalOutput output = null; | |||
private static void onStateChange(object sender, | |||
DigitalInputStateChangeEventArgs e) | |||
{ | |||
//Be sure the other Phidget you are trying to access is attached before using it | |||
if (output.Attached == true) | |||
output.State = e.State; | |||
} | |||
static void Main(string[] args) | |||
{ | |||
button = new DigitalInput(); | |||
output = new DigitalOutput(); | |||
//Set Any Addressing Parameters Here | |||
button.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... | |||
} | |||
} | } | ||
} | |||
</syntaxhighlight> | </syntaxhighlight> | ||
|-| | |||
C= | |||
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: | ||
<syntaxhighlight lang=C> | |||
static void CCONV onStateChangeHandler(PhidgetDigitalInputHandle pdih, void *ctx, int state) { | |||
int attached; | |||
//Extract our output handle from the context pointer | |||
PhidgetDigitalOutputHandle linkedOutput = (PhidgetDigitalOutputHandle)ctx; | |||
//Be sure the other Phidget you are trying to access is attached before using it | |||
Phidget_getAttached((PhidgetHandle)linkedOutput, &attached); | |||
if(attached) | |||
PhidgetDigitalOutput_setState(linkedOutput, state); | |||
} | |||
int main() { | |||
PhidgetDigitalInputHandle button = NULL; | |||
PhidgetDigitalOutputHandle output = 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 event | |||
PhidgetDigitalInput_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... | |||
} | |||
</syntaxhighlight> | |||
|-| | |||
JavaScript= | |||
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 {{code|this}} parameter of the event. | |||
For example, if we wanted to make a Digital Output channel follow the state of a button: | |||
<syntaxhighlight lang=javaScript> | |||
const button = new phidget22.DigitalInput(); | |||
const output = new phidget22.DigitalOutput(); | |||
... | |||
//Here we create an attribute of input called "linkedOutput", and assign it the handle for output | |||
button.linkedOutput = output; | |||
button.onStateChange = function(state){ | |||
//Be sure the other Phidget you are trying to access is attached before using it | |||
if(this.linkedOutput.attached) | |||
this.linkedOutput.state = state; | |||
} | |||
await output.open(); | |||
await button.open(); | |||
//The rest of your code here... | |||
</syntaxhighlight> | |||
</tabber> | |||
==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. | |||
{{Flow_Navigation_Buttons|{{Flow Page Number|{{PAGENAME}} }} }} |
Latest revision as of 21:05, 19 April 2022
12 . Using Multiple Phidgets
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 normal
ch = TemperatureSensor()
ch.setDeviceSerialNumber(12345)
ch.setHubPort(4)
ch.setChannel(0)
ch.openWaitForAttachment(5000)
#For a second channel, simply repeat the process with different addressing information
ch1 = 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 done
ch.close()
ch1.close()
//Set up the first channel as normal
TemperatureSensor ch = new TemperatureSensor();
ch.setDeviceSerialNumber(12345);
ch.setHubPort(4);
ch.setChannel(0);
ch.open(5000);
//For a second channel, simply repeat the process with different addressing information
TemperatureSensor ch1 = new TemperatureSensor();
ch1.setDeviceSerialNumber(12345);
ch1.setHubPort(3);
ch1.setChannel(0);
ch1.open(5000);
//Do stuff with your Phidgets here...
//Remember to close the channels when done
ch.close();
ch1.close();
//Set up the first channel as normal
TemperatureSensor ch = new TemperatureSensor();
ch.DeviceSerialNumber = 12345;
ch.HubPort = 4;
ch.Channel = 0;
ch.Open(5000);
//For a second channel, simply repeat the process with different addressing information
TemperatureSensor ch1 = new TemperatureSensor();
ch1.DeviceSerialNumber = 12345;
ch1.HubPort = 3;
ch1.Channel = 0;
ch1.Open(5000);
//Do stuff with your Phidgets here...
//Remember to close the channels when done
ch.Close();
ch1.Close();
//Set up the first channel as normal
PhidgetTemperatureSensorHandle ch;
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 information
PhidgetTemperatureSensorHandle ch1;
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 done
Phidget_close((PhidgetHandle)ch);
Phidget_close((PhidgetHandle)ch1);
PhidgetTemperatureSensor_delete(&ch);
PhidgetTemperatureSensor_delete(&ch1);
// Set up the first channel as normal
const ch = new phidget22.TemperatureSensor()
ch.deviceSerialNumber = 12345
ch.hubPort = 4
ch.channel = 0
await ch.open(5000)
// For a second channel, simply repeat the process with different addressing information
const ch1 = new phidget22.TemperatureSensor()
ch1.deviceSerialNumber = 12345
ch1.hubPort = 3
ch1.channel = 0
await ch1.open(5000)
// Do stuff with your Phidgets here...
// Remember to close the channels when done
await ch.close()
await ch1.close()
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 channels
ch = [DigitalOutput() for i in range (0, 8)]
for i in range (0, 8):
#Address, then open the channels
ch[i].setChannel(i)
ch[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)
for i in range (0, 8):
ch[i].close()
//Create an array for your Phidget channels
DigitalOutput[] ch = new DigitalOutput[8];
for(int i = 0; i < 8; i++) {
//Create the channels
ch[i] = new DigitalOutput();
//Address, then open the channels
ch[i].setChannel(i);
ch[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 done
for(int i=0; i<8; i++) {
ch[i].close();
}
//Create an array for your Phidget channels
DigitalOutput[] ch = new DigitalOutput[8];
//Open the channels
for(int i=0; i<8; i++)
{
//Create the channels
ch[i] = new DigitalOutput();
//Address, then open the channels
ch[i].Channel = i;
ch[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 done
for(int i=0; i<8; i++)
{
ch[i].Close();
}
//Create an array for your Phidget channels
PhidgetDigitalOutputHandle ch[8];
for (int i = 0; i < 8; i++) {
//Create the channels
PhidgetDigitalOutput_create(&ch[i]);
//Address, then open the channels
Phidget_setChannel((PhidgetHandle)ch[i], i);
Phidget_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 done
for (int i = 0; i < 8; i++) {
Phidget_close((PhidgetHandle)ch[i]);
}
// Create the array of Phidget channels
var ch = []
for(i = 0; i < 8; i++) {
// Create, address, then open the channels
var tmp = new phidget22.DigitalInput()
tmp.channel = i
await tmp.open(5000)
ch.push(tmp)
}
// 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
for(i = 0; i < 8; i++) {
await ch[i].close()
}
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 handler
def onAttachHandler(self):
#You can access the Phidget that fired the event using the "self" parameter
ph = self
deviceSerialNumber = ph.getDeviceSerialNumber()
...
#Declare your object. Replace "DigitalInput" with the object for your Phidget
ch = DigitalInput()
...
#Assign the handler that will be called when the event occurs
ch.setOnAttachHandler(onAttachHandler)
getSource()
on the event parameter to get the Phidget that caused the event.
//Declare the event listener
public static AttachListener onAttach = new AttachListener() {
@Override
public void onAttach(AttachEvent e) {
//You can access the Phidget that fired the event by calling "getSource()"
//on the event parameter.
//Replace "DigitalInput" with the object for your Phidget.
DigitalInput ph = (DigitalInput) e.getSource();
int deviceSerialNumber = ph.getDeviceSerialNumber();
}
};
...
//Declare your object. Replace "DigitalInput" with the object for your Phidget.
DigitalInput ch;
...
//Assign the event listener that will be called when the event occurs
ch.addAttachListener(onAttach);
sender
parameter to the appropriate Phidget object type.
//Declare the event handler
void attach(object sender, Phidget22.Events.AttachEventArgs e) {
//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.
DigitalInput ph = ((DigitalInput)sender);
int deviceSerial = ph.DeviceSerialNumber;
}
...
//Declare your object. Replace "DigitalInput" with the object for your Phidget.
DigitalInput ch;
...
//Assign the handler that will be called when the event occurs
ch.Attach += attach;
//Declare the event handler
static void CCONV onAttachHandler(PhidgetHandle ph, void *ctx) {
//You can access the Phidget that fired the event by using the first parameter
//of the event handler
int deviceSerialNumber;
Phidget_getDeviceSerialNumber(ph, &deviceSerialNumber);
}
...
//Declare your object. Replace "PhidgetDigitalInputHandle" with the handle for your Phidget object.
PhidgetDigitalInputHandle ch;
...
//Assign the handler that will be called when the event occurs
Phidget_setOnAttachHandler((PhidgetHandle)ch, onAttachHandler, NULL);
// Declare your object. Replace "DigitalInput" with the object for your Phidget
const ch = new phidget22.DigitalInput()
// Assign the handler that will be called when the event occurs
ch.onAttach = function {
// You can access the Phidget that fired the event using the "this" parameter
let deviceSerial = this.deviceSerialNumber
}
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:
def onStateChangeHandler(self, state):
#Be sure the other Phidget you are trying to access is attached before using it
if(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 output
button.linkedOutput = output
button.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....
For example, if we wanted to make a Digital Output channel follow the state of a button:
public class MultiPhidgetExample {
private static DigitalInput button = null;
private static DigitalOutput output = null;
public static DigitalInputStateChangeListener onStateChange =
new DigitalInputStateChangeListener() {
@Override
public void onStateChange(DigitalInputStateChangeEvent e) {
//Be sure the other Phidget you are trying to access is attached before using it
if(output.getAttached() == true)
output.setState(e.getState());
}
};
public static void main(String[] args) throws Exception {
try {
button = new DigitalInput();
output = new DigitalOutput();
//Set Any Addressing Parameters Here
button.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 (PhidgetException ex) {
System.out.println(ex.getDescription());
}
}
}
For example, if we wanted to make a Digital Output channel follow the state of a button:
namespace ConsoleApplication
{
class Program
{
private static DigitalInput button = null;
private static DigitalOutput output = null;
private static void onStateChange(object sender,
DigitalInputStateChangeEventArgs e)
{
//Be sure the other Phidget you are trying to access is attached before using it
if (output.Attached == true)
output.State = e.State;
}
static void Main(string[] args)
{
button = new DigitalInput();
output = new DigitalOutput();
//Set Any Addressing Parameters Here
button.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...
}
}
}
For example, if we wanted to make a Digital Output channel follow the state of a button:
static void CCONV onStateChangeHandler(PhidgetDigitalInputHandle pdih, void *ctx, int state) {
int attached;
//Extract our output handle from the context pointer
PhidgetDigitalOutputHandle linkedOutput = (PhidgetDigitalOutputHandle)ctx;
//Be sure the other Phidget you are trying to access is attached before using it
Phidget_getAttached((PhidgetHandle)linkedOutput, &attached);
if(attached)
PhidgetDigitalOutput_setState(linkedOutput, state);
}
int main() {
PhidgetDigitalInputHandle button = NULL;
PhidgetDigitalOutputHandle output = 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 event
PhidgetDigitalInput_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...
}
this
parameter of the event.
For example, if we wanted to make a Digital Output channel follow the state of a button:
const button = new phidget22.DigitalInput();
const output = new phidget22.DigitalOutput();
...
//Here we create an attribute of input called "linkedOutput", and assign it the handle for output
button.linkedOutput = output;
button.onStateChange = function(state){
//Be sure the other Phidget you are trying to access is attached before using it
if(this.linkedOutput.attached)
this.linkedOutput.state = state;
}
await output.open();
await 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.