Polling vs. Events: Difference between revisions

From Phidgets Support
No edit summary
No edit summary
Line 1: Line 1:
[[Category:Programming]]
[[Category:Programming]]
In your program, user and device actions can be handled by either:
*Letting the program tell you when they happen and then doing something ('''event driven''' code)
*Checking for certain things to happen (polling) and then doing something ('''logic''' code)


The style of programming you choose depends on what you want to do with the Phidget.  The two sections, [[#Event Driven Code|Event Driven Code]] and [[#Logic Code|Logic Code]] below give benefits, drawbacks, and general examples of each style. Programs will always contain some amount of logic code, for initialization of variables and event handlers, for example. This page is mostly discussing the differences between choosing to handle Phidget data with
The Phidget library operates asynchronously.  The library fires attach and detach events when a device channel appears and disappears (plugged in or unplugged).  After a user channel is attached, data and status updates from the device channel begin being delivered. These events cause the library to update properties of the user channel, and to call any event handlers set by the program.
events or with polling.


Examples in pseudo-code are given below for each style type.
===Discussion===


=== Logic Code ===
====Attach====
Once a channel is opened, the Phidget library begins attempting to match the channel to a device channel.  While the channel is not '''attached''', the {{Code|Attached}} property of the channel will be '''false'''.  As soon as the Phidget library matches the channel with a device channel the {{Code|Attached}} property is updated to be '''true'''.  A program could poll the {{Code|Attached}} property to determine when the channel becomes '''attached''', or set an attach handler to be notified asynchronously.


Logic code is best used for:
====Detach====
* Simple test applications
While a channel is '''open''' and '''attached''', the device channel could disappear for some reason (could be unplugged).  As a result, the Phidget library would '''detach''' the user channel, and update the {{Code|Attached}} property to be '''false'''.  A program could poll the {{Code|Attached}} property to detect when the channel becomes '''dettached''', or set a detach handler to be notified asynchronously.
* Non-GUI applications (GUIs usually are event driven)
* The user driving the device rather than listening to it
* Low-power applications that only need to read a sensor on very infrequent intervals


Logic code is relatively easy to writeFor example, creating and opening a Phidget in logic code might be written like this:
====Data====
While a channel is '''open''' and '''attached''', data and status updates received by the Phidget library are delivered to the channelA program could poll data and status properties (for example, {{Code|Acceleration}}, {{Code|Temperature}}, and {{Code|State}}), or set handlers that would be called when the data or state changes.


<br>
===Recommendations===
Generally, setting event handlers is preferred and the most flexible.  The code required to poll for attach and detach states, and to detect data and state changes can be complicated and error prone.  Event handlers are simple and work in a very predicable manor.


[[Image:logic.png|link=]]
A simple program that only wants to read a small amount of data from a device could simply open a channel and wait for attachment, read a data or state property, and then close the channel. In that case, the code to implement and set event handlers might not be worth the effort.  Error checking however becomes very important, as accessing some channel properties while the channel is '''detached''' will result in an error or exception that could kill the program.  There will always be a race between checking the {{Code|Attached}} property and accessing a data or state property.


<br>
All but the most simple program should set handlers that will be called when a channel attaches or detaches, and when the channel receives data or changes state.  The channel will only receive change events while '''attached''', and no external calls are required to access the changed data, which eliminates a chance for error.  In addition, change triggers and data interval settings will not get reset accidentally if they are always set from within an attach handler, eliminating another common mistake.


This design does not explicitly capture every event that fires when data or input changes. You would typically only use polling when you don't need a constant stream of data. For many Phidgets, the maximum data rate is 1 minute. In some low-power applications where you only want data on hourly intervals or longer, polling with logic code and an internal timer is the most effective solution.
When in doubt, use event handlers.
 
Logic code cannot handle constant, asynchronous data as cleanly as [[#Event Driven Code|event driven code]] can.
 
If you find that in logic code you have a highly complex loop driving your program, you should consider changing some of it to event driven code.  This type of awkward if-loop might look like this:
 
<div class="source">
<syntaxhighlight lang=cpp>
 
  Create Device Software Object
  Open Device
 
  Loop Until Exit Requested {
    if No Device Attached {
        Try to open device until timeout
        if Wait Timeout Reached {
            break
        } else {
            Initialize Device
        }
    } else {  // Device Is Attached
        if Device Data Type 1 Changed {
            Do Something
        }
        if Device Data Type 2 Changed {
            Do Something Else
        }
        // ... More data change functions here
    }
    Collect User Input
  }
 
  Close Device
  Delete Device
 
</syntaxhighlight>
</div>
 
In the next section, we'll talk about how events can make this type of program easier to write.
 
=== Event Driven Code ===
 
Event driven code allows for clean handling of complex, asynchronous programs:
*Handling multiple Phidgets
*Handling active plugging or unplugging of the Phidget (multiple attach and detach events)
*Working behind a GUI, as many GUIs are already event driven
*Capturing all sensor data - or input and output - without constantly polling
 
''Without'' event driven code, you will need to constantly poll the device to see if any state has changed.  If you poll at a slower rate than your input or output changes, you will not capture all data.
 
However, event driven code is usually not as useful or efficient for:
*Only one open and close event
*Using only one device
*Having the user make changes to the device (in contrast to reading data ''from'' the device),
 
Event driven code can be difficult to design properly.  It may help to draw out a '''flowchart''', '''state machine''', or at least a '''pseudo-code outline''' of your system design and all events you wish to handle before writing code.  One of the most important things to remember when designing event driven code is to keep the amount of code in the actual event handler to a minimum.  If events are coming in at a rapid pace and you have large blocks of code in the event handlers, there is a good chance that the events coming in will overwhelm the processor and you will start missing data samples, which will manifest as "sample overrun" errors. Actually, it's not necessarily the amount of code, but the amount of time it takes to execute. For this reason, slow processes like printing text to the console or updating a GUI may cause overrun errors. If you have a lot you need to accomplish for each event, make separate functions and call them in an entirely new thread from the event handler.  This way new events can continue to come in while the code executes in parallel.
 
The code examples given for each [[Software Overview#Language Support|specific language]] use event-driven code.
 
For example, creating and opening a Phidget in an event-driven program may look like this:
 
[[Image:event.png|link=]]
 
As you can see, the attach handler and event handler are separate functions that trigger when the Phidget is plugged in or when some data is available, respectively. The rest of the program is logic-driven, and simply initializes the Phidget and GUI, sets up the event handlers, and then waits for events to fire and make updates to the GUI. This continues until the user decides to close the program.
 
Once you have written this code flow, the actual order of events that occur within the program look something like this:
 
[[Image:Eventhandler.jpg|link=|160px]]
 
Note that the device itself (not the program), initiates the function call by 'firing' the event.  This allows you to update only when events fire, and ensures that you can capture and respond to all data events.


=== Further Reading ===
=== Further Reading ===

Revision as of 16:38, 12 July 2017


The Phidget library operates asynchronously. The library fires attach and detach events when a device channel appears and disappears (plugged in or unplugged). After a user channel is attached, data and status updates from the device channel begin being delivered. These events cause the library to update properties of the user channel, and to call any event handlers set by the program.

Discussion

Attach

Once a channel is opened, the Phidget library begins attempting to match the channel to a device channel. While the channel is not attached, the Attached property of the channel will be false. As soon as the Phidget library matches the channel with a device channel the Attached property is updated to be true. A program could poll the Attached property to determine when the channel becomes attached, or set an attach handler to be notified asynchronously.

Detach

While a channel is open and attached, the device channel could disappear for some reason (could be unplugged). As a result, the Phidget library would detach the user channel, and update the Attached property to be false. A program could poll the Attached property to detect when the channel becomes dettached, or set a detach handler to be notified asynchronously.

Data

While a channel is open and attached, data and status updates received by the Phidget library are delivered to the channel. A program could poll data and status properties (for example, Acceleration, Temperature, and State), or set handlers that would be called when the data or state changes.

Recommendations

Generally, setting event handlers is preferred and the most flexible. The code required to poll for attach and detach states, and to detect data and state changes can be complicated and error prone. Event handlers are simple and work in a very predicable manor.

A simple program that only wants to read a small amount of data from a device could simply open a channel and wait for attachment, read a data or state property, and then close the channel. In that case, the code to implement and set event handlers might not be worth the effort. Error checking however becomes very important, as accessing some channel properties while the channel is detached will result in an error or exception that could kill the program. There will always be a race between checking the Attached property and accessing a data or state property.

All but the most simple program should set handlers that will be called when a channel attaches or detaches, and when the channel receives data or changes state. The channel will only receive change events while attached, and no external calls are required to access the changed data, which eliminates a chance for error. In addition, change triggers and data interval settings will not get reset accidentally if they are always set from within an attach handler, eliminating another common mistake.

When in doubt, use event handlers.

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.

Using Multiple Phidgets - It can be difficult to figure out how to use more than one Phidget in your program. This page will guide you through the steps.

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.