Using Multiple Phidgets

From Phidgets Support
Revision as of 21:20, 8 May 2017 by Mparadis (talk | contribs)

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 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 Phidget Manager within your program to detect attached devices and return their serial numbers and object types.

Using the Serial Number

Each Phidget has a unique serial number. Using this serial number, you can open the object belonging to a specific Phidget.

For example, in Java, this would be:

 device.setDeviceSerialNumber();
 device.open();

Or in C:

 Phidget_setDeviceSerialNumber((CPhidgetHandle) device, serialNumber);
 Phidget_open((CPhidgetHandle) device);

Using the Label

This section should be reviewed closer to release once we're sure of Label support

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 Phidgets. In 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, for any newer generation Phidget. The disadvantage of Labels is that they are not available on all operating systems and languages.

Some limitations are:

  • You cannot set a label using any language in Windows, for any language
    • However, you can get the label of a Phidget on Windows, and open a Phidget by its label
  • Android Java has support for only a subset of the open() functions that use labels, see the Android Java language page for details
  • Older Phidgets do not support labels
  • LabVIEW cannot open by label
  • Python cannot open by label

When opening by label, you would use the openLabel("mylabel") function (or similar, check the API for your language) rather than the generic open() function.

Note that setting the label should be done by a separate program. On a Mac OS computer, you can set a label through the Phidget Preference Pane. On a Linux computer, you should write a special short program specifically for setting the label. There are two reasons to not set a label within your main program:

  • If you set a label every time you run that program, when not needing to, you can easily reach the 10,000 re-write limit for the flash that stores the label
  • If you are using event driven programming, you cannot set the label from any function called from the attach event, as it will hang (on a mutual exclusion lock).

Because of the second point, your special program to set the label on a Phidget should use waitForAttach() in logic code and not event-driven programming

Using the Manager

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.

This is especially true for running programs automatically at scheduled times on the Single Board Computer, where you would be replacing Phidgets without the benefit of keyboard or screen.

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

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

public static void main(String[] args) throws Exception {

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

  // define the attach handler
  manager.addAttachListener((ManagerAttachEvent ev)->{
            Phidget phid = ev.getChannel();
            try{
                serials.add(phid.getDeviceSerialNumber());
            }catch(PhidgetException ex){
                System.out.println(ex.getDescription());
            }
  });

  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)
  ....


Or, in C:


int serials[100];

int main() {
 
     // 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;
     }

}

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

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.