Debugging is hard and any help in the process is a welcome respite. When working with a Phidget application, one of the best tools you have available is Phidget Logging. In our API we have a few functions that spit out data about what is happening beneath your code, which gives you very useful information about problems that are occurring. As the technical support for Phidgets, one of the first things I ask people to do when they are having issues is to generate logs and send them to me.
The easiest way to get logging information is to open the Phidget Control Panel and tick the “Enable Logging in Examples” checkbox. This will enable logging in all of examples you run from the control panel. The log files can then be accessed via the “View Logs” link.
If you want to get a bit fancier however you can use some API calls to enable logging in your own application.
Note: The code examples in this article use Phidget21 code and may not work with newer versions of the Phidget library.
The main function we are concerned with is the enableLogging function, which turns on logging. You specify the filename of the file where you want the log data output to, as well as the log level. The log level is an enum which changes how much information is generated by the log. The options are as follows:
PHIDGET_LOG_CRITICAL //Really important errors that can't be recovered. Usually followed by an abort() PHIDGET_LOG_ERROR //Errors that are recovered from. PHIDGET_LOG_WARNING //Warning's about weird things that aren't neccesarily wrong. PHIDGET_LOG_DEBUG //Should only be used during development - only shows up in the debug library. PHIDGET_LOG_INFO //Info about the going on's in the library. PHIDGET_LOG_VERBOSE //Everything, including very common messages.
Generally, you want to enable logging at the very beginning of your application to get the maximum amount of information.
Let’s have a look at what the logging functions look like in some of the more commonly used langauges we support. For the exact syntax in other languages you can refer to the API manual for that language.
int CPhidget_enableLogging (CPhidgetLog_level level, const char *outputFile) CPhidget_enableLogging(PHIDGET_LOG_VERBOSE, "phidgetlog.log");
public static void enableLogging(Phidget.LogLevel level, string file) Phidget.enableLogging(Phidget.LogLevel.PHIDGET_LOG_VERBOSE, "phidgetLog.log")
static void enableLogging(int level, java.lang.String file) Phidget.enableLogging(Phidget.PHIDGET_LOG_VERBOSE, "phidgetLog.log");
DEVICEHANDLE.enableLogging(level, file) interfaceKit.enableLogging(Phidgets.Phidget.PhidgetLogLevel.PHIDGET_LOG_VERBOSE, "phidgetLog.log")
So now you know how to log, but what do the logs actually look like? How do you debug issues with the data generated
0,".\clog.c(62)",INFO,"Enabling logging" 0,".\cthread.c(373)",INFO,"WriteThread running" 0,".\cthread.c(253)",INFO,"ReadThread running" 0,".\cthread.c(307)",INFO,"ReadThread exiting normally (Phidget detach detected in CPhidget_read)" 0,".\cthread.c(437)",INFO,"WriteThread exiting normally (Phidget detach detected in CPhidget_write)" 0,".\cthread.c(373)",INFO,"WriteThread running" 0,".\cthread.c(253)",INFO,"ReadThread running" 0,".\cthread.c(307)",INFO,"ReadThread exiting normally (Phidget detach detected in CPhidget_read)" 0,".\cthread.c(437)",INFO,"WriteThread exiting normally (Phidget detach detected in CPhidget_write)" 0,".\cthread.c(373)",INFO,"WriteThread running" 0,".\cthread.c(253)",INFO,"ReadThread running" 0,".\cthread.c(240)",INFO,"Central Thread exiting" 0,".\cthread.c(418)",INFO,"WriteThread exiting normally (signaled by writeStopFlag)" 0,".\cthread.c(360)",INFO,"ReadThread exiting normally (Phidget detached)" 0,".\cphidget.c(423)",INFO,"Close was called on an already closed Phidget handle."
In the sample log file above, you can see that there are two detaches that occurred. This would happen if a device were physically unplugged from the computer.
There are too many messages to go through them all, but there are a few that happen frequently that are worth pointing out.
Phidget devices can only be opened locally in one application at a time. If you try to open a device from a second program, before closing it in the first, you will see this:
0,".\windows\cusbwindows.c(560)",INFO,"CreateFileW failed with ERROR_SHARING_VIOLATION - probably the Phidget is opened elsewhere."
The next message means there’s a USB error and the device is being reset in an attempt to clear the error:
0,".\cphidgetmanager.c(220)",WARN,"PHIDGET_USB_ERROR_FLAG is set - cycling device through a detach"
When communication with the device was lost, most likely due to interference, the message will look like this:
0,".\cthread.c(347)",ERR,"ReadThread exiting - unexpected timeout (could be an ESD event)"
There are many other messages that can be generated, too many to make an exhaustive list. Hopefully, the messages are clear about what they mean. If you are not able to decipher what the logs are telling you, the easiest thing to do is send them to us, so we can go over them with you. If you log in verbose mode the log files can quite large and intimidating so I often recommend starting on a lower level and working your way up to make sure the important information isn’t getting lost in a sea of useless USB messages etc…
Phidget logging also allows you to write your own information to the log file using the log function. For example, to append a message to a log in C:
int CPhidget_log (CPhidgetLog_level level, const char *id, const char *message)
Where the parameters are:
levelis the level at which to log the message.
idis an arbitrary identifier.
messageis the message (printf style).
Hopefully, this provides enough information to get you going. You can always refer to the API manual for the language you are using for more specific syntax questions. Using these tools can really help cut down on the amount of head scratching that is inevitably involved in writing code.