Using Multiple Phidgets: Difference between revisions

From Phidgets Support
No edit summary
Line 1: Line 1:
[[Category:Programming]]
[[Category:Programming]]
It is possible to use more than one Phidget within your program.  The trick lies in using a unique identifier for each one.  You can either hard-code the [[#Using the Serial Number|serial number in by hand]] (the number will be on the bottom of the board, or you can run our example code for the Phidget to obtain it on-screen), or you can use the [[#Using the Manager|Phidget Manager within your program]] to detect attached devices and return their serial numbers and object types.


===Using the Serial Number===
Before opening a channel, it is important to set enough of the matching properties to ensure the desired device channel is matched.  By default, the matching code in the Phidget library will match the first available device channel that is of the correct class.  For example, if two temperature sensor devices are connected to a computer, it is undefined which will attach when the device serial number is not specified before the channel is opened.


Each Phidget has a unique serial number.  Using this serial number, you can [[Phidget Programming Basics#Opening the Phidget|open]] the object belonging to a specific Phidget.
===Using the Channel ID===


For example, in Java, this would be:
Each channel exported by a Phidget device has an id, normally starting at 0. The {{Code|channel}} property must be set to ensure the device channel the Phidget software library matches is right oneIf a 4-channel temperature sensor is connected, and the {{Code|channel}} property is not specified, the matching code will attach to channel 0 if available, and the next available channel if not.
<div class="source">
<syntaxhighlight lang=java>
device.setDeviceSerialNumber();
  device.open();
</syntaxhighlight>
</div>


Or in C:
Set the '''channel id''' with the {{Code|Channel}} property.
<div class="source">
<syntaxhighlight lang=cpp>
Phidget_setDeviceSerialNumber((CPhidgetHandle) device, serialNumber);
Phidget_open((CPhidgetHandle) device);
</syntaxhighlight>
</div>


===Using the Label===
===Using the Hub Port===


If you want to have a human-readable way to reference your Phidget (as opposed to a serial number), or to have multiple different Phidgets of the same type with the same handle (for re-usable system code), you can use the Label feature of PhidgetsIn many development setups, you can change the label to whatever you like, get the label within your code, and open a Phidget based on its label. The disadvantage of Labels is that they are not available on all operating systems and languages.
VINT hubs have a number of ports that VINT devices can be connected to.  To ensure the correct VINT device is attached, the hub port must be specifiedIf two temperature sensors are attached to the same hub, and the hub port is not specified prior to opening a channel, it is undefined which temperature sensor will be attached.


Some limitations are:
Set the '''hub port''' with the {{Code|HubPort}} property.
* In [[OS - Windows|Windows]], label can be read on any Phidget that has a serial number, but label can only be written for Phidgets that support firmware upgrading.
* Some programming languages do not support writing to labels. See the {{Phidget22API}} to see if it's supported in your language.  


When opening by label, you would use the {{Code|setDeviceLabel("mylabel")}} function (or similar, check the {{Phidget22API}}) before calling {{Code|Open()}}.
===Using the Serial Number===


'''Note:''' You should be careful when writing labels to your Phidgets in your code, because the label is stored in flash which can only be re-written around 10,000 times before it will no longer write. If you accidentally leave your program running or if it loops unexpectedly, you could burn out the flash, which would prevent you from using labels with that Phidget.
Each Phidget has a unique serial number (VINT devices inherit the serial number of the hub). When there is more than one device that exports the same channel class, the device serial number must be specified to ensure the channel on the desired device is matched.  The device serial number can be found on a label on the bottom of the Phidget, or determined by reading the {{Code|DeviceSerialNumber}} property.


===Using the Manager===
Set the '''device serial number''' with the {{Code|DeviceSerialNumber}} property.


The [[Phidget Manager]] object can detect all Phidgets as they attach to a system.  In your attach handler, you can read the serial number of each Phidget and deal with each one individually.  This is the preferred method for systems where you will be using multiple Phidgets and expecting the system to operate long enough (or under harsh enough conditions)  that the Phidgets would need to be replaced without having to update the code by hard-coding in serial numbers. 
===Using the Label===


This is especially true for running programs [[OS - Phidget SBC#Running a Program Automatically| automatically at scheduled times on the Single Board Computer]], where you would be replacing Phidgets without the benefit of keyboard or screen.  
Most Phidgets can be assigned a label that may be used as a human-readable way to reference them (VINT devices inherit the serial number of the hub).  In software that will be distributed, or cannot easily be modified it is useful to attach to channels based on the label of the device. This way, the device can be labelled prior to running the software, and the new device will be matched


For example, in Java (note for Enumerations you also need to include {{Code|java.util.*}}):


<div class="source">
Set the '''device label''' with the {{Code|DeviceLabel}} property.
<syntaxhighlight lang=java>


List<int> serials = new ArrayList<int>();


public static void main(String[] args) throws Exception {
Some limitations are:
* In [[OS - Windows|Windows]], label can be read on any Phidget that has a serial number, but label can only be written for Phidgets that support firmware upgrading.
* Some programming languages do not support writing to labels. See the {{Phidget22API}}.


  // Create and open the manager
===Code Examples===
  Manager manager = new Manager();


  // define the attach handler
For example, in Java, this would be:
  manager.addAttachListener((ManagerAttachEvent ev)->{
<div class="source">
            Phidget phid = ev.getChannel();
<syntaxhighlight lang=java>
            try{
ch.setDeviceSerialNumber(12345); // match device 12345
                serials.add(phid.getDeviceSerialNumber());
ch.setHubPort(4);                 // match hub port 4
            }catch(PhidgetException ex){
ch.setChannel(1);                 // match channel 1 port 4 dev 12345
                System.out.println(ex.getDescription());
ch.open();                       // start matching
            }
  });
 
  try {
      manager.open();
  } catch (PhidgetException exception) {
      printError(exception.getErrorNumber(), exception.getDescription());
  }
 
  // Wait for all of the attach events for already-attached Phidgets to resolve
  Thread.sleep(1000);
 
  // Retrieve the list of attached Phidgets' serial numbers
  serials.forEach(serial -> System.out.println(serial));
 
  // Close the manager
  try {
      manager.close();
  } catch (PhidgetException exception) {
      printError(exception.getErrorNumber(), exception.getDescription());
  }
  manager = null;
 
  // Do something with names and serial numbers stored above (i.e. open and use Phidget objects)
  ....
</syntaxhighlight>
</syntaxhighlight>
</div>
</div>


 
Or in C:
Or, in C:
 
 
<div class="source">
<div class="source">
<syntaxhighlight lang=cpp>
<syntaxhighlight lang=c>
 
  Phidget_setDeviceSerialNumber((PhidgetHandle)ch, 12345);  // match device 12345
int serials[100];
  Phidget_setHubPort((PhidgetHandle)ch, 4);                 // match hub port 4
 
Phidget_setChannel((PhidgetHandle)ch, 1);                 // match channel 1 port 4 dev 12345
int main() {
Phidget_open((CPhidgetHandle)ch);                         // start matching
   
    // Define the manager handle and create
    PhidgetManagerHandle device = 0;
    PhidgetManager_create(&device);
    // Set up event handlers
    PhidgetManager_setOnAttachHandler(device, AttachHandler, NULL);
    PhidgetManager_setOnDetachHandler(device, DetachHandler, NULL);
   
    // Open the Phidget Manager
    PhidgetManager_open(device);
   
    // Do something with the non-zero numbers stored in the serials[] array, like open(), control, etc.
    ....
    // Close and clean up manager object
    PhidgetManager_close(device);
    PhidgetManager_delete(&device);
    return 0;
}
 
void CCONV AttachHandler(PhidgetManagerHandle manager, void *userptr, PhidgetHandle device) {
 
    const char *serialnum;
    int i;
    Phidget_getDeviceSerialNumber(device, &serialnum);
    for(i=0; i < 100; i++) {
          if(serials[i] == 0) {
              serials[i] = serialnum;
              break;
          }
    }
   
    if(i == 100)
          printf("Serial array is full.\n");
}
 
void CCONV DetachHandler(PhidgetManagerHandle manager, void *userptr, PhidgetHandle device) {
    const char *serialNumber;
    // Get the serial number of the detached device and clear it from the list
    Phidget_getDeviceSerialNumber(device, &serialNumber);
 
    for(int i=0; i < 100; i++) {
          if(serials[i] == serialNumber)
              serials[i] = 0;
    }
 
}
 
</syntaxhighlight>
</syntaxhighlight>
</div>
</div>
In either example, serial numbers are gathered as Phidgets attached so they can be used later. You may want to gather other pieces of data such as device name and channel number for your program to eventually use.


===Distinguishing Events===
===Distinguishing Events===

Revision as of 18:32, 11 July 2017


Before opening a channel, it is important to set enough of the matching properties to ensure the desired device channel is matched. By default, the matching code in the Phidget library will match the first available device channel that is of the correct class. For example, if two temperature sensor devices are connected to a computer, it is undefined which will attach when the device serial number is not specified before the channel is opened.

Using the Channel ID

Each channel exported by a Phidget device has an id, normally starting at 0. The channel property must be set to ensure the device channel the Phidget software library matches is right one. If a 4-channel temperature sensor is connected, and the channel property is not specified, the matching code will attach to channel 0 if available, and the next available channel if not.

Set the channel id with the Channel property.

Using the Hub Port

VINT hubs have a number of ports that VINT devices can be connected to. To ensure the correct VINT device is attached, the hub port must be specified. If two temperature sensors are attached to the same hub, and the hub port is not specified prior to opening a channel, it is undefined which temperature sensor will be attached.

Set the hub port with the HubPort property.

Using the Serial Number

Each Phidget has a unique serial number (VINT devices inherit the serial number of the hub). When there is more than one device that exports the same channel class, the device serial number must be specified to ensure the channel on the desired device is matched. The device serial number can be found on a label on the bottom of the Phidget, or determined by reading the DeviceSerialNumber property.

Set the device serial number with the DeviceSerialNumber property.

Using the Label

Most Phidgets can be assigned a label that may be used as a human-readable way to reference them (VINT devices inherit the serial number of the hub). In software that will be distributed, or cannot easily be modified it is useful to attach to channels based on the label of the device. This way, the device can be labelled prior to running the software, and the new device will be matched


Set the device label with the DeviceLabel property.


Some limitations are:

  • In Windows, label can be read on any Phidget that has a serial number, but label can only be written for Phidgets that support firmware upgrading.
  • Some programming languages do not support writing to labels. See the Phidget22 API.

Code Examples

For example, in Java, this would be:

 ch.setDeviceSerialNumber(12345);  // match device 12345
 ch.setHubPort(4);                 // match hub port 4
 ch.setChannel(1);                 // match channel 1 port 4 dev 12345
 ch.open();                        // start matching

Or in C:

 Phidget_setDeviceSerialNumber((PhidgetHandle)ch, 12345);  // match device 12345
 Phidget_setHubPort((PhidgetHandle)ch, 4);                 // match hub port 4
 Phidget_setChannel((PhidgetHandle)ch, 1);                 // match channel 1 port 4 dev 12345
 Phidget_open((CPhidgetHandle)ch);                         // start matching

Distinguishing Events

If you are using event-driven code, once you have correctly opened multiple Phidgets of different types, they will have different event handlers and hence you will know what Phidget triggered which event. If you are using multiple Phidgets of the same type, or you are trying to determine within general events (such as Attach Events) which Phidget triggered the event, you can then check the serial number (or device type) of the triggering device and act accordingly.

For example, in Java, your attach event handler might look like this:

    detachHandler = new DetachListener() { 
        public void detached(DetachEvent event) {
            int serialNumber = ((Phidget)event.getSource()).getSerialNumber();
            // Do something according to serialNumber
    }    }


Or in C:

    int AttachHandler(CPhidgetHandle device, void *userptr) {
	int serialNo;
	CPhidget_getSerialNumber(device, &serialNo);
         // Do something according to serialNumber
    }

Further Reading

Phidget Programming Basics - Here you can find the basic concepts to help you get started with making your own programs that use Phidgets.

Data Interval/Change Trigger - Learn about these two properties that control how much data comes in from your sensors.

Polling vs. Events - Your program can gather data in either a polling-driven or event-driven manner. Learn the difference to determine which is best for your application.

Logging, Exceptions, and Errors - Learn about all the tools you can use to debug your program.

Phidget Network Server - Phidgets can be controlled and communicated with over your network- either wirelessly or over ethernet.

Best Phidgets Practices - Good programming habits that will save you from common problems when writing code for your Phidgets.