|
|
(4 intermediate revisions by one other user not shown) |
Line 1: |
Line 1: |
| [[Category:Programming]] | | [[Category:Programming]]{{Recommended_Flow_Links|{{Flow Page Number|{{PAGENAME}} }} }} |
| | <div class="ProgrammingBasicsIntro"> |
| {| | | {| |
| |style="vertical-align:middle; width: 60%;"|
| | | |
| == Before You Start == | | ==Welcome!== |
| Before trying to start programming Phidgets, you should have a basic understanding of what a Phidget is, and how they can be used. For an introduction to Phidgets, check out [[What is a Phidget?]].
| | Welcome to the Phidget Programming Basics guide! |
|
| |
|
| This page will explain the concepts behind how Phidgets are used in any software application.
| | By following this guide, you will learn the important concepts behind how Phidgets are used in any software application. |
| |{{TOC limit|2}}
| |
| |}
| |
|
| |
|
| == Channels == | | ==Before You Start== |
| To program with Phidgets, it is important to understand how the physical input and output channels of Phidget devices correspond to the software controlling them.
| | We recommend having a few things set up before starting this guide on how to program with Phidgets: |
|
| |
|
| The Phidgets library is very modular, with each part of the device's behaviour split into individual parts called ''Channels''. Each channel represents a single part of a device, such as a single input on a digital input Phidget, the humidity sensor on a humidity Phidget, or one motor on a DC motor controller.
| | '''1.''' You will need the Phidget22 libraries installed on your machine. To get the Phidgets libraries for your operating system, check out our page on [[Operating System Support]]. |
|
| |
|
| [[Image:DCC1000_Channels.jpg|link={{SERVER}}/docs/images/7/72/DCC1000_Channels.jpg|400px|right]]
| | '''2.''' We recommend knowing which programming language you intend to use before starting this guide, so you can follow along. We provide a list of [[Programming Resources|programming languages]] we support, and instructions of how to set them up for use with Phidgets. |
| Each channel has a ''Channel Class'', corresponding to the type of function the channel is to perform. For example, a TemperatureSensor channel will be used to measure temperature, and an RFID channel will deal with an RFID reader. Each channel class is designed make using channels of that class as similar as possible regardless of the Phidget they are a part of, while also supporting the unique features of each. You can find out what channel classes are available to your Phidget by looking at its [[User_Guides|User Guide]].
| |
|
| |
|
| Each channel class has a set of functions tailored to the use of that type of device. For example, a {{Code|VoltageInput}} channel has functions you can use to control and read the Voltage Input, such as setting the data interval or reading the voltage:
| | '''3.''' This guide will work best if you have a Phidget to work with, and have already tried it out using the '''Phidget22 Control Panel'''. If you haven't yet, navigate to the [[Product_Page_Links|product page]] for your Phidget and follow the instructions in the '''User Guide''' tab to try it out. |
| | | |
| | {|class="ProgrammingBasicsTOC" style="color: black; width: 100%; border-style: solid; border-width: 2px;" cellpadding="10" |
| | |<font size=5>'''Table of Contents'''</font> |
| | <font size=4> |
| | #'''[[{{Flow Page Number Name| 1 }}]]''' |
| | #'''[[{{Flow Page Number Name| 2 }}]]''' |
| | #'''[[{{Flow Page Number Name| 3 }}]]''' |
| | #'''[[{{Flow Page Number Name| 4 }}]]''' |
| | #'''[[{{Flow Page Number Name| 5 }}]]''' |
| | #'''[[{{Flow Page Number Name| 6 }}]]''' |
| | #'''[[{{Flow Page Number Name| 7 }}]]''' |
| | #'''[[{{Flow Page Number Name| 8 }}]]''' |
| | #'''[[{{Flow Page Number Name| 9 }}]]''' |
| | #'''[[{{Flow Page Number Name| 10 }}]]''' |
| | #'''[[{{Flow Page Number Name| 11 }}]]''' |
| | #'''[[{{Flow Page Number Name| 12 }}]]''' |
| | #'''[[{{Flow Page Number Name| 13 }}]]''' |
| | #'''[[{{Flow Page Number Name| 14 }}]]''' |
| | #'''[[{{Flow Page Number Name| 15 }}]]''' |
| | #'''[[{{Flow Page Number Name| 16 }}]]''' |
| | </font> |
| | |} |
| | |} |
|
| |
|
| The set of all functions and other tools used to program with Phidgets is called the Phidgets Application Programming Interface ('''API'''). In addition to features unique to the class, every channel class also includes some functionality common to all channel classes, documented in the Phidgets API under {{Code|Phidget Common}}. For example, every channel has basic functions like {{Code|open()}} and {{Code|close()}}, which are the same no matter which Phidget you're using.
| | {|class="ProgrammingBasicsTOCsmall" style="color: black; width: 100%; border-style: solid; border-width: 2px;" cellpadding="10" |
| | | |<font size=5>'''Table of Contents'''</font> |
| ==Outline of a Program with Phidgets==
| | <font size=4> |
| [[Image:General_Phidget_Program_Flowchart.png|right|200px]]
| | #'''[[{{Flow Page Number Name| 1 }}]]''' |
| Every Phidget channel you use in any program will follow the same life cycle:
| | #'''[[{{Flow Page Number Name| 2 }}]]''' |
| # '''[[#Creating a Channel|Create]] a channel:''' Make a variable to keep track of your Phidget | | #'''[[{{Flow Page Number Name| 3 }}]]''' |
| # '''[[#Addressing Phidgets| Address]] the channel:''' Set some basic parameters to indicate which Phidget to connect to. | | #'''[[{{Flow Page Number Name| 4 }}]]''' |
| #*You can specify as much, or as little as you deem necessary. You can even use a Phidget without specifying any parameters, if your system is simple enough.
| | #'''[[{{Flow Page Number Name| 5 }}]]''' |
| # '''[[#Opening a Channel|Open]] the channel:''' Opening the channel will begin trying to match a physical Phidget channel to your software channel. | | #'''[[{{Flow Page Number Name| 6 }}]]''' |
| # '''[[#Attaching a Channel|Detect when the channel is attached]]:''' Your program must wait until a physical Phidget channel has been ''attached'' to your software channel. | | #'''[[{{Flow Page Number Name| 7 }}]]''' |
| #* The attachment process is handled automatically, and will attach to the first available Phidget channel that matches all your specified addressing parameters.
| | #'''[[{{Flow Page Number Name| 8 }}]]''' |
| #* A channel is attached when the Phidget libraries link a physical Phidget channel to your software channel.
| | #'''[[{{Flow Page Number Name| 9 }}]]''' |
| #* Waiting for attachment can be handled automatically as part of ''opening'' the channel or separately, as best suits your program.
| | #'''[[{{Flow Page Number Name| 10 }}]]''' |
| # '''[[#Do Things with a Channel|Do things with the channel]]:''' Send commands to and receive data from your Phidget. | | #'''[[{{Flow Page Number Name| 11 }}]]''' |
| #* This section will encompass the majority of your program. The Phidget API / libraries will make this process as straightforward as possible, and is similar across all types of Phidgets.
| | #'''[[{{Flow Page Number Name| 12 }}]]''' |
| # '''[[#Close a Channel|Close]] the channel:''' Once your program is done, you close the Phidget channel. | | #'''[[{{Flow Page Number Name| 13 }}]]''' |
| #* This frees up the Phidget for the next program that might need it. | | #'''[[{{Flow Page Number Name| 14 }}]]''' |
| | | #'''[[{{Flow Page Number Name| 15 }}]]''' |
| ==A Closer Look, with Examples==
| | #'''[[{{Flow Page Number Name| 16 }}]]''' |
| | | </font> |
| For a closer look at the parts of a Phidget program, this section will dissect the sections of a Phidget program in more detail. Small code snippets are provided for each step in the sections below to provide a representation of the code.
| | |} |
| | | </div> |
| For a look at how these steps are handled in your specific programming language, check out the
| | {{Flow_Navigation_Buttons|{{Flow Page Number|{{PAGENAME}} }} }} |
| '''Write Code''' section of the [[Programming Resources|Language Page]] for your programming language.
| |
| | |
| The best reference to the features of each channel class is the {{Phidget22API}} for your specific device and language. This page is intended to be a high-level introduction.
| |
| | |
| === Creating a Channel ===
| |
| | |
| To control a Phidget channel, you must first create an instance of its channel class that will be used to keep track of the channel through your program.
| |
| | |
| For example:
| |
| | |
| <tabber>
| |
| Java=<syntaxhighlight lang=java>
| |
| // Create a new Accelerometer channel
| |
| Accelerometer accel = new Accelerometer();
| |
| </syntaxhighlight>
| |
| <syntaxhighlight lang=java>
| |
| // Create a new RFID channel
| |
| RFID rfid = new RFID();
| |
| </syntaxhighlight>
| |
| |-|
| |
| Python=<syntaxhighlight lang=python>
| |
| # Create a new Accelerometer channel
| |
| accel = Accelerometer()
| |
| </syntaxhighlight>
| |
| <syntaxhighlight lang=python>
| |
| # Create a new RFID channel
| |
| rfid = RFID()
| |
| </syntaxhighlight>
| |
| |-|
| |
| C#=<syntaxhighlight lang=cSharp>
| |
| // Create a new Accelerometer channel
| |
| Accelerometer accel = new Accelerometer();
| |
| </syntaxhighlight>
| |
| <syntaxhighlight lang=cSharp>
| |
| // Create a new RFID channel
| |
| RFID rfid = new RFID();
| |
| </syntaxhighlight>
| |
| |-|
| |
| C=<syntaxhighlight lang=c>
| |
| // Create a new Accelerometer channel
| |
| PhidgetAccelerometerHandle ch;
| |
| PhidgetAccelerometer_create(&ch);
| |
| </syntaxhighlight>
| |
| <syntaxhighlight lang=c>
| |
| // Create a new RFID channel
| |
| PhidgetRFIDHandle ch;
| |
| PhidgetRFID_create(&ch);
| |
| </syntaxhighlight>
| |
| </tabber>
| |
| | |
| ===Addressing Phidgets===
| |
| | |
| In this step you set up the parameters the Phidget library will use to match your software channel to a physical channel on a Phidget.
| |
| | |
| By default, the matching code in the Phidget library will attach the first available Phidget channel that is of the correct channel class. This works well for single Phidgets, but can be insufficient for systems with multiple Phidgets present. If not enough addressing parameters are specified, your software channel may attach to the wrong Phidget.
| |
| | |
| Full descriptions of all the addressing parameters can be found on the [[Addressing Phidgets]] page.
| |
| | |
| ==== Addressing Example ====
| |
| | |
| In this example, we have a [{{SERVER}}/products.php?product_id=TMP1101 TMP1101 4x Thermocouple Phidget] and a [{{SERVER}}/products.php?product_id=HUB0000 HUB0000 VINT Hub].
| |
| | |
| [[Image:channel-matching-3.jpg|link=|500px|center]]
| |
| | |
| If we wanted to open the thermocouple connected to channel 0, on hub port 2, the Java code would look like:
| |
| | |
| <tabber>
| |
| Java=<syntaxhighlight lang=java>
| |
| TemperatureSensor tc = new TemperatureSensor(); //Create
| |
| | |
| tc.setDeviceSerialNumber(370181); //Address
| |
| tc.setHubPort(2);
| |
| tc.setChannel(0);
| |
| | |
| tc.open(5000); //Open
| |
| </syntaxhighlight>
| |
| |-|
| |
| Python=<syntaxhighlight lang=python>
| |
| tc = TemperatureSensor() #Create
| |
| | |
| tc.setDeviceSerialNumber(370181) #Address
| |
| tc.setHubPort(2)
| |
| tc.setChannel(0)
| |
| | |
| tc.openWaitForAttachment(5000); #Open
| |
| </syntaxhighlight>
| |
| |-|
| |
| C#=<syntaxhighlight lang=cSharp>
| |
| TemperatureSensor tc = new TemperatureSensor(); //Create
| |
| | |
| tc.DeviceSerialNumber = 370181; //Address
| |
| tc.HubPort = 2;
| |
| tc.Channel = 0;
| |
| | |
| tc.openWaitForAttachment(5000); //Open
| |
| </syntaxhighlight>
| |
| |-|
| |
| C=<syntaxhighlight lang=c>
| |
| PhidgetTemperatureSensorHandle tc; //Create
| |
| PhidgetTemperatureSensor_create(&tc);
| |
| | |
| PhidgetTemperatureSensor_setDeviceSerialNumber(tc, 370181); //Address
| |
| PhidgetTemperatureSensor_setHubPort(tc, 2);
| |
| PhidgetTemperatureSensor_setChannel(tc, 0);
| |
| | |
| Phidget_openWaitForAttachment((PhidgetHandle)tc, 5000); //Open
| |
| </syntaxhighlight>
| |
| </tabber>
| |
| | |
| === Opening a Channel ===
| |
| | |
| After you have created and addressed a channel, you need to open it to begin the process of attaching the software channel to a physical channel.
| |
| | |
| For example:
| |
| | |
| <tabber>
| |
| Java=<syntaxhighlight lang=java>
| |
| ch.open(5000);
| |
| </syntaxhighlight>
| |
| |-|
| |
| Python=<syntaxhighlight lang=python>
| |
| ch.openWaitForAttachment(5000);
| |
| </syntaxhighlight>
| |
| |-|
| |
| C#=<syntaxhighlight lang=cSharp>
| |
| ch.Open(5000);
| |
| </syntaxhighlight>
| |
| |-|
| |
| C=<syntaxhighlight lang=c>
| |
| Phdiget_openWaitForAttachment((PhidgetHandle)ch, 5000);
| |
| </syntaxhighlight>
| |
| </tabber>
| |
| | |
| ''In Java and C# <code>open()</code> is overloaded. In other languages, you would use <code>openWaitForAttachment(5000)</code> to perform the same function.'' | |
| | |
| The <code>openWaitForAttachment()</code> function will hold the program until a Phidget channel matching the one you specified is attached, or the function times out. There is a similar function called <code>open()</code> that will do the attachment process in the background, and allow your program to continue before the channel has been attached.
| |
| | |
| The <code>open()</code> and <code>openWaitForAttachment()</code> functions only begin the process of matching the channel handle you created to a channel of a Phidget device, and do not actually ''open'' the Phidget itself. An open channel that does not match any Phidget channels at first can still attach to a matching channel that is plugged in long after it was first opened.
| |
| | |
| === Attaching a Channel ===
| |
| | |
| When a channel is open (and not ''attached''), the system will continue to try to match it with a
| |
| Phidget device channel until either a match is found, or the channel is closed.
| |
| | |
| Any one physical channel can only be attached to one software channel at a time. For example, if you connected a single Phidget Accelerometer to a computer, and you created and opened two software <code>Accelerometer</code> channels, only one of the channels would attach while the other would remain ''open'' but not ''attached''. If the ''attached'' channel were to be closed, the other software channel would then attach to the Accelerometer.
| |
| | |
| | |
| When the software channel is matched with a physical channel, the channel is ''attached'' and an <code>Attach</code> event is fired.
| |
| | |
| An event handler can be registered to catch the <code>Attach</code> event. Each channel also has an <code>Attached</code> property that can be read to determine if the channel has been matched to a physical channel.
| |
| | |
| The following examples show how to set an event handler to detect the <code>Attach</code> event:
| |
| | |
| <tabber>
| |
| Java=<syntaxhighlight lang=java>
| |
| public static DigitalInputAttachListener onAttach = new DigitalInputAttachListener() {
| |
| @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>
| |
| |-| | |
| Python=<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 Phidgetch = DigitalInput()
| |
| ...
| |
| #Assign the handler that will be called when the event occurs
| |
| ch.setOnAttachHandler(onAttachHandler)
| |
| </syntaxhighlight>
| |
| |-|
| |
| C#=<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=<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>
| |
| </tabber>
| |
| | |
| The attach event handler should be set '''before''' the channel is opened; otherwise, the attach event could occur before the handler is set to deal with it.
| |
| | |
| | |
| '''Note:''' Once a physical channel is attached to a software channel, it will not be available to attach to another software channel until the first channel is closed. The one exception is if the Phidget device channel is ''attached'' over the network through the [[Phidget Network Server]]. In that case, multiple channels are allowed to match and attach to the Phidget device channel. Some Phidgets, such as motor controllers will never match more than one channel at a time, for safety reasons.
| |
| | |
| === Do Things with a Channel ===
| |
| | |
| After a channel has been ''opened'' and ''attached'', software can control the Phidget through the functions available to its channel class.
| |
| | |
| This is the stage of your program where you can send commands to your channel, and handle the information it sends back.
| |
| | |
| Generally, we recommend configuring any initial setup for your channel in its <code>Attach</code> handler, so it is set up before your program uses it, and so it can be re-initialized in case it is somehow detached and re-attached (such as if it is unplugged and plugged back in).
| |
| | |
| Additionally, you can set up event handlers to handle events from the channel, such as when a state change occurs, or when sensor data is received. Event handlers should be set up before opening the channel to avoid missing events, but they will begin executing during this phase of the program.
| |
| | |
| For example, with a Voltage Input channel, you could set up an event handler to process Voltage Change events.
| |
| | |
| <tabber>
| |
| Java=<syntaxhighlight lang=java>
| |
| //Declare the event listener
| |
| public static VoltageInputVoltageChangeListener onVoltageChange = new VoltageInputVoltageChangeListener() {
| |
| @Override
| |
| public void onVoltageChange(VoltageInputVoltageChangeEvent e) {
| |
| System.out.println("Voltage: " + e.getVoltage());
| |
| }
| |
| }; | |
| ...
| |
| VoltageInput ch;
| |
| ...
| |
| //Assign the event listener that will be called when the event occurs
| |
| ch.addVoltageChangeListener(onVoltageChange);
| |
| </syntaxhighlight> | |
| |-| | |
| Python=<syntaxhighlight lang=python>
| |
| #Declare the event handler
| |
| def onVoltageChangeHandler(self, voltage):
| |
| print("Voltage: " + str(voltage))
| |
| ...
| |
| ch = VoltageInput()
| |
| ...
| |
| #Assign the handler that will be called when the event occurs
| |
| ch.setOnVoltageChangeHandler(onVoltageChangeHandler)
| |
| </syntaxhighlight> | |
| |-| | |
| C#=<syntaxhighlight lang=cSharp>
| |
| //Declare the event handler
| |
| void voltageChange(object sender, Phidget22.Events.VoltageChangeEventArgs e) {
| |
| Console.WriteLine("Voltage: " + e.Voltage.ToString());
| |
| } | |
| ...
| |
| VoltageInput ch;
| |
| ...
| |
| //Assign the handler that will be called when the event occurs
| |
| ch.VoltageChange += voltageChange;
| |
| </syntaxhighlight>
| |
| |-|
| |
| C=<syntaxhighlight lang=c>
| |
| //Declare the event handler
| |
| static void CCONV onVoltageChangeHandler(PhidgetVoltageInputHandle ph, void *ctx, double voltage) {
| |
| printf("Voltage: %lf\n", voltage);
| |
| } | |
| ...
| |
| PhidgetVoltageInputHandle ch;
| |
| ...
| |
| //Assign the handler that will be called when the event occurs
| |
| PhidgetVoltageInput_setOnVoltageChangeHandler(ch, onVoltageChangeHandler, NULL);
| |
| </syntaxhighlight>
| |
| </tabber>
| |
| | |
| | |
| Alternately, data from the device can be accessed from the main body of a program using the associated properties. Note that the values returned by getting the values of these properties will be the same as the value from the latest event associated with the property.
| |
| | |
| <tabber>
| |
| Java=<syntaxhighlight lang=java>
| |
| double val = ch.getVoltage();
| |
| </syntaxhighlight>
| |
| |-|
| |
| Python=<syntaxhighlight lang=python>
| |
| val = ch.getVoltage()
| |
| </syntaxhighlight>
| |
| |-|
| |
| C#=<syntaxhighlight lang=cSharp>
| |
| double val = ch.Voltage;
| |
| </syntaxhighlight>
| |
| |-|
| |
| C=<syntaxhighlight lang=c>
| |
| double voltage;
| |
| PhidgetVoltageInput_getVoltage(ch, &voltage);
| |
| </syntaxhighlight>
| |
| </tabber>
| |
| | |
| === Close a Channel ===
| |
| | |
| When you are finished with a channel, you should close and (in some languages) delete it. Once closed, the physical Phidget channel the software channel was matched to will be released, and made available to attach to other software channels.
| |
| | |
| For example:
| |
| | |
| <tabber>
| |
| Java=<syntaxhighlight lang=java>
| |
| ch.close();
| |
| </syntaxhighlight>
| |
| |-|
| |
| Python=<syntaxhighlight lang=python>
| |
| ch.close()
| |
| </syntaxhighlight>
| |
| |-|
| |
| C#=<syntaxhighlight lang=cSharp>
| |
| ch.Close();
| |
| </syntaxhighlight>
| |
| |-|
| |
| C=<syntaxhighlight lang=c>
| |
| Phidget_close((PhidgetHandle)ch);
| |
| PhidgetDigitalInput_delete(&ch); //Replace DigitalInput with the channel class of your channel
| |
| </syntaxhighlight>
| |
| </tabber>
| |
| | |
| | |
| When you close a channel, it will reset all of the properties of that channel. For example, a digital output will revert back to FALSE when it is closed.
| |
| | |
| == Further Reading ==
| |
| | |
| [[Using Multiple Phidgets]] - Tips about using multiple Phidgets in your program.
| |
| | |
| [[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.
| |
| | |
| [[Data Interval/Change Trigger]] - Learn about these two properties that control how much data comes in from your sensors.
| |
| | |
| [[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.
| |