/*
 * This file is part of libphidget22
 *
 * Copyright (c) 2015-2026 Phidgets Inc.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the copyright holder nor the names of its
 *    contributors may be used to endorse or promote products derived from
 *    this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

/**
 * @mainpage Phidget22 C API
 *
 * This header declares the Phidget22 C API: the low-level interface used to create, configure, and
 * communicate with Phidget devices.
 *
 * Every sensor, motor, or other input/output is represented by a channel, and each channel type has
 * its own handle (eg. `PhidgetAccelerometerHandle`), declared together with its methods,
 * properties, and events under its own module - see the **Topics** page for the full API reference,
 * organized by channel type.
 *
 * The typical lifecycle for any channel is:
 *
 * *   Create a channel object with its `_create()` function.
 * *   Optionally narrow down which physical channel to attach to, eg. by serial number, hub
 *     port, or channel index.
 * *   Optionally subscribe to its events.
 * *   Call `Phidget_open()` to begin the attach process.
 * *   Read and write the channel's properties and call its methods to send and receive data.
 * *   Call `Phidget_close()` and then the channel's `_delete()` function to release it.
 *
 * Every function returns a @ref PhidgetReturnCode indicating success or failure.
 */

#ifndef PHIDGET22_H
#define PHIDGET22_H

#if !defined(__BEGIN_DECLS)
    #if defined(__cplusplus)
        #define __BEGIN_DECLS     extern "C" {
        #define __END_DECLS       }
    #else
        #define __BEGIN_DECLS
        #define __END_DECLS
    #endif
#endif

#if defined(_WIN32)
    #define CCONV __stdcall
#else
    #define CCONV
#endif

#if defined(_WIN32)
    #define PHIDGET22_API __declspec(dllimport)
#else
    #if defined(__GNUC__) && __GNUC__ >= 4
        #define PHIDGET22_API __attribute__((visibility("default")))
    #else
        #define PHIDGET22_API
    #endif
#endif

#include <stdint.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdlib.h>

#ifndef _PHIDGET_CONSTANTS_H_
#define _PHIDGET_CONSTANTS_H_
#define PUNK_BOOL 0x02          /**< Unknown Boolean */
#define PUNK_INT8 INT8_MAX      /**< Unknown Short   (8-bit) */
#define PUNK_UINT8 UINT8_MAX    /**< Unknown Short   (8-bit unsigned) */
#define PUNK_INT16 INT16_MAX    /**< Unknown Short   (16-bit) */
#define PUNK_UINT16 UINT16_MAX  /**< Unknown Short   (16-bit unsigned) */
#define PUNK_INT32 INT32_MAX    /**< Unknown Integer (32-bit) */
#define PUNK_UINT32 UINT32_MAX  /**< Unknown Integer (32-bit unsigned) */
#define PUNK_INT64 INT64_MAX    /**< Unknown Integer (64-bit) */
#define PUNK_UINT64 UINT64_MAX  /**< Unknown Integer (64-bit unsigned) */
#define PUNK_DBL 1e300          /**< Unknown Double */
#define PUNK_FLT 1e30           /**< Unknown Float */
#define PUNK_ENUM INT32_MAX     /**< Unknown Enum */
#define PUNK_SIZE SIZE_MAX      /**< Unknown size_t */

#define PFALSE 0x00 /**< False. Used for boolean values. */
#define PTRUE 0x01  /**< True. Used for boolean values. */

#define PRIphid "P" /**< mos_printf format string for printing a PhidgetHandle */
#endif /* _PHIDGET_CONSTANTS_H_ */

__BEGIN_DECLS


/**
 * Encoder interface mode
 */
typedef enum {
    ENCODER_IO_MODE_PUSH_PULL = 0x1,            /**< Push-Pull */
    ENCODER_IO_MODE_LINE_DRIVER_2K2 = 0x2,      /**< Line Driver 2.2K */
    ENCODER_IO_MODE_LINE_DRIVER_10K = 0x3,      /**< Line Driver 10K */
    ENCODER_IO_MODE_OPEN_COLLECTOR_2K2 = 0x4,   /**< Open Collector 2.2K */
    ENCODER_IO_MODE_OPEN_COLLECTOR_10K = 0x5,   /**< Open Collector 10K */
} Phidget_EncoderIOMode;

/**
 * The result codes returned by all functions
 */
typedef enum {
    EPHIDGET_OK = 0x0,              /**< Success */
    EPHIDGET_PERM = 0x1,            /**< Not Permitted */
    EPHIDGET_NOENT = 0x2,           /**< No Such Entity */
    EPHIDGET_TIMEOUT = 0x3,         /**< Timed Out */
    EPHIDGET_KEEPALIVE = 0x3a,      /**< Keep Alive Failure */
    EPHIDGET_INTERRUPTED = 0x4,     /**< Op Interrupted */
    EPHIDGET_IO = 0x5,              /**< IO Issue */
    EPHIDGET_NOMEMORY = 0x6,        /**< Memory Issue */
    EPHIDGET_ACCESS = 0x7,          /**< Access (Permission) Issue */
    EPHIDGET_FAULT = 0x8,           /**< Address Issue */
    EPHIDGET_BUSY = 0x9,            /**< Resource Busy */
    EPHIDGET_EXIST = 0xa,           /**< Object Exists */
    EPHIDGET_NOTDIR = 0xb,          /**< Object is not a directory */
    EPHIDGET_ISDIR = 0xc,           /**< Object is a directory */
    EPHIDGET_INVALID = 0xd,         /**< Invalid */
    EPHIDGET_NFILE = 0xe,           /**< Too many open files in system */
    EPHIDGET_MFILE = 0xf,           /**< Too many open files */
    EPHIDGET_NOSPC = 0x10,          /**< Not enough space */
    EPHIDGET_FBIG = 0x11,           /**< File too Big */
    EPHIDGET_ROFS = 0x12,           /**< Read Only Filesystem */
    EPHIDGET_RO = 0x13,             /**< Read Only Object */
    EPHIDGET_UNSUPPORTED = 0x14,    /**< Operation Not Supported */
    EPHIDGET_INVALIDARG = 0x15,     /**< Invalid Argument */
    EPHIDGET_AGAIN = 0x16,          /**< Try again */
    EPHIDGET_NOTEMPTY = 0x1a,       /**< Not Empty */
    EPHIDGET_UNEXPECTED = 0x1c,     /**< Unexpected Error */
    EPHIDGET_DUPLICATE = 0x1b,      /**< Duplicate */
    EPHIDGET_BADPASSWORD = 0x25,    /**< Bad Credential */
    EPHIDGET_NETUNAVAIL = 0x2d,     /**< Network Unavailable */
    EPHIDGET_CONNREF = 0x23,        /**< Connection Refused */
    EPHIDGET_CONNRESET = 0x2e,      /**< Connection Reset */
    EPHIDGET_HOSTUNREACH = 0x30,    /**< No route to host */
    EPHIDGET_NODEV = 0x28,          /**< No Such Device */
    EPHIDGET_WRONGDEVICE = 0x32,    /**< Wrong Device */
    EPHIDGET_PIPE = 0x29,           /**< Broken Pipe */
    EPHIDGET_RESOLV = 0x2c,         /**< Name Resolution Failure */
    EPHIDGET_UNKNOWNVAL = 0x33,     /**< Unknown or Invalid Value */
    EPHIDGET_NOTATTACHED = 0x34,    /**< Device not Attached */
    EPHIDGET_INVALIDPACKET = 0x35,  /**< Invalid or Unexpected Packet */
    EPHIDGET_2BIG = 0x36,           /**< Argument List Too Long */
    EPHIDGET_BADVERSION = 0x37,     /**< Bad Version */
    EPHIDGET_CLOSED = 0x38,         /**< Closed */
    EPHIDGET_NOTCONFIGURED = 0x39,  /**< Not Configured */
    EPHIDGET_EOF = 0x1f,            /**< End of File */
    EPHIDGET_FAILSAFE = 0x3b,       /**< Failsafe Triggered */
    EPHIDGET_UNKNOWNVALHIGH = 0x3c, /**< Invalid Value - Too High */
    EPHIDGET_UNKNOWNVALLOW = 0x3d,  /**< Invalid Value - Too Low */
    EPHIDGET_BADPOWER = 0x3e,       /**< Bad Power Supply */
    EPHIDGET_POWERCYCLE = 0x3f,     /**< Power Cycle Required */
    EPHIDGET_HALLSENSOR = 0x40,     /**< Hall Sensor Error */
    EPHIDGET_BADCURRENT = 0x41,     /**< Bad Current Readings */
    EPHIDGET_BADCONNECTION = 0x42,  /**< Bad Connection */
    EPHIDGET_NACK = 0x43,           /**< NACK */
    EPHIDGET_REJECTED = 0x44,       /**< Rejected */
} PhidgetReturnCode;

/**
 * The error code from an Error event
 */
typedef enum {
    EEPHIDGET_BADVERSION = 0x1,         /**< Version Mismatch */
    EEPHIDGET_BUSY = 0x2,               /**< Phidget in Use */
    EEPHIDGET_NETWORK = 0x3,            /**< Network Error */
    EEPHIDGET_DISPATCH = 0x4,           /**< Dispatch Error */
    EEPHIDGET_FAILURE = 0x5,            /**< General Failure */
    EEPHIDGET_OK = 0x1000,              /**< Error Cleared */
    EEPHIDGET_OVERRUN = 0x1002,         /**< Sample Overrun */
    EEPHIDGET_PACKETLOST = 0x1003,      /**< Packet Lost */
    EEPHIDGET_WRAP = 0x1004,            /**< Wrap-Around */
    EEPHIDGET_OVERTEMP = 0x1005,        /**< Over-Temperature */
    EEPHIDGET_OVERCURRENT = 0x1006,     /**< Over-Current */
    EEPHIDGET_OUTOFRANGE = 0x1007,      /**< Out of Range */
    EEPHIDGET_BADPOWER = 0x1008,        /**< Bad Power */
    EEPHIDGET_SATURATION = 0x1009,      /**< Saturation */
    EEPHIDGET_OVERVOLTAGE = 0x100b,     /**< Over-Voltage */
    EEPHIDGET_FAILSAFE = 0x100c,        /**< Failsafe */
    EEPHIDGET_VOLTAGEERROR = 0x100d,    /**< Voltage Error */
    EEPHIDGET_ENERGYDUMP = 0x100e,      /**< Energy Dump */
    EEPHIDGET_MOTORSTALL = 0x100f,      /**< Motor Stall */
    EEPHIDGET_INVALIDSTATE = 0x1010,    /**< Invalid State */
    EEPHIDGET_BADCONNECTION = 0x1011,   /**< Bad Connection */
    EEPHIDGET_OUTOFRANGEHIGH = 0x1012,  /**< Out of Range High */
    EEPHIDGET_OUTOFRANGELOW = 0x1013,   /**< Out of Range Low */
    EEPHIDGET_FAULT = 0x1014,           /**< Fault Condition */
    EEPHIDGET_ESTOP = 0x1015,           /**< External Stop Condition */
    EEPHIDGET_BADCURRENT = 0x1016,      /**< Bad Current */
} Phidget_ErrorEventCode;

/**
 * Phidget device ID
 */
typedef enum {
    PHIDID_NOTHING = 0x0,                   /**< Unknown device */
    PHIDID_UNKNOWN = 0x7d,                  /**< Unknown Device */
    PHIDID_DIGITALINPUT_PORT = 0x5f,        /**< Hub Port - Digital Input mode */
    PHIDID_DIGITALOUTPUT_PORT = 0x60,       /**< Hub Port - Digital Output mode */
    PHIDID_VOLTAGEINPUT_PORT = 0x61,        /**< Hub Port - Voltage Input mode */
    PHIDID_VOLTAGERATIOINPUT_PORT = 0x62,   /**< Hub Port - Voltage Ratio Input mode */
    PHIDID_DICTIONARY = 0x6f,               /**< Dictionary */
    PHIDID_1000 = 0x2,                      /**< PhidgetServo 1-Motor (1000) */
    PHIDID_1001 = 0x3,                      /**< PhidgetServo 4-Motor (1001) */
    PHIDID_1002 = 0x4,                      /**< PhidgetAnalog 4-Output (1002) */
    PHIDID_1008 = 0x5,                      /**< PhidgetAccelerometer 2-Axis (1008) */
    PHIDID_1010_1013_1018_1019 = 0x6,       /**< PhidgetInterfaceKit 8/8/8 (1010, 1013, 1018, 1019) */
    PHIDID_1011 = 0x7,                      /**< PhidgetInterfaceKit 2/2/2 (1011) */
    PHIDID_1012 = 0x8,                      /**< PhidgetInterfaceKit 0/16/16 (1012) */
    PHIDID_1014 = 0x9,                      /**< PhidgetInterfaceKit 0/0/4 (1014) */
    PHIDID_1015 = 0xa,                      /**< PhidgetLinearTouch (1015) */
    PHIDID_1016 = 0xb,                      /**< PhidgetCircularTouch (1016) */
    PHIDID_1017 = 0xc,                      /**< PhidgetInterfaceKit 0/0/8 (1017) */
    PHIDID_1023 = 0xd,                      /**< PhidgetRFID (1023) */
    PHIDID_1024 = 0xe,                      /**< PhidgetRFID Read-Write (1024) */
    PHIDID_1030 = 0xf,                      /**< PhidgetLED-64 (1030) */
    PHIDID_1031 = 0x10,                     /**< PhidgetLED-64 Advanced (1031) */
    PHIDID_1032 = 0x11,                     /**< PhidgetLED-64 Advanced (1032) */
    PHIDID_1040 = 0x12,                     /**< PhidgetGPS (1040) */
    PHIDID_1041 = 0x13,                     /**< PhidgetSpatial 0/0/3 Basic (1041) */
    PHIDID_1042 = 0x14,                     /**< PhidgetSpatial 3/3/3 Basic (1042) */
    PHIDID_1043 = 0x15,                     /**< PhidgetSpatial Precision 0/0/3 High Resolution (1043) */
    PHIDID_1044 = 0x16,                     /**< PhidgetSpatial Precision 3/3/3 High Resolution (1044) */
    PHIDID_1045 = 0x17,                     /**< PhidgetTemperatureSensor IR (1045) */
    PHIDID_1046 = 0x18,                     /**< PhidgetBridge 4-Input (1046) */
    PHIDID_1047 = 0x19,                     /**< PhidgetEncoder HighSpeed 4-Input (1047) */
    PHIDID_1048 = 0x1a,                     /**< PhidgetTemperatureSensor 4-Input (1048) */
    PHIDID_1049 = 0x1b,                     /**< PhidgetSpatial 0/0/3 (1049) */
    PHIDID_1051 = 0x1c,                     /**< PhidgetTemperatureSensor 1-Input (1051) */
    PHIDID_1052 = 0x1d,                     /**< PhidgetEncoder (1052) */
    PHIDID_1053 = 0x1e,                     /**< PhidgetAccelerometer 2-Axis (1053) */
    PHIDID_1054 = 0x1f,                     /**< PhidgetFrequencyCounter (1054) */
    PHIDID_1054_ACCEL = 0xaa,               /**< PhidgetAccelerometer 2-Axis (1054) */
    PHIDID_1055 = 0x20,                     /**< PhidgetIR (1055) */
    PHIDID_1056 = 0x21,                     /**< PhidgetSpatial 3/3/3 (1056) */
    PHIDID_1057 = 0x22,                     /**< PhidgetEncoder HighSpeed (1057) */
    PHIDID_1058 = 0x23,                     /**< PhidgetPHSensor (1058) */
    PHIDID_1059 = 0x24,                     /**< PhidgetAccelerometer 3-Axis (1059) */
    PHIDID_1060 = 0x25,                     /**< PhidgetMotorControl LV (1060) */
    PHIDID_1061 = 0x26,                     /**< PhidgetAdvancedServo 8-Motor (1061) */
    PHIDID_1062 = 0x27,                     /**< PhidgetStepper Unipolar 4-Motor (1062) */
    PHIDID_1063 = 0x28,                     /**< PhidgetStepper Bipolar 1-Motor (1063) */
    PHIDID_1064 = 0x29,                     /**< PhidgetMotorControl HC (1064) */
    PHIDID_1065 = 0x2a,                     /**< PhidgetMotorControl 1-Motor (1065) */
    PHIDID_1066 = 0x2b,                     /**< PhidgetAdvancedServo 1-Motor (1066) */
    PHIDID_1067 = 0x2c,                     /**< PhidgetStepper Bipolar HC (1067) */
    PHIDID_1202_1203 = 0x2d,                /**< PhidgetTextLCD 20x2 with PhidgetInterfaceKit 8/8/8 (1202, 1203) */
    PHIDID_1204 = 0x2e,                     /**< PhidgetTextLCD Adapter (1204) */
    PHIDID_1215__1218 = 0x2f,               /**< PhidgetTextLCD 20x2 (1215, 1216, 1217, 1218) */
    PHIDID_1219__1222 = 0x30,               /**< PhidgetTextLCD 20x2 with PhidgetInterfaceKit 0/8/8 (1219, 1220, 1221, 1222) */
    PHIDID_ADP0001 = 0x86,                  /**< I2C Adapter Phidget */
    PHIDID_ADP0002 = 0xa0,                  /**< SPI Adapter Phidget */
    PHIDID_ADP1000 = 0x31,                  /**< pH Adapter Phidget (ADP1000) */
    PHIDID_DAQ1000 = 0x33,                  /**< 8x Voltage Input Phidget (DAQ1000) */
    PHIDID_DAQ1001 = 0x9d,                  /**< 8x Voltage Input Phidget (DAQ1001) */
    PHIDID_DAQ1200 = 0x34,                  /**< 4x Digital Input Phidget (DAQ1200) */
    PHIDID_DAQ1300 = 0x35,                  /**< 4x Isolated Digital Input Phidget (DAQ1300) */
    PHIDID_DAQ1301 = 0x36,                  /**< 16x Isolated Digital Input Phidget (DAQ1301) */
    PHIDID_DAQ1400 = 0x37,                  /**< Versatile Input Phidget (DAQ1400) */
    PHIDID_DAQ1500 = 0x38,                  /**< Wheatstone Bridge Phidget (DAQ1500) */
    PHIDID_DCC1000 = 0x39,                  /**< DC Motor Phidget (DCC1000) */
    PHIDID_DCC1001 = 0x6e,                  /**< 2A DC Motor Phidget (DCC1001) */
    PHIDID_DCC1002 = 0x75,                  /**< 4A DC Motor Phidget (DCC1002) */
    PHIDID_DCC1003 = 0x78,                  /**< 2x DC Motor Phidget (DCC1003) */
    PHIDID_DCC1020 = 0x80,                  /**< 30V 50A DC Motor Phidget (DCC1020) */
    PHIDID_DCC1030 = 0x98,                  /**< 60V 50A DC Motor Phidget (DCC1030) */
    PHIDID_DCC1100 = 0x6c,                  /**< Brushless DC Motor Phidget (DCC1100) */
    PHIDID_DCC1120 = 0x96,                  /**< 30V 50A Brushless DC Motor Phidget (DCC1120) */
    PHIDID_DCC1130 = 0x9a,                  /**< 60V 50A Brushless DC Motor Phidget (DCC1130) */
    PHIDID_DST1000 = 0x3a,                  /**< Distance Phidget (DST1000) */
    PHIDID_DST1001 = 0x79,                  /**< Distance Phidget 650mm (DST1001) */
    PHIDID_DST1002 = 0x7e,                  /**< Distance Phidget 1300mm (DST1002) */
    PHIDID_DST1200 = 0x3b,                  /**< Sonar Phidget (DST1200) */
    PHIDID_ENC1000 = 0x3c,                  /**< Quadrature Encoder Phidget (ENC1000) */
    PHIDID_ENC1001 = 0x9b,                  /**< Quadrature Encoder Phidget (ENC1001) */
    PHIDID_FIRMWARE_UPGRADE_SPI = 0x68,     /**< SPI Phidget in firmware upgrade mode */
    PHIDID_FIRMWARE_UPGRADE_STM32F0 = 0x66, /**< VINT Phidget in firmware upgrade mode, STM32F0 Proc. */
    PHIDID_FIRMWARE_UPGRADE_STM32F3 = 0x91, /**< VINT Phidget in firmware upgrade mode, STM32F3 Proc. */
    PHIDID_FIRMWARE_UPGRADE_STM32G0 = 0x8f, /**< VINT Phidget in firmware upgrade mode, STM32G0 Proc. */
    PHIDID_FIRMWARE_UPGRADE_STM8S = 0x67,   /**< VINT Phidget in firmware upgrade mode, STM8S Proc. */
    PHIDID_FIRMWARE_UPGRADE_USB = 0x65,     /**< USB Phidget in firmware upgrade mode */
    PHIDID_HIN1000 = 0x3d,                  /**< Touch Keypad Phidget (HIN1000) */
    PHIDID_HIN1001 = 0x3e,                  /**< Touch Wheel Phidget (HIN1001) */
    PHIDID_HIN1100 = 0x3f,                  /**< Thumbstick Phidget (HIN1100) */
    PHIDID_HIN1101 = 0x6d,                  /**< Phidget Dial (HIN1101) */
    PHIDID_HUB0000 = 0x40,                  /**< 6-Port USB VINT Hub Phidget (HUB0000) */
    PHIDID_HUB0001 = 0x8e,                  /**< 6-Port USB VINT Hub Phidget (HUB0001) */
    PHIDID_HUB0002 = 0x93,                  /**< 6-Port USB VINT Hub Phidget (HUB0002) */
    PHIDID_HUB0004 = 0x43,                  /**< 6-Port PhidgetSBC VINT Hub Phidget (HUB0004) */
    PHIDID_HUB0007 = 0x94,                  /**< 1-Port USB VINT Hub Phidget (HUB0007) */
    PHIDID_HUB5000 = 0x7b,                  /**< 6-Port Network VINT Hub Phidget (HUB5000) */
    PHIDID_HUM1000 = 0x45,                  /**< Humidity Phidget (HUM1000) */
    PHIDID_HUM1001 = 0x7f,                  /**< Humidity Phidget (HUM1001) */
    PHIDID_HUM1100 = 0x88,                  /**< Soil Moisture Phidget (HUM1100) */
    PHIDID_INTERFACEKIT_4_8_8 = 0x1,        /**< PhidgetInterfaceKit 4/8/8 */
    PHIDID_LCD1100 = 0x46,                  /**< Graphic LCD Phidget (LCD1100) */
    PHIDID_LED0100 = 0xa1,                  /**< Addressable LED Phidget */
    PHIDID_LED1000 = 0x47,                  /**< 32x Isolated LED Phidget (LED1000) */
    PHIDID_LUX1000 = 0x48,                  /**< Light Phidget (LUX1000) */
    PHIDID_MOT0100 = 0x92,                  /**< PhidgetAccelerometer (MOT0100) */
    PHIDID_MOT0109 = 0x8c,                  /**< PhidgetSpatial Precision 3/3/3 (MOT0109) */
    PHIDID_MOT0110 = 0x8d,                  /**< PhidgetSpatial Precision 3/3/3 (MOT0110) */
    PHIDID_MOT1100 = 0x49,                  /**< Accelerometer Phidget (MOT1100) */
    PHIDID_MOT1101 = 0x4a,                  /**< Spatial Phidget (MOT1101) */
    PHIDID_MOT1102 = 0x89,                  /**< Spatial Phidget (MOT1102) */
    PHIDID_OUT1000 = 0x4b,                  /**< 12-bit Voltage Output Phidget (OUT1000) */
    PHIDID_OUT1001 = 0x4c,                  /**< Isolated 12-bit Voltage Output Phidget (OUT1001) */
    PHIDID_OUT1002 = 0x4d,                  /**< Isolated 16-bit Voltage Output Phidget (OUT1002) */
    PHIDID_OUT1100 = 0x4e,                  /**< 4x Digital Output Phidget (OUT1100) */
    PHIDID_PRE1000 = 0x4f,                  /**< Barometer Phidget (PRE1000) */
    PHIDID_RCC0004 = 0x7c,                  /**< PhidgetAdvancedServo 8-Motor (RCC0004) */
    PHIDID_RCC1000 = 0x50,                  /**< 16x RC Servo Phidget (RCC1000) */
    PHIDID_REL1000 = 0x51,                  /**< 4x Relay Phidget (REL1000) */
    PHIDID_REL1100 = 0x52,                  /**< 4x Isolated Solid State Relay Phidget (REL1100) */
    PHIDID_REL1101 = 0x53,                  /**< 16x Isolated Solid State Relay Phidget (REL1101) */
    PHIDID_SAF1000 = 0x54,                  /**< Programmable Power Guard Phidget (SAF1000) */
    PHIDID_SND1000 = 0x55,                  /**< Sound Phidget (SND1000) */
    PHIDID_STC1000 = 0x56,                  /**< Stepper Phidget (STC1000) */
    PHIDID_STC1001 = 0x73,                  /**< 2.5A Stepper Phidget (STC1001) */
    PHIDID_STC1002 = 0x76,                  /**< 8A Stepper Phidget (STC1002) */
    PHIDID_STC1003 = 0x77,                  /**< 4A Stepper Phidget (STC1003) */
    PHIDID_STC1005 = 0x95,                  /**< 4A Stepper Phidget (STC1005) */
    PHIDID_TMP1000 = 0x57,                  /**< Temperature Phidget (TMP1000) */
    PHIDID_TMP1100 = 0x58,                  /**< Isolated Thermocouple Phidget (TMP1100) */
    PHIDID_TMP1101 = 0x59,                  /**< 4x Thermocouple Phidget (TMP1101) */
    PHIDID_TMP1200 = 0x5a,                  /**< RTD Phidget (TMP1200) */
    PHIDID_TMP1202 = 0x9e,                  /**< RTD Phidget (TMP1202) */
    PHIDID_VCP1000 = 0x5c,                  /**< 20-bit (+-40V) Voltage Input Phidget (VCP1000) */
    PHIDID_VCP1001 = 0x5d,                  /**< 10-bit (+-40V) Voltage Input Phidget (VCP1001) */
    PHIDID_VCP1002 = 0x5e,                  /**< 10-bit (+-1V) Voltage Input Phidget (VCP1002) */
    PHIDID_VCP1100 = 0x69,                  /**< 30A Current Sensor Phidget (VCP1100) */
} Phidget_DeviceID;

/**
 * Phidget logging level
 */
typedef enum {
    PHIDGET_LOG_CRITICAL = 0x1, /**< Critical */
    PHIDGET_LOG_ERROR = 0x2,    /**< Error */
    PHIDGET_LOG_WARNING = 0x3,  /**< Warning */
    PHIDGET_LOG_INFO = 0x4,     /**< Info */
    PHIDGET_LOG_DEBUG = 0x5,    /**< Debug */
    PHIDGET_LOG_VERBOSE = 0x6,  /**< Verbose */
} Phidget_LogLevel;

/**
 * Phidget device class
 */
typedef enum {
    PHIDCLASS_NOTHING = 0x0,            /**< PhidgetNone */
    PHIDCLASS_ACCELEROMETER = 0x1,      /**< PhidgetAccelerometer */
    PHIDCLASS_ADVANCEDSERVO = 0x2,      /**< PhidgetAdvancedServo */
    PHIDCLASS_ANALOG = 0x3,             /**< PhidgetAnalog */
    PHIDCLASS_BRIDGE = 0x4,             /**< PhidgetBridge */
    PHIDCLASS_CURRENTINPUT = 0x1c,      /**< PhidgetCurrentInput */
    PHIDCLASS_CURRENTOUTPUT = 0x1a,     /**< PhidgetCurrentOutput */
    PHIDCLASS_DATAADAPTER = 0x19,       /**< PhidgetDataAdapter */
    PHIDCLASS_DICTIONARY = 0x18,        /**< PhidgetDictionary */
    PHIDCLASS_ENCODER = 0x5,            /**< PhidgetEncoder */
    PHIDCLASS_FIRMWAREUPGRADE = 0x17,   /**< PhidgetFirmwareUpgrade */
    PHIDCLASS_FREQUENCYCOUNTER = 0x6,   /**< PhidgetFrequencyCounter */
    PHIDCLASS_FREQUENCYOUTPUT = 0x1b,   /**< PhidgetFrequencyOutput */
    PHIDCLASS_GENERIC = 0x16,           /**< PhidgetGeneric */
    PHIDCLASS_GPS = 0x7,                /**< PhidgetGPS */
    PHIDCLASS_HUB = 0x8,                /**< PhidgetHub */
    PHIDCLASS_INTERFACEKIT = 0x9,       /**< PhidgetInterfaceKit */
    PHIDCLASS_IR = 0xa,                 /**< PhidgetIR */
    PHIDCLASS_LED = 0xb,                /**< PhidgetLED */
    PHIDCLASS_LEDARRAY = 0xc,           /**< PhidgetLEDArray */
    PHIDCLASS_MOTORCONTROL = 0xd,       /**< PhidgetMotorControl */
    PHIDCLASS_PHSENSOR = 0xe,           /**< PhidgetPHSensor */
    PHIDCLASS_RFID = 0xf,               /**< PhidgetRFID */
    PHIDCLASS_SERVO = 0x10,             /**< PhidgetServo */
    PHIDCLASS_SPATIAL = 0x11,           /**< PhidgetSpatial */
    PHIDCLASS_STEPPER = 0x12,           /**< PhidgetStepper */
    PHIDCLASS_TEMPERATURESENSOR = 0x13, /**< PhidgetTemperatureSensor */
    PHIDCLASS_TEXTLCD = 0x14,           /**< PhidgetTextLCD */
    PHIDCLASS_VINT = 0x15,              /**< PhidgetVINT */
    PHIDCLASS_VOLTAGEINPUT = 0x1d,      /**< PhidgetVoltageInput */
} Phidget_DeviceClass;

/**
 * Phidget channel class
 */
typedef enum {
    PHIDCHCLASS_NOTHING = 0x0,                  /**< PhidgetNone */
    PHIDCHCLASS_ACCELEROMETER = 0x1,            /**< PhidgetAccelerometer */
    PHIDCHCLASS_BLDCMOTOR = 0x23,               /**< PhidgetBLDCMotor */
    PHIDCHCLASS_CAPACITIVETOUCH = 0xe,          /**< PhidgetCapacitiveTouch */
    PHIDCHCLASS_CURRENTINPUT = 0x2,             /**< PhidgetCurrentInput */
    PHIDCHCLASS_CURRENTOUTPUT = 0x26,           /**< PhidgetCurrentOutput */
    PHIDCHCLASS_DATAADAPTER = 0x3,              /**< PhidgetDataAdapter */
    PHIDCHCLASS_DCMOTOR = 0x4,                  /**< PhidgetDCMotor */
    PHIDCHCLASS_DICTIONARY = 0x24,              /**< PhidgetDictionary */
    PHIDCHCLASS_DIGITALINPUT = 0x5,             /**< PhidgetDigitalInput */
    PHIDCHCLASS_DIGITALOUTPUT = 0x6,            /**< PhidgetDigitalOutput */
    PHIDCHCLASS_DISTANCESENSOR = 0x7,           /**< PhidgetDistanceSensor */
    PHIDCHCLASS_ENCODER = 0x8,                  /**< PhidgetEncoder */
    PHIDCHCLASS_FIRMWAREUPGRADE = 0x20,         /**< PhidgetFirmwareUpgrade */
    PHIDCHCLASS_FREQUENCYCOUNTER = 0x9,         /**< PhidgetFrequencyCounter */
    PHIDCHCLASS_GENERIC = 0x21,                 /**< PhidgetGeneric */
    PHIDCHCLASS_GPS = 0xa,                      /**< PhidgetGPS */
    PHIDCHCLASS_GYROSCOPE = 0xc,                /**< PhidgetGyroscope */
    PHIDCHCLASS_HUB = 0xd,                      /**< PhidgetHub */
    PHIDCHCLASS_HUMIDITYSENSOR = 0xf,           /**< PhidgetHumiditySensor */
    PHIDCHCLASS_IR = 0x10,                      /**< PhidgetIR */
    PHIDCHCLASS_LCD = 0xb,                      /**< PhidgetLCD */
    PHIDCHCLASS_LEDARRAY = 0x13,                /**< PhidgetLEDArray */
    PHIDCHCLASS_LIGHTSENSOR = 0x11,             /**< PhidgetLightSensor */
    PHIDCHCLASS_MAGNETOMETER = 0x12,            /**< PhidgetMagnetometer */
    PHIDCHCLASS_MOTORPOSITIONCONTROLLER = 0x22, /**< PhidgetMotorPositionController */
    PHIDCHCLASS_MOTORVELOCITYCONTROLLER = 0x27, /**< PhidgetMotorVelocityController */
    PHIDCHCLASS_PHSENSOR = 0x25,                /**< PhidgetPHSensor */
    PHIDCHCLASS_POWERGUARD = 0x14,              /**< PhidgetPowerGuard */
    PHIDCHCLASS_PRESSURESENSOR = 0x15,          /**< PhidgetPressureSensor */
    PHIDCHCLASS_RCSERVO = 0x16,                 /**< PhidgetRCServo */
    PHIDCHCLASS_RESISTANCEINPUT = 0x17,         /**< PhidgetResistanceInput */
    PHIDCHCLASS_RFID = 0x18,                    /**< PhidgetRFID */
    PHIDCHCLASS_SOUNDSENSOR = 0x19,             /**< PhidgetSoundSensor */
    PHIDCHCLASS_SPATIAL = 0x1a,                 /**< PhidgetSpatial */
    PHIDCHCLASS_STEPPER = 0x1b,                 /**< PhidgetStepper */
    PHIDCHCLASS_TEMPERATURESENSOR = 0x1c,       /**< PhidgetTemperatureSensor */
    PHIDCHCLASS_VOLTAGEINPUT = 0x1d,            /**< PhidgetVoltageInput */
    PHIDCHCLASS_VOLTAGEOUTPUT = 0x1e,           /**< PhidgetVoltageOutput */
    PHIDCHCLASS_VOLTAGERATIOINPUT = 0x1f,       /**< PhidgetVoltageRatioInput */
} Phidget_ChannelClass;

/**
 * Phidget channel sub class
 */
typedef enum {
    PHIDCHSUBCLASS_NONE = 0x1,                              /**< No subclass */
    PHIDCHSUBCLASS_DIGITALOUTPUT_DUTY_CYCLE = 0x10,         /**< Digital output duty cycle */
    PHIDCHSUBCLASS_DIGITALOUTPUT_FREQUENCY = 0x12,          /**< Digital output frequency */
    PHIDCHSUBCLASS_DIGITALOUTPUT_LED_DRIVER = 0x11,         /**< Digital output LED driver */
    PHIDCHSUBCLASS_ENCODER_MODE_SETTABLE = 0x60,            /**< Encoder IO mode settable */
    PHIDCHSUBCLASS_LCD_GRAPHIC = 0x50,                      /**< Graphic LCD */
    PHIDCHSUBCLASS_LCD_TEXT = 0x51,                         /**< Text LCD */
    PHIDCHSUBCLASS_RFID_NFC = 0x80,                         /**< RFID NFC */
    PHIDCHSUBCLASS_SPATIAL_AHRS = 0x70,                     /**< Spatial AHRS/IMU */
    PHIDCHSUBCLASS_TEMPERATURESENSOR_RTD = 0x20,            /**< Temperature sensor RTD */
    PHIDCHSUBCLASS_TEMPERATURESENSOR_THERMOCOUPLE = 0x21,   /**< Temperature sensor thermocouple */
    PHIDCHSUBCLASS_VOLTAGEINPUT_SENSOR_PORT = 0x30,         /**< Voltage sensor port */
    PHIDCHSUBCLASS_VOLTAGERATIOINPUT_BRIDGE = 0x41,         /**< Voltage ratio bridge input */
    PHIDCHSUBCLASS_VOLTAGERATIOINPUT_SENSOR_PORT = 0x40,    /**< Voltage ratio sensor port */
} Phidget_ChannelSubclass;

/**
 * The voltage level being provided to the sensor
 */
typedef enum {
    POWER_SUPPLY_OFF = 0x1, /**< Off */
    POWER_SUPPLY_12V = 0x2, /**< 12 V */
    POWER_SUPPLY_24V = 0x3, /**< 24 V */
    POWER_SUPPLY_5V = 0x4,  /**< 5 V */
} Phidget_PowerSupply;

/**
 * The DataAdapter Voltage
 */
typedef enum {
    DATAADAPTER_VOLTAGE_EXTERN = 0x1,   /**< External */
    DATAADAPTER_VOLTAGE_2_5V = 0x3,     /**< 2.5V */
    DATAADAPTER_VOLTAGE_3_3V = 0x4,     /**< 3.3V */
    DATAADAPTER_VOLTAGE_5_0V = 0x5,     /**< 5.0V */
} Phidget_DataAdapterVoltage;

/**
 * RTD wiring configuration
 */
typedef enum {
    RTD_WIRE_SETUP_2WIRE = 0x1, /**< 2 Wire */
    RTD_WIRE_SETUP_3WIRE = 0x2, /**< 3 Wire */
    RTD_WIRE_SETUP_4WIRE = 0x3, /**< 4 Wire */
} Phidget_RTDWireSetup;

/**
 * The selected polarity mode for the digital input
 */
typedef enum {
    INPUT_MODE_NPN = 0x1,       /**< NPN */
    INPUT_MODE_PNP = 0x2,       /**< PNP */
    INPUT_MODE_FLOATING = 0x3,  /**< Floating */
    INPUT_MODE_PULLUP = 0x4,    /**< Pullup */
} Phidget_InputMode;

/**
 * The operating condition of the fan. Choose between on, off, or automatic (based on temperature).
 */
typedef enum {
    FAN_MODE_OFF = 0x1,     /**< Off */
    FAN_MODE_ON = 0x2,      /**< On */
    FAN_MODE_AUTO = 0x3,    /**< Automatic */
} Phidget_FanMode;

/**
 * The drive type selection for the motor
 */
typedef enum {
    DRIVE_MODE_COAST = 0x1,     /**< Coast */
    DRIVE_MODE_FORCED = 0x2,    /**< Forced */
} Phidget_DriveMode;

/**
 * The position type selection
 */
typedef enum {
    POSITION_TYPE_ENCODER = 0x1,        /**< Encoder */
    POSITION_TYPE_HALL_SENSOR = 0x2,    /**< Hall-Effect Sensor */
} Phidget_PositionType;

/**
 * Controls how data from primary and backup spatial sensing chips are used.
 */
typedef enum {
    SPATIAL_PRECISION_HYBRID = 0x0, /**< Hybrid */
    SPATIAL_PRECISION_HIGH = 0x1,   /**< High */
    SPATIAL_PRECISION_LOW = 0x2,    /**< Low */
} Phidget_SpatialPrecision;

/**
 * Analog sensor units. These correspond to the types of quantities that can be measured by Phidget
 * analog sensors.
 */
typedef enum {
    PHIDUNIT_NONE = 0x0,            /**< Unitless */
    PHIDUNIT_BOOLEAN = 0x1,         /**< Boolean */
    PHIDUNIT_PERCENT = 0x2,         /**< Percent */
    PHIDUNIT_DECIBEL = 0x3,         /**< Decibel */
    PHIDUNIT_MILLIMETER = 0x4,      /**< Millimeter */
    PHIDUNIT_CENTIMETER = 0x5,      /**< Centimeter */
    PHIDUNIT_METER = 0x6,           /**< Meter */
    PHIDUNIT_GRAM = 0x7,            /**< Gram */
    PHIDUNIT_KILOGRAM = 0x8,        /**< Kilogram */
    PHIDUNIT_MILLIAMPERE = 0x9,     /**< Milliampere */
    PHIDUNIT_AMPERE = 0xa,          /**< Ampere */
    PHIDUNIT_KILOPASCAL = 0xb,      /**< Kilopascal */
    PHIDUNIT_VOLT = 0xc,            /**< Volt */
    PHIDUNIT_DEGREE_CELCIUS = 0xd,  /**< Degree Celcius */
    PHIDUNIT_LUX = 0xe,             /**< Lux */
    PHIDUNIT_GAUSS = 0xf,           /**< Gauss */
    PHIDUNIT_PH = 0x10,             /**< pH */
    PHIDUNIT_WATT = 0x11,           /**< Watt */
} Phidget_Unit;

/**
 * The name, symbol, and Phidgets enumeration of the units of the sensor value calculated from the
 * analog sensor's measurements.
 */
typedef struct {
    Phidget_Unit unit;      /**< Unit */
    const char * name;      /**< Name */
    const char * symbol;    /**< Symbol */
} Phidget_UnitInfo, *Phidget_UnitInfoHandle;

/**
 * Phidget Server Types
 */
typedef enum {
    PHIDGETSERVER_NONE = 0x0,           /**< Unknown or unspecified server type */
    PHIDGETSERVER_DEVICELISTENER = 0x1, /**< Phidget22 Server listener */
    PHIDGETSERVER_DEVICE = 0x2,         /**< Phidget22 Server connection */
    PHIDGETSERVER_DEVICEREMOTE = 0x3,   /**< Phidget22 Server */
    PHIDGETSERVER_WWWLISTENER = 0x4,    /**< Phidget22 Web Server */
    PHIDGETSERVER_WWW = 0x5,            /**< Phidget22 Web Server connection */
    PHIDGETSERVER_WWWREMOTE = 0x6,      /**< Phidget22 Web server */
    PHIDGETSERVER_SBC = 0x7,            /**< Phidget SBC */
} PhidgetServerType;

/**
 * Describes a known server. See Constants for supported flags.
 */
typedef struct {
    const char * name;      /**< The name of the server */
    const char * stype;     /**< Name of the server type */
    PhidgetServerType type; /**< The server type */
    int flags;              /**< Flags describing the server state */
    const char * addr;      /**< The address of the server */
    const char * host;      /**< The hostname of the server */
    int port;               /**< The port number of the server */
} PhidgetServer, *PhidgetServerHandle;

/**
 * Bridge gain amplification setting. Higher gain results in better resolution, but narrower voltage
 * range.
 */
typedef enum {
    BRIDGE_GAIN_1 = 0x1,    /**< 1x */
    BRIDGE_GAIN_2 = 0x2,    /**< 2x */
    BRIDGE_GAIN_4 = 0x3,    /**< 4x */
    BRIDGE_GAIN_8 = 0x4,    /**< 8x */
    BRIDGE_GAIN_16 = 0x5,   /**< 16x */
    BRIDGE_GAIN_32 = 0x6,   /**< 32x */
    BRIDGE_GAIN_64 = 0x7,   /**< 64x */
    BRIDGE_GAIN_128 = 0x8,  /**< 128x */
} PhidgetVoltageRatioInput_BridgeGain;

/**
 * The type of sensor attached to the voltage ratio input
 */
typedef enum {
    SENSOR_TYPE_VOLTAGERATIO = 0x0,         /**< Generic ratiometric sensor */
    SENSOR_TYPE_1101_SHARP_2D120X = 0x2b03, /**< 1101 - IR Distance Adapter, with Sharp Distance Sensor 2D120X (4-30cm) */
    SENSOR_TYPE_1101_SHARP_2Y0A21 = 0x2b04, /**< 1101 - IR Distance Adapter, with Sharp Distance Sensor 2Y0A21 (10-80cm) */
    SENSOR_TYPE_1101_SHARP_2Y0A02 = 0x2b05, /**< 1101 - IR Distance Adapter, with Sharp Distance Sensor 2Y0A02 (20-150cm) */
    SENSOR_TYPE_1102 = 0x2b0c,              /**< 1102 - IR Reflective Sensor 5mm */
    SENSOR_TYPE_1103 = 0x2b16,              /**< 1103 - IR Reflective Sensor 10cm */
    SENSOR_TYPE_1104 = 0x2b20,              /**< 1104 - Vibration Sensor */
    SENSOR_TYPE_1105 = 0x2b2a,              /**< 1105 - Light Sensor */
    SENSOR_TYPE_1106 = 0x2b34,              /**< 1106 - Force Sensor */
    SENSOR_TYPE_1107 = 0x2b3e,              /**< 1107 - Humidity Sensor */
    SENSOR_TYPE_1108 = 0x2b48,              /**< 1108 - Magnetic Sensor */
    SENSOR_TYPE_1109 = 0x2b52,              /**< 1109 - Rotation Sensor */
    SENSOR_TYPE_1110 = 0x2b5c,              /**< 1110 - Touch Sensor */
    SENSOR_TYPE_1111 = 0x2b66,              /**< 1111 - Motion Sensor */
    SENSOR_TYPE_1112 = 0x2b70,              /**< 1112 - Slider 60 */
    SENSOR_TYPE_1113 = 0x2b7a,              /**< 1113 - Mini Joy Stick Sensor */
    SENSOR_TYPE_1115 = 0x2b8e,              /**< 1115 - Pressure Sensor */
    SENSOR_TYPE_1116 = 0x2b98,              /**< 1116 - Multi-turn Rotation Sensor */
    SENSOR_TYPE_1118_AC = 0x2bad,           /**< 1118 - 50Amp Current Sensor AC */
    SENSOR_TYPE_1118_DC = 0x2bae,           /**< 1118 - 50Amp Current Sensor DC */
    SENSOR_TYPE_1119_AC = 0x2bb7,           /**< 1119 - 20Amp Current Sensor AC */
    SENSOR_TYPE_1119_DC = 0x2bb8,           /**< 1119 - 20Amp Current Sensor DC */
    SENSOR_TYPE_1120 = 0x2bc0,              /**< 1120 - FlexiForce Adapter */
    SENSOR_TYPE_1121 = 0x2bca,              /**< 1121 - Voltage Divider */
    SENSOR_TYPE_1122_AC = 0x2bd5,           /**< 1122 - 30 Amp Current Sensor AC */
    SENSOR_TYPE_1122_DC = 0x2bd6,           /**< 1122 - 30 Amp Current Sensor DC */
    SENSOR_TYPE_1124 = 0x2be8,              /**< 1124 - Precision Temperature Sensor */
    SENSOR_TYPE_1125_HUMIDITY = 0x2bf3,     /**< 1125 - Humidity Sensor */
    SENSOR_TYPE_1125_TEMPERATURE = 0x2bf4,  /**< 1125 - Temperature Sensor */
    SENSOR_TYPE_1126 = 0x2bfc,              /**< 1126 - Differential Air Pressure Sensor +- 25kPa */
    SENSOR_TYPE_1128 = 0x2c10,              /**< 1128 - MaxBotix EZ-1 Sonar Sensor */
    SENSOR_TYPE_1129 = 0x2c1a,              /**< 1129 - Touch Sensor */
    SENSOR_TYPE_1131 = 0x2c2e,              /**< 1131 - Thin Force Sensor */
    SENSOR_TYPE_1134 = 0x2c4c,              /**< 1134 - Switchable Voltage Divider */
    SENSOR_TYPE_1136 = 0x2c60,              /**< 1136 - Differential Air Pressure Sensor +-2 kPa */
    SENSOR_TYPE_1137 = 0x2c6a,              /**< 1137 - Differential Air Pressure Sensor +-7 kPa */
    SENSOR_TYPE_1138 = 0x2c74,              /**< 1138 - Differential Air Pressure Sensor 50 kPa */
    SENSOR_TYPE_1139 = 0x2c7e,              /**< 1139 - Differential Air Pressure Sensor 100 kPa */
    SENSOR_TYPE_1140 = 0x2c88,              /**< 1140 - Absolute Air Pressure Sensor 20-400 kPa */
    SENSOR_TYPE_1141 = 0x2c92,              /**< 1141 - Absolute Air Pressure Sensor 15-115 kPa */
    SENSOR_TYPE_1146 = 0x2cc4,              /**< 1146 - IR Reflective Sensor 1-4mm */
    SENSOR_TYPE_3120 = 0x79e0,              /**< 3120 - Compression Load Cell (0-4.5 kg) */
    SENSOR_TYPE_3121 = 0x79ea,              /**< 3121 - Compression Load Cell (0-11.3 kg) */
    SENSOR_TYPE_3122 = 0x79f4,              /**< 3122 - Compression Load Cell (0-22.7 kg) */
    SENSOR_TYPE_3123 = 0x79fe,              /**< 3123 - Compression Load Cell (0-45.3 kg) */
    SENSOR_TYPE_3130 = 0x7a44,              /**< 3130 - Relative Humidity Sensor */
    SENSOR_TYPE_3520 = 0x8980,              /**< 3520 - Sharp Distance Sensor (4-30cm) */
    SENSOR_TYPE_3521 = 0x898a,              /**< 3521 - Sharp Distance Sensor (10-80cm) */
    SENSOR_TYPE_3522 = 0x8994,              /**< 3522 - Sharp Distance Sensor (20-150cm) */
} PhidgetVoltageRatioInput_SensorType;

/**
 * The forward voltage setting of the LED
 */
typedef enum {
    LED_FORWARD_VOLTAGE_1_7V = 0x1,     /**< 1.7 V */
    LED_FORWARD_VOLTAGE_2_75V = 0x2,    /**< 2.75 V */
    LED_FORWARD_VOLTAGE_3_2V = 0x3,     /**< 3.2 V */
    LED_FORWARD_VOLTAGE_3_9V = 0x4,     /**< 3.9 V */
    LED_FORWARD_VOLTAGE_4_0V = 0x5,     /**< 4.0 V */
    LED_FORWARD_VOLTAGE_4_8V = 0x6,     /**< 4.8 V */
    LED_FORWARD_VOLTAGE_5_0V = 0x7,     /**< 5.0 V */
    LED_FORWARD_VOLTAGE_5_6V = 0x8,     /**< 5.6 V */
} PhidgetDigitalOutput_LEDForwardVoltage;

/**
 * The voltage of the output
 */
typedef enum {
    OUTPUT_VOLTAGE_OFF = 0x1,   /**< Off */
    OUTPUT_VOLTAGE_3_3V = 0x2,  /**< 3.3 V */
    OUTPUT_VOLTAGE_5V = 0x3,    /**< 5 V */
    OUTPUT_VOLTAGE_12V = 0x4,   /**< 12 V */
    OUTPUT_VOLTAGE_24V = 0x5,   /**< 24 V */
} PhidgetDigitalOutput_OutputVoltage;

/**
 * Voltage supplied to all attached servos
 */
typedef enum {
    RCSERVO_VOLTAGE_5V = 0x1,   /**< 5.0 V */
    RCSERVO_VOLTAGE_6V = 0x2,   /**< 6.0 V */
    RCSERVO_VOLTAGE_7_4V = 0x3, /**< 7.4 V */
} PhidgetRCServo_Voltage;

/**
 * The selected output voltage range
 */
typedef enum {
    VOLTAGE_OUTPUT_RANGE_10V = 0x1, /**< ±10V DC */
    VOLTAGE_OUTPUT_RANGE_5V = 0x2,  /**< 0-5V DC */
} PhidgetVoltageOutput_VoltageOutputRange;

/**
 * The selected output voltage range
 */
typedef enum {
    VOLTAGE_OUTPUT_WAVEFORM_SINE = 0x1,     /**< sine */
    VOLTAGE_OUTPUT_WAVEFORM_SAWTOOTH = 0x2, /**< sawtooth */
    VOLTAGE_OUTPUT_WAVEFORM_TRIANGLE = 0x3, /**< triangle */
    VOLTAGE_OUTPUT_WAVEFORM_SQUARE = 0x4,   /**< square */
} PhidgetVoltageOutput_WaveformShape;

/**
 * Measurement range of the voltage input. Larger ranges have less resolution.
 */
typedef enum {
    VOLTAGE_RANGE_10mV = 0x1,       /**< 10 mV */
    VOLTAGE_RANGE_40mV = 0x2,       /**< 40 mV */
    VOLTAGE_RANGE_200mV = 0x3,      /**< 200 mV */
    VOLTAGE_RANGE_312_5mV = 0x4,    /**< 312.5 mV */
    VOLTAGE_RANGE_400mV = 0x5,      /**< 400 mV */
    VOLTAGE_RANGE_1000mV = 0x6,     /**< 1000 mV */
    VOLTAGE_RANGE_2V = 0x7,         /**< 2 V */
    VOLTAGE_RANGE_5V = 0x8,         /**< 5 V */
    VOLTAGE_RANGE_15V = 0x9,        /**< 15 V */
    VOLTAGE_RANGE_40V = 0xa,        /**< 40 V */
    VOLTAGE_RANGE_AUTO = 0xb,       /**< Auto */
} PhidgetVoltageInput_VoltageRange;

/**
 * Type of sensor attached to the voltage input
 */
typedef enum {
    SENSOR_TYPE_VOLTAGE = 0x0,          /**< Generic voltage sensor */
    SENSOR_TYPE_1114 = 0x2b84,          /**< 1114 - Temperature Sensor */
    SENSOR_TYPE_1117 = 0x2ba2,          /**< 1117 - Voltage Sensor */
    SENSOR_TYPE_1123 = 0x2bde,          /**< 1123 - Precision Voltage Sensor */
    SENSOR_TYPE_1127 = 0x2c06,          /**< 1127 - Precision Light Sensor */
    SENSOR_TYPE_1130_PH = 0x2c25,       /**< 1130 - pH Adapter */
    SENSOR_TYPE_1130_ORP = 0x2c26,      /**< 1130 - ORP Adapter */
    SENSOR_TYPE_1132 = 0x2c38,          /**< 1132 - 4-20mA Adapter */
    SENSOR_TYPE_1133 = 0x2c42,          /**< 1133 - Sound Sensor */
    SENSOR_TYPE_1135 = 0x2c56,          /**< 1135 - Precision Voltage Sensor */
    SENSOR_TYPE_1142 = 0x2c9c,          /**< 1142 - Light Sensor 1000 lux */
    SENSOR_TYPE_1143 = 0x2ca6,          /**< 1143 - Light Sensor 70000 lux */
    SENSOR_TYPE_3500 = 0x88b8,          /**< 3500 - AC Current Sensor 10Amp */
    SENSOR_TYPE_3501 = 0x88c2,          /**< 3501 - AC Current Sensor 25Amp */
    SENSOR_TYPE_3502 = 0x88cc,          /**< 3502 - AC Current Sensor 50Amp */
    SENSOR_TYPE_3503 = 0x88d6,          /**< 3503 - AC Current Sensor 100Amp */
    SENSOR_TYPE_3507 = 0x88fe,          /**< 3507 - AC Voltage Sensor 0-250V (50Hz) */
    SENSOR_TYPE_3508 = 0x8908,          /**< 3508 - AC Voltage Sensor 0-250V (60Hz) */
    SENSOR_TYPE_3509 = 0x8912,          /**< 3509 - DC Voltage Sensor 0-200V */
    SENSOR_TYPE_3510 = 0x891c,          /**< 3510 - DC Voltage Sensor 0-75V */
    SENSOR_TYPE_3511 = 0x8926,          /**< 3511 - DC Current Sensor 0-10mA */
    SENSOR_TYPE_3512 = 0x8930,          /**< 3512 - DC Current Sensor 0-100mA */
    SENSOR_TYPE_3513 = 0x893a,          /**< 3513 - DC Current Sensor 0-1A */
    SENSOR_TYPE_3514 = 0x8944,          /**< 3514 - AC Active Power Sensor 0-250V*0-30A (50Hz) */
    SENSOR_TYPE_3515 = 0x894e,          /**< 3515 - AC Active Power Sensor 0-250V*0-30A (60Hz) */
    SENSOR_TYPE_3516 = 0x8958,          /**< 3516 - AC Active Power Sensor 0-250V*0-5A (50Hz) */
    SENSOR_TYPE_3517 = 0x8962,          /**< 3517 - AC Active Power Sensor 0-250V*0-5A (60Hz) */
    SENSOR_TYPE_3518 = 0x896c,          /**< 3518 - AC Active Power Sensor 0-110V*0-5A (60Hz) */
    SENSOR_TYPE_3519 = 0x8976,          /**< 3519 - AC Active Power Sensor 0-110V*0-15A (60Hz) */
    SENSOR_TYPE_3584 = 0x8c00,          /**< 3584 - 0-50A DC Current Transducer */
    SENSOR_TYPE_3585 = 0x8c0a,          /**< 3585 - 0-100A DC Current Transducer */
    SENSOR_TYPE_3586 = 0x8c14,          /**< 3586 - 0-250A DC Current Transducer */
    SENSOR_TYPE_3587 = 0x8c1e,          /**< 3587 - +-50A DC Current Transducer */
    SENSOR_TYPE_3588 = 0x8c28,          /**< 3588 - +-100A DC Current Transducer */
    SENSOR_TYPE_3589 = 0x8c32,          /**< 3589 - +-250A DC Current Transducer */
    SENSOR_TYPE_MOT2002_LOW = 0x4e34,   /**< MOT2002 - Motion Sensor Low Sensitivity */
    SENSOR_TYPE_MOT2002_MED = 0x4e35,   /**< MOT2002 - Motion Sensor Medium Sensitivity */
    SENSOR_TYPE_MOT2002_HIGH = 0x4e36,  /**< MOT2002 - Motion Sensor High Sensitivity */
    SENSOR_TYPE_VCP4114 = 0xa0b4,       /**< VCP4114 - +-25A DC Current Transducer */
    SENSOR_TYPE_VCP4115 = 0xa0be,       /**< VCP4115 - +-75A DC Current Transducer */
    SENSOR_TYPE_VCP4116 = 0xa0c8,       /**< VCP4116 - +-100A DC Current Transducer */
} PhidgetVoltageInput_SensorType;

/**
 * The protocol used to encode the tag data
 */
typedef enum {
    PROTOCOL_EM4100 = 0x1,          /**< EM4100 Series */
    PROTOCOL_ISO11785_FDX_B = 0x2,  /**< ISO11785 FDX B */
    PROTOCOL_PHIDGETS = 0x3,        /**< PhidgetTAG */
    PROTOCOL_HID_GENERIC = 0x4,     /**< HID Generic */
    PROTOCOL_HID_H10301 = 0x5,      /**< HID H10301 */
} PhidgetRFID_Protocol;

/**
 * The chipset of the writable tag
 */
typedef enum {
    CHIPSET_T5577 = 0x1,    /**< T5577 */
    CHIPSET_EM4305 = 0x2,   /**< EM4305 */
} PhidgetRFID_Chipset;

/**
 * The tag type of the NFC tag
 */
typedef enum {
    TAGTYPE_MIFARE_CLASSIC_1K = 0x1,        /**< MIFARE Classic 1K */
    TAGTYPE_MIFARE_CLASSIC_4K = 0x2,        /**< MIFARE Classic 4K */
    TAGTYPE_GENERIC_TYPE_2 = 0x3,           /**< Generic Type 2 */
    TAGTYPE_MIFARE_ULTRALIGHT = 0x4,        /**< MIFARE Ultralight */
    TAGTYPE_MIFARE_ULTRALIGHT_EV1 = 0x5,    /**< MIFARE Ultralight EV1 */
    TAGTYPE_MIFARE_ULTRALIGHT_C = 0x6,      /**< MIFARE Ultralight C */
    TAGTYPE_MIFARE_NTAG_213 = 0x7,          /**< NTAG 213 */
    TAGTYPE_MIFARE_NTAG_215 = 0x8,          /**< NTAG 215 */
    TAGTYPE_MIFARE_NTAG_216 = 0x9,          /**< NTAG 216 */
    TAGTYPE_UNSUPPORTED = 0xff,             /**< Unsupported */
} PhidgetRFID_TagType;

/**
 * The protocol used to encode the tag data
 */
typedef enum {
    TNF_EMPTY = 0x0,        /**< Record is Empty */
    TNF_WELL_KNOWN = 0x1,   /**< Record is well known type */
    TNF_MIME_MEDIA = 0x2,   /**< Record contains a media type */
    TNF_ABSOLUTE_URI = 0x3, /**< Record is ABSOLUTE_URI */
    TNF_EXTERNAL = 0x4,     /**< Record is EXTERNAL */
    TNF_UNKNOWN = 0x5,      /**< Record is unknown, treat payload as binary */
    TNF_UNCHANGED = 0x6,    /**< Used in chunked records, same type as previous chunk. */
} PhidgetRFID_TNF;

/**
 * NDEF record
 */
typedef struct {
    PhidgetRFID_TNF TNF;    /**< The TNF field */
    uint8_t * type;         /**< The NDEF Type field, see other for details. */
    uint8_t typeLen;        /**< The number of bytes being sent. */
    uint8_t * id;           /**< The NDEF ID field, typically left blank */
    uint8_t idLen;          /**< The number of bytes being sent. */
    uint8_t * payload;      /**< The NDEF Payload field */
    uint32_t payloadLen;    /**< The number of bytes being sent. */
} PhidgetRFID_NDEFRecord, *PhidgetRFID_NDEFRecordHandle;

/**
 * The GPS time in UTC
 */
typedef struct {
    int16_t tm_ms;      /**< Milliseconds */
    int16_t tm_sec;     /**< Seconds */
    int16_t tm_min;     /**< Minutes */
    int16_t tm_hour;    /**< Hours */
} PhidgetGPS_Time, *PhidgetGPS_TimeHandle;

/**
 * GPS Date in UTC
 */
typedef struct {
    int16_t tm_mday;    /**< Day (1-31) */
    int16_t tm_mon;     /**< Month (1-12) */
    int16_t tm_year;    /**< Year */
} PhidgetGPS_Date, *PhidgetGPS_DateHandle;

/**
 * NMEA GGA Sentence
 */
typedef struct {
    double latitude;            /**< Latitude */
    double longitude;           /**< Longitude */
    int16_t fixQuality;         /**< GPS quality indicator */
    int16_t numSatellites;      /**< Number of satellites in use */
    double horizontalDilution;  /**< Horizontal dilution of precision */
    double altitude;            /**< Mean sea level altitude */
    double heightOfGeoid;       /**< Geoidal separation */
} PhidgetGPS_GPGGA, *PhidgetGPS_GPGGAHandle;

/**
 * NMEA GSA sentence
 */
typedef struct {
    char mode;              /**< Manual/Automatic mode (A = auto, M = manual) */
    int16_t fixType;        /**< Fix type (1 = no fix, 2 = 2D, 3 = 3D) */
    int16_t satUsed[12];    /**< Satellite IDs */
    double posnDilution;    /**< Position dilution of precision */
    double horizDilution;   /**< Horizontal dilution of precision */
    double vertDilution;    /**< Vertical dilution of precision */
} PhidgetGPS_GPGSA, *PhidgetGPS_GPGSAHandle;

/**
 * NMEA RMC sentence
 */
typedef struct {
    char status;                /**< Status of the data */
    double latitude;            /**< Latitude */
    double longitude;           /**< Longitude */
    double speedKnots;          /**< Speed over ground in knots */
    double heading;             /**< Heading over ground in degrees */
    double magneticVariation;   /**< Magnetic variation */
    char mode;                  /**< Mode indicator */
} PhidgetGPS_GPRMC, *PhidgetGPS_GPRMCHandle;

/**
 * NMEA VTG sentence
 */
typedef struct {
    double trueHeading;     /**< True heading over ground */
    double magneticHeading; /**< Magnetic heading */
    double speedKnots;      /**< Speed over ground in knots */
    double speed;           /**< Speed over ground in km/h */
    char mode;              /**< Mode indicator */
} PhidgetGPS_GPVTG, *PhidgetGPS_GPVTGHandle;

/**
 * The NMEA Data structure
 */
typedef struct {
    PhidgetGPS_GPGGA GGA;   /**< NMEA GGA Sentence */
    PhidgetGPS_GPGSA GSA;   /**< NMEA GSA Sentence */
    PhidgetGPS_GPRMC RMC;   /**< NMEA RMC Sentence */
    PhidgetGPS_GPVTG VTG;   /**< NMEA VTG Sentence */
} PhidgetGPS_NMEAData, *PhidgetGPS_NMEADataHandle;

/**
 * Controls the AHRS algorithm.
 */
typedef enum {
    SPATIAL_ALGORITHM_NONE = 0x0,   /**< None */
    SPATIAL_ALGORITHM_AHRS = 0x1,   /**< AHRS */
    SPATIAL_ALGORITHM_IMU = 0x2,    /**< IMU */
} Phidget_SpatialAlgorithm;

/**
 * A quaternion from a PhidgetSpatial
 */
typedef struct {
    double x;   /**< The x component of the quaternion */
    double y;   /**< The y component of the quaternion */
    double z;   /**< The z component of the quaternion */
    double w;   /**< The W component of the quaternion */
} PhidgetSpatial_SpatialQuaternion, *PhidgetSpatial_SpatialQuaternionHandle;

/**
 * A set of Euler Angles from a PhidgetSpatial
 */
typedef struct {
    double pitch;   /**< The pitch angle, in degrees */
    double roll;    /**< The roll angle, in degrees */
    double heading; /**< The heading angle, in degrees */
} PhidgetSpatial_SpatialEulerAngles, *PhidgetSpatial_SpatialEulerAnglesHandle;

/**
 * RTD sensor type
 */
typedef enum {
    RTD_TYPE_PT100_3850 = 0x1,  /**< PT100 3850 */
    RTD_TYPE_PT1000_3850 = 0x2, /**< PT1000 3850 */
    RTD_TYPE_PT100_3920 = 0x3,  /**< PT100 3920 */
    RTD_TYPE_PT1000_3920 = 0x4, /**< PT1000 3920 */
} PhidgetTemperatureSensor_RTDType;

/**
 * The type of thermocouple being used
 */
typedef enum {
    THERMOCOUPLE_TYPE_J = 0x1,  /**< J-Type */
    THERMOCOUPLE_TYPE_K = 0x2,  /**< K-Type */
    THERMOCOUPLE_TYPE_E = 0x3,  /**< E-Type */
    THERMOCOUPLE_TYPE_T = 0x4,  /**< T-Type */
} PhidgetTemperatureSensor_ThermocoupleType;

/**
 * Type of filter used on the frequency input
 */
typedef enum {
    FILTER_TYPE_ZERO_CROSSING = 0x1,    /**< Zero Crossing */
    FILTER_TYPE_LOGIC_LEVEL = 0x2,      /**< Logic Level */
} PhidgetFrequencyCounter_FilterType;

/**
 * Describes the encoding technique used for the code
 */
typedef enum {
    IR_ENCODING_UNKNOWN = 0x1,  /**< Unknown */
    IR_ENCODING_SPACE = 0x2,    /**< Space */
    IR_ENCODING_PULSE = 0x3,    /**< Pulse */
    IR_ENCODING_BIPHASE = 0x4,  /**< BiPhase */
    IR_ENCODING_RC5 = 0x5,      /**< RC5 */
    IR_ENCODING_RC6 = 0x6,      /**< RC6 */
} PhidgetIR_Encoding;

/**
 * The length type of the bitstream and gaps
 */
typedef enum {
    IR_LENGTH_UNKNOWN = 0x1,    /**< Unknown */
    IR_LENGTH_CONSTANT = 0x2,   /**< Constant */
    IR_LENGTH_VARIABLE = 0x3,   /**< Variable */
} PhidgetIR_Length;

/**
 * The PhidgetIR CodeInfo structure contains all information needed to transmit a code, apart from
 * the actual code data.
 *
 * *   Some values can be set to null to select defaults.
 */
typedef struct {
    uint32_t bitCount;              /**< Number of bits in the code */
    PhidgetIR_Encoding encoding;    /**< Encoding technique used to encode the data */
    PhidgetIR_Length length;        /**< Constant or Variable length encoding */
    uint32_t gap;                   /**< Gap time in microseconds */
    uint32_t trail;                 /**< Trail time in microseconds. Can be zero for no trail */
    uint32_t header[2];             /**< Header pulse and space. Can be zero for no header */
    uint32_t one[2];                /**< Pulse and Space times to represent a '1' bit, in microseconds */
    uint32_t zero[2];               /**< Pulse and Space times to represent a '0' bit, in microseconds */
    uint32_t repeat[26];            /**< A series or pulse and space times to represent the repeat code. Start and end with pulses and null terminate. Set to 0 for none. */
    uint32_t minRepeat;             /**< Minium number of times to repeat a code on transmit */
    double dutyCycle;               /**< Duty Cycle in percent (0.1-0.5). Defaults to 0.33 */
    uint32_t carrierFrequency;      /**< Carrier frequency in Hz - defaults to 38kHz */
    char toggleMask[33];            /**< Bit toggles, which are applied to the code after each transmit */
} PhidgetIR_CodeInfo, *PhidgetIR_CodeInfoHandle;

/**
 * Method of motor control
 */
typedef enum {
    CONTROL_MODE_STEP = 0x0,    /**< Step */
    CONTROL_MODE_RUN = 0x1,     /**< Run */
} PhidgetStepper_ControlMode;

/**
 * The drescription of the desired set of mevements
 */
typedef struct {
    double targetPosition;  /**< The position to move towards */
    double velocityLimit;   /**< The maximum velocity of the motion */
    double acceleration;    /**< The rate at which to accelerate */
    double time;            /**< The time after START to begin this movement */
} PhidgetStepper_MotionProfilePoint, *PhidgetStepper_MotionProfilePointHandle;

/**
 * The type of font being used
 */
typedef enum {
    FONT_User1 = 0x1,   /**< User 1 */
    FONT_User2 = 0x2,   /**< User 2 */
    FONT_6x10 = 0x3,    /**< 6x10 */
    FONT_5x8 = 0x4,     /**< 5x8 */
    FONT_6x12 = 0x5,    /**< 6x12 */
} PhidgetLCD_Font;

/**
 * Size of the attached LCD screen
 */
typedef enum {
    SCREEN_SIZE_NONE = 0x1,     /**< No Screen */
    SCREEN_SIZE_1x8 = 0x2,      /**< 1x8 */
    SCREEN_SIZE_2x8 = 0x3,      /**< 2x8 */
    SCREEN_SIZE_1x16 = 0x4,     /**< 1x16 */
    SCREEN_SIZE_2x16 = 0x5,     /**< 2x16 */
    SCREEN_SIZE_4x16 = 0x6,     /**< 4x16 */
    SCREEN_SIZE_2x20 = 0x7,     /**< 2x20 */
    SCREEN_SIZE_4x20 = 0x8,     /**< 4x20 */
    SCREEN_SIZE_2x24 = 0x9,     /**< 2x24 */
    SCREEN_SIZE_1x40 = 0xa,     /**< 1x40 */
    SCREEN_SIZE_2x40 = 0xb,     /**< 2x40 */
    SCREEN_SIZE_4x40 = 0xc,     /**< 4x40 */
    SCREEN_SIZE_64x128 = 0xd,   /**< 64x128 */
} PhidgetLCD_ScreenSize;

/**
 * The on/off state of the pixel to be set
 */
typedef enum {
    PIXEL_STATE_OFF = 0x0,      /**< Off */
    PIXEL_STATE_ON = 0x1,       /**< On */
    PIXEL_STATE_INVERT = 0x2,   /**< Invert */
} PhidgetLCD_PixelState;

/**
 * The SPI Mode
 */
typedef enum {
    SPI_MODE_0 = 0x1,   /**< Mode 0 */
    SPI_MODE_1 = 0x2,   /**< Mode 1 */
    SPI_MODE_2 = 0x3,   /**< Mode 2 */
    SPI_MODE_3 = 0x4,   /**< Mode 3 */
} PhidgetDataAdapter_SPIMode;

/**
 * The communication frequency
 */
typedef enum {
    FREQUENCY_10kHz = 0x1,      /**< 10kHz */
    FREQUENCY_100kHz = 0x2,     /**< 100kHz */
    FREQUENCY_400kHz = 0x3,     /**< 400kHz */
    FREQUENCY_188kHz = 0x4,     /**< 188kHz */
    FREQUENCY_375kHz = 0x5,     /**< 375kHz */
    FREQUENCY_750kHz = 0x6,     /**< 750kHz */
    FREQUENCY_1500kHz = 0x7,    /**< 1500kHz */
    FREQUENCY_3MHz = 0x8,       /**< 3MHz */
    FREQUENCY_6MHz = 0x9,       /**< 6MHz */
} PhidgetDataAdapter_Frequency;

/**
 * The Type of Error on the Packet
 */
typedef enum {
    PACKET_ERROR_OK = 0x0,      /**< No error */
    PACKET_ERROR_UNKNOWN = 0x1, /**< Unknown Error */
    PACKET_ERROR_TIMEOUT = 0x2, /**< Timeout Error */
    PACKET_ERROR_FORMAT = 0x3,  /**< Format Error */
    PACKET_ERROR_INVALID = 0x4, /**< Invalid Error */
    PACKET_ERROR_OVERRUN = 0x5, /**< Overrun Error */
    PACKET_ERROR_CORRUPT = 0x6, /**< Corrupt Error */
    PACKET_ERROR_NACK = 0x7,    /**< NACK Error */
} PhidgetDataAdapter_PacketErrorCode;

/**
 * The SPI Chip Select
 */
typedef enum {
    SPI_CHIP_SELECT_ACTIVE_LOW = 0x1,   /**< Active Low */
    SPI_CHIP_SELECT_ACTIVE_HIGH = 0x2,  /**< Active High */
    SPI_CHIP_SELECT_LOW = 0x3,          /**< Low */
    SPI_CHIP_SELECT_HIGH = 0x4,         /**< High */
} PhidgetDataAdapter_SPIChipSelect;

/**
 * The endianness of data being transmitted
 */
typedef enum {
    ENDIANNESS_MSB_FIRST = 0x1, /**< MSB First */
    ENDIANNESS_LSB_FIRST = 0x2, /**< LSB First */
} PhidgetDataAdapter_Endianness;

/**
 * The parity of the data being transmitted
 */
typedef enum {
    PARITY_MODE_NONE = 0x1, /**< None */
    PARITY_MODE_EVEN = 0x2, /**< Even */
    PARITY_MODE_ODD = 0x3,  /**< Odd */
} PhidgetDataAdapter_Parity;

/**
 * Modbus function codes for coil, register, and diagnostic operations
 */
typedef enum {
    MODBUS_COIL_READ = 0x1,                 /**< Read coils (FC01) */
    MODBUS_DISCRETE_INPUT_READ = 0x2,       /**< Read discrete inputs (FC02) */
    MODBUS_REGISTER_READ_HOLDING = 0x3,     /**< Read holding registers (FC03) */
    MODBUS_REGISTER_READ_INPUT = 0x4,       /**< Read input registers (FC04) */
    MODBUS_COIL_WRITE_SINGLE = 0x5,         /**< Write single coil (FC05) */
    MODBUS_REGISTER_WRITE_SINGLE = 0x6,     /**< Write single register (FC06) */
    MODBUS_COIL_WRITE_MULTIPLE = 0xf,       /**< Write multiple coils (FC15) */
    MODBUS_REGISTER_WRITE_MULTIPLE = 0x10,  /**< Write multiple registers (FC16) */
} PhidgetDataAdapter_ModbusFunction;

/**
 * LED color values (RGBW - Red, Green, Blue, White)
 */
typedef struct {
    uint8_t r;  /**< Red Value */
    uint8_t g;  /**< Green Value */
    uint8_t b;  /**< Blue Value */
    uint8_t w;  /**< White Value (application dependent) */
} PhidgetLEDArray_Color, *PhidgetLEDArray_ColorHandle;

/**
 * The order that color information is to be sent to the LEDs
 */
typedef enum {
    LED_COLOR_ORDER_RGB = 0x1,  /**< Byte order RGB (WS2811) */
    LED_COLOR_ORDER_GRB = 0x2,  /**< Byte order GRB (WS2812B, SK6812) */
    LED_COLOR_ORDER_RGBW = 0x3, /**< Byte order RGBW */
    LED_COLOR_ORDER_GRBW = 0x4, /**< Byte order GRBW (SK6812RGBW) */
} PhidgetLEDArray_ColorOrder;

/**
 * The animation type
 */
typedef enum {
    ANIMATION_TYPE_FORWARD_SCROLL = 0x1,        /**< Forward Scroll */
    ANIMATION_TYPE_REVERSE_SCROLL = 0x2,        /**< Reverse Scroll */
    ANIMATION_TYPE_RANDOMIZE = 0x3,             /**< Randomize */
    ANIMATION_TYPE_FORWARD_SCROLL_MIRROR = 0x4, /**< Forward Scroll Mirror */
    ANIMATION_TYPE_REVERSE_SCROLL_MIRROR = 0x5, /**< Reverse Scroll Mirror */
} PhidgetLEDArray_AnimationType;

/**
 * LED animation description
 */
typedef struct {
    uint32_t startAddress;                          /**< Which LED to start the animation from */
    uint32_t endAddress;                            /**< Which LED the animation will end on */
    uint32_t time;                                  /**< Time between changes in ms */
    PhidgetLEDArray_AnimationType animationType;    /**< The type of animation */
} PhidgetLEDArray_Animation, *PhidgetLEDArray_AnimationHandle;

/**
 * The measurement range of the sound sensor
 */
typedef enum {
    SPL_RANGE_102dB = 0x1,  /**< 102 dB */
    SPL_RANGE_82dB = 0x2,   /**< 82 dB */
} PhidgetSoundSensor_SPLRange;

/**
 * The mode of the VINT port
 */
typedef enum {
    PORT_MODE_VINT_PORT = 0x0,              /**< VINT */
    PORT_MODE_DIGITAL_INPUT = 0x1,          /**< Digital Input */
    PORT_MODE_DIGITAL_OUTPUT = 0x2,         /**< Digital Output */
    PORT_MODE_VOLTAGE_INPUT = 0x3,          /**< Voltage Input */
    PORT_MODE_VOLTAGE_RATIO_INPUT = 0x4,    /**< Voltage Ratio Input */
} PhidgetHub_PortMode;

/**
 * @defgroup Phidget Phidget
 * @brief The core Phidget class deals with functionality common to all Phidgets, such as
 *     opening and closing them, or setting Attach, Detach, Error event handlers.
 * @{
 */

/**
 * The core Phidget class deals with functionality common to all Phidgets, such as opening and
 * closing them, or setting Attach, Detach, Error event handlers.
 *
 * This class is also used to specify the associations between the Phidget software objects and
 * their corresponding physical devices, and makes it possible to determine which Phidget is which
 * in cases where it might otherwise be ambiguous.
 *
 * This class contains various functions such as **Release**, **Retain**, and **getParent** designed
 * to be used with the **Phidget Manager**. These specialized functions may be safely ignored if
 * your application does not require a **Manager**. You can check the **Manager API** for more
 * information.
 */
typedef struct _Phidget *PhidgetHandle;

/**
 * @brief Generic asynchronous completion callback.
 *
 * @param[in] ch The channel handle
 * @param[in] ctx The user context pointer that was supplied when registering the callback
 * @param[in] returnCode EPHIDGET_OK if the call succeeded, or an error code (@ref
 *     PhidgetReturnCode) otherwise
 */
typedef void(CCONV *Phidget_AsyncCallback)(PhidgetHandle ch, void *ctx, PhidgetReturnCode returnCode);

/**
 * Gets the string describing the given Phidget return code.
 *
 * @param[in] errorCode The error code
 * @param[out] errorString The error string
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_getErrorDescription(PhidgetReturnCode errorCode,
  const char **errorString);

/**
 * Release memory and threads used by the Phidget library. Should be called prior to unloading the
 * library from the address space.
 *
 * This function is intended for use in special cases where it is desired for the Phidget library to
 * be unloaded before a program's termination. All other API calls are unsafe after calling this.
 *
 * @param[in] flags Reserved for future use. Pass 0
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_finalize(int flags);

/**
 * Gets details about the last error on this thread
 *
 * @param[out] errorCode The error code
 * @param[out] errorString The error string
 * @param[out] errorDetail The buffer to store the error details in. If NULL, errorDetailLen is
 *     set to the required buffer length
 * @param[in,out] errorDetailLen The length of the error detail buffer
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_getLastError(PhidgetReturnCode *errorCode,
  const char **errorString, char *errorDetail, size_t *errorDetailLen);

/**
 * Releases an existing reference to a Phidget handle. This may cause the handle's resources to be
 * freed; therefore, the handle should not be referred to again after it is released.
 *
 * @ref Phidget_release() must not be called on handles that have not had @ref Phidget_retain()
 * called on them.
 *
 * @param[out] phid The Phidget handle to release
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_release(PhidgetHandle *phid);

/**
 * Closes all channels, and stops all threads. The library is reset to a newly loaded state. All
 * channel handles have been freed.
 *
 * This function is intended for use in special cases where the library cannot be unloaded between
 * program runs, such as LabVIEW and Unity Editor.
 *
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_resetLibrary(void);

/**
 * Creates a additional reference to a Phidget handle.@ref Phidget_retain() is used to keep a handle
 * from a **Manager** event alive after the event method returns.
 *
 * @param[in] phid The Phidget handle to retain
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_retain(PhidgetHandle phid);

/**
 * @ref Phidget_delete() releases a Phidget channel handle.
 * If the channel is open when @ref Phidget_delete() is called, it will be closed.
 *
 * @private
 * @param[out] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_delete(PhidgetHandle *ch);

/**
 * Gets the network protocol version of the client, for a network attached channel.
 *
 * @private
 * @param[in] ch The channel handle
 * @param[out] major The Major version
 * @param[out] minor The Minor version
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_getClientVersion(PhidgetHandle ch, int *major,
  int *minor);

/**
 * Closes a Phidget channel that has been opened.@ref Phidget_close() will release the channel on
 * the Phidget device, and should be called prior to `PhidgetChannel_delete()`.
 *
 * @param[in] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_close(PhidgetHandle ch);

/**
 * Gets the number of channels of the specified channel class on the device. Pass @ref
 * PHIDCHCLASS_NOTHING to get the total number of channels.
 *
 * @param[in] ch The channel handle
 * @param[in] cls The Channel Class
 * @param[out] count The Channel Count
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_getDeviceChannelCount(PhidgetHandle ch,
  Phidget_ChannelClass cls, uint32_t *count);

/**
 * Opens the Phidget channel. The specific channel to be opened can be specified by setting any of
 * the following properties:
 *
 * *   DeviceSerialNumber
 * *   DeviceLabel
 * *   Channel
 * *   HubPort
 * *   IsHubPortDevice
 * *   ServerName
 * *   IsLocal
 * *   IsRemote
 *
 * @ref Phidget_open() will return immediately, with the attachment process proceeding
 * asynchronously. Use the Attach event or Attached property to determine when the channel is ready
 * to use.
 *
 * @param[in] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_open(PhidgetHandle ch);

/**
 * Opens the Phidget channel and waits a defined amount of time for the device to attach.The
 * specific channel to be opened can be specified by setting any of the following properties:
 *
 * *   DeviceSerialNumber
 * *   DeviceLabel
 * *   Channel
 * *   HubPort
 * *   IsHubPortDevice
 * *   ServerName
 * *   IsLocal
 * *   IsRemote
 *
 * @ref Phidget_openWaitForAttachment() will block until the channel is attached or a timeout
 * occurs. A timeout value of 0 will wait forever.
 *
 * @param[in] ch The channel handle
 * @param[in] timeout Timeout in milliseconds
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_openWaitForAttachment(PhidgetHandle ch, uint32_t timeout);

/**
 * Reboots the device into the regular firmware.
 *
 * @private
 * @param[in] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_reboot(PhidgetHandle ch);

/**
 * Reboots the device into firmware upgrade mode.
 *
 * @private
 * @param[in] ch The channel handle
 * @param[in] upgradeTimeout The reboot timeout
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_rebootFirmwareUpgrade(PhidgetHandle ch,
  uint32_t upgradeTimeout);

/**
 * Gets the protocol version of the remote Network Server, for a network attached channel.
 *
 * @private
 * @param[in] ch The channel handle
 * @param[out] major The Major version
 * @param[out] minor The Minor version
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_getServerVersion(PhidgetHandle ch, int *major,
  int *minor);

/**
 * Writes a label to the device in the form of a string in the device flash memory. This label can
 * then be used to identify the device, and will persist across power cycles.
 *
 * The label can be at most 10 UTF-16 code units. Most unicode characters take up a single code
 * unit, but some, such as emoji, can take several.
 *
 * Some older devices can not have their labels set from Windows. For these devices the label should
 * be set from Linux or macOS.
 *
 * Note: You should be careful when writing labels 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 your
 * program is complex, be sure to test it thoroughly before using WriteLabel to avoid accidentally
 * burning out the flash.
 *
 * @param[in] ch The channel handle
 * @param[in] deviceLabel The device label
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_writeDeviceLabel(PhidgetHandle ch,
  const char *deviceLabel);

/**
 * Write all config data to flash on M3 Phidgets.
 *
 * @private
 * @param[in] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_writeFlash(PhidgetHandle ch);

/**
 * @brief The Phidget library version.
 *
 * Gets the version of the Phidget library being used by the program in human readable form.
 *
 * @param[out] libraryVersion The Phidget library version
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_getLibraryVersion(const char **libraryVersion);

/**
 * @brief The Phidget library version number.
 *
 * Gets the version of the Phidget library being used by the program as a version number string.
 *
 * @param[out] libraryVersionNumber The Phidget library version number
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_getLibraryVersionNumber(const char **libraryVersionNumber);

/**
 * @brief True if the channel is attached
 *
 * Gets the attached status of channel. A Phidget is attached after it has been opened and the
 * Phidget library finds and connects to the corresponding hardware device.
 *
 * *   Most API calls are only valid on attached Phidgets.
 *
 * @param[in] ch The channel handle
 * @param[out] attached True if the channel is attached
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_getAttached(PhidgetHandle ch, int *attached);

/**
 * @brief The channel index
 *
 * Gets the channel index of the channel on the device.
 *
 * @param[in] ch The channel handle
 * @param[in] channel The channel index
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_setChannel(PhidgetHandle ch, int channel);

/**
 * @brief The channel index
 *
 * Gets the channel index of the channel on the device.
 *
 * @param[in] ch The channel handle
 * @param[out] channel The channel index
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_getChannel(PhidgetHandle ch, int *channel);

/**
 * @brief True if the handle is for a channel.
 *
 * Returns true if this represents a channel, false if this represents a device. Mostly for use
 * alongside @ref Phidget_getParent() to distinguish channel handles from device handles.
 *
 * @param[in] ch The channel handle
 * @param[out] isChannel True if the handle is for a channel
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_getIsChannel(PhidgetHandle ch, int *isChannel);

/**
 * @brief The channel class
 *
 * Gets the channel class of the channel.
 *
 * @param[in] ch The channel handle
 * @param[out] channelClass The channel class
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_getChannelClass(PhidgetHandle ch,
  Phidget_ChannelClass *channelClass);

/**
 * @brief The name of the channel's class
 *
 * Gets the name of the channel class the channel belongs to.
 *
 * @param[in] ch The channel handle
 * @param[out] channelClassName The name of the channel's class
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_getChannelClassName(PhidgetHandle ch,
  const char **channelClassName);

/**
 * @brief The channel's name
 *
 * Gets the channel's name. This name serves as a description of the specific nature of the channel.
 *
 * @param[in] ch The channel handle
 * @param[out] channelName The channel's name
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_getChannelName(PhidgetHandle ch,
  const char **channelName);

/**
 * @brief Channel state persistence across open-close cycles
 *
 * Controls whether the state of this channel persists across attach and close. By default, channels
 * are reset on attach and close. Note that any defaults listed in the API must be set by the user
 * when Persistence is enabled.
 *
 * @param[in] ch The channel handle
 * @param[in] channelPersistence Channel state persistence across open-close cycles
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_setChannelPersistence(PhidgetHandle ch,
  int channelPersistence);

/**
 * @brief Channel state persistence across open-close cycles
 *
 * Controls whether the state of this channel persists across attach and close. By default, channels
 * are reset on attach and close. Note that any defaults listed in the API must be set by the user
 * when Persistence is enabled.
 *
 * @param[in] ch The channel handle
 * @param[out] channelPersistence Channel state persistence across open-close cycles
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_getChannelPersistence(PhidgetHandle ch,
  int *channelPersistence);

/**
 * @brief The channel's subclass
 *
 * Gets the subclass for this channel. Allows for identifying channels with specific characteristics
 * without needing to know the exact device and channel index.
 *
 * @param[in] ch The channel handle
 * @param[out] channelSubclass The channel's subclass
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_getChannelSubclass(PhidgetHandle ch,
  Phidget_ChannelSubclass *channelSubclass);

/**
 * @brief The data interval of the channel
 *
 * Gets the data interval for any channel that supports one.
 * The `DataInterval` is the time that must elapse before the channel will fire another event.
 *
 * *   The data interval is bounded by @ref Phidget_getMinDataInterval() and @ref
 *     Phidget_getMaxDataInterval().
 * *   The timing between events can also be affected by the change trigger.
 *
 * @param[in] ch The channel handle
 * @param[in] dataInterval The data interval of the channel
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_setDataInterval(PhidgetHandle ch, uint32_t dataInterval);

/**
 * @brief The data interval of the channel
 *
 * Gets the data interval for any channel that supports one.
 * The `DataInterval` is the time that must elapse before the channel will fire another event.
 *
 * *   The data interval is bounded by @ref Phidget_getMinDataInterval() and @ref
 *     Phidget_getMaxDataInterval().
 * *   The timing between events can also be affected by the change trigger.
 *
 * @param[in] ch The channel handle
 * @param[out] dataInterval The data interval of the channel
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_getDataInterval(PhidgetHandle ch, uint32_t *dataInterval);

/**
 * @brief The data interval value
 *
 * The minimum value that `DataInterval` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minDataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_getMinDataInterval(PhidgetHandle ch,
  uint32_t *minDataInterval);

/**
 * @brief The data interval value
 *
 * The maximum value that `DataInterval` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxDataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_getMaxDataInterval(PhidgetHandle ch,
  uint32_t *maxDataInterval);

/**
 * @brief The data rate for the channel
 *
 * The `DataRate` is the frequency of events from the device.
 *
 * *   The data rate is bounded by @ref Phidget_getMinDataRate() and @ref
 *     Phidget_getMaxDataRate().
 * *   Changing `DataRate` will change the channel's `DataInterval` to a corresponding value,
 *     rounded to the nearest integer number of milliseconds.
 * *   The timing between events can also affected by the change trigger.
 *
 * @param[in] ch The channel handle
 * @param[in] dataRate The data rate for the channel
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_setDataRate(PhidgetHandle ch, double dataRate);

/**
 * @brief The data rate for the channel
 *
 * The `DataRate` is the frequency of events from the device.
 *
 * *   The data rate is bounded by @ref Phidget_getMinDataRate() and @ref
 *     Phidget_getMaxDataRate().
 * *   Changing `DataRate` will change the channel's `DataInterval` to a corresponding value,
 *     rounded to the nearest integer number of milliseconds.
 * *   The timing between events can also affected by the change trigger.
 *
 * @param[in] ch The channel handle
 * @param[out] dataRate The data rate for the channel
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_getDataRate(PhidgetHandle ch, double *dataRate);

/**
 * @brief The data rate value
 *
 * The minimum value that `DataRate` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minDataRate The data rate value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_getMinDataRate(PhidgetHandle ch, double *minDataRate);

/**
 * @brief The data rate value
 *
 * The maximum value that `DataRate` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxDataRate The data rate value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_getMaxDataRate(PhidgetHandle ch, double *maxDataRate);

/**
 * @brief The class of the device the channel is a part of.
 *
 * Gets the device class for the Phidget which this channel is a part of.
 *
 * @param[in] ch The channel handle
 * @param[out] deviceClass The class of the device the channel is a part of
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_getDeviceClass(PhidgetHandle ch,
  Phidget_DeviceClass *deviceClass);

/**
 * @brief The class name of the device the channel is a part of.
 *
 * Gets the name of the device class for the Phidget which this channel is a part of.
 *
 * @param[in] ch The channel handle
 * @param[out] deviceClassName The class name of the device the channel is a part of
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_getDeviceClassName(PhidgetHandle ch,
  const char **deviceClassName);

/**
 * @brief The firmware upgrade string
 *
 * Gets the string which will match the filename of the firmware upgrade file
 *
 * @private
 * @param[in] ch The channel handle
 * @param[out] deviceFirmwareUpgradeString The firmware upgrade string
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_getDeviceFirmwareUpgradeString(PhidgetHandle ch,
  const char **deviceFirmwareUpgradeString);

/**
 * @brief The device id of the device the channel is a part of
 *
 * Gets the Device ID for the Phidget which this channel is a part of.
 *
 * @param[in] ch The channel handle
 * @param[out] deviceID The device id of the device the channel is a part of
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_getDeviceID(PhidgetHandle ch, Phidget_DeviceID *deviceID);

/**
 * @brief The device label
 *
 * Gets the label of the Phidget which this channel is a part of. A device label is a custom string
 * used to more easily identify a Phidget. Labels are written to a Phidget using @ref
 * Phidget_writeDeviceLabel(), or by right-clicking the device and setting a label in the Phidget
 * Control Panel for Windows.
 *
 * @param[in] ch The channel handle
 * @param[in] deviceLabel The device label
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_setDeviceLabel(PhidgetHandle ch,
  const char * deviceLabel);

/**
 * @brief The device label
 *
 * Gets the label of the Phidget which this channel is a part of. A device label is a custom string
 * used to more easily identify a Phidget. Labels are written to a Phidget using @ref
 * Phidget_writeDeviceLabel(), or by right-clicking the device and setting a label in the Phidget
 * Control Panel for Windows.
 *
 * @param[in] ch The channel handle
 * @param[out] deviceLabel The device label
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_getDeviceLabel(PhidgetHandle ch,
  const char **deviceLabel);

/**
 * @brief The name of the device the channel is a part of
 *
 * Gets the name of the Phidget which this channel is a part of.
 *
 * @param[in] ch The channel handle
 * @param[out] deviceName The name of the device the channel is a part of
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_getDeviceName(PhidgetHandle ch, const char **deviceName);

/**
 * @brief The device serial number
 *
 * Gets the serial number of the Phidget which this channel is a part of.
 * If the channel is part of a VINT device, this will be the serial number of the VINT Hub the
 * device is attached to.
 *
 * @param[in] ch The channel handle
 * @param[in] deviceSerialNumber The device serial number
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_setDeviceSerialNumber(PhidgetHandle ch,
  int32_t deviceSerialNumber);

/**
 * @brief The device serial number
 *
 * Gets the serial number of the Phidget which this channel is a part of.
 * If the channel is part of a VINT device, this will be the serial number of the VINT Hub the
 * device is attached to.
 *
 * @param[in] ch The channel handle
 * @param[out] deviceSerialNumber The device serial number
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_getDeviceSerialNumber(PhidgetHandle ch,
  int32_t *deviceSerialNumber);

/**
 * @brief The SKU of the device the channel is a part of
 *
 * Gets the SKU of the Phidget which this channel is a part of. If there are multiple possible SKUs,
 * they will be separated by a /.
 *
 * @param[in] ch The channel handle
 * @param[out] deviceSKU The SKU of the device the channel is a part of
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_getDeviceSKU(PhidgetHandle ch, const char **deviceSKU);

/**
 * @brief The SKU_Revision of the device the channel is a part of
 *
 * Gets the SKU\_Revision of the Phidget which this channel is a part of. If there are multiple
 * possible SKU\_Revisions, they will be separated by a /. The SKU_Revision is a string used to
 * identify the exact revision of the device, and can be found on the packaging or on the device
 * itself.
 *
 * @private
 * @param[in] ch The channel handle
 * @param[out] deviceSKU_Revision The SKU_Revision of the device the channel is a part of
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_getDeviceSKU_Revision(PhidgetHandle ch,
  const char **deviceSKU_Revision);

/**
 * @brief The version of the device the channel is a part of
 *
 * Gets the firmware version of the Phidget which this channel is a part of.
 *
 * @param[in] ch The channel handle
 * @param[out] deviceVersion The version of the device the channel is a part of
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_getDeviceVersion(PhidgetHandle ch, int *deviceVersion);

/**
 * @brief The vint id of the channels device
 *
 * Gets the vint id for the Phidget which this channel is a part of.
 *
 * @private
 * @param[in] ch The channel handle
 * @param[out] deviceVINTID The vint id of the channels device
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_getDeviceVINTID(PhidgetHandle ch, uint32_t *deviceVINTID);

/**
 * @brief The hub the channels device is attached to
 *
 * Gets the hub that this channel is attached to. Must be freed with @ref Phidget_release()
 *
 * @param[in] ch The channel handle
 * @param[out] hub The hub the channels device is attached to
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_getHub(PhidgetHandle ch, PhidgetHandle *hub);

/**
 * @brief The hub port index
 *
 * Gets the hub port index of the VINT Hub port that the channel is attached to.
 *
 * @param[in] ch The channel handle
 * @param[in] hubPort The hub port index
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_setHubPort(PhidgetHandle ch, int hubPort);

/**
 * @brief The hub port index
 *
 * Gets the hub port index of the VINT Hub port that the channel is attached to.
 *
 * @param[in] ch The channel handle
 * @param[out] hubPort The hub port index
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_getHubPort(PhidgetHandle ch, int *hubPort);

/**
 * @brief The number of ports on the VINT Hub
 *
 * Gets the number of VINT ports present on the VINT Hub that the channel is attached to.
 *
 * @param[in] ch The channel handle
 * @param[out] hubPortCount The number of ports on the VINT Hub
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_getHubPortCount(PhidgetHandle ch, int *hubPortCount);

/**
 * @brief The hub port mode (True if the channel is a hub port itself)
 *
 * Gets whether this channel is a VINT Hub port channel, or part of a VINT device attached to a hub
 * port.
 *
 * @param[in] ch The channel handle
 * @param[in] isHubPortDevice The hub port mode (True if the channel is a hub port itself)
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_setIsHubPortDevice(PhidgetHandle ch, int isHubPortDevice);

/**
 * @brief The hub port mode (True if the channel is a hub port itself)
 *
 * Gets whether this channel is a VINT Hub port channel, or part of a VINT device attached to a hub
 * port.
 *
 * @param[in] ch The channel handle
 * @param[out] isHubPortDevice The hub port mode (True if the channel is a hub port itself)
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_getIsHubPortDevice(PhidgetHandle ch,
  int *isHubPortDevice);

/**
 * @brief The VINT Device communication speed
 *
 * Configures the communication speed for this VINT device. Both the @ref
 * Phidget_getHubPortSupportsSetSpeed() and @ref Phidget_getVINTDeviceSupportsSetSpeed() must be
 * true in order to set the hub port speed.Available speeds are: 100000, 160000, 250000, 400000,
 * 500000, 800000 and 1000000. Setting any other speed will select the nearest lower supported
 * speed. The upper speed is bound by the lesser of @ref Phidget_getMaxHubPortSpeed() and @ref
 * Phidget_getMaxVINTDeviceSpeed(). Set the speed to @ref PHIDGET_HUBPORTSPEED_AUTO to enable Auto
 * Set Speed on Hubs that support it (enabled by default).
 *
 * @param[in] ch The channel handle
 * @param[in] hubPortSpeed The VINT Device communication speed
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_setHubPortSpeed(PhidgetHandle ch, uint32_t hubPortSpeed);

/**
 * @brief The VINT Device communication speed
 *
 * Configures the communication speed for this VINT device. Both the @ref
 * Phidget_getHubPortSupportsSetSpeed() and @ref Phidget_getVINTDeviceSupportsSetSpeed() must be
 * true in order to set the hub port speed.Available speeds are: 100000, 160000, 250000, 400000,
 * 500000, 800000 and 1000000. Setting any other speed will select the nearest lower supported
 * speed. The upper speed is bound by the lesser of @ref Phidget_getMaxHubPortSpeed() and @ref
 * Phidget_getMaxVINTDeviceSpeed(). Set the speed to @ref PHIDGET_HUBPORTSPEED_AUTO to enable Auto
 * Set Speed on Hubs that support it (enabled by default).
 *
 * @param[in] ch The channel handle
 * @param[out] hubPortSpeed The VINT Device communication speed
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_getHubPortSpeed(PhidgetHandle ch, uint32_t *hubPortSpeed);

/**
 * @brief The VINT Port max speed
 *
 * The max communication speed of a high-speed capable VINT Port.
 *
 * @param[in] ch The channel handle
 * @param[out] maxHubPortSpeed The VINT Port max speed
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_getMaxHubPortSpeed(PhidgetHandle ch,
  uint32_t *maxHubPortSpeed);

/**
 * @brief The VINT Port supports auto set speed
 *
 * Indicates that the communication speed of this VINT port can be set automatically.
 *
 * @param[in] ch The channel handle
 * @param[out] hubPortSupportsAutoSetSpeed The VINT Port supports auto set speed
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_getHubPortSupportsAutoSetSpeed(PhidgetHandle ch,
  int *hubPortSupportsAutoSetSpeed);

/**
 * @brief The VINT Port supports set speed
 *
 * Indicates that the communication speed of this VINT port can be set.
 *
 * @param[in] ch The channel handle
 * @param[out] hubPortSupportsSetSpeed The VINT Port supports set speed
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_getHubPortSupportsSetSpeed(PhidgetHandle ch,
  int *hubPortSupportsSetSpeed);

/**
 * @brief True if the channel is attached to a local device
 *
 * Returns true when this channel is attached directly on the local machine, or false otherwise.
 *
 * @param[in] ch The channel handle
 * @param[in] isLocal True if the channel is attached to a local device
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_setIsLocal(PhidgetHandle ch, int isLocal);

/**
 * @brief True if the channel is attached to a local device
 *
 * Returns true when this channel is attached directly on the local machine, or false otherwise.
 *
 * @param[in] ch The channel handle
 * @param[out] isLocal True if the channel is attached to a local device
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_getIsLocal(PhidgetHandle ch, int *isLocal);

/**
 * @brief True if the channel is opened.
 *
 * Returns true if @ref Phidget_open() has been called on this channel.
 *
 * @param[in] ch The channel handle
 * @param[out] isOpen True if the channel is opened
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_getIsOpen(PhidgetHandle ch, int *isOpen);

/**
 * @brief The handle of the parent
 *
 * Gets the handle of the parent device of the given Phidget handle.
 *
 * For example, this would refer to the device the channel is a part of, or the Hub that a device is
 * plugged into.
 *
 * This is useful when used alongside a **Phidget Manager** to create device trees like the one in
 * the Phidget Control Panel.
 *
 * @ref Phidget_release() must be called on the handle returned by this function to release the
 * reference created by this call.
 *
 * *   This can be used to travel up the device tree and get device information at each step.
 * *   The root device will return a null handle
 * *   Parent handles always refer to devices. See @ref Phidget_getIsChannel()
 *
 * @param[in] ch The channel handle
 * @param[out] parent The handle of the parent
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_getParent(PhidgetHandle ch, PhidgetHandle *parent);

/**
 * @brief True if the channel is attached to a network device
 *
 * Returns true when this channel is attached via a Phidget network server, or false otherwise.
 *
 * @param[in] ch The channel handle
 * @param[in] isRemote True if the channel is attached to a network device
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_setIsRemote(PhidgetHandle ch, int isRemote);

/**
 * @brief True if the channel is attached to a network device
 *
 * Returns true when this channel is attached via a Phidget network server, or false otherwise.
 *
 * @param[in] ch The channel handle
 * @param[out] isRemote True if the channel is attached to a network device
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_getIsRemote(PhidgetHandle ch, int *isRemote);

/**
 * @brief The hostname of the channel's server
 *
 * Gets the hostname of the Phidget network server for network attached Phidgets.
 * Fails if the channel is not connected to a Phidget network server.
 *
 * @param[in] ch The channel handle
 * @param[out] serverHostname The hostname of the channel's server
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_getServerHostname(PhidgetHandle ch,
  const char **serverHostname);

/**
 * @brief The name of the Phidget network server the channel is from
 *
 * Gets the name of the Phidget network server the channel is attached to, if any.
 * Fails if the channel is not connected to a Phidget network server.
 *
 * @param[in] ch The channel handle
 * @param[in] serverName The name of the Phidget network server the channel is from
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_setServerName(PhidgetHandle ch, const char * serverName);

/**
 * @brief The name of the Phidget network server the channel is from
 *
 * Gets the name of the Phidget network server the channel is attached to, if any.
 * Fails if the channel is not connected to a Phidget network server.
 *
 * @param[in] ch The channel handle
 * @param[out] serverName The name of the Phidget network server the channel is from
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_getServerName(PhidgetHandle ch, const char **serverName);

/**
 * @brief The address and port of the channel's server
 *
 * Gets the peer name (address and port) of the Phidget server for network attached Phidgets,
 * formatted as: `address:port`
 * Fails if the channel is not connected to a Phidget network server.
 *
 * @param[in] ch The channel handle
 * @param[out] serverPeerName The address and port of the channel's server
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_getServerPeerName(PhidgetHandle ch,
  const char **serverPeerName);

/**
 * @brief The unique name of the server
 *
 * Gets the unique name for the server the channel is attached to, if any. This is either a unique
 * mDNS name, or the name specified in @ref PhidgetNet_addServer()
 * Fails if the channel is not connected to a Phidget network server.
 *
 * @param[in] ch The channel handle
 * @param[out] serverUniqueName The unique name of the server
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_getServerUniqueName(PhidgetHandle ch,
  const char **serverUniqueName);

/**
 * @brief The VINT Device max commuinication speed
 *
 * The max communication speed of a high-speed capable VINT Device.
 *
 * @param[in] ch The channel handle
 * @param[out] maxVINTDeviceSpeed The VINT Device max commuinication speed
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_getMaxVINTDeviceSpeed(PhidgetHandle ch,
  uint32_t *maxVINTDeviceSpeed);

/**
 * @brief The VINT Device supports auto set speed
 *
 * Indicates that the communication speed of this VINT device can be set automatically.
 *
 * @param[in] ch The channel handle
 * @param[out] VINTDeviceSupportsAutoSetSpeed The VINT Device supports auto set speed
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_getVINTDeviceSupportsAutoSetSpeed(PhidgetHandle ch,
  int *VINTDeviceSupportsAutoSetSpeed);

/**
 * @brief The VINT Device supports set speed
 *
 * Indicates that the communication speed of this VINT device can be set.
 *
 * @param[in] ch The channel handle
 * @param[out] VINTDeviceSupportsSetSpeed The VINT Device supports set speed
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_getVINTDeviceSupportsSetSpeed(PhidgetHandle ch,
  int *VINTDeviceSupportsSetSpeed);

/**
 * @brief Callback function type for Phidget_setOnAttachHandler().
 *
 * @param[in] ch The channel handle
 * @param[in] ctx Pointer to the user context
 */
typedef void (CCONV *Phidget_OnAttachCallback)(PhidgetHandle ch, void *ctx);

/**
 * Occurs when the channel is attached to a physical channel on a Phidget.
 *
 * @ref Phidget_setOnAttachHandler() must be registered prior to calling @ref Phidget_open(), and
 * will be called when the Phidget library matches the channel with a physical channel on a Phidget.
 * @ref Phidget_setOnAttachHandler() may be called more than once if the channel is detached during
 * its lifetime.
 *
 * @ref Phidget_setOnAttachHandler() is the recommended place to configuration properties of the
 * channel such as the data interval or change trigger.
 *
 * @param[in] ch The channel handle
 * @param[in] fptr The event handler callback function
 * @param[in] ctx User supplied context pointer
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_setOnAttachHandler(PhidgetHandle ch,
  Phidget_OnAttachCallback fptr, void *ctx);

/**
 * @brief Callback function type for Phidget_setOnDetachHandler().
 *
 * @param[in] ch The channel handle
 * @param[in] ctx Pointer to the user context
 */
typedef void (CCONV *Phidget_OnDetachCallback)(PhidgetHandle ch, void *ctx);

/**
 * Occurs when the channel is detached from a Phidget device channel.@ref
 * Phidget_setOnDetachHandler() typically occurs when the Phidget device is removed from the system.
 *
 * @param[in] ch The channel handle
 * @param[in] fptr The event handler callback function
 * @param[in] ctx User supplied context pointer
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_setOnDetachHandler(PhidgetHandle ch,
  Phidget_OnDetachCallback fptr, void *ctx);

/**
 * @brief Callback function type for Phidget_setOnErrorHandler().
 *
 * @param[in] ch The channel handle
 * @param[in] ctx Pointer to the user context
 * @param[in] code The error code
 * @param[in] description The error description
 */
typedef void (CCONV *Phidget_OnErrorCallback)(PhidgetHandle ch, void *ctx, Phidget_ErrorEventCode code,
  const char *description);

/**
 * @ref Phidget_setOnErrorHandler() is called when an error condition has been detected.
 *
 * See the documentation for your specific channel class to see what error events it might throw.
 *
 * @param[in] ch The channel handle
 * @param[in] fptr The event handler callback function
 * @param[in] ctx User supplied context pointer
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_setOnErrorHandler(PhidgetHandle ch,
  Phidget_OnErrorCallback fptr, void *ctx);

/**
 * @brief Callback function type for Phidget_setOnPropertyChangeHandler().
 *
 * @param[in] ch The channel handle
 * @param[in] ctx Pointer to the user context
 * @param[in] propertyName The name of the property that has changed
 */
typedef void (CCONV *Phidget_OnPropertyChangeCallback)(PhidgetHandle ch, void *ctx,
  const char *propertyName);

/**
 * Occurs when a property is changed externally from the user channel, usually from a network client
 * attached to the same channel.
 *
 * @param[in] ch The channel handle
 * @param[in] fptr The event handler callback function
 * @param[in] ctx User supplied context pointer
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_setOnPropertyChangeHandler(PhidgetHandle ch,
  Phidget_OnPropertyChangeCallback fptr, void *ctx);

#define PHIDGET_SERIALNUMBER_ANY -1     /**< Pass to ${PROPERTY:DeviceSerialNumber:set} to open any serial number. */
#define PHIDGET_HUBPORT_ANY -1          /**< Pass to ${PROPERTY:HubPort:set} to open any hub port. */
#define PHIDGET_CHANNEL_ANY -1          /**< Pass to ${PROPERTY:Channel:set} to open any channel. */
#define PHIDGET_LABEL_ANY NULL          /**< Pass to ${PROPERTY:DeviceLabel:set} to open any label. */
#define PHIDGET_TIMEOUT_INFINITE 0x0    /**< Pass to ${METHOD:openWaitForAttachment} for an infinite timeout. */
#define PHIDGET_TIMEOUT_DEFAULT 0x3e8   /**< Pass to ${METHOD:openWaitForAttachment} for the default timeout. */
#define PHIDGET_HUBPORTSPEED_AUTO 0x0   /**< Pass to ${PROPERTY:HubPortSpeed:set} to set the Hub Port speed automatically when supported by both the hub port and the VINT device. */

/** @} */ /* Phidget */

/**
 * @defgroup PhidgetManager Manager
 * @brief The Phidget Manager allows tracking of which Phidgets are available to be controlled
 *     from the current program. This is useful for listing all available Phidgets so you can select
 *     which ones to use at runtime.
 * @{
 */

/**
 * The Phidget Manager allows tracking of which Phidgets are available to be controlled from the
 * current program. This is useful for listing all available Phidgets so you can select which ones
 * to use at runtime.
 *
 * You do not need to use a Phidget Manager if you know what Phidgets will be required for your
 * application in advance.
 *
 * Phidget channels that become available will each send an **Attach** event, and Phidgets that are
 * removed from the system will send corresponding **Detach** events. If you are using a Phidget
 * Manager, your program is responsible for keeping track of available Phidgets using these events.
 */
typedef struct _PhidgetManager *PhidgetManagerHandle;

/**
 * @ref PhidgetManager_create() creates an instance of a Phidget Manager, which can then be opened
 * by calling @ref PhidgetManager_open().
 * The Phidget Manager handle must be released with @ref PhidgetManager_delete().
 *
 * @param[out] man The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetManager_create(PhidgetManagerHandle *man);

/**
 * @ref PhidgetManager_delete() releases a Phidget Manager handle created with @ref
 * PhidgetManager_create().
 * If the Manager is open when @ref PhidgetManager_delete() is called, it will be closed.
 *
 * @param[out] man The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetManager_delete(PhidgetManagerHandle *man);

/**
 * Closes a Phidget Manager that has been opened.
 *
 * @param[in] man The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetManager_close(PhidgetManagerHandle man);

/**
 * Opens the Phidget Manager.
 *
 * Be sure to register **Attach** and **Detach** event handlers for the Manager before opening it,
 * to ensure you program doesn't miss the events reported for devices already connected to your
 * system.
 *
 * @param[in] man The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetManager_open(PhidgetManagerHandle man);

/**
 * @brief Callback function type for PhidgetManager_setOnAttachHandler().
 *
 * @param[in] man The channel handle
 * @param[in] ctx Pointer to the user context
 * @param[in] channel The Phidget channel that attached
 */
typedef void (CCONV *PhidgetManager_OnAttachCallback)(PhidgetManagerHandle man, void *ctx,
  PhidgetHandle channel);

/**
 * Occurs when a channel is attached.
 *
 * *   Phidget channels you get from the manager are informational only, you can read
 *     information about them such as serial number, class, name, etc. but they are not opened. In
 *     order to interact with one, you must `create` and `open` a Phidget object of the correct
 *     type.
 *
 * @param[in] man The channel handle
 * @param[in] fptr The event handler callback function
 * @param[in] ctx User supplied context pointer
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetManager_setOnAttachHandler(PhidgetManagerHandle man,
  PhidgetManager_OnAttachCallback fptr, void *ctx);

/**
 * @brief Callback function type for PhidgetManager_setOnDetachHandler().
 *
 * @param[in] man The channel handle
 * @param[in] ctx Pointer to the user context
 * @param[in] channel The Phidget channel that detached
 */
typedef void (CCONV *PhidgetManager_OnDetachCallback)(PhidgetManagerHandle man, void *ctx,
  PhidgetHandle channel);

/**
 * Occurs when a channel is detached.
 *
 * *   Phidget channels you get from the manager are informational only, you can read
 *     information about them such as serial number, class, name, etc. but they are not opened. In
 *     order to interact with one, you must `create` and `open` a Phidget object of the correct
 *     type.
 *
 * @param[in] man The channel handle
 * @param[in] fptr The event handler callback function
 * @param[in] ctx User supplied context pointer
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetManager_setOnDetachHandler(PhidgetManagerHandle man,
  PhidgetManager_OnDetachCallback fptr, void *ctx);

/** @} */ /* PhidgetManager */

/**
 * @defgroup PhidgetNet Net
 * @brief The Phidget NET class controls all network functionality of a Phidget program, and
 *     allows for the use of remote Phidgets in your program. It can be used to enable automated
 *     Phidget server discovery over the local network, and to connect to or reject specific
 *     servers.
 * @{
 */

/**
 * Removes all server registrations
 *
 * @private
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetNet_removeAllServers(void);

/**
 * Frees the address list
 *
 * @private
 * @param[in] addressList The addresses
 * @param[in] count The number of addresses
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetNet_freeServerAddressList(const char **addressList,
  uint32_t count);

/**
 * Sets a network property value
 *
 * @private
 * @param[in] key The name of the network parameter
 * @param[in] property The new value of the network parameter
 * @param[in] ... The arguments to the parameter format
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetNet_setProperty(const char *key, const char *property,
  ...);

/**
 * Registers a server that the client (your program) will try to connect to. The client will
 * continually try to connect to the server, increasing the time between each attempt to a maximum
 * interval of 16 seconds.
 *
 * This call is intended for use when server discovery is not enabled, or to connect to a server
 * that is not discoverable.
 *
 * The server name used by this function does not have to match the name of the server running on
 * the host machine. Only the address, port, and password need to match.
 *
 * This call will fail if a server with the same name has already been discovered.
 *
 * This call will fail if @ref PhidgetNet_setServerPassword() has already been called with the same
 * server name, as @ref PhidgetNet_setServerPassword() registers the server entry anticipating the
 * discovery of the server.
 *
 * See:
 *
 * *   @ref PhidgetNet_removeServer()
 * *   @ref PhidgetNet_enableServerDiscovery()
 *
 * @param[in] serverName A unique name for the server (not the hostname)
 * @param[in] address The hostname or address of the server to connect to
 * @param[in] port The port number of the server to connect to
 * @param[in] password The password for the server to connect to (empty string if no password is
 *     required)
 * @param[in] flags connection flags: should be set to 0
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetNet_addServer(const char *serverName, const char *address,
  int port, const char *password, int flags);

/**
 * Removes a registration for a server that the client (your program) is trying to connect to.If the
 * client is currently connected to the server, the connection will be closed.
 *
 * If the server was discovered (not added by @ref PhidgetNet_addServer()), the connection may be
 * reestablished if and when the server is rediscovered. @ref PhidgetNet_disableServer() should be
 * used to prevent the reconnection of a discovered server
 *
 * See:
 *
 * *   @ref PhidgetNet_addServer()
 * *   @ref PhidgetNet_disableServer()
 * *   @ref PhidgetNet_disableServerDiscovery()
 *
 * @param[in] serverName The name of the server to remove
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetNet_removeServer(const char *serverName);

/**
 * Enables attempts to connect to a discovered server, if attempts were previously disabled by @ref
 * PhidgetNet_disableServer(). All servers are enabled by default.
 *
 * This call will fail if the server was not previously added, disabled or discovered.
 *
 * See:
 *
 * *   @ref PhidgetNet_disableServer()
 *
 * @param[in] serverName The name of the server to enable
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetNet_enableServer(const char *serverName);

/**
 * Prevents attempts to automatically connect to a server.
 *
 * By default the client (your program) will continually attempt to connect to added or discovered
 * servers.This call will disable those attempts, but will not close an already established
 * connection.
 *
 * See:
 *
 * *   @ref PhidgetNet_addServer()
 * *   @ref PhidgetNet_enableServer()
 * *   @ref PhidgetNet_enableServerDiscovery()
 *
 * @param[in] serverName The name of the server to stop connections to
 * @param[in] flags Should be 0
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetNet_disableServer(const char *serverName, int flags);

/**
 * Returns a list of addresses for a server
 *
 * @private
 * @param[in] hostname The server hostname
 * @param[in] addressFamily The address family to look up
 * @param[out] addressList The addresses
 * @param[in,out] count The number of addresses
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetNet_getServerAddressList(const char *hostname,
  int addressFamily, const char **addressList, uint32_t *count);

/**
 * Enables the dynamic discovery of servers that publish their identity to the network. Currently
 * Multicast DNS is used to discover and publish Phidget servers.
 *
 * To connect to remote Phidgets, call this function with server type @ref
 * PHIDGETSERVER_DEVICEREMOTE.
 *
 * @ref PhidgetNet_enableServerDiscovery() must be called once for each server type your program
 * requires. Multiple calls for the same server type are ignored
 *
 * This call will fail with the error code @ref EPHIDGET_UNSUPPORTED if your computer does not have
 * the required mDNS support. We recommend using Bonjour on Windows and Mac, and Avahi on Linux.
 *
 * For more information, visit our [Network Server
 * Guide](https://www.phidgets.com/docs/Network_Server_Guide#Enabling_Server_Discovery)
 *
 * See:
 *
 * *   @ref PhidgetNet_disableServerDiscovery()
 * *   @ref PhidgetNet_addServer()
 *
 * @param[in] serverType The server type listen for
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetNet_enableServerDiscovery(PhidgetServerType serverType);

/**
 * Disables the dynamic discovery of servers that publish their identity.
 *
 * @ref PhidgetNet_disableServerDiscovery() does not disconnect already established connections.
 *
 * See:
 *
 * *   @ref PhidgetNet_enableServerDiscovery()
 * *   @ref PhidgetNet_disableServer()
 * *   @ref PhidgetNet_removeServer()
 *
 * @param[in] serverType The server type to disable
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetNet_disableServerDiscovery(PhidgetServerType serverType);

/**
 * Sets the password that will be used to attempt to connect to the server. If the server has not
 * already been added or discovered, a placeholder server entry will be registered to use this
 * password on the server once it is discovered.
 *
 * @param[in] serverName The name of the server
 * @param[in] password The password to use for the server (empty string if no password)
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetNet_setServerPassword(const char *serverName,
  const char *password);

/**
 * Creates and starts a Phidget network server instance
 *
 * @private
 * @param[in] flags server control flags: PHIDGET\_NETWORK\_PUBLISHMDNS or 0
 * @param[in] addressFamily The address family to listen on
 * @param[in] serverName The name of the server (not the address)
 * @param[in] address The address or hostname of the server: NULL indicates any address
 * @param[in] port The port number to listen on
 * @param[in] password The password to require from clients: Empty string indicates no password
 * @param[out] server A pointer to a server handle that will be created on success
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetNet_startServer(int flags, int addressFamily,
  const char *serverName, const char *address, int port, const char *password, PhidgetServer **server);

/**
 * Stops a Phidget network server instance, and releases the resources associated with it.
 *
 * @private
 * @param[out] server A pointer to a server handle that will be stopped and released
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetNet_stopServer(PhidgetServer **server);

/**
 * @brief Callback function type for PhidgetNet_setOnServerAddedHandler().
 *
 * @param[in] ctx Pointer to the user context
 * @param[in] server The server that has been added
 * @param[in] kv Opaque structure containing keys related to the server
 */
typedef void (CCONV *PhidgetNet_OnServerAddedCallback)(void *ctx, PhidgetServer *server, void *kv);

/**
 * Subscribe to this event if you would like to know when a server has been added.
 *
 * @param[in] fptr The event handler callback function
 * @param[in] ctx User supplied context pointer
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetNet_setOnServerAddedHandler(PhidgetNet_OnServerAddedCallback fptr,
  void *ctx);

/**
 * @brief Callback function type for PhidgetNet_setOnServerRemovedHandler().
 *
 * @param[in] ctx Pointer to the user context
 * @param[in] server The server that has been removed
 */
typedef void (CCONV *PhidgetNet_OnServerRemovedCallback)(void *ctx, PhidgetServer *server);

/**
 * Subscribe to this event if you would like to know when a server has been removed.
 *
 * @param[in] fptr The event handler callback function
 * @param[in] ctx User supplied context pointer
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetNet_setOnServerRemovedHandler(PhidgetNet_OnServerRemovedCallback fptr,
  void *ctx);

#define PHIDGETSERVER_AUTHREQUIRED 0x1  /**< PhidgetServer flag indicating that the server requires a password to authenticate */

/** @} */ /* PhidgetNet */

/**
 * @defgroup PhidgetLog Log
 * @brief The Phidget Log class is used to track and store information about the operation of
 *     programs using the Phidget22 library.
 * @{
 */

/**
 * Disables logging within the Phidget library.
 *
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLog_disable(void);

/**
 * Enables logging within the Phidget library.
 *
 * @param[in] level The logging level
 * @param[in] destination The log file path, or `NULL` for `STDOUT`
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLog_enable(Phidget_LogLevel level,
  const char *destination);

/**
 * Gets the log level for the phidget22 source.
 *
 * @param[out] level The current log level
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLog_getLevel(Phidget_LogLevel *level);

/**
 * Sets the log level for all sources not prefaced with _phidget22.
 *
 * @param[in] level The new log level
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLog_setLevel(Phidget_LogLevel level);

/**
 * Writes a message to the Phidget library log. Supports `printf` style formatting
 *
 * @param[in] level The logging level
 * @param[in] message The message
 * @param[in] ... The arguments to the log message
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLog_log(Phidget_LogLevel level, const char *message, ...);

/**
 * Writes a message to the Phidget library log from a specified source. Supports `printf` style
 * formatting
 *
 * @param[in] file The file the message is from. Use NULL to ignore this
 * @param[in] line The line number the message is from. Use 0 to ignore this
 * @param[in] function The function the message is from. Use NULL to ignore this
 * @param[in] source The name of the log source the message is from
 * @param[in] level The logging level
 * @param[in] message The message
 * @param[in] ... The arguments to the log message
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLog_loge(const char *file, int line, const char *function,
  const char *source, Phidget_LogLevel level, const char *message, ...);

/**
 * Writes a message to the Phidget library log with a specified source.
 *
 * @private
 * @param[in] level The logging level
 * @param[in] source The name of the log source the message is from
 * @param[in] message The message
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLog_loges(Phidget_LogLevel level, const char *source,
  const char *message);

/**
 * Writes a message to the Phidget library log.
 *
 * @private
 * @param[in] level The logging level
 * @param[in] message The message
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLog_logs(Phidget_LogLevel level, const char *message);

/**
 * Manually rotate the log file. This will only have an effect if automatic rotation is disabled and
 * the log file is larger than the specified maximum file size.
 *
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLog_rotate(void);

/**
 * Determines if the library is automatically rotating the log file
 *
 * @param[out] isrotating If the library is automatically rotating the log file
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLog_isRotating(int *isrotating);

/**
 * Gets the current log rotation parameters
 *
 * @param[out] size The file size above which the log file should be rotated
 * @param[out] keepCount The number of log files that will be kept after rotation
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLog_getRotating(uint64_t *size, int *keepCount);

/**
 * Sets log rotation parameters.
 *
 * @param[in] size The file size above which the file should be rotated in bytes. Min: 32768 (32
 *     KiB) Def: 10485760 (10 MiB)
 * @param[in] keepCount The number of log files that should be kept after rotation. Min: 0 Def:
 *     1 Max: 64
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLog_setRotating(uint64_t size, int keepCount);

/**
 * Enables automatic rotation of the log file (the default).
 *
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLog_enableRotating(void);

/**
 * Disables automatic rotation of the log file.
 *
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLog_disableRotating(void);

/**
 * Adds a source to the Phidget logging system. This is useful for declaring a source and setting
 * its log level before sending any messages.
 *
 * @param[in] source The source name
 * @param[in] level The log level of the source
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLog_addSource(const char *source, Phidget_LogLevel level);

/**
 * Gets the log level of the specified log source.
 *
 * @param[in] source The log source name
 * @param[out] level The log level of the source
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLog_getSourceLevel(const char *source,
  Phidget_LogLevel *level);

/**
 * Sets the log level of the specified log source.
 *
 * @param[in] source The log source name
 * @param[in] level The new log level
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLog_setSourceLevel(const char *source,
  Phidget_LogLevel level);

/**
 * Determies the number of log sources in the system, and the names of those sources if `sources` is
 * not `NULL`.
 *
 * If `sources` is `NULL`, the number of sources is calculated; otherwise,`count` indicates how many
 * entries `sources` contains and that many names will be assigned
 *
 * @param[out] sources The source names
 * @param[in,out] count The number of log sources
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLog_getSources(const char **sources, uint32_t *count);

/** @} */ /* PhidgetLog */

/**
 * @defgroup PhidgetAccelerometer Accelerometer
 * @brief The Accelerometer class is used to gather acceleration data from Phidget accelerometer
 *     boards. Phidget accelerometers usually have multiple sensors, each oriented in a different
 *     axis, so multiple dimensions of acceleration can be recorded.
 * @{
 */

/**
 * The Accelerometer class is used to gather acceleration data from Phidget accelerometer boards.
 * Phidget accelerometers usually have multiple sensors, each oriented in a different axis, so
 * multiple dimensions of acceleration can be recorded.
 *
 * If the Phidget you're using also has a gyroscope and a magnetometer, you may want to use the
 * Spatial class in order to get all of the data at the same time, in a single event.
 */
typedef struct _PhidgetAccelerometer *PhidgetAccelerometerHandle;

/**
 * @ref PhidgetAccelerometer_create() creates an instance of a Phidget channel. Once created the
 * channel may need to be configured to match the physical device and channel index you want to
 * attach to, and then be opened by calling @ref Phidget_open().
 * The Phidget channel handle must be released with @ref PhidgetAccelerometer_delete().
 *
 * @param[out] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetAccelerometer_create(PhidgetAccelerometerHandle *ch);

/**
 * @ref PhidgetAccelerometer_delete() releases a Phidget channel handle created with @ref
 * PhidgetAccelerometer_create().
 * If the channel is open when @ref PhidgetAccelerometer_delete() is called, it will be closed.
 *
 * @param[out] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetAccelerometer_delete(PhidgetAccelerometerHandle *ch);

/**
 * @brief The acceleration values
 *
 * The most recent acceleration value that the channel has reported.
 *
 * *   This value will always be between @ref PhidgetAccelerometer_getMinAcceleration() and @ref
 *     PhidgetAccelerometer_getMaxAcceleration().
 *
 * @param[in] ch The channel handle
 * @param[out] acceleration The acceleration values
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetAccelerometer_getAcceleration(PhidgetAccelerometerHandle ch,
  double (*acceleration)[3]);

/**
 * @brief The minimum acceleration value
 *
 * The minimum value the @ref PhidgetAccelerometer_setOnAccelerationChangeHandler() event will
 * report.
 *
 * @param[in] ch The channel handle
 * @param[out] minAcceleration The minimum acceleration value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetAccelerometer_getMinAcceleration(PhidgetAccelerometerHandle ch,
  double (*minAcceleration)[3]);

/**
 * @brief The maximum acceleration values
 *
 * The maximum value the @ref PhidgetAccelerometer_setOnAccelerationChangeHandler() event will
 * report.
 *
 * @param[in] ch The channel handle
 * @param[out] maxAcceleration The maximum acceleration values
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetAccelerometer_getMaxAcceleration(PhidgetAccelerometerHandle ch,
  double (*maxAcceleration)[3]);

/**
 * @brief The change trigger value
 *
 * The channel will not issue a @ref PhidgetAccelerometer_setOnAccelerationChangeHandler() event
 * until the acceleration value has changed by the amount specified by the
 * `AccelerationChangeTrigger`.
 *
 * *   Setting the `AccelerationChangeTrigger` to 0 will result in the channel firing events
 *     every `DataInterval`. This is useful for applications that implement their own data filtering
 *
 * @param[in] ch The channel handle
 * @param[in] accelerationChangeTrigger The change trigger value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetAccelerometer_setAccelerationChangeTrigger(PhidgetAccelerometerHandle ch,
  double accelerationChangeTrigger);

/**
 * @brief The change trigger value
 *
 * The channel will not issue a @ref PhidgetAccelerometer_setOnAccelerationChangeHandler() event
 * until the acceleration value has changed by the amount specified by the
 * `AccelerationChangeTrigger`.
 *
 * *   Setting the `AccelerationChangeTrigger` to 0 will result in the channel firing events
 *     every `DataInterval`. This is useful for applications that implement their own data filtering
 *
 * @param[in] ch The channel handle
 * @param[out] accelerationChangeTrigger The change trigger value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetAccelerometer_getAccelerationChangeTrigger(PhidgetAccelerometerHandle ch,
  double *accelerationChangeTrigger);

/**
 * @brief The minimum change trigger value
 *
 * The minimum value that `AccelerationChangeTrigger` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minAccelerationChangeTrigger The minimum change trigger value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetAccelerometer_getMinAccelerationChangeTrigger(PhidgetAccelerometerHandle ch,
  double *minAccelerationChangeTrigger);

/**
 * @brief The maximum change trigger value
 *
 * The maximum value that `AccelerationChangeTrigger` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxAccelerationChangeTrigger The maximum change trigger value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetAccelerometer_getMaxAccelerationChangeTrigger(PhidgetAccelerometerHandle ch,
  double *maxAccelerationChangeTrigger);

/**
 * @brief The number of axes
 *
 * The number of axes the channel can measure acceleration on.
 *
 * *   See your device's User Guide for more information about the number of axes and their
 *     orientation.
 *
 * @param[in] ch The channel handle
 * @param[out] axisCount The number of axes
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetAccelerometer_getAxisCount(PhidgetAccelerometerHandle ch,
  int *axisCount);

/**
 * @brief The data interval value
 *
 * The `DataInterval` is the time that must elapse before the channel will fire another @ref
 * PhidgetAccelerometer_setOnAccelerationChangeHandler() event.
 *
 * *   The data interval is bounded by @ref PhidgetAccelerometer_getMinDataInterval() and @ref
 *     PhidgetAccelerometer_getMaxDataInterval().
 * *   The timing between @ref PhidgetAccelerometer_setOnAccelerationChangeHandler() events can
 *     also be affected by the `AccelerationChangeTrigger`.
 *
 * @param[in] ch The channel handle
 * @param[in] dataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetAccelerometer_setDataInterval(PhidgetAccelerometerHandle ch,
  uint32_t dataInterval);

/**
 * @brief The data interval value
 *
 * The `DataInterval` is the time that must elapse before the channel will fire another @ref
 * PhidgetAccelerometer_setOnAccelerationChangeHandler() event.
 *
 * *   The data interval is bounded by @ref PhidgetAccelerometer_getMinDataInterval() and @ref
 *     PhidgetAccelerometer_getMaxDataInterval().
 * *   The timing between @ref PhidgetAccelerometer_setOnAccelerationChangeHandler() events can
 *     also be affected by the `AccelerationChangeTrigger`.
 *
 * @param[in] ch The channel handle
 * @param[out] dataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetAccelerometer_getDataInterval(PhidgetAccelerometerHandle ch,
  uint32_t *dataInterval);

/**
 * @brief The minimum data interval value
 *
 * The minimum value that `DataInterval` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minDataInterval The minimum data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetAccelerometer_getMinDataInterval(PhidgetAccelerometerHandle ch,
  uint32_t *minDataInterval);

/**
 * @brief The data interval value
 *
 * The maximum value that `DataInterval` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxDataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetAccelerometer_getMaxDataInterval(PhidgetAccelerometerHandle ch,
  uint32_t *maxDataInterval);

/**
 * @brief The data rate for the channel
 *
 * The `DataRate` is the frequency of events from the device.
 *
 * *   The data rate is bounded by @ref PhidgetAccelerometer_getMinDataRate() and @ref
 *     PhidgetAccelerometer_getMaxDataRate().
 * *   Changing `DataRate` will change the channel's `DataInterval` to a corresponding value,
 *     rounded to the nearest integer number of milliseconds.
 * *   The timing between events can also affected by the change trigger.
 *
 * @param[in] ch The channel handle
 * @param[in] dataRate The data rate for the channel
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetAccelerometer_setDataRate(PhidgetAccelerometerHandle ch,
  double dataRate);

/**
 * @brief The data rate for the channel
 *
 * The `DataRate` is the frequency of events from the device.
 *
 * *   The data rate is bounded by @ref PhidgetAccelerometer_getMinDataRate() and @ref
 *     PhidgetAccelerometer_getMaxDataRate().
 * *   Changing `DataRate` will change the channel's `DataInterval` to a corresponding value,
 *     rounded to the nearest integer number of milliseconds.
 * *   The timing between events can also affected by the change trigger.
 *
 * @param[in] ch The channel handle
 * @param[out] dataRate The data rate for the channel
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetAccelerometer_getDataRate(PhidgetAccelerometerHandle ch,
  double *dataRate);

/**
 * @brief The data rate value
 *
 * The minimum value that `DataRate` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minDataRate The data rate value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetAccelerometer_getMinDataRate(PhidgetAccelerometerHandle ch,
  double *minDataRate);

/**
 * @brief The data rate value
 *
 * The maximum value that `DataRate` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxDataRate The data rate value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetAccelerometer_getMaxDataRate(PhidgetAccelerometerHandle ch,
  double *maxDataRate);

/**
 * @brief Whether self-heating temperature stabilization is enabled
 *
 * Set to TRUE to enable the temperature stabilization feature of this device. This enables onboard
 * heating elements to bring the board up to a known temperature to minimize ambient temerature
 * effects on the sensor's reading. You can leave this setting FALSE to conserve power consumption.
 *
 * If you enable heating, it is strongly recommended to keep the board in its enclosure to keep it
 * insulated from moving air.
 *
 * This property is shared by any and all spatial-related objects on this device (Accelerometer,
 * Gyroscope, Magnetometer, Spatial)
 *
 * @param[in] ch The channel handle
 * @param[in] heatingEnabled Whether self-heating temperature stabilization is enabled
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetAccelerometer_setHeatingEnabled(PhidgetAccelerometerHandle ch,
  int heatingEnabled);

/**
 * @brief Whether self-heating temperature stabilization is enabled
 *
 * Set to TRUE to enable the temperature stabilization feature of this device. This enables onboard
 * heating elements to bring the board up to a known temperature to minimize ambient temerature
 * effects on the sensor's reading. You can leave this setting FALSE to conserve power consumption.
 *
 * If you enable heating, it is strongly recommended to keep the board in its enclosure to keep it
 * insulated from moving air.
 *
 * This property is shared by any and all spatial-related objects on this device (Accelerometer,
 * Gyroscope, Magnetometer, Spatial)
 *
 * @param[in] ch The channel handle
 * @param[out] heatingEnabled Whether self-heating temperature stabilization is enabled
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetAccelerometer_getHeatingEnabled(PhidgetAccelerometerHandle ch,
  int *heatingEnabled);

/**
 * @brief The sensor precision value
 *
 * Selects between high/low precision sensing chips.
 *
 * @private
 * @param[in] ch The channel handle
 * @param[in] precision The sensor precision value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetAccelerometer_setPrecision(PhidgetAccelerometerHandle ch,
  Phidget_SpatialPrecision precision);

/**
 * @brief The sensor precision value
 *
 * Selects between high/low precision sensing chips.
 *
 * @private
 * @param[in] ch The channel handle
 * @param[out] precision The sensor precision value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetAccelerometer_getPrecision(PhidgetAccelerometerHandle ch,
  Phidget_SpatialPrecision *precision);

/**
 * @brief The timestamp value
 *
 * The most recent timestamp value that the channel has reported. This is an extremely accurate time
 * measurement streamed from the device.
 *
 * *   If your application requires a time measurement, you should use this value over a local
 *     software timestamp.
 *
 * @param[in] ch The channel handle
 * @param[out] timestamp The timestamp value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetAccelerometer_getTimestamp(PhidgetAccelerometerHandle ch,
  double *timestamp);

/**
 * @brief Callback function type for PhidgetAccelerometer_setOnAccelerationChangeHandler().
 *
 * @param[in] ch The channel handle
 * @param[in] ctx Pointer to the user context
 * @param[in] acceleration The acceleration values
 * @param[in] timestamp The timestamp value
 */
typedef void (CCONV *PhidgetAccelerometer_OnAccelerationChangeCallback)(PhidgetAccelerometerHandle ch,
  void *ctx, const double acceleration[3], double timestamp);

/**
 * The most recent acceleration values the channel has measured will be reported in this event,
 * which occurs when the `DataInterval` has elapsed.
 *
 * *   If a `AccelerationChangeTrigger` has been set to a non-zero value, the @ref
 *     PhidgetAccelerometer_setOnAccelerationChangeHandler() event will not occur until the
 *     acceleration has changed by at least the `AccelerationChangeTrigger` value.
 *
 * @param[in] ch The channel handle
 * @param[in] fptr The event handler callback function
 * @param[in] ctx User supplied context pointer
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetAccelerometer_setOnAccelerationChangeHandler(PhidgetAccelerometerHandle ch,
  PhidgetAccelerometer_OnAccelerationChangeCallback fptr, void *ctx);

/** @} */ /* PhidgetAccelerometer */

/**
 * @defgroup PhidgetBLDCMotor BLDCMotor
 * @brief The BLDC Motor class controls the power applied to attached brushless DC motors to
 *     affect its speed and direction. It can also contain various other control and monitoring
 *     functions that aid in the control of brushless DC motors.
 * @{
 */

/**
 * The BLDC Motor class controls the power applied to attached brushless DC motors to affect its
 * speed and direction. It can also contain various other control and monitoring functions that aid
 * in the control of brushless DC motors.
 */
typedef struct _PhidgetBLDCMotor *PhidgetBLDCMotorHandle;

/**
 * @ref PhidgetBLDCMotor_create() creates an instance of a Phidget channel. Once created the channel
 * may need to be configured to match the physical device and channel index you want to attach to,
 * and then be opened by calling @ref Phidget_open().
 * The Phidget channel handle must be released with @ref PhidgetBLDCMotor_delete().
 *
 * @param[out] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetBLDCMotor_create(PhidgetBLDCMotorHandle *ch);

/**
 * @ref PhidgetBLDCMotor_delete() releases a Phidget channel handle created with @ref
 * PhidgetBLDCMotor_create().
 * If the channel is open when @ref PhidgetBLDCMotor_delete() is called, it will be closed.
 *
 * @param[out] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetBLDCMotor_delete(PhidgetBLDCMotorHandle *ch);

/**
 * Enables the **failsafe** feature for the channel, with the specified **failsafe time**.
 *
 * Enabling the failsafe feature starts a recurring **failsafe timer** for the channel. Once the
 * failsafe is enabled, the timer must be reset within the specified time or the channel will enter
 * a **failsafe state**. For BLDC Motor channels, this will cut power to the motor, allowing it to
 * coast (freewheel) instead. The failsafe timer can be reset by using any API call **_except_** for
 * the following:
 *
 * *   @ref PhidgetBLDCMotor_setRescaleFactor()
 * *   @ref PhidgetBLDCMotor_addPositionOffset()
 * *   'get' API calls
 *
 * For more information about failsafe, visit our [Failsafe
 * Guide](https://www.phidgets.com/docs/Failsafe_Guide).
 *
 * @param[in] ch The channel handle
 * @param[in] failsafeTime Failsafe timeout in milliseconds
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetBLDCMotor_enableFailsafe(PhidgetBLDCMotorHandle ch,
  uint32_t failsafeTime);

/**
 * Adds an offset (positive or negative) to the current position.
 *
 * *   This can be especially useful for zeroing position.
 *
 * @param[in] ch The channel handle
 * @param[in] positionOffset Amount to offset the position by
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetBLDCMotor_addPositionOffset(PhidgetBLDCMotorHandle ch,
  double positionOffset);

/**
 * Resets the failsafe timer, if one has been set. See @ref PhidgetBLDCMotor_enableFailsafe() for
 * details.
 *
 * This function will fail if no failsafe timer has been set for the channel.
 *
 * @param[in] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetBLDCMotor_resetFailsafe(PhidgetBLDCMotorHandle ch);

/**
 * @brief The acceleration value
 *
 * The rate at which the controller can change the motor's @ref PhidgetBLDCMotor_getVelocity().
 *
 * For more information about `Acceleration`, visit our [BLDCMotor API
 * Guide](https://www.phidgets.com/docs/BLDCMotor_API_Guide#Acceleration)
 *
 * @param[in] ch The channel handle
 * @param[in] acceleration The acceleration value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetBLDCMotor_setAcceleration(PhidgetBLDCMotorHandle ch,
  double acceleration);

/**
 * @brief The acceleration value
 *
 * The rate at which the controller can change the motor's @ref PhidgetBLDCMotor_getVelocity().
 *
 * For more information about `Acceleration`, visit our [BLDCMotor API
 * Guide](https://www.phidgets.com/docs/BLDCMotor_API_Guide#Acceleration)
 *
 * @param[in] ch The channel handle
 * @param[out] acceleration The acceleration value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetBLDCMotor_getAcceleration(PhidgetBLDCMotorHandle ch,
  double *acceleration);

/**
 * @brief The acceleration value.
 *
 * The minimum value that `Acceleration` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minAcceleration The acceleration value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetBLDCMotor_getMinAcceleration(PhidgetBLDCMotorHandle ch,
  double *minAcceleration);

/**
 * @brief The acceleration value.
 *
 * The maximum value that `Acceleration` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxAcceleration The acceleration value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetBLDCMotor_getMaxAcceleration(PhidgetBLDCMotorHandle ch,
  double *maxAcceleration);

/**
 * @brief The active current limit value
 *
 * The current limit that the controller is actively following. The `SurgeCurrentLimit`,
 * `CurrentLimit`, and temperature will impact this value.
 *
 * For more information about @ref PhidgetBLDCMotor_getActiveCurrentLimit(), visit our [BLDCMotor
 * API Guide](https://www.phidgets.com/docs/BLDCMotor_API_Guide#Active_Current_Limit)
 *
 * @param[in] ch The channel handle
 * @param[out] activeCurrentLimit The active current limit value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetBLDCMotor_getActiveCurrentLimit(PhidgetBLDCMotorHandle ch,
  double *activeCurrentLimit);

/**
 * @brief Enable braking when stopped
 *
 * This setting allows you to choose whether the motor will resist being turned when it is not being
 * driven forward or reverse (@ref PhidgetBLDCMotor_getVelocity() = 0).
 *
 * *   Setting `BrakingEnabled` to FALSE corresponds to free-wheeling. This means:
 *     *   The motor will continue to rotate after the controller is no longer driving the motor
 * (@ref PhidgetBLDCMotor_getVelocity() = 0), due to its momentum.
 *     *   The motor shaft will provide little resistance to being turned when it is stopped.
 * *   Setting `BrakingEnabled` to TRUE will engage electrical braking of the DC motor. This
 *     means:
 *     *   The motor will stop more quickly if it is in motion when braking is requested.
 *     *   The motor shaft will resist rotation by outside forces.
 * *   Braking will be added gradually, according to the `Acceleration` setting, once the motor
 *     controller's @ref PhidgetBLDCMotor_getVelocity() reaches 0.0
 * *   Braking will be immediately stopped when a new (non-zero) `TargetVelocity` is set, and
 *     the motor will accelerate to the requested velocity.
 * *   Braking mode is enabled by setting the @ref PhidgetBLDCMotor_getVelocity() to 0.0
 *
 * @param[in] ch The channel handle
 * @param[in] brakingEnabled Enable braking when stopped
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetBLDCMotor_setBrakingEnabled(PhidgetBLDCMotorHandle ch,
  int brakingEnabled);

/**
 * @brief Enable braking when stopped
 *
 * This setting allows you to choose whether the motor will resist being turned when it is not being
 * driven forward or reverse (@ref PhidgetBLDCMotor_getVelocity() = 0).
 *
 * *   Setting `BrakingEnabled` to FALSE corresponds to free-wheeling. This means:
 *     *   The motor will continue to rotate after the controller is no longer driving the motor
 * (@ref PhidgetBLDCMotor_getVelocity() = 0), due to its momentum.
 *     *   The motor shaft will provide little resistance to being turned when it is stopped.
 * *   Setting `BrakingEnabled` to TRUE will engage electrical braking of the DC motor. This
 *     means:
 *     *   The motor will stop more quickly if it is in motion when braking is requested.
 *     *   The motor shaft will resist rotation by outside forces.
 * *   Braking will be added gradually, according to the `Acceleration` setting, once the motor
 *     controller's @ref PhidgetBLDCMotor_getVelocity() reaches 0.0
 * *   Braking will be immediately stopped when a new (non-zero) `TargetVelocity` is set, and
 *     the motor will accelerate to the requested velocity.
 * *   Braking mode is enabled by setting the @ref PhidgetBLDCMotor_getVelocity() to 0.0
 *
 * @param[in] ch The channel handle
 * @param[out] brakingEnabled Enable braking when stopped
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetBLDCMotor_getBrakingEnabled(PhidgetBLDCMotorHandle ch,
  int *brakingEnabled);

/**
 * @brief The braking strength value
 *
 * The most recent braking strength value that the controller has reported.
 *
 * @param[in] ch The channel handle
 * @param[out] brakingStrength The braking strength value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetBLDCMotor_getBrakingStrength(PhidgetBLDCMotorHandle ch,
  double *brakingStrength);

/**
 * @brief The braking value
 *
 * The minimum value that @ref PhidgetBLDCMotor_getBrakingStrength() can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minBrakingStrength The braking value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetBLDCMotor_getMinBrakingStrength(PhidgetBLDCMotorHandle ch,
  double *minBrakingStrength);

/**
 * @brief The braking value
 *
 * The maximum value that @ref PhidgetBLDCMotor_getBrakingStrength() can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxBrakingStrength The braking value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetBLDCMotor_getMaxBrakingStrength(PhidgetBLDCMotorHandle ch,
  double *maxBrakingStrength);

/**
 * @brief The current value
 *
 * The controller will limit the current through the motor to the `CurrentLimit` value.
 *
 * For more information about `CurrentLimit`, visit our [BLDCMotor API
 * Guide](https://www.phidgets.com/docs/BLDCMotor_API_Guide#Current_Limit)
 *
 * @param[in] ch The channel handle
 * @param[in] currentLimit The current value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetBLDCMotor_setCurrentLimit(PhidgetBLDCMotorHandle ch,
  double currentLimit);

/**
 * @brief The current value
 *
 * The controller will limit the current through the motor to the `CurrentLimit` value.
 *
 * For more information about `CurrentLimit`, visit our [BLDCMotor API
 * Guide](https://www.phidgets.com/docs/BLDCMotor_API_Guide#Current_Limit)
 *
 * @param[in] ch The channel handle
 * @param[out] currentLimit The current value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetBLDCMotor_getCurrentLimit(PhidgetBLDCMotorHandle ch,
  double *currentLimit);

/**
 * @brief The current value
 *
 * The minimum value that `CurrentLimit` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minCurrentLimit The current value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetBLDCMotor_getMinCurrentLimit(PhidgetBLDCMotorHandle ch,
  double *minCurrentLimit);

/**
 * @brief The current value
 *
 * The maximum value that `CurrentLimit` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxCurrentLimit The current value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetBLDCMotor_getMaxCurrentLimit(PhidgetBLDCMotorHandle ch,
  double *maxCurrentLimit);

/**
 * @brief The data interval value
 *
 * The `DataInterval` is the time that must elapse before the channel will fire another @ref
 * PhidgetBLDCMotor_setOnVelocityUpdateHandler() / @ref
 * PhidgetBLDCMotor_setOnPositionChangeHandler() / @ref
 * PhidgetBLDCMotor_setOnBrakingStrengthChangeHandler() event.
 *
 * *   The data interval is bounded by @ref PhidgetBLDCMotor_getMinDataInterval() and @ref
 *     PhidgetBLDCMotor_getMaxDataInterval().
 *
 * @param[in] ch The channel handle
 * @param[in] dataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetBLDCMotor_setDataInterval(PhidgetBLDCMotorHandle ch,
  uint32_t dataInterval);

/**
 * @brief The data interval value
 *
 * The `DataInterval` is the time that must elapse before the channel will fire another @ref
 * PhidgetBLDCMotor_setOnVelocityUpdateHandler() / @ref
 * PhidgetBLDCMotor_setOnPositionChangeHandler() / @ref
 * PhidgetBLDCMotor_setOnBrakingStrengthChangeHandler() event.
 *
 * *   The data interval is bounded by @ref PhidgetBLDCMotor_getMinDataInterval() and @ref
 *     PhidgetBLDCMotor_getMaxDataInterval().
 *
 * @param[in] ch The channel handle
 * @param[out] dataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetBLDCMotor_getDataInterval(PhidgetBLDCMotorHandle ch,
  uint32_t *dataInterval);

/**
 * @brief The data interval value
 *
 * The minimum value that `DataInterval` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minDataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetBLDCMotor_getMinDataInterval(PhidgetBLDCMotorHandle ch,
  uint32_t *minDataInterval);

/**
 * @brief The data interval value
 *
 * The maximum value that `DataInterval` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxDataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetBLDCMotor_getMaxDataInterval(PhidgetBLDCMotorHandle ch,
  uint32_t *maxDataInterval);

/**
 * @brief The data rate for the channel
 *
 * The `DataRate` is the frequency of events from the device.
 *
 * *   The data rate is bounded by @ref PhidgetBLDCMotor_getMinDataRate() and @ref
 *     PhidgetBLDCMotor_getMaxDataRate().
 * *   Changing `DataRate` will change the channel's `DataInterval` to a corresponding value,
 *     rounded to the nearest integer number of milliseconds.
 * *   The timing between events can also affected by the change trigger.
 *
 * @param[in] ch The channel handle
 * @param[in] dataRate The data rate for the channel
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetBLDCMotor_setDataRate(PhidgetBLDCMotorHandle ch,
  double dataRate);

/**
 * @brief The data rate for the channel
 *
 * The `DataRate` is the frequency of events from the device.
 *
 * *   The data rate is bounded by @ref PhidgetBLDCMotor_getMinDataRate() and @ref
 *     PhidgetBLDCMotor_getMaxDataRate().
 * *   Changing `DataRate` will change the channel's `DataInterval` to a corresponding value,
 *     rounded to the nearest integer number of milliseconds.
 * *   The timing between events can also affected by the change trigger.
 *
 * @param[in] ch The channel handle
 * @param[out] dataRate The data rate for the channel
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetBLDCMotor_getDataRate(PhidgetBLDCMotorHandle ch,
  double *dataRate);

/**
 * @brief The data rate value
 *
 * The minimum value that `DataRate` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minDataRate The data rate value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetBLDCMotor_getMinDataRate(PhidgetBLDCMotorHandle ch,
  double *minDataRate);

/**
 * @brief The data rate value
 *
 * The maximum value that `DataRate` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxDataRate The data rate value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetBLDCMotor_getMaxDataRate(PhidgetBLDCMotorHandle ch,
  double *maxDataRate);

/**
 * @brief The drive type selection
 *
 * This setting impacts how your motor decelerates and the amount of current that is available to
 * your motor at any given moment.
 *
 * For more information about `DriveMode`, visit our [BLDCMotor API
 * Guide](https://www.phidgets.com/docs/BLDCMotor_API_Guide#Drive_Mode)
 *
 * @param[in] ch The channel handle
 * @param[in] driveMode The drive type selection
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetBLDCMotor_setDriveMode(PhidgetBLDCMotorHandle ch,
  Phidget_DriveMode driveMode);

/**
 * @brief The drive type selection
 *
 * This setting impacts how your motor decelerates and the amount of current that is available to
 * your motor at any given moment.
 *
 * For more information about `DriveMode`, visit our [BLDCMotor API
 * Guide](https://www.phidgets.com/docs/BLDCMotor_API_Guide#Drive_Mode)
 *
 * @param[in] ch The channel handle
 * @param[out] driveMode The drive type selection
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetBLDCMotor_getDriveMode(PhidgetBLDCMotorHandle ch,
  Phidget_DriveMode *driveMode);

/**
 * @brief Enables failsafe braking
 *
 * This setting allows you to choose whether motor will forcibly stop once it enters a **FAILSAFE**
 * state.
 *
 * *   A setting of FALSE will simply stop applying power to the motor, allowing it to spin down
 *     naturally.
 * *   A setting of TRUE will apply braking up to the `FailsafeCurrentLimit`, actively stopping
 *     the motor
 *
 * For more information about `FailsafeBrakingEnabled`, visit our [BLDCMotor API
 * Guide](https://www.phidgets.com/docs/BLDCMotor_API_Guide#Failsafe_Braking_Enabled)
 *
 * @param[in] ch The channel handle
 * @param[in] failsafeBrakingEnabled Enables failsafe braking
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetBLDCMotor_setFailsafeBrakingEnabled(PhidgetBLDCMotorHandle ch,
  int failsafeBrakingEnabled);

/**
 * @brief Enables failsafe braking
 *
 * This setting allows you to choose whether motor will forcibly stop once it enters a **FAILSAFE**
 * state.
 *
 * *   A setting of FALSE will simply stop applying power to the motor, allowing it to spin down
 *     naturally.
 * *   A setting of TRUE will apply braking up to the `FailsafeCurrentLimit`, actively stopping
 *     the motor
 *
 * For more information about `FailsafeBrakingEnabled`, visit our [BLDCMotor API
 * Guide](https://www.phidgets.com/docs/BLDCMotor_API_Guide#Failsafe_Braking_Enabled)
 *
 * @param[in] ch The channel handle
 * @param[out] failsafeBrakingEnabled Enables failsafe braking
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetBLDCMotor_getFailsafeBrakingEnabled(PhidgetBLDCMotorHandle ch,
  int *failsafeBrakingEnabled);

/**
 * @brief The failsafe current limit value
 *
 * When the controller enters a **FAILSAFE** state, the controller will limit the current through
 * the motor to the `FailsafeCurrentLimit` value.
 *
 * For more information about `FailsafeCurrentLimit`, visit our [BLDCMotor API
 * Guide](https://www.phidgets.com/docs/BLDCMotor_API_Guide#Failsafe_Current_Limit)
 *
 * @param[in] ch The channel handle
 * @param[in] failsafeCurrentLimit The failsafe current limit value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetBLDCMotor_setFailsafeCurrentLimit(PhidgetBLDCMotorHandle ch,
  double failsafeCurrentLimit);

/**
 * @brief The failsafe current limit value
 *
 * When the controller enters a **FAILSAFE** state, the controller will limit the current through
 * the motor to the `FailsafeCurrentLimit` value.
 *
 * For more information about `FailsafeCurrentLimit`, visit our [BLDCMotor API
 * Guide](https://www.phidgets.com/docs/BLDCMotor_API_Guide#Failsafe_Current_Limit)
 *
 * @param[in] ch The channel handle
 * @param[out] failsafeCurrentLimit The failsafe current limit value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetBLDCMotor_getFailsafeCurrentLimit(PhidgetBLDCMotorHandle ch,
  double *failsafeCurrentLimit);

/**
 * @brief The failsafe time
 *
 * The minimum value that `failsafeTime` can be set to when calling @ref
 * PhidgetBLDCMotor_enableFailsafe().
 *
 * @param[in] ch The channel handle
 * @param[out] minFailsafeTime The failsafe time
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetBLDCMotor_getMinFailsafeTime(PhidgetBLDCMotorHandle ch,
  uint32_t *minFailsafeTime);

/**
 * @brief The failsafe time
 *
 * The maximum value that `failsafeTime` can be set to when calling @ref
 * PhidgetBLDCMotor_enableFailsafe().
 *
 * @param[in] ch The channel handle
 * @param[out] maxFailsafeTime The failsafe time
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetBLDCMotor_getMaxFailsafeTime(PhidgetBLDCMotorHandle ch,
  uint32_t *maxFailsafeTime);

/**
 * @brief The inductance of your motor
 *
 * The controller will attempt to measure the inductance of your motor when opened. This value is
 * used to improve control of the motor.
 *
 * *   Set this value during the @ref Phidget_setOnAttachHandler() event to skip motor
 *     characterization (including the audible beeps). You can use a previously saved `Inductance`
 *     value, or information from your motor's datasheet.
 *
 * For more information about `Inductance`, visit our [BLDCMotor API
 * Guide](https://www.phidgets.com/docs/BLDCMotor_API_Guide#Motor_Inductance)
 *
 * @param[in] ch The channel handle
 * @param[in] inductance The inductance of your motor
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetBLDCMotor_setInductance(PhidgetBLDCMotorHandle ch,
  double inductance);

/**
 * @brief The inductance of your motor
 *
 * The controller will attempt to measure the inductance of your motor when opened. This value is
 * used to improve control of the motor.
 *
 * *   Set this value during the @ref Phidget_setOnAttachHandler() event to skip motor
 *     characterization (including the audible beeps). You can use a previously saved `Inductance`
 *     value, or information from your motor's datasheet.
 *
 * For more information about `Inductance`, visit our [BLDCMotor API
 * Guide](https://www.phidgets.com/docs/BLDCMotor_API_Guide#Motor_Inductance)
 *
 * @param[in] ch The channel handle
 * @param[out] inductance The inductance of your motor
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetBLDCMotor_getInductance(PhidgetBLDCMotorHandle ch,
  double *inductance);

/**
 * @brief The motor inductance value
 *
 * The minimum value that `Inductance` can be set to. See `Inductance` for details.
 *
 * @param[in] ch The channel handle
 * @param[out] minInductance The motor inductance value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetBLDCMotor_getMinInductance(PhidgetBLDCMotorHandle ch,
  double *minInductance);

/**
 * @brief The motor inductance value
 *
 * The maximum value that `Inductance` can be set to. See `Inductance` for details.
 *
 * @param[in] ch The channel handle
 * @param[out] maxInductance The motor inductance value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetBLDCMotor_getMaxInductance(PhidgetBLDCMotorHandle ch,
  double *maxInductance);

/**
 * @brief The position value
 *
 * The most recent position value that the controller has reported.
 *
 * *   Position values are calculated using Hall Effect sensors mounted on the motor, therefore,
 *     the resolution of position depends on the motor you are using.
 * *   Units for @ref PhidgetBLDCMotor_getPosition() can be set by the user through the
 *     `RescaleFactor`. The `RescaleFactor` allows you to use more intuitive units such as
 *     rotations, or degrees. For more information on how to apply the `RescaleFactor` to your
 *     application, see your controller's User Guide.
 *
 * For more information about @ref PhidgetBLDCMotor_getPosition(), visit our [BLDCMotor API
 * Guide](https://www.phidgets.com/docs/BLDCMotor_API_Guide#Position)
 *
 * @param[in] ch The channel handle
 * @param[out] position The position value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetBLDCMotor_getPosition(PhidgetBLDCMotorHandle ch,
  double *position);

/**
 * @brief The position value
 *
 * The lower bound of @ref PhidgetBLDCMotor_getPosition().
 *
 * @param[in] ch The channel handle
 * @param[out] minPosition The position value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetBLDCMotor_getMinPosition(PhidgetBLDCMotorHandle ch,
  double *minPosition);

/**
 * @brief The position value
 *
 * The upper bound of @ref PhidgetBLDCMotor_getPosition().
 *
 * @param[in] ch The channel handle
 * @param[out] maxPosition The position value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetBLDCMotor_getMaxPosition(PhidgetBLDCMotorHandle ch,
  double *maxPosition);

/**
 * @brief The rescale factor value
 *
 * Change the units of your parameters so that your application is more intuitive.
 *
 * For more information about `RescaleFactor`, visit our [BLDCMotor API
 * Guide](https://www.phidgets.com/docs/BLDCMotor_API_Guide#Rescale_Factor)
 *
 * @param[in] ch The channel handle
 * @param[in] rescaleFactor The rescale factor value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetBLDCMotor_setRescaleFactor(PhidgetBLDCMotorHandle ch,
  double rescaleFactor);

/**
 * @brief The rescale factor value
 *
 * Change the units of your parameters so that your application is more intuitive.
 *
 * For more information about `RescaleFactor`, visit our [BLDCMotor API
 * Guide](https://www.phidgets.com/docs/BLDCMotor_API_Guide#Rescale_Factor)
 *
 * @param[in] ch The channel handle
 * @param[out] rescaleFactor The rescale factor value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetBLDCMotor_getRescaleFactor(PhidgetBLDCMotorHandle ch,
  double *rescaleFactor);

/**
 * @brief The stall velocity value.
 *
 * Before reading this description, it is important to note the difference between the units of
 * `StallVelocity` and @ref PhidgetBLDCMotor_getVelocity().
 *
 * *   @ref PhidgetBLDCMotor_getVelocity() is a number between -1 and 1 with units of 'duty
 *     cycle'. It simply represents the average voltage across the motor.
 * *   `StallVelocity` represents a real velocity (e.g. m/s, RPM, etc.) and the units are
 *     determined by the `RescaleFactor`. With a `RescaleFactor` of 1, the default units would be in
 *     commutations per second.
 *
 * If the load on your motor is large, your motor may begin rotating more slowly, or even fully
 * stall. Depending on the voltage across your motor, this may result in a large amount of current
 * through both the controller and the motor. In order to prevent damage in these situations, you
 * can use the `StallVelocity` property.
 *
 * The `StallVelocity` should be set to the lowest velocity you would expect from your motor. The
 * controller will then monitor the motor's velocity, as well as the @ref
 * PhidgetBLDCMotor_getVelocity(), and prevent a 'dangerous stall' from occuring. If the controller
 * detects a dangerous stall, it will immediately reduce the @ref PhidgetBLDCMotor_getVelocity()
 * (i.e. average voltage) to 0 and an error will be reported to your program.
 *
 * *   A 'dangerous stall' will occur faster when the @ref PhidgetBLDCMotor_getVelocity() is
 *     higher (i.e. when the average voltage across the motor is higher)
 * *   A 'dangerous stall' will occur faster as (`StallVelocity` \- motor velocity) becomes
 *     larger .
 *
 * Setting `StallVelocity` to 0 will turn off stall protection functionality.
 *
 * @param[in] ch The channel handle
 * @param[in] stallVelocity The stall velocity value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetBLDCMotor_setStallVelocity(PhidgetBLDCMotorHandle ch,
  double stallVelocity);

/**
 * @brief The stall velocity value.
 *
 * Before reading this description, it is important to note the difference between the units of
 * `StallVelocity` and @ref PhidgetBLDCMotor_getVelocity().
 *
 * *   @ref PhidgetBLDCMotor_getVelocity() is a number between -1 and 1 with units of 'duty
 *     cycle'. It simply represents the average voltage across the motor.
 * *   `StallVelocity` represents a real velocity (e.g. m/s, RPM, etc.) and the units are
 *     determined by the `RescaleFactor`. With a `RescaleFactor` of 1, the default units would be in
 *     commutations per second.
 *
 * If the load on your motor is large, your motor may begin rotating more slowly, or even fully
 * stall. Depending on the voltage across your motor, this may result in a large amount of current
 * through both the controller and the motor. In order to prevent damage in these situations, you
 * can use the `StallVelocity` property.
 *
 * The `StallVelocity` should be set to the lowest velocity you would expect from your motor. The
 * controller will then monitor the motor's velocity, as well as the @ref
 * PhidgetBLDCMotor_getVelocity(), and prevent a 'dangerous stall' from occuring. If the controller
 * detects a dangerous stall, it will immediately reduce the @ref PhidgetBLDCMotor_getVelocity()
 * (i.e. average voltage) to 0 and an error will be reported to your program.
 *
 * *   A 'dangerous stall' will occur faster when the @ref PhidgetBLDCMotor_getVelocity() is
 *     higher (i.e. when the average voltage across the motor is higher)
 * *   A 'dangerous stall' will occur faster as (`StallVelocity` \- motor velocity) becomes
 *     larger .
 *
 * Setting `StallVelocity` to 0 will turn off stall protection functionality.
 *
 * @param[in] ch The channel handle
 * @param[out] stallVelocity The stall velocity value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetBLDCMotor_getStallVelocity(PhidgetBLDCMotorHandle ch,
  double *stallVelocity);

/**
 * @brief The velocity value
 *
 * The lower bound of `StallVelocity`.
 *
 * @param[in] ch The channel handle
 * @param[out] minStallVelocity The velocity value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetBLDCMotor_getMinStallVelocity(PhidgetBLDCMotorHandle ch,
  double *minStallVelocity);

/**
 * @brief The velocity value
 *
 * The upper bound of `StallVelocity`.
 *
 * @param[in] ch The channel handle
 * @param[out] maxStallVelocity The velocity value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetBLDCMotor_getMaxStallVelocity(PhidgetBLDCMotorHandle ch,
  double *maxStallVelocity);

/**
 * @brief The surge current limit value
 *
 * The `SurgeCurrentLimit` allows for increased performance from your motor. The controller will
 * limit the current through your motor to the `SurgeCurrentLimit` briefly, then scale current down
 * to the `CurrentLimit`.
 *
 * *   View @ref PhidgetBLDCMotor_getActiveCurrentLimit() for information about what current
 *     limit the controller is actively following.
 *
 * For more information about `SurgeCurrentLimit`, visit our [BLDCMotor API
 * Guide](https://www.phidgets.com/docs/BLDCMotor_API_Guide#Surge_Current_Limit)
 *
 * @param[in] ch The channel handle
 * @param[in] surgeCurrentLimit The surge current limit value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetBLDCMotor_setSurgeCurrentLimit(PhidgetBLDCMotorHandle ch,
  double surgeCurrentLimit);

/**
 * @brief The surge current limit value
 *
 * The `SurgeCurrentLimit` allows for increased performance from your motor. The controller will
 * limit the current through your motor to the `SurgeCurrentLimit` briefly, then scale current down
 * to the `CurrentLimit`.
 *
 * *   View @ref PhidgetBLDCMotor_getActiveCurrentLimit() for information about what current
 *     limit the controller is actively following.
 *
 * For more information about `SurgeCurrentLimit`, visit our [BLDCMotor API
 * Guide](https://www.phidgets.com/docs/BLDCMotor_API_Guide#Surge_Current_Limit)
 *
 * @param[in] ch The channel handle
 * @param[out] surgeCurrentLimit The surge current limit value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetBLDCMotor_getSurgeCurrentLimit(PhidgetBLDCMotorHandle ch,
  double *surgeCurrentLimit);

/**
 * @brief The surge current value
 *
 * The minimum value that `SurgeCurrentLimit` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minSurgeCurrentLimit The surge current value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetBLDCMotor_getMinSurgeCurrentLimit(PhidgetBLDCMotorHandle ch,
  double *minSurgeCurrentLimit);

/**
 * @brief The surge current value
 *
 * The maximum value that `SurgeCurrentLimit` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxSurgeCurrentLimit The surge current value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetBLDCMotor_getMaxSurgeCurrentLimit(PhidgetBLDCMotorHandle ch,
  double *maxSurgeCurrentLimit);

/**
 * @brief The braking value
 *
 * When a motor is not being actively driven forward or reverse, you can choose if the motor will be
 * allowed to freely turn, or will resist being turned.
 *
 * *   A low `TargetBrakingStrength` value corresponds to free wheeling, this will have the
 *     following effects:
 *     *   The motor will continue to rotate after the controller is no longer driving the motor
 * (i.e. @ref PhidgetBLDCMotor_getVelocity() is 0), due to inertia.
 *     *   The motor shaft will provide little resistance to being turned when it is stopped.
 * *   A higher `TargetBrakingStrength` value will resist being turned, this will have the
 *     following effects:
 *     *   The motor will more stop more quickly if it is in motion and braking has been requested.
 * It will fight against the rotation of the shaft.
 * *   Braking mode is enabled by setting the @ref PhidgetBLDCMotor_getVelocity() to @ref
 *     PhidgetBLDCMotor_getMinVelocity()
 *
 * @param[in] ch The channel handle
 * @param[in] targetBrakingStrength The braking value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetBLDCMotor_setTargetBrakingStrength(PhidgetBLDCMotorHandle ch,
  double targetBrakingStrength);

/**
 * @brief The braking value
 *
 * When a motor is not being actively driven forward or reverse, you can choose if the motor will be
 * allowed to freely turn, or will resist being turned.
 *
 * *   A low `TargetBrakingStrength` value corresponds to free wheeling, this will have the
 *     following effects:
 *     *   The motor will continue to rotate after the controller is no longer driving the motor
 * (i.e. @ref PhidgetBLDCMotor_getVelocity() is 0), due to inertia.
 *     *   The motor shaft will provide little resistance to being turned when it is stopped.
 * *   A higher `TargetBrakingStrength` value will resist being turned, this will have the
 *     following effects:
 *     *   The motor will more stop more quickly if it is in motion and braking has been requested.
 * It will fight against the rotation of the shaft.
 * *   Braking mode is enabled by setting the @ref PhidgetBLDCMotor_getVelocity() to @ref
 *     PhidgetBLDCMotor_getMinVelocity()
 *
 * @param[in] ch The channel handle
 * @param[out] targetBrakingStrength The braking value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetBLDCMotor_getTargetBrakingStrength(PhidgetBLDCMotorHandle ch,
  double *targetBrakingStrength);

/**
 * @brief The velocity value
 *
 * The average voltage across the motor is based on the `TargetVelocity` value.
 *
 * *   At a constant load, increasing the target velocity will increase the speed of the motor.
 * *   `TargetVelocity` is bounded by -@ref PhidgetBLDCMotor_getMaxVelocity() and +@ref
 *     PhidgetBLDCMotor_getMaxVelocity(), where a sign change (±) is indicative of a direction
 *     change.
 * *   Setting `TargetVelocity` to @ref PhidgetBLDCMotor_getMinVelocity() will stop the motor.
 *     See `BrakingEnabled` for more information on stopping the motor.
 *
 * For more information about `TargetVelocity`, visit our [BLDCMotor API
 * Guide](https://www.phidgets.com/docs/BLDCMotor_API_Guide#Target_Velocity)
 *
 * @param[in] ch The channel handle
 * @param[in] targetVelocity The velocity value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetBLDCMotor_setTargetVelocity(PhidgetBLDCMotorHandle ch,
  double targetVelocity);

/**
 * @brief The velocity value
 *
 * The average voltage across the motor is based on the `TargetVelocity` value.
 *
 * *   At a constant load, increasing the target velocity will increase the speed of the motor.
 * *   `TargetVelocity` is bounded by -@ref PhidgetBLDCMotor_getMaxVelocity() and +@ref
 *     PhidgetBLDCMotor_getMaxVelocity(), where a sign change (±) is indicative of a direction
 *     change.
 * *   Setting `TargetVelocity` to @ref PhidgetBLDCMotor_getMinVelocity() will stop the motor.
 *     See `BrakingEnabled` for more information on stopping the motor.
 *
 * For more information about `TargetVelocity`, visit our [BLDCMotor API
 * Guide](https://www.phidgets.com/docs/BLDCMotor_API_Guide#Target_Velocity)
 *
 * @param[in] ch The channel handle
 * @param[in] targetVelocity The velocity value
 * @param[in] fptr Asynchronous completion callback
 * @param[in] ctx User supplied context pointer
 */
PHIDGET22_API void CCONV PhidgetBLDCMotor_setTargetVelocity_async(PhidgetBLDCMotorHandle ch,
  double targetVelocity, Phidget_AsyncCallback fptr, void *ctx);

/**
 * @brief The velocity value
 *
 * The average voltage across the motor is based on the `TargetVelocity` value.
 *
 * *   At a constant load, increasing the target velocity will increase the speed of the motor.
 * *   `TargetVelocity` is bounded by -@ref PhidgetBLDCMotor_getMaxVelocity() and +@ref
 *     PhidgetBLDCMotor_getMaxVelocity(), where a sign change (±) is indicative of a direction
 *     change.
 * *   Setting `TargetVelocity` to @ref PhidgetBLDCMotor_getMinVelocity() will stop the motor.
 *     See `BrakingEnabled` for more information on stopping the motor.
 *
 * For more information about `TargetVelocity`, visit our [BLDCMotor API
 * Guide](https://www.phidgets.com/docs/BLDCMotor_API_Guide#Target_Velocity)
 *
 * @param[in] ch The channel handle
 * @param[out] targetVelocity The velocity value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetBLDCMotor_getTargetVelocity(PhidgetBLDCMotorHandle ch,
  double *targetVelocity);

/**
 * @brief The velocity value
 *
 * The most recent @ref PhidgetBLDCMotor_getVelocity() value that the controller has reported.
 *
 * For more information about @ref PhidgetBLDCMotor_getVelocity(), visit our [BLDCMotor API
 * Guide](https://www.phidgets.com/docs/BLDCMotor_API_Guide#Velocity)
 *
 * @param[in] ch The channel handle
 * @param[out] velocity The velocity value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetBLDCMotor_getVelocity(PhidgetBLDCMotorHandle ch,
  double *velocity);

/**
 * @brief The velocity value
 *
 * The minimum value that `TargetVelocity` can be set to.
 *
 * *   Set the `TargetVelocity` to @ref PhidgetBLDCMotor_getMinVelocity() to stop the motor. See
 *     `BrakingEnabled` for more information on stopping the motor.
 * *   `TargetVelocity` is bounded by -@ref PhidgetBLDCMotor_getMaxVelocity() and +@ref
 *     PhidgetBLDCMotor_getMaxVelocity(), where a sign change (±) is indicative of a direction
 *     change.
 *
 * @param[in] ch The channel handle
 * @param[out] minVelocity The velocity value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetBLDCMotor_getMinVelocity(PhidgetBLDCMotorHandle ch,
  double *minVelocity);

/**
 * @brief The velocity value
 *
 * The maximum value that `TargetVelocity` can be set to.
 *
 * *   `TargetVelocity` is bounded by -@ref PhidgetBLDCMotor_getMaxVelocity() and +@ref
 *     PhidgetBLDCMotor_getMaxVelocity(), where a sign change (±) is indicative of a direction
 *     change.
 *
 * @param[in] ch The channel handle
 * @param[out] maxVelocity The velocity value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetBLDCMotor_getMaxVelocity(PhidgetBLDCMotorHandle ch,
  double *maxVelocity);

/**
 * @brief Callback function type for PhidgetBLDCMotor_setOnBrakingStrengthChangeHandler().
 *
 * @param[in] ch The channel handle
 * @param[in] ctx Pointer to the user context
 * @param[in] brakingStrength The braking strength value
 */
typedef void (CCONV *PhidgetBLDCMotor_OnBrakingStrengthChangeCallback)(PhidgetBLDCMotorHandle ch,
  void *ctx, double brakingStrength);

/**
 * The most recent braking strength value will be reported in this event, which occurs when the
 * `DataInterval` has elapsed.
 *
 * *   Regardless of the `DataInterval`, this event will occur only when the braking strength
 *     value has changed from the previous value reported.
 * *   Braking mode is enabled by setting the @ref PhidgetBLDCMotor_getVelocity() to @ref
 *     PhidgetBLDCMotor_getMinVelocity()
 *
 * @param[in] ch The channel handle
 * @param[in] fptr The event handler callback function
 * @param[in] ctx User supplied context pointer
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetBLDCMotor_setOnBrakingStrengthChangeHandler(PhidgetBLDCMotorHandle ch,
  PhidgetBLDCMotor_OnBrakingStrengthChangeCallback fptr, void *ctx);

/**
 * @brief Callback function type for PhidgetBLDCMotor_setOnPositionChangeHandler().
 *
 * @param[in] ch The channel handle
 * @param[in] ctx Pointer to the user context
 * @param[in] position The position value
 */
typedef void (CCONV *PhidgetBLDCMotor_OnPositionChangeCallback)(PhidgetBLDCMotorHandle ch, void *ctx,
  double position);

/**
 * The most recent position value will be reported in this event, which occurs when the
 * `DataInterval` has elapsed.
 *
 * *   Regardless of the `DataInterval`, this event will occur only when the position value has
 *     changed from the previous value reported.
 * *   Position values are calculated using Hall Effect sensors mounted on the motor, therefore,
 *     the resolution of position depends on the motor you are using.
 * *   Units for @ref PhidgetBLDCMotor_getPosition() can be set by the user through the
 *     `RescaleFactor`. The `RescaleFactor` allows you to use more intuitive units such as
 *     rotations, or degrees. For more information on how to apply the `RescaleFactor` to your
 *     application, see your controller's User Guide.
 *
 * @param[in] ch The channel handle
 * @param[in] fptr The event handler callback function
 * @param[in] ctx User supplied context pointer
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetBLDCMotor_setOnPositionChangeHandler(PhidgetBLDCMotorHandle ch,
  PhidgetBLDCMotor_OnPositionChangeCallback fptr, void *ctx);

/**
 * @brief Callback function type for PhidgetBLDCMotor_setOnVelocityUpdateHandler().
 *
 * @param[in] ch The channel handle
 * @param[in] ctx Pointer to the user context
 * @param[in] velocity The velocity value
 */
typedef void (CCONV *PhidgetBLDCMotor_OnVelocityUpdateCallback)(PhidgetBLDCMotorHandle ch, void *ctx,
  double velocity);

/**
 * The most recent velocity value will be reported in this event, which occurs when the
 * `DataInterval` has elapsed.
 *
 * *   This event will **always** occur when the `DataInterval` elapses. You can depend on this
 *     event for constant timing when implementing control loops in code. This is the last event to
 *     fire, giving you up-to-date access to all properties.
 *
 * @param[in] ch The channel handle
 * @param[in] fptr The event handler callback function
 * @param[in] ctx User supplied context pointer
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetBLDCMotor_setOnVelocityUpdateHandler(PhidgetBLDCMotorHandle ch,
  PhidgetBLDCMotor_OnVelocityUpdateCallback fptr, void *ctx);

/** @} */ /* PhidgetBLDCMotor */

/**
 * @defgroup PhidgetCapacitiveTouch CapacitiveTouch
 * @brief The Capacitive Touch class gathers input data from capacitive buttons and sliders on
 *     Phidget boards.
 * @{
 */

/**
 * The Capacitive Touch class gathers input data from capacitive buttons and sliders on Phidget
 * boards.
 */
typedef struct _PhidgetCapacitiveTouch *PhidgetCapacitiveTouchHandle;

/**
 * @ref PhidgetCapacitiveTouch_create() creates an instance of a Phidget channel. Once created the
 * channel may need to be configured to match the physical device and channel index you want to
 * attach to, and then be opened by calling @ref Phidget_open().
 * The Phidget channel handle must be released with @ref PhidgetCapacitiveTouch_delete().
 *
 * @param[out] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetCapacitiveTouch_create(PhidgetCapacitiveTouchHandle *ch);

/**
 * @ref PhidgetCapacitiveTouch_delete() releases a Phidget channel handle created with @ref
 * PhidgetCapacitiveTouch_create().
 * If the channel is open when @ref PhidgetCapacitiveTouch_delete() is called, it will be closed.
 *
 * @param[out] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetCapacitiveTouch_delete(PhidgetCapacitiveTouchHandle *ch);

/**
 * @brief The data interval value
 *
 * The `DataInterval` is the time that must elapse before the channel will fire another @ref
 * PhidgetCapacitiveTouch_setOnTouchHandler() event.
 *
 * *   The data interval is bounded by @ref PhidgetCapacitiveTouch_getMinDataInterval() and @ref
 *     PhidgetCapacitiveTouch_getMaxDataInterval().
 * *   The timing between @ref PhidgetCapacitiveTouch_setOnTouchHandler() events can also be
 *     affected by the `TouchValueChangeTrigger`.
 *
 * @param[in] ch The channel handle
 * @param[in] dataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetCapacitiveTouch_setDataInterval(PhidgetCapacitiveTouchHandle ch,
  uint32_t dataInterval);

/**
 * @brief The data interval value
 *
 * The `DataInterval` is the time that must elapse before the channel will fire another @ref
 * PhidgetCapacitiveTouch_setOnTouchHandler() event.
 *
 * *   The data interval is bounded by @ref PhidgetCapacitiveTouch_getMinDataInterval() and @ref
 *     PhidgetCapacitiveTouch_getMaxDataInterval().
 * *   The timing between @ref PhidgetCapacitiveTouch_setOnTouchHandler() events can also be
 *     affected by the `TouchValueChangeTrigger`.
 *
 * @param[in] ch The channel handle
 * @param[out] dataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetCapacitiveTouch_getDataInterval(PhidgetCapacitiveTouchHandle ch,
  uint32_t *dataInterval);

/**
 * @brief The minimum data interval value
 *
 * The minimum value that `DataInterval` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minDataInterval The minimum data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetCapacitiveTouch_getMinDataInterval(PhidgetCapacitiveTouchHandle ch,
  uint32_t *minDataInterval);

/**
 * @brief The maximum data interval value
 *
 * The maximum value that `DataInterval` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxDataInterval The maximum data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetCapacitiveTouch_getMaxDataInterval(PhidgetCapacitiveTouchHandle ch,
  uint32_t *maxDataInterval);

/**
 * @brief The data rate for the channel
 *
 * The `DataRate` is the frequency of events from the device.
 *
 * *   The data rate is bounded by @ref PhidgetCapacitiveTouch_getMinDataRate() and @ref
 *     PhidgetCapacitiveTouch_getMaxDataRate().
 * *   Changing `DataRate` will change the channel's `DataInterval` to a corresponding value,
 *     rounded to the nearest integer number of milliseconds.
 * *   The timing between events can also affected by the change trigger.
 *
 * @param[in] ch The channel handle
 * @param[in] dataRate The data rate for the channel
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetCapacitiveTouch_setDataRate(PhidgetCapacitiveTouchHandle ch,
  double dataRate);

/**
 * @brief The data rate for the channel
 *
 * The `DataRate` is the frequency of events from the device.
 *
 * *   The data rate is bounded by @ref PhidgetCapacitiveTouch_getMinDataRate() and @ref
 *     PhidgetCapacitiveTouch_getMaxDataRate().
 * *   Changing `DataRate` will change the channel's `DataInterval` to a corresponding value,
 *     rounded to the nearest integer number of milliseconds.
 * *   The timing between events can also affected by the change trigger.
 *
 * @param[in] ch The channel handle
 * @param[out] dataRate The data rate for the channel
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetCapacitiveTouch_getDataRate(PhidgetCapacitiveTouchHandle ch,
  double *dataRate);

/**
 * @brief The data rate value
 *
 * The minimum value that `DataRate` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minDataRate The data rate value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetCapacitiveTouch_getMinDataRate(PhidgetCapacitiveTouchHandle ch,
  double *minDataRate);

/**
 * @brief The data rate value
 *
 * The maximum value that `DataRate` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxDataRate The data rate value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetCapacitiveTouch_getMaxDataRate(PhidgetCapacitiveTouchHandle ch,
  double *maxDataRate);

/**
 * @brief The sensitivity value
 *
 * Determines the sensitivity of all capacitive regions on the device.
 *
 * *   Higher values result in greater touch sensitivity.
 * *   The sensitivity value is bounded by @ref PhidgetCapacitiveTouch_getMinSensitivity() and
 *     @ref PhidgetCapacitiveTouch_getMaxSensitivity().
 *
 * @param[in] ch The channel handle
 * @param[in] sensitivity The sensitivity value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetCapacitiveTouch_setSensitivity(PhidgetCapacitiveTouchHandle ch,
  double sensitivity);

/**
 * @brief The sensitivity value
 *
 * Determines the sensitivity of all capacitive regions on the device.
 *
 * *   Higher values result in greater touch sensitivity.
 * *   The sensitivity value is bounded by @ref PhidgetCapacitiveTouch_getMinSensitivity() and
 *     @ref PhidgetCapacitiveTouch_getMaxSensitivity().
 *
 * @param[in] ch The channel handle
 * @param[out] sensitivity The sensitivity value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetCapacitiveTouch_getSensitivity(PhidgetCapacitiveTouchHandle ch,
  double *sensitivity);

/**
 * @brief The minimum sensitivity value
 *
 * The minimum value that `Sensitivity` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minSensitivity The minimum sensitivity value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetCapacitiveTouch_getMinSensitivity(PhidgetCapacitiveTouchHandle ch,
  double *minSensitivity);

/**
 * @brief The maximum sensitivity value
 *
 * The maximum value that `Sensitivity` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxSensitivity The maximum sensitivity value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetCapacitiveTouch_getMaxSensitivity(PhidgetCapacitiveTouchHandle ch,
  double *maxSensitivity);

/**
 * @brief The touched state
 *
 * The most recent touch state that the channel has reported.
 *
 * *   This will be 0 or 1
 *
 * *   0 is not touched
 * *   1 is touched
 *
 * @param[in] ch The channel handle
 * @param[out] isTouched The touched state
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetCapacitiveTouch_getIsTouched(PhidgetCapacitiveTouchHandle ch,
  int *isTouched);

/**
 * @brief The touch input value
 *
 * The most recent touch value that the channel has reported.
 *
 * *   This will be 0 or 1 for button-type inputs, or a ratio between 0-1 for axis-type inputs.
 * *   This value is bounded by @ref PhidgetCapacitiveTouch_getMinTouchValue() and @ref
 *     PhidgetCapacitiveTouch_getMaxTouchValue()
 * *   The value is not reset when the touch ends
 *
 * @param[in] ch The channel handle
 * @param[out] touchValue The touch input value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetCapacitiveTouch_getTouchValue(PhidgetCapacitiveTouchHandle ch,
  double *touchValue);

/**
 * @brief The minimum touch input value
 *
 * The minimum value the @ref PhidgetCapacitiveTouch_setOnTouchHandler() event will report.
 *
 * @param[in] ch The channel handle
 * @param[out] minTouchValue The minimum touch input value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetCapacitiveTouch_getMinTouchValue(PhidgetCapacitiveTouchHandle ch,
  double *minTouchValue);

/**
 * @brief The maximum touch input value
 *
 * The maximum value the @ref PhidgetCapacitiveTouch_setOnTouchHandler() event will report.
 *
 * @param[in] ch The channel handle
 * @param[out] maxTouchValue The maximum touch input value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetCapacitiveTouch_getMaxTouchValue(PhidgetCapacitiveTouchHandle ch,
  double *maxTouchValue);

/**
 * @brief The change trigger value
 *
 * The channel will not issue a @ref PhidgetCapacitiveTouch_setOnTouchHandler() event until the
 * touch value has changed by the amount specified by the `TouchValueChangeTrigger`.
 *
 * *   Setting the `TouchValueChangeTrigger` to 0 will result in the channel firing events every
 *     `DataInterval`. This is useful for applications that implement their own data filtering
 *
 * @param[in] ch The channel handle
 * @param[in] touchValueChangeTrigger The change trigger value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetCapacitiveTouch_setTouchValueChangeTrigger(PhidgetCapacitiveTouchHandle ch,
  double touchValueChangeTrigger);

/**
 * @brief The change trigger value
 *
 * The channel will not issue a @ref PhidgetCapacitiveTouch_setOnTouchHandler() event until the
 * touch value has changed by the amount specified by the `TouchValueChangeTrigger`.
 *
 * *   Setting the `TouchValueChangeTrigger` to 0 will result in the channel firing events every
 *     `DataInterval`. This is useful for applications that implement their own data filtering
 *
 * @param[in] ch The channel handle
 * @param[out] touchValueChangeTrigger The change trigger value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetCapacitiveTouch_getTouchValueChangeTrigger(PhidgetCapacitiveTouchHandle ch,
  double *touchValueChangeTrigger);

/**
 * @brief The minimum change trigger value
 *
 * The minimum value that `TouchValueChangeTrigger` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minTouchValueChangeTrigger The minimum change trigger value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetCapacitiveTouch_getMinTouchValueChangeTrigger(PhidgetCapacitiveTouchHandle ch,
  double *minTouchValueChangeTrigger);

/**
 * @brief The maximum change trigger value
 *
 * The maximum value that `TouchValueChangeTrigger` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxTouchValueChangeTrigger The maximum change trigger value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetCapacitiveTouch_getMaxTouchValueChangeTrigger(PhidgetCapacitiveTouchHandle ch,
  double *maxTouchValueChangeTrigger);

/**
 * @brief Callback function type for PhidgetCapacitiveTouch_setOnTouchHandler().
 *
 * @param[in] ch The channel handle
 * @param[in] ctx Pointer to the user context
 * @param[in] touchValue Value of the touch input axis
 */
typedef void (CCONV *PhidgetCapacitiveTouch_OnTouchCallback)(PhidgetCapacitiveTouchHandle ch, void *ctx,
  double touchValue);

/**
 * The most recent touch value the channel has measured will be reported in this event, which occurs
 * when the `DataInterval` has elapsed.
 *
 * *   If a `TouchValueChangeTrigger` has been set to a non-zero value, the @ref
 *     PhidgetCapacitiveTouch_setOnTouchHandler() event will not occur until the touch value has
 *     changed by at least the `TouchValueChangeTrigger` value.
 *
 * @param[in] ch The channel handle
 * @param[in] fptr The event handler callback function
 * @param[in] ctx User supplied context pointer
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetCapacitiveTouch_setOnTouchHandler(PhidgetCapacitiveTouchHandle ch,
  PhidgetCapacitiveTouch_OnTouchCallback fptr, void *ctx);

/**
 * @brief Callback function type for PhidgetCapacitiveTouch_setOnTouchEndHandler().
 *
 * @param[in] ch The channel handle
 * @param[in] ctx Pointer to the user context
 */
typedef void (CCONV *PhidgetCapacitiveTouch_OnTouchEndCallback)(PhidgetCapacitiveTouchHandle ch,
  void *ctx);

/**
 * The channel will report a @ref PhidgetCapacitiveTouch_setOnTouchEndHandler() event to signify
 * that it is no longer detecting a touch.
 *
 * @param[in] ch The channel handle
 * @param[in] fptr The event handler callback function
 * @param[in] ctx User supplied context pointer
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetCapacitiveTouch_setOnTouchEndHandler(PhidgetCapacitiveTouchHandle ch,
  PhidgetCapacitiveTouch_OnTouchEndCallback fptr, void *ctx);

/** @} */ /* PhidgetCapacitiveTouch */

/**
 * @defgroup PhidgetCurrentInput CurrentInput
 * @brief The Current Input class is used to measure current flowing through the Phidget from
 *     outside sources.
 * @{
 */

/**
 * The Current Input class is used to measure current flowing through the Phidget from outside
 * sources.
 *
 * This class may be used on a simple current sensor, or sometimes on a more complex Phidget that
 * measures the amount of current flowing through an attached device, such as a motor controller,
 * for diagnostic or control purposes.
 */
typedef struct _PhidgetCurrentInput *PhidgetCurrentInputHandle;

/**
 * @ref PhidgetCurrentInput_create() creates an instance of a Phidget channel. Once created the
 * channel may need to be configured to match the physical device and channel index you want to
 * attach to, and then be opened by calling @ref Phidget_open().
 * The Phidget channel handle must be released with @ref PhidgetCurrentInput_delete().
 *
 * @param[out] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetCurrentInput_create(PhidgetCurrentInputHandle *ch);

/**
 * @ref PhidgetCurrentInput_delete() releases a Phidget channel handle created with @ref
 * PhidgetCurrentInput_create().
 * If the channel is open when @ref PhidgetCurrentInput_delete() is called, it will be closed.
 *
 * @param[out] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetCurrentInput_delete(PhidgetCurrentInputHandle *ch);

/**
 * @brief The current value
 *
 * The most recent current value that the channel has reported.
 *
 * *   This value will always be between @ref PhidgetCurrentInput_getMinCurrent() and @ref
 *     PhidgetCurrentInput_getMaxCurrent().
 *
 * @param[in] ch The channel handle
 * @param[out] current The current value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetCurrentInput_getCurrent(PhidgetCurrentInputHandle ch,
  double *current);

/**
 * @brief The current value
 *
 * The minimum value the @ref PhidgetCurrentInput_setOnCurrentChangeHandler() event will report.
 *
 * @param[in] ch The channel handle
 * @param[out] minCurrent The current value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetCurrentInput_getMinCurrent(PhidgetCurrentInputHandle ch,
  double *minCurrent);

/**
 * @brief The current value
 *
 * The maximum value the @ref PhidgetCurrentInput_setOnCurrentChangeHandler() event will report.
 *
 * @param[in] ch The channel handle
 * @param[out] maxCurrent The current value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetCurrentInput_getMaxCurrent(PhidgetCurrentInputHandle ch,
  double *maxCurrent);

/**
 * @brief The change trigger value
 *
 * The channel will not issue a @ref PhidgetCurrentInput_setOnCurrentChangeHandler() event until the
 * current value has changed by the amount specified by the `CurrentChangeTrigger`.
 *
 * *   Setting the `CurrentChangeTrigger` to 0 will result in the channel firing events every
 *     `DataInterval`. This is useful for applications that implement their own data filtering
 *
 * @param[in] ch The channel handle
 * @param[in] currentChangeTrigger The change trigger value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetCurrentInput_setCurrentChangeTrigger(PhidgetCurrentInputHandle ch,
  double currentChangeTrigger);

/**
 * @brief The change trigger value
 *
 * The channel will not issue a @ref PhidgetCurrentInput_setOnCurrentChangeHandler() event until the
 * current value has changed by the amount specified by the `CurrentChangeTrigger`.
 *
 * *   Setting the `CurrentChangeTrigger` to 0 will result in the channel firing events every
 *     `DataInterval`. This is useful for applications that implement their own data filtering
 *
 * @param[in] ch The channel handle
 * @param[out] currentChangeTrigger The change trigger value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetCurrentInput_getCurrentChangeTrigger(PhidgetCurrentInputHandle ch,
  double *currentChangeTrigger);

/**
 * @brief The change trigger value
 *
 * The minimum value that `CurrentChangeTrigger` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minCurrentChangeTrigger The change trigger value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetCurrentInput_getMinCurrentChangeTrigger(PhidgetCurrentInputHandle ch,
  double *minCurrentChangeTrigger);

/**
 * @brief The change trigger value
 *
 * The maximum value that `CurrentChangeTrigger` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxCurrentChangeTrigger The change trigger value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetCurrentInput_getMaxCurrentChangeTrigger(PhidgetCurrentInputHandle ch,
  double *maxCurrentChangeTrigger);

/**
 * @brief The data interval value
 *
 * The `DataInterval` is the time that must elapse before the channel will fire another @ref
 * PhidgetCurrentInput_setOnCurrentChangeHandler() event.
 *
 * *   The data interval is bounded by @ref PhidgetCurrentInput_getMinDataInterval() and @ref
 *     PhidgetCurrentInput_getMaxDataInterval().
 * *   The timing between @ref PhidgetCurrentInput_setOnCurrentChangeHandler() events can also
 *     be affected by the `CurrentChangeTrigger`.
 *
 * @param[in] ch The channel handle
 * @param[in] dataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetCurrentInput_setDataInterval(PhidgetCurrentInputHandle ch,
  uint32_t dataInterval);

/**
 * @brief The data interval value
 *
 * The `DataInterval` is the time that must elapse before the channel will fire another @ref
 * PhidgetCurrentInput_setOnCurrentChangeHandler() event.
 *
 * *   The data interval is bounded by @ref PhidgetCurrentInput_getMinDataInterval() and @ref
 *     PhidgetCurrentInput_getMaxDataInterval().
 * *   The timing between @ref PhidgetCurrentInput_setOnCurrentChangeHandler() events can also
 *     be affected by the `CurrentChangeTrigger`.
 *
 * @param[in] ch The channel handle
 * @param[out] dataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetCurrentInput_getDataInterval(PhidgetCurrentInputHandle ch,
  uint32_t *dataInterval);

/**
 * @brief The data interval value
 *
 * The minimum value that `DataInterval` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minDataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetCurrentInput_getMinDataInterval(PhidgetCurrentInputHandle ch,
  uint32_t *minDataInterval);

/**
 * @brief The data interval value
 *
 * The maximum value that `DataInterval` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxDataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetCurrentInput_getMaxDataInterval(PhidgetCurrentInputHandle ch,
  uint32_t *maxDataInterval);

/**
 * @brief The data rate for the channel
 *
 * The `DataRate` is the frequency of events from the device.
 *
 * *   The data rate is bounded by @ref PhidgetCurrentInput_getMinDataRate() and @ref
 *     PhidgetCurrentInput_getMaxDataRate().
 * *   Changing `DataRate` will change the channel's `DataInterval` to a corresponding value,
 *     rounded to the nearest integer number of milliseconds.
 * *   The timing between events can also affected by the change trigger.
 *
 * @param[in] ch The channel handle
 * @param[in] dataRate The data rate for the channel
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetCurrentInput_setDataRate(PhidgetCurrentInputHandle ch,
  double dataRate);

/**
 * @brief The data rate for the channel
 *
 * The `DataRate` is the frequency of events from the device.
 *
 * *   The data rate is bounded by @ref PhidgetCurrentInput_getMinDataRate() and @ref
 *     PhidgetCurrentInput_getMaxDataRate().
 * *   Changing `DataRate` will change the channel's `DataInterval` to a corresponding value,
 *     rounded to the nearest integer number of milliseconds.
 * *   The timing between events can also affected by the change trigger.
 *
 * @param[in] ch The channel handle
 * @param[out] dataRate The data rate for the channel
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetCurrentInput_getDataRate(PhidgetCurrentInputHandle ch,
  double *dataRate);

/**
 * @brief The data rate value
 *
 * The minimum value that `DataRate` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minDataRate The data rate value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetCurrentInput_getMinDataRate(PhidgetCurrentInputHandle ch,
  double *minDataRate);

/**
 * @brief The data rate value
 *
 * The maximum value that `DataRate` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxDataRate The data rate value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetCurrentInput_getMaxDataRate(PhidgetCurrentInputHandle ch,
  double *maxDataRate);

/**
 * @brief The power supply value
 *
 * Choose the power supply voltage.
 *
 * *   Set this to the voltage specified in the attached sensor's data sheet to power it.
 * *   Set to @ref POWER_SUPPLY_OFF to turn off the supply to save power.
 *
 * @param[in] ch The channel handle
 * @param[in] powerSupply The power supply value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetCurrentInput_setPowerSupply(PhidgetCurrentInputHandle ch,
  Phidget_PowerSupply powerSupply);

/**
 * @brief The power supply value
 *
 * Choose the power supply voltage.
 *
 * *   Set this to the voltage specified in the attached sensor's data sheet to power it.
 * *   Set to @ref POWER_SUPPLY_OFF to turn off the supply to save power.
 *
 * @param[in] ch The channel handle
 * @param[out] powerSupply The power supply value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetCurrentInput_getPowerSupply(PhidgetCurrentInputHandle ch,
  Phidget_PowerSupply *powerSupply);

/**
 * @brief Callback function type for PhidgetCurrentInput_setOnCurrentChangeHandler().
 *
 * @param[in] ch The channel handle
 * @param[in] ctx Pointer to the user context
 * @param[in] current The current value
 */
typedef void (CCONV *PhidgetCurrentInput_OnCurrentChangeCallback)(PhidgetCurrentInputHandle ch, void *ctx,
  double current);

/**
 * The most recent current value the channel has measured will be reported in this event, which
 * occurs when the `DataInterval` has elapsed.
 *
 * *   If a `CurrentChangeTrigger` has been set to a non-zero value, the @ref
 *     PhidgetCurrentInput_setOnCurrentChangeHandler() event will not occur until the current value
 *     has changed by at least the `CurrentChangeTrigger` value.
 *
 * @param[in] ch The channel handle
 * @param[in] fptr The event handler callback function
 * @param[in] ctx User supplied context pointer
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetCurrentInput_setOnCurrentChangeHandler(PhidgetCurrentInputHandle ch,
  PhidgetCurrentInput_OnCurrentChangeCallback fptr, void *ctx);

/** @} */ /* PhidgetCurrentInput */

/**
 * @defgroup PhidgetCurrentOutput CurrentOutput
 * @brief The Current Output class controls the variable DC current output on a Phidget board.
 *     This class provides settings for the output current as well as various safety controls.
 * @{
 */

/**
 * The Current Output class controls the variable DC current output on a Phidget board. This class
 * provides settings for the output current as well as various safety controls.
 */
typedef struct _PhidgetCurrentOutput *PhidgetCurrentOutputHandle;

/**
 * @ref PhidgetCurrentOutput_create() creates an instance of a Phidget channel. Once created the
 * channel may need to be configured to match the physical device and channel index you want to
 * attach to, and then be opened by calling @ref Phidget_open().
 * The Phidget channel handle must be released with @ref PhidgetCurrentOutput_delete().
 *
 * @param[out] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetCurrentOutput_create(PhidgetCurrentOutputHandle *ch);

/**
 * @ref PhidgetCurrentOutput_delete() releases a Phidget channel handle created with @ref
 * PhidgetCurrentOutput_create().
 * If the channel is open when @ref PhidgetCurrentOutput_delete() is called, it will be closed.
 *
 * @param[out] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetCurrentOutput_delete(PhidgetCurrentOutputHandle *ch);

/**
 * Enables the **failsafe** feature for the channel, with the specified **failsafe time**.
 *
 * Enabling the failsafe feature starts a recurring **failsafe timer** for the channel. Once the
 * failsafe is enabled, the timer must be reset within the specified time or the channel will enter
 * a **failsafe state**. For Power Guard channels, this will turn off the output. The failsafe timer
 * can be reset by using any of the following API calls:
 *
 * *   @ref PhidgetCurrentOutput_setCurrent()
 * *   @ref PhidgetCurrentOutput_resetFailsafe()
 *
 * For more information about failsafe, visit our [Failsafe
 * Guide](https://www.phidgets.com/docs/Failsafe_Guide).
 *
 * @param[in] ch The channel handle
 * @param[in] failsafeTime Failsafe timeout in milliseconds
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetCurrentOutput_enableFailsafe(PhidgetCurrentOutputHandle ch,
  uint32_t failsafeTime);

/**
 * Resets the failsafe timer, if one has been set. See @ref PhidgetCurrentOutput_enableFailsafe()
 * for details.
 *
 * This function will fail if no failsafe timer has been set for the channel.
 *
 * @param[in] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetCurrentOutput_resetFailsafe(PhidgetCurrentOutputHandle ch);

/**
 * @brief The current value
 *
 * The current value that the channel will output.
 *
 * *   The `Current` value is bounded by @ref PhidgetCurrentOutput_getMinCurrent() and @ref
 *     PhidgetCurrentOutput_getMaxCurrent().
 *
 * @param[in] ch The channel handle
 * @param[in] current The current value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetCurrentOutput_setCurrent(PhidgetCurrentOutputHandle ch,
  double current);

/**
 * @brief The current value
 *
 * The current value that the channel will output.
 *
 * *   The `Current` value is bounded by @ref PhidgetCurrentOutput_getMinCurrent() and @ref
 *     PhidgetCurrentOutput_getMaxCurrent().
 *
 * @param[in] ch The channel handle
 * @param[in] current The current value
 * @param[in] fptr Asynchronous completion callback
 * @param[in] ctx User supplied context pointer
 */
PHIDGET22_API void CCONV PhidgetCurrentOutput_setCurrent_async(PhidgetCurrentOutputHandle ch,
  double current, Phidget_AsyncCallback fptr, void *ctx);

/**
 * @brief The current value
 *
 * The current value that the channel will output.
 *
 * *   The `Current` value is bounded by @ref PhidgetCurrentOutput_getMinCurrent() and @ref
 *     PhidgetCurrentOutput_getMaxCurrent().
 *
 * @param[in] ch The channel handle
 * @param[out] current The current value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetCurrentOutput_getCurrent(PhidgetCurrentOutputHandle ch,
  double *current);

/**
 * @brief The current value
 *
 * The minimum value that `Current` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minCurrent The current value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetCurrentOutput_getMinCurrent(PhidgetCurrentOutputHandle ch,
  double *minCurrent);

/**
 * @brief The current value
 *
 * The maximum value that `Current` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxCurrent The current value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetCurrentOutput_getMaxCurrent(PhidgetCurrentOutputHandle ch,
  double *maxCurrent);

/**
 * @brief The failsafe time
 *
 * The minimum value that `failsafeTime` can be set to when calling @ref
 * PhidgetCurrentOutput_enableFailsafe().
 *
 * @param[in] ch The channel handle
 * @param[out] minFailsafeTime The failsafe time
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetCurrentOutput_getMinFailsafeTime(PhidgetCurrentOutputHandle ch,
  uint32_t *minFailsafeTime);

/**
 * @brief The failsafe time
 *
 * The maximum value that `failsafeTime` can be set to when calling @ref
 * PhidgetCurrentOutput_enableFailsafe().
 *
 * @param[in] ch The channel handle
 * @param[out] maxFailsafeTime The failsafe time
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetCurrentOutput_getMaxFailsafeTime(PhidgetCurrentOutputHandle ch,
  uint32_t *maxFailsafeTime);

/** @} */ /* PhidgetCurrentOutput */

/**
 * @defgroup PhidgetDataAdapter DataAdapter
 * @brief The Data Adapter class is used to interface third party devices and microcontrollers
 *     with Phidgets.
 * @{
 */

/**
 * The Data Adapter class is used to interface third party devices and microcontrollers with
 * Phidgets.
 */
typedef struct _PhidgetDataAdapter *PhidgetDataAdapterHandle;

/**
 * @ref PhidgetDataAdapter_create() creates an instance of a Phidget channel. Once created the
 * channel may need to be configured to match the physical device and channel index you want to
 * attach to, and then be opened by calling @ref Phidget_open().
 * The Phidget channel handle must be released with @ref PhidgetDataAdapter_delete().
 *
 * @param[out] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDataAdapter_create(PhidgetDataAdapterHandle *ch);

/**
 * @ref PhidgetDataAdapter_delete() releases a Phidget channel handle created with @ref
 * PhidgetDataAdapter_create().
 * If the channel is open when @ref PhidgetDataAdapter_delete() is called, it will be closed.
 *
 * @param[out] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDataAdapter_delete(PhidgetDataAdapterHandle *ch);

/**
 * Initiates a set of write and read transactions to happen in quick succession.
 *
 * @param[in] ch The channel handle
 * @param[in] address The address of the I2C device
 * @param[in] I2CPacketString Specify the bytes of your I2C packet using 's' for start, 'R' for
 *     read, 'T' for write, and 'p' for stop. Only one stop condition per call is supported. For
 *     example, if you wanted to write two bytes, generate a repeat start, write one more byte, then
 *     read three bytes, the string would be "sTTsTsRRRp". You can also use numbers to indicate the
 *     number of bytes, e.g. "sT2sTsR3p"
 * @param[in] data The entire set of data to send, in order from first to last. The length of
 *     this data must match the total number of bytes specified to be sent in the
 *     **I2CPacketString**
 * @param[in] dataLen The length of the _data_ array. Must be ≤ @ref
 *     PhidgetDataAdapter_getMaxSendPacketLength()
 * @param[out] recvData The received data. This will be made up of all 'R' bytes as specified in
 *     the **I2CPacketString**, in order from first to last
 * @param[in,out] recvDataLen Specifies the length of the _recvData_ array. Returns the number
 *     of bytes recieved. If the received data is longer than the _recvData_ array, an error will be
 *     thrown. Any error detected in the received data will result in this argument becoming 0
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDataAdapter_i2cComplexTransaction(PhidgetDataAdapterHandle ch,
  int32_t address, const char *I2CPacketString, const uint8_t *data, size_t dataLen, uint8_t *recvData,
  size_t *recvDataLen);

/**
 * Write a number of bytes and immediately read a number of bytes over I2C.
 *
 * @param[in] ch The channel handle
 * @param[in] address The address of the I2C device
 * @param[in] data The data to send
 * @param[in] dataLen The length of the _data_ array. Must be ≤ @ref
 *     PhidgetDataAdapter_getMaxSendPacketLength()
 * @param[out] recvData The received data
 * @param[in] recvDataLen The number of bytes to receive. Must be ≤ @ref
 *     PhidgetDataAdapter_getMaxReceivePacketLength(). Ensure that the _recvData_ array is long
 *     enough
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDataAdapter_i2cSendReceive(PhidgetDataAdapterHandle ch,
  int32_t address, const uint8_t *data, size_t dataLen, uint8_t *recvData, size_t recvDataLen);

/**
 * Transmits a packet of data using the selected protocol information on the corresponding
 * communication terminals to any connected device(s).
 *
 * @param[in] ch The channel handle
 * @param[in] data The data to send
 * @param[in] dataLen The length of the _data_ array. Must be ≤ @ref
 *     PhidgetDataAdapter_getMaxSendPacketLength()
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDataAdapter_sendPacket(PhidgetDataAdapterHandle ch,
  const uint8_t *data, size_t dataLen);

/**
 * Transmits a packet of data using the selected protocol information on the corresponding
 * communication terminals to any connected device(s).
 *
 * @param[in] ch The channel handle
 * @param[in] data The data to send
 * @param[in] dataLen The length of the _data_ array. Must be ≤ @ref
 *     PhidgetDataAdapter_getMaxSendPacketLength()
 * @param[in] fptr Asynchronous completion callback
 * @param[in] ctx User supplied context pointer
 */
PHIDGET22_API void CCONV PhidgetDataAdapter_sendPacket_async(PhidgetDataAdapterHandle ch,
  const uint8_t *data, size_t dataLen, Phidget_AsyncCallback fptr, void *ctx);

/**
 * Sends a packet and waits for a corresponding response from the external device, until the timeout
 * elapses.
 *
 * @param[in] ch The channel handle
 * @param[in] data The data to send
 * @param[in] dataLen The length of the _data_ array. Must be ≤ @ref
 *     PhidgetDataAdapter_getMaxSendPacketLength()
 * @param[out] recvData The received data
 * @param[in,out] recvDataLen Specifies the length of the _recvData_ array. Returns the number
 *     of bytes recieved. If the received data is longer than the _recvData_ array, an error will be
 *     thrown. Any error detected in the received data will result in this argument becoming 0
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDataAdapter_sendPacketWaitResponse(PhidgetDataAdapterHandle ch,
  const uint8_t *data, size_t dataLen, uint8_t *recvData, size_t *recvDataLen);

/**
 * @brief The voltage value
 *
 * The voltage used to communicate with and power the external device.
 *
 * @param[in] ch The channel handle
 * @param[in] dataAdapterVoltage The voltage value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDataAdapter_setDataAdapterVoltage(PhidgetDataAdapterHandle ch,
  Phidget_DataAdapterVoltage dataAdapterVoltage);

/**
 * @brief The voltage value
 *
 * The voltage used to communicate with and power the external device.
 *
 * @param[in] ch The channel handle
 * @param[out] dataAdapterVoltage The voltage value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDataAdapter_getDataAdapterVoltage(PhidgetDataAdapterHandle ch,
  Phidget_DataAdapterVoltage *dataAdapterVoltage);

/**
 * @brief The number of data bits
 *
 * Configures the number of data bits used for communication. Refer to the documentation for the
 * device you are communicating with.
 *
 * @param[in] ch The channel handle
 * @param[in] dataBits The number of data bits
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDataAdapter_setDataBits(PhidgetDataAdapterHandle ch,
  uint32_t dataBits);

/**
 * @brief The number of data bits
 *
 * Configures the number of data bits used for communication. Refer to the documentation for the
 * device you are communicating with.
 *
 * @param[in] ch The channel handle
 * @param[out] dataBits The number of data bits
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDataAdapter_getDataBits(PhidgetDataAdapterHandle ch,
  uint32_t *dataBits);

/**
 * @brief The number of data bits
 *
 * The minimum number of data bits
 *
 * @param[in] ch The channel handle
 * @param[out] minDataBits The number of data bits
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDataAdapter_getMinDataBits(PhidgetDataAdapterHandle ch,
  uint32_t *minDataBits);

/**
 * @brief The number of data bits
 *
 * The maximum number of data bits
 *
 * @param[in] ch The channel handle
 * @param[out] maxDataBits The number of data bits
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDataAdapter_getMaxDataBits(PhidgetDataAdapterHandle ch,
  uint32_t *maxDataBits);

/**
 * @brief The endianness of the data bytes.
 *
 * Configures endianness of each byte.
 *
 * @param[in] ch The channel handle
 * @param[in] endianness The endianness of the data bytes
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDataAdapter_setEndianness(PhidgetDataAdapterHandle ch,
  PhidgetDataAdapter_Endianness endianness);

/**
 * @brief The endianness of the data bytes.
 *
 * Configures endianness of each byte.
 *
 * @param[in] ch The channel handle
 * @param[out] endianness The endianness of the data bytes
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDataAdapter_getEndianness(PhidgetDataAdapterHandle ch,
  PhidgetDataAdapter_Endianness *endianness);

/**
 * @brief The communication frequency to use for future data transfers.
 *
 * The rate at which data is transmitted over the communication lines in bits per second.
 *
 * @param[in] ch The channel handle
 * @param[in] frequency The communication frequency to use for future data transfers
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDataAdapter_setFrequency(PhidgetDataAdapterHandle ch,
  PhidgetDataAdapter_Frequency frequency);

/**
 * @brief The communication frequency to use for future data transfers.
 *
 * The rate at which data is transmitted over the communication lines in bits per second.
 *
 * @param[in] ch The channel handle
 * @param[out] frequency The communication frequency to use for future data transfers
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDataAdapter_getFrequency(PhidgetDataAdapterHandle ch,
  PhidgetDataAdapter_Frequency *frequency);

/**
 * @brief The maximum length of a received packet.
 *
 * The maximum length of a packet that can be received in bytes.
 *
 * @param[in] ch The channel handle
 * @param[out] maxReceivePacketLength The maximum length of a received packet
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDataAdapter_getMaxReceivePacketLength(PhidgetDataAdapterHandle ch,
  uint32_t *maxReceivePacketLength);

/**
 * @brief The maximum length of a sent packet.
 *
 * The maximum length of a packet that can be sent in bytes.
 *
 * @param[in] ch The channel handle
 * @param[out] maxSendPacketLength The maximum length of a sent packet
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDataAdapter_getMaxSendPacketLength(PhidgetDataAdapterHandle ch,
  uint32_t *maxSendPacketLength);

/**
 * @brief The SPI chip select polarity.
 *
 * Configures functionality of the SPI chip select pin
 *
 * @param[in] ch The channel handle
 * @param[in] SPIChipSelect The SPI chip select polarity
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDataAdapter_setSPIChipSelect(PhidgetDataAdapterHandle ch,
  PhidgetDataAdapter_SPIChipSelect SPIChipSelect);

/**
 * @brief The SPI chip select polarity.
 *
 * Configures functionality of the SPI chip select pin
 *
 * @param[in] ch The channel handle
 * @param[out] SPIChipSelect The SPI chip select polarity
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDataAdapter_getSPIChipSelect(PhidgetDataAdapterHandle ch,
  PhidgetDataAdapter_SPIChipSelect *SPIChipSelect);

/**
 * @brief The SPI mode.
 *
 * Configures SCLK polarity and phase.
 *
 * @param[in] ch The channel handle
 * @param[in] SPIMode The SPI mode
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDataAdapter_setSPIMode(PhidgetDataAdapterHandle ch,
  PhidgetDataAdapter_SPIMode SPIMode);

/**
 * @brief The SPI mode.
 *
 * Configures SCLK polarity and phase.
 *
 * @param[in] ch The channel handle
 * @param[out] SPIMode The SPI mode
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDataAdapter_getSPIMode(PhidgetDataAdapterHandle ch,
  PhidgetDataAdapter_SPIMode *SPIMode);

/** @} */ /* PhidgetDataAdapter */

/**
 * @defgroup PhidgetDCMotor DCMotor
 * @brief The DC Motor class controls the power applied to attached DC motors to affect its
 *     speed and direction. It can also contain various other control and monitoring functions that
 *     aid in the control of DC motors.
 * @{
 */

/**
 * The DC Motor class controls the power applied to attached DC motors to affect its speed and
 * direction. It can also contain various other control and monitoring functions that aid in the
 * control of DC motors.
 */
typedef struct _PhidgetDCMotor *PhidgetDCMotorHandle;

/**
 * @ref PhidgetDCMotor_create() creates an instance of a Phidget channel. Once created the channel
 * may need to be configured to match the physical device and channel index you want to attach to,
 * and then be opened by calling @ref Phidget_open().
 * The Phidget channel handle must be released with @ref PhidgetDCMotor_delete().
 *
 * @param[out] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDCMotor_create(PhidgetDCMotorHandle *ch);

/**
 * @ref PhidgetDCMotor_delete() releases a Phidget channel handle created with @ref
 * PhidgetDCMotor_create().
 * If the channel is open when @ref PhidgetDCMotor_delete() is called, it will be closed.
 *
 * @param[out] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDCMotor_delete(PhidgetDCMotorHandle *ch);

/**
 * Enables the **failsafe** feature for the channel, with the specified **failsafe time**.
 *
 * Enabling the failsafe feature starts a recurring **failsafe timer** for the channel. Once the
 * failsafe is enabled, the timer must be reset within the specified time or the channel will enter
 * a **failsafe state**. For DC Motor channels, this will disengage the motor. The failsafe timer
 * can be reset by using any API call **_except_** for 'get' API calls.
 *
 * For more information about failsafe, visit our [Failsafe
 * Guide](https://www.phidgets.com/docs/Failsafe_Guide).
 *
 * @param[in] ch The channel handle
 * @param[in] failsafeTime Failsafe timeout in milliseconds
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDCMotor_enableFailsafe(PhidgetDCMotorHandle ch,
  uint32_t failsafeTime);

/**
 * Resets the failsafe timer, if one has been set. See @ref PhidgetDCMotor_enableFailsafe() for
 * details.
 *
 * This function will fail if no failsafe timer has been set for the channel.
 *
 * @param[in] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDCMotor_resetFailsafe(PhidgetDCMotorHandle ch);

/**
 * @brief The acceleration value
 *
 * The rate at which the controller can change the motor's @ref PhidgetDCMotor_getVelocity().
 *
 * @param[in] ch The channel handle
 * @param[in] acceleration The acceleration value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDCMotor_setAcceleration(PhidgetDCMotorHandle ch,
  double acceleration);

/**
 * @brief The acceleration value
 *
 * The rate at which the controller can change the motor's @ref PhidgetDCMotor_getVelocity().
 *
 * @param[in] ch The channel handle
 * @param[out] acceleration The acceleration value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDCMotor_getAcceleration(PhidgetDCMotorHandle ch,
  double *acceleration);

/**
 * @brief The acceleration value.
 *
 * The minimum value that `Acceleration` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minAcceleration The acceleration value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDCMotor_getMinAcceleration(PhidgetDCMotorHandle ch,
  double *minAcceleration);

/**
 * @brief The acceleration value.
 *
 * The maximum value that `Acceleration` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxAcceleration The acceleration value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDCMotor_getMaxAcceleration(PhidgetDCMotorHandle ch,
  double *maxAcceleration);

/**
 * @brief The active current limit value
 *
 * The current limit that the controller is actively following. The `SurgeCurrentLimit`,
 * `CurrentLimit`, and temperature will impact this value.
 *
 * @param[in] ch The channel handle
 * @param[out] activeCurrentLimit The active current limit value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDCMotor_getActiveCurrentLimit(PhidgetDCMotorHandle ch,
  double *activeCurrentLimit);

/**
 * @brief The back EMF value
 *
 * The most recent @ref PhidgetDCMotor_getBackEMF() value that the controller has reported.
 *
 * @param[in] ch The channel handle
 * @param[out] backEMF The back EMF value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDCMotor_getBackEMF(PhidgetDCMotorHandle ch,
  double *backEMF);

/**
 * @brief The back EMF state
 *
 * When `BackEMFSensingState` is enabled, the controller will measure and report the @ref
 * PhidgetDCMotor_getBackEMF().
 *
 * *   The motor will coast (freewheel) 5% of the time while the back EMF is being measured
 *     (800μs every 16ms). Therefore, at a @ref PhidgetDCMotor_getVelocity() of 100%, the motor will
 *     only be driven for 95% of the time.
 *
 * @param[in] ch The channel handle
 * @param[in] backEMFSensingState The back EMF state
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDCMotor_setBackEMFSensingState(PhidgetDCMotorHandle ch,
  int backEMFSensingState);

/**
 * @brief The back EMF state
 *
 * When `BackEMFSensingState` is enabled, the controller will measure and report the @ref
 * PhidgetDCMotor_getBackEMF().
 *
 * *   The motor will coast (freewheel) 5% of the time while the back EMF is being measured
 *     (800μs every 16ms). Therefore, at a @ref PhidgetDCMotor_getVelocity() of 100%, the motor will
 *     only be driven for 95% of the time.
 *
 * @param[in] ch The channel handle
 * @param[out] backEMFSensingState The back EMF state
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDCMotor_getBackEMFSensingState(PhidgetDCMotorHandle ch,
  int *backEMFSensingState);

/**
 * @brief Enable braking when stopped
 *
 * This setting allows you to choose whether the motor will resist being turned when it is not being
 * driven forward or reverse (@ref PhidgetDCMotor_getVelocity() = 0).
 *
 * *   Setting `BrakingEnabled` to FALSE corresponds to free-wheeling. This means:
 *     *   The motor will continue to rotate after the controller is no longer driving the motor
 * (@ref PhidgetDCMotor_getVelocity() = 0), due to its momentum.
 *     *   The motor shaft will provide little resistance to being turned when it is stopped.
 * *   Setting `BrakingEnabled` to TRUE will engage electrical braking of the DC motor. This
 *     means:
 *     *   The motor will stop more quickly if it is in motion when braking is requested.
 *     *   The motor shaft will resist rotation by outside forces.
 * *   Braking will be added gradually, according to the `Acceleration` setting, once the motor
 *     controller's @ref PhidgetDCMotor_getVelocity() reaches 0.0
 * *   Braking will be immediately stopped when a new (non-zero) `TargetVelocity` is set, and
 *     the motor will accelerate to the requested velocity.
 * *   Braking mode is enabled by setting the @ref PhidgetDCMotor_getVelocity() to 0.0
 *
 * @param[in] ch The channel handle
 * @param[in] brakingEnabled Enable braking when stopped
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDCMotor_setBrakingEnabled(PhidgetDCMotorHandle ch,
  int brakingEnabled);

/**
 * @brief Enable braking when stopped
 *
 * This setting allows you to choose whether the motor will resist being turned when it is not being
 * driven forward or reverse (@ref PhidgetDCMotor_getVelocity() = 0).
 *
 * *   Setting `BrakingEnabled` to FALSE corresponds to free-wheeling. This means:
 *     *   The motor will continue to rotate after the controller is no longer driving the motor
 * (@ref PhidgetDCMotor_getVelocity() = 0), due to its momentum.
 *     *   The motor shaft will provide little resistance to being turned when it is stopped.
 * *   Setting `BrakingEnabled` to TRUE will engage electrical braking of the DC motor. This
 *     means:
 *     *   The motor will stop more quickly if it is in motion when braking is requested.
 *     *   The motor shaft will resist rotation by outside forces.
 * *   Braking will be added gradually, according to the `Acceleration` setting, once the motor
 *     controller's @ref PhidgetDCMotor_getVelocity() reaches 0.0
 * *   Braking will be immediately stopped when a new (non-zero) `TargetVelocity` is set, and
 *     the motor will accelerate to the requested velocity.
 * *   Braking mode is enabled by setting the @ref PhidgetDCMotor_getVelocity() to 0.0
 *
 * @param[in] ch The channel handle
 * @param[out] brakingEnabled Enable braking when stopped
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDCMotor_getBrakingEnabled(PhidgetDCMotorHandle ch,
  int *brakingEnabled);

/**
 * @brief The braking strength value
 *
 * The most recent braking strength value that the controller has reported. See `BrakingEnabled` for
 * details.
 *
 * @param[in] ch The channel handle
 * @param[out] brakingStrength The braking strength value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDCMotor_getBrakingStrength(PhidgetDCMotorHandle ch,
  double *brakingStrength);

/**
 * @brief The braking strength value
 *
 * The minimum value that @ref PhidgetDCMotor_getBrakingStrength() can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minBrakingStrength The braking strength value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDCMotor_getMinBrakingStrength(PhidgetDCMotorHandle ch,
  double *minBrakingStrength);

/**
 * @brief The braking strength value
 *
 * The maximum value that @ref PhidgetDCMotor_getBrakingStrength() can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxBrakingStrength The braking strength value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDCMotor_getMaxBrakingStrength(PhidgetDCMotorHandle ch,
  double *maxBrakingStrength);

/**
 * @brief The current limit value
 *
 * The controller will limit the current through the motor to the `CurrentLimit` value.
 *
 * @param[in] ch The channel handle
 * @param[in] currentLimit The current limit value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDCMotor_setCurrentLimit(PhidgetDCMotorHandle ch,
  double currentLimit);

/**
 * @brief The current limit value
 *
 * The controller will limit the current through the motor to the `CurrentLimit` value.
 *
 * @param[in] ch The channel handle
 * @param[out] currentLimit The current limit value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDCMotor_getCurrentLimit(PhidgetDCMotorHandle ch,
  double *currentLimit);

/**
 * @brief The current value
 *
 * The minimum value that `CurrentLimit` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minCurrentLimit The current value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDCMotor_getMinCurrentLimit(PhidgetDCMotorHandle ch,
  double *minCurrentLimit);

/**
 * @brief The current value
 *
 * The maximum value that `CurrentLimit` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxCurrentLimit The current value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDCMotor_getMaxCurrentLimit(PhidgetDCMotorHandle ch,
  double *maxCurrentLimit);

/**
 * @brief The current regulator gain value
 *
 * Depending on power supply voltage and motor coil inductance, current through the motor can change
 * relatively slowly or extremely rapidly. A physically larger DC Motor will typically have a lower
 * inductance, requiring a higher current regulator gain. A higher power supply voltage will result
 * in motor current changing more rapidly, requiring a higher current regulator gain. If the current
 * regulator gain is too small, spikes in current will occur, causing large variations in torque,
 * and possibly damaging the motor controller. If the current regulator gain is too high, the
 * current will jitter, causing the motor to sound 'rough', especially when changing directions.
 *
 * As a rule of thumb, we recommend setting this value as follows:
 *
 * CurrentRegulatorGain = CurrentLimit * (Voltage / 12)
 *
 * @param[in] ch The channel handle
 * @param[in] currentRegulatorGain The current regulator gain value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDCMotor_setCurrentRegulatorGain(PhidgetDCMotorHandle ch,
  double currentRegulatorGain);

/**
 * @brief The current regulator gain value
 *
 * Depending on power supply voltage and motor coil inductance, current through the motor can change
 * relatively slowly or extremely rapidly. A physically larger DC Motor will typically have a lower
 * inductance, requiring a higher current regulator gain. A higher power supply voltage will result
 * in motor current changing more rapidly, requiring a higher current regulator gain. If the current
 * regulator gain is too small, spikes in current will occur, causing large variations in torque,
 * and possibly damaging the motor controller. If the current regulator gain is too high, the
 * current will jitter, causing the motor to sound 'rough', especially when changing directions.
 *
 * As a rule of thumb, we recommend setting this value as follows:
 *
 * CurrentRegulatorGain = CurrentLimit * (Voltage / 12)
 *
 * @param[in] ch The channel handle
 * @param[out] currentRegulatorGain The current regulator gain value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDCMotor_getCurrentRegulatorGain(PhidgetDCMotorHandle ch,
  double *currentRegulatorGain);

/**
 * @brief The current regulator gain value
 *
 * The minimum value that `CurrentRegulatorGain` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minCurrentRegulatorGain The current regulator gain value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDCMotor_getMinCurrentRegulatorGain(PhidgetDCMotorHandle ch,
  double *minCurrentRegulatorGain);

/**
 * @brief The current regulator gain value
 *
 * The maximum value that `CurrentRegulatorGain` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxCurrentRegulatorGain The current regulator gain value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDCMotor_getMaxCurrentRegulatorGain(PhidgetDCMotorHandle ch,
  double *maxCurrentRegulatorGain);

/**
 * @brief The data interval value
 *
 * The `DataInterval` is the time that must elapse before the channel will fire another @ref
 * PhidgetDCMotor_setOnVelocityUpdateHandler() / @ref
 * PhidgetDCMotor_setOnBrakingStrengthChangeHandler() event.
 *
 * *   The data interval is bounded by @ref PhidgetDCMotor_getMinDataInterval() and @ref
 *     PhidgetDCMotor_getMaxDataInterval().
 *
 * *   Note: @ref PhidgetDCMotor_setOnBrakingStrengthChangeHandler() events will only fire if a
 *     change in braking has occurred.
 *
 * @param[in] ch The channel handle
 * @param[in] dataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDCMotor_setDataInterval(PhidgetDCMotorHandle ch,
  uint32_t dataInterval);

/**
 * @brief The data interval value
 *
 * The `DataInterval` is the time that must elapse before the channel will fire another @ref
 * PhidgetDCMotor_setOnVelocityUpdateHandler() / @ref
 * PhidgetDCMotor_setOnBrakingStrengthChangeHandler() event.
 *
 * *   The data interval is bounded by @ref PhidgetDCMotor_getMinDataInterval() and @ref
 *     PhidgetDCMotor_getMaxDataInterval().
 *
 * *   Note: @ref PhidgetDCMotor_setOnBrakingStrengthChangeHandler() events will only fire if a
 *     change in braking has occurred.
 *
 * @param[in] ch The channel handle
 * @param[out] dataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDCMotor_getDataInterval(PhidgetDCMotorHandle ch,
  uint32_t *dataInterval);

/**
 * @brief The data interval value
 *
 * The minimum value that `DataInterval` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minDataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDCMotor_getMinDataInterval(PhidgetDCMotorHandle ch,
  uint32_t *minDataInterval);

/**
 * @brief The data interval value
 *
 * The maximum value that `DataInterval` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxDataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDCMotor_getMaxDataInterval(PhidgetDCMotorHandle ch,
  uint32_t *maxDataInterval);

/**
 * @brief The data rate for the channel
 *
 * The `DataRate` is the frequency of events from the device.
 *
 * *   The data rate is bounded by @ref PhidgetDCMotor_getMinDataRate() and @ref
 *     PhidgetDCMotor_getMaxDataRate().
 * *   Changing `DataRate` will change the channel's `DataInterval` to a corresponding value,
 *     rounded to the nearest integer number of milliseconds.
 * *   The timing between events can also affected by the change trigger.
 *
 * @param[in] ch The channel handle
 * @param[in] dataRate The data rate for the channel
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDCMotor_setDataRate(PhidgetDCMotorHandle ch,
  double dataRate);

/**
 * @brief The data rate for the channel
 *
 * The `DataRate` is the frequency of events from the device.
 *
 * *   The data rate is bounded by @ref PhidgetDCMotor_getMinDataRate() and @ref
 *     PhidgetDCMotor_getMaxDataRate().
 * *   Changing `DataRate` will change the channel's `DataInterval` to a corresponding value,
 *     rounded to the nearest integer number of milliseconds.
 * *   The timing between events can also affected by the change trigger.
 *
 * @param[in] ch The channel handle
 * @param[out] dataRate The data rate for the channel
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDCMotor_getDataRate(PhidgetDCMotorHandle ch,
  double *dataRate);

/**
 * @brief The data rate value
 *
 * The minimum value that `DataRate` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minDataRate The data rate value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDCMotor_getMinDataRate(PhidgetDCMotorHandle ch,
  double *minDataRate);

/**
 * @brief The data rate value
 *
 * The maximum value that `DataRate` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxDataRate The data rate value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDCMotor_getMaxDataRate(PhidgetDCMotorHandle ch,
  double *maxDataRate);

/**
 * @brief The drive type selection
 *
 * This setting impacts how your motor decelerates and the amount of current that is available to
 * your motor at any given moment.
 *
 * For more information about `DriveMode`, visit our [DCMotor API
 * Guide](https://www.phidgets.com/docs/DCMotor_API_Guide#Drive_Mode)
 *
 * @param[in] ch The channel handle
 * @param[in] driveMode The drive type selection
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDCMotor_setDriveMode(PhidgetDCMotorHandle ch,
  Phidget_DriveMode driveMode);

/**
 * @brief The drive type selection
 *
 * This setting impacts how your motor decelerates and the amount of current that is available to
 * your motor at any given moment.
 *
 * For more information about `DriveMode`, visit our [DCMotor API
 * Guide](https://www.phidgets.com/docs/DCMotor_API_Guide#Drive_Mode)
 *
 * @param[in] ch The channel handle
 * @param[out] driveMode The drive type selection
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDCMotor_getDriveMode(PhidgetDCMotorHandle ch,
  Phidget_DriveMode *driveMode);

/**
 * @brief Enables failsafe braking
 *
 * This setting allows you to choose whether motor will forcibly stop once it enters a **FAILSAFE**
 * state.
 *
 * *   A setting of FALSE will simply stop applying power to the motor, allowing it to spin down
 *     naturally.
 * *   A setting of TRUE will apply braking up to the `FailsafeCurrentLimit`, actively stopping
 *     the motor
 *
 * For more information about `FailsafeBrakingEnabled`, visit our [DCMotor API
 * Guide](https://www.phidgets.com/docs/DCMotor_API_Guide#Failsafe_Braking_Enabled)
 *
 * @param[in] ch The channel handle
 * @param[in] failsafeBrakingEnabled Enables failsafe braking
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDCMotor_setFailsafeBrakingEnabled(PhidgetDCMotorHandle ch,
  int failsafeBrakingEnabled);

/**
 * @brief Enables failsafe braking
 *
 * This setting allows you to choose whether motor will forcibly stop once it enters a **FAILSAFE**
 * state.
 *
 * *   A setting of FALSE will simply stop applying power to the motor, allowing it to spin down
 *     naturally.
 * *   A setting of TRUE will apply braking up to the `FailsafeCurrentLimit`, actively stopping
 *     the motor
 *
 * For more information about `FailsafeBrakingEnabled`, visit our [DCMotor API
 * Guide](https://www.phidgets.com/docs/DCMotor_API_Guide#Failsafe_Braking_Enabled)
 *
 * @param[in] ch The channel handle
 * @param[out] failsafeBrakingEnabled Enables failsafe braking
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDCMotor_getFailsafeBrakingEnabled(PhidgetDCMotorHandle ch,
  int *failsafeBrakingEnabled);

/**
 * @brief The failsafe current limit value
 *
 * When the controller enters a **FAILSAFE** state, the controller will limit the current through
 * the motor to the `FailsafeCurrentLimit` value.
 *
 * For more information about `FailsafeCurrentLimit`, visit our [DCMotor API
 * Guide](https://www.phidgets.com/docs/DCMotor_API_Guide#Failsafe_Current_Limit)
 *
 * @param[in] ch The channel handle
 * @param[in] failsafeCurrentLimit The failsafe current limit value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDCMotor_setFailsafeCurrentLimit(PhidgetDCMotorHandle ch,
  double failsafeCurrentLimit);

/**
 * @brief The failsafe current limit value
 *
 * When the controller enters a **FAILSAFE** state, the controller will limit the current through
 * the motor to the `FailsafeCurrentLimit` value.
 *
 * For more information about `FailsafeCurrentLimit`, visit our [DCMotor API
 * Guide](https://www.phidgets.com/docs/DCMotor_API_Guide#Failsafe_Current_Limit)
 *
 * @param[in] ch The channel handle
 * @param[out] failsafeCurrentLimit The failsafe current limit value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDCMotor_getFailsafeCurrentLimit(PhidgetDCMotorHandle ch,
  double *failsafeCurrentLimit);

/**
 * @brief The failsafe time
 *
 * The minimum value that `failsafeTime` can be set to when calling @ref
 * PhidgetDCMotor_enableFailsafe().
 *
 * @param[in] ch The channel handle
 * @param[out] minFailsafeTime The failsafe time
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDCMotor_getMinFailsafeTime(PhidgetDCMotorHandle ch,
  uint32_t *minFailsafeTime);

/**
 * @brief The failsafe time
 *
 * The maximum value that `failsafeTime` can be set to when calling @ref
 * PhidgetDCMotor_enableFailsafe().
 *
 * @param[in] ch The channel handle
 * @param[out] maxFailsafeTime The failsafe time
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDCMotor_getMaxFailsafeTime(PhidgetDCMotorHandle ch,
  uint32_t *maxFailsafeTime);

/**
 * @brief The fan mode
 *
 * The `FanMode` dictates the operating condition of the fan.
 *
 * *   Choose between on, off, or automatic (based on temperature).
 * *   If the `FanMode` is set to automatic, the fan will turn on when the temperature reaches
 *     70°C and it will remain on until the temperature falls below 55°C.
 * *   If the `FanMode` is off, the controller will still turn on the fan if the temperature
 *     reaches 85°C and it will remain on until it falls below 70°C.
 *
 * @param[in] ch The channel handle
 * @param[in] fanMode The fan mode
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDCMotor_setFanMode(PhidgetDCMotorHandle ch,
  Phidget_FanMode fanMode);

/**
 * @brief The fan mode
 *
 * The `FanMode` dictates the operating condition of the fan.
 *
 * *   Choose between on, off, or automatic (based on temperature).
 * *   If the `FanMode` is set to automatic, the fan will turn on when the temperature reaches
 *     70°C and it will remain on until the temperature falls below 55°C.
 * *   If the `FanMode` is off, the controller will still turn on the fan if the temperature
 *     reaches 85°C and it will remain on until it falls below 70°C.
 *
 * @param[in] ch The channel handle
 * @param[out] fanMode The fan mode
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDCMotor_getFanMode(PhidgetDCMotorHandle ch,
  Phidget_FanMode *fanMode);

/**
 * @brief The inductance of your motor
 *
 * The controller will attempt to measure the inductance of your motor when opened. This value is
 * used to improve control of the motor.
 *
 * *   Set this value during the **Attach Event** to skip motor characterization (including the
 *     audible beeps). You can use a previously saved `Inductance` value, or information from your
 *     motor's datasheet.
 *
 * For more information about `Inductance`, visit our [DCMotor API
 * Guide](https://www.phidgets.com/docs/DCMotor_API_Guide#Motor_Inductance)
 *
 * @param[in] ch The channel handle
 * @param[in] inductance The inductance of your motor
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDCMotor_setInductance(PhidgetDCMotorHandle ch,
  double inductance);

/**
 * @brief The inductance of your motor
 *
 * The controller will attempt to measure the inductance of your motor when opened. This value is
 * used to improve control of the motor.
 *
 * *   Set this value during the **Attach Event** to skip motor characterization (including the
 *     audible beeps). You can use a previously saved `Inductance` value, or information from your
 *     motor's datasheet.
 *
 * For more information about `Inductance`, visit our [DCMotor API
 * Guide](https://www.phidgets.com/docs/DCMotor_API_Guide#Motor_Inductance)
 *
 * @param[in] ch The channel handle
 * @param[out] inductance The inductance of your motor
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDCMotor_getInductance(PhidgetDCMotorHandle ch,
  double *inductance);

/**
 * @brief The motor inductance value
 *
 * The minimum value that `Inductance` can be set to. See `Inductance` for details.
 *
 * @param[in] ch The channel handle
 * @param[out] minInductance The motor inductance value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDCMotor_getMinInductance(PhidgetDCMotorHandle ch,
  double *minInductance);

/**
 * @brief The motor inductance value
 *
 * The maximum value that `Inductance` can be set to. See `Inductance` for details.
 *
 * @param[in] ch The channel handle
 * @param[out] maxInductance The motor inductance value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDCMotor_getMaxInductance(PhidgetDCMotorHandle ch,
  double *maxInductance);

/**
 * @brief The surge current limit value
 *
 * The `SurgeCurrentLimit` allows for increased performance from your motor. The controller will
 * limit the current through your motor to the `SurgeCurrentLimit` briefly, then scale current down
 * to the `CurrentLimit`.
 *
 * *   View @ref PhidgetDCMotor_getActiveCurrentLimit() for information about what current limit
 *     the controller is actively following.
 *
 * For more information about `SurgeCurrentLimit`, visit our [DCMotor API
 * Guide](https://www.phidgets.com/docs/DCMotor_API_Guide#Surge_Current_Limit)
 *
 * @param[in] ch The channel handle
 * @param[in] surgeCurrentLimit The surge current limit value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDCMotor_setSurgeCurrentLimit(PhidgetDCMotorHandle ch,
  double surgeCurrentLimit);

/**
 * @brief The surge current limit value
 *
 * The `SurgeCurrentLimit` allows for increased performance from your motor. The controller will
 * limit the current through your motor to the `SurgeCurrentLimit` briefly, then scale current down
 * to the `CurrentLimit`.
 *
 * *   View @ref PhidgetDCMotor_getActiveCurrentLimit() for information about what current limit
 *     the controller is actively following.
 *
 * For more information about `SurgeCurrentLimit`, visit our [DCMotor API
 * Guide](https://www.phidgets.com/docs/DCMotor_API_Guide#Surge_Current_Limit)
 *
 * @param[in] ch The channel handle
 * @param[out] surgeCurrentLimit The surge current limit value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDCMotor_getSurgeCurrentLimit(PhidgetDCMotorHandle ch,
  double *surgeCurrentLimit);

/**
 * @brief The surge current value
 *
 * The minimum value that `SurgeCurrentLimit` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minSurgeCurrentLimit The surge current value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDCMotor_getMinSurgeCurrentLimit(PhidgetDCMotorHandle ch,
  double *minSurgeCurrentLimit);

/**
 * @brief The surge current value
 *
 * The maximum value that `SurgeCurrentLimit` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxSurgeCurrentLimit The surge current value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDCMotor_getMaxSurgeCurrentLimit(PhidgetDCMotorHandle ch,
  double *maxSurgeCurrentLimit);

/**
 * @brief The braking strength value
 *
 * This setting allows you to choose how hard the motor will resist being turned when it is not
 * being driven forward or reverse (@ref PhidgetDCMotor_getVelocity() = 0). The
 * `TargetBrakingStrength` sets the relative amount of electrical braking to be applied to the DC
 * motor, with @ref PhidgetDCMotor_getMinBrakingStrength() corresponding to no braking
 * (free-wheeling), and @ref PhidgetDCMotor_getMaxBrakingStrength() indicating full braking.
 *
 * *   A low `TargetBrakingStrength` value corresponds to free-wheeling. This means:
 *     *   The motor will continue to rotate after the controller is no longer driving the motor
 * (@ref PhidgetDCMotor_getVelocity() = 0), due to its momentum.
 *     *   The motor shaft will provide little resistance to being turned when it is stopped.
 * *   As `TargetBrakingStrength` increases, this will engage electrical braking of the DC
 *     motor. This means:
 *     *   The motor will stop more quickly if it is in motion when braking is requested.
 *     *   The motor shaft will resist rotation by outside forces.
 * *   Braking will be added gradually, according to the `Acceleration` setting, once the motor
 *     controller's @ref PhidgetDCMotor_getVelocity() reaches 0.0
 * *   Braking will be immediately stopped when a new (non-zero) `TargetVelocity` is set, and
 *     the motor will accelerate to the requested velocity.
 * *   Braking mode is enabled by setting the @ref PhidgetDCMotor_getVelocity() to 0.0
 *
 * @param[in] ch The channel handle
 * @param[in] targetBrakingStrength The braking strength value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDCMotor_setTargetBrakingStrength(PhidgetDCMotorHandle ch,
  double targetBrakingStrength);

/**
 * @brief The braking strength value
 *
 * This setting allows you to choose how hard the motor will resist being turned when it is not
 * being driven forward or reverse (@ref PhidgetDCMotor_getVelocity() = 0). The
 * `TargetBrakingStrength` sets the relative amount of electrical braking to be applied to the DC
 * motor, with @ref PhidgetDCMotor_getMinBrakingStrength() corresponding to no braking
 * (free-wheeling), and @ref PhidgetDCMotor_getMaxBrakingStrength() indicating full braking.
 *
 * *   A low `TargetBrakingStrength` value corresponds to free-wheeling. This means:
 *     *   The motor will continue to rotate after the controller is no longer driving the motor
 * (@ref PhidgetDCMotor_getVelocity() = 0), due to its momentum.
 *     *   The motor shaft will provide little resistance to being turned when it is stopped.
 * *   As `TargetBrakingStrength` increases, this will engage electrical braking of the DC
 *     motor. This means:
 *     *   The motor will stop more quickly if it is in motion when braking is requested.
 *     *   The motor shaft will resist rotation by outside forces.
 * *   Braking will be added gradually, according to the `Acceleration` setting, once the motor
 *     controller's @ref PhidgetDCMotor_getVelocity() reaches 0.0
 * *   Braking will be immediately stopped when a new (non-zero) `TargetVelocity` is set, and
 *     the motor will accelerate to the requested velocity.
 * *   Braking mode is enabled by setting the @ref PhidgetDCMotor_getVelocity() to 0.0
 *
 * @param[in] ch The channel handle
 * @param[out] targetBrakingStrength The braking strength value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDCMotor_getTargetBrakingStrength(PhidgetDCMotorHandle ch,
  double *targetBrakingStrength);

/**
 * @brief The velocity value
 *
 * The average voltage across the motor is based on the `TargetVelocity` value.
 *
 * *   At a constant load, increasing the target velocity will increase the speed of the motor.
 * *   `TargetVelocity` is bounded by -@ref PhidgetDCMotor_getMaxVelocity() and +@ref
 *     PhidgetDCMotor_getMaxVelocity(), where a sign change (±) is indicative of a direction change.
 * *   Setting `TargetVelocity` to @ref PhidgetDCMotor_getMinVelocity() will stop the motor. See
 *     `BrakingEnabled` for more information on stopping the motor.
 *
 * @param[in] ch The channel handle
 * @param[in] targetVelocity The velocity value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDCMotor_setTargetVelocity(PhidgetDCMotorHandle ch,
  double targetVelocity);

/**
 * @brief The velocity value
 *
 * The average voltage across the motor is based on the `TargetVelocity` value.
 *
 * *   At a constant load, increasing the target velocity will increase the speed of the motor.
 * *   `TargetVelocity` is bounded by -@ref PhidgetDCMotor_getMaxVelocity() and +@ref
 *     PhidgetDCMotor_getMaxVelocity(), where a sign change (±) is indicative of a direction change.
 * *   Setting `TargetVelocity` to @ref PhidgetDCMotor_getMinVelocity() will stop the motor. See
 *     `BrakingEnabled` for more information on stopping the motor.
 *
 * @param[in] ch The channel handle
 * @param[in] targetVelocity The velocity value
 * @param[in] fptr Asynchronous completion callback
 * @param[in] ctx User supplied context pointer
 */
PHIDGET22_API void CCONV PhidgetDCMotor_setTargetVelocity_async(PhidgetDCMotorHandle ch,
  double targetVelocity, Phidget_AsyncCallback fptr, void *ctx);

/**
 * @brief The velocity value
 *
 * The average voltage across the motor is based on the `TargetVelocity` value.
 *
 * *   At a constant load, increasing the target velocity will increase the speed of the motor.
 * *   `TargetVelocity` is bounded by -@ref PhidgetDCMotor_getMaxVelocity() and +@ref
 *     PhidgetDCMotor_getMaxVelocity(), where a sign change (±) is indicative of a direction change.
 * *   Setting `TargetVelocity` to @ref PhidgetDCMotor_getMinVelocity() will stop the motor. See
 *     `BrakingEnabled` for more information on stopping the motor.
 *
 * @param[in] ch The channel handle
 * @param[out] targetVelocity The velocity value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDCMotor_getTargetVelocity(PhidgetDCMotorHandle ch,
  double *targetVelocity);

/**
 * @brief The velocity value
 *
 * The most recent @ref PhidgetDCMotor_getVelocity() value that the controller has reported.
 *
 * @param[in] ch The channel handle
 * @param[out] velocity The velocity value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDCMotor_getVelocity(PhidgetDCMotorHandle ch,
  double *velocity);

/**
 * @brief The velocity value
 *
 * The minimum value that `TargetVelocity` can be set to.
 *
 * *   Set the `TargetVelocity` to @ref PhidgetDCMotor_getMinVelocity() to stop the motor. See
 *     `BrakingEnabled` for more information on stopping the motor.
 * *   `TargetVelocity` is bounded by -@ref PhidgetDCMotor_getMaxVelocity() and +@ref
 *     PhidgetDCMotor_getMaxVelocity(), where a sign change (±) is indicative of a direction change.
 *
 * @param[in] ch The channel handle
 * @param[out] minVelocity The velocity value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDCMotor_getMinVelocity(PhidgetDCMotorHandle ch,
  double *minVelocity);

/**
 * @brief The velocity value
 *
 * The maximum value that `TargetVelocity` can be set to.
 *
 * *   `TargetVelocity` is bounded by -@ref PhidgetDCMotor_getMaxVelocity() and +@ref
 *     PhidgetDCMotor_getMaxVelocity(), where a sign change (±) is indicative of a direction change.
 *
 * @param[in] ch The channel handle
 * @param[out] maxVelocity The velocity value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDCMotor_getMaxVelocity(PhidgetDCMotorHandle ch,
  double *maxVelocity);

/**
 * @brief Callback function type for PhidgetDCMotor_setOnBackEMFChangeHandler().
 *
 * @param[in] ch The channel handle
 * @param[in] ctx Pointer to the user context
 * @param[in] backEMF The back EMF voltage from the motor
 */
typedef void (CCONV *PhidgetDCMotor_OnBackEMFChangeCallback)(PhidgetDCMotorHandle ch, void *ctx,
  double backEMF);

/**
 * The most recent back emf value will be reported in this event.
 *
 * @param[in] ch The channel handle
 * @param[in] fptr The event handler callback function
 * @param[in] ctx User supplied context pointer
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDCMotor_setOnBackEMFChangeHandler(PhidgetDCMotorHandle ch,
  PhidgetDCMotor_OnBackEMFChangeCallback fptr, void *ctx);

/**
 * @brief Callback function type for PhidgetDCMotor_setOnBrakingStrengthChangeHandler().
 *
 * @param[in] ch The channel handle
 * @param[in] ctx Pointer to the user context
 * @param[in] brakingStrength The most recent braking strength value will be reported in this
 *     event. *   This event will occur only when the value of braking strength has changed *   See
 *     `BrakingEnabled` for details about what this number represents
 */
typedef void (CCONV *PhidgetDCMotor_OnBrakingStrengthChangeCallback)(PhidgetDCMotorHandle ch, void *ctx,
  double brakingStrength);

/**
 * Occurs when the motor braking strength changes.
 *
 * @param[in] ch The channel handle
 * @param[in] fptr The event handler callback function
 * @param[in] ctx User supplied context pointer
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDCMotor_setOnBrakingStrengthChangeHandler(PhidgetDCMotorHandle ch,
  PhidgetDCMotor_OnBrakingStrengthChangeCallback fptr, void *ctx);

/**
 * @brief Callback function type for PhidgetDCMotor_setOnVelocityUpdateHandler().
 *
 * @param[in] ch The channel handle
 * @param[in] ctx Pointer to the user context
 * @param[in] velocity The most recent velocity value will be reported in this event
 */
typedef void (CCONV *PhidgetDCMotor_OnVelocityUpdateCallback)(PhidgetDCMotorHandle ch, void *ctx,
  double velocity);

/**
 * Occurs at a rate defined by the `DataInterval`.
 *
 * @param[in] ch The channel handle
 * @param[in] fptr The event handler callback function
 * @param[in] ctx User supplied context pointer
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDCMotor_setOnVelocityUpdateHandler(PhidgetDCMotorHandle ch,
  PhidgetDCMotor_OnVelocityUpdateCallback fptr, void *ctx);

/** @} */ /* PhidgetDCMotor */

/**
 * @defgroup PhidgetDictionary Dictionary
 * @brief Dictionaries are useful for passing information between multiple programs using
 *     Phidgets. A common example would be to have one program controlling your application that
 *     receives commands sent via a Phidget dictionary from a web interface, as outlined in many of
 *     our [articles](https://www.phidgets.com/?view=articles).
 * @{
 */

/**
 * Dictionaries are useful for passing information between multiple programs using Phidgets. A
 * common example would be to have one program controlling your application that receives commands
 * sent via a Phidget dictionary from a web interface, as outlined in many of our
 * [articles](https://www.phidgets.com/?view=articles).
 *
 * Keys can be thought of as being similar to variable names, with their values as their associated
 * value. Phidget dictionaries contain groups of related key-value pairs, and are stored on a
 * central [Phigdet Network Server](https://www.phidgets.com/docs/Phidget_Network_Server).
 * Dictionaries, and the key-value pairs within may be accessed from programs that have access to
 * the [Phigdet Network Server](https://www.phidgets.com/docs/Phidget_Network_Server).
 *
 * The Dictionary API supports connecting to a dictionary on the server, managing key-value pairs,
 * and monitoring changes made to the dictionary.
 *
 * More information on Phidget Dictionaries can be found on the [Phidget
 * Dictionary](https://www.phidgets.com/docs/Phidget_Dictionary) support page.
 */
typedef struct _PhidgetDictionary *PhidgetDictionaryHandle;

/**
 * Adds a new dictionary that exports the control interface from the system
 *
 * @private
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDictionary_enableControlDictionary(void);

/**
 * Adds a new dictionary to the system.
 *
 * The serial number must be greater than 1000.
 *
 * @private
 * @param[in] deviceSerialNumber the serial number to assign the new dictionary (> 1000)
 * @param[in] label the label to assign the new dictionary
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDictionary_addDictionary(int deviceSerialNumber,
  const char *label);

/**
 * Removes a dictionary from the system.
 *
 * @private
 * @param[in] deviceSerialNumber the serial number of the dictionary
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDictionary_removeDictionary(int deviceSerialNumber);

/**
 * Loads data from a file into the specified dictionary.
 *
 * *   The data is loaded from a file of the form key=value
 * *   Blank lines are ignored
 * *   Whitespace before and after the key and value is stripped
 * *   Only the first = is observed
 * *   Lines starting with # are ignored
 *
 * @private
 * @param[in] dictionarySerialNumber the serial number of the dictionary to load into
 * @param[in] file path to the file to load the data from
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDictionary_loadDictionary(int dictionarySerialNumber,
  const char *file);

/**
 * Adds a new dictionary that exports runtime statistics from the system
 *
 * @private
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDictionary_enableStatsDictionary(void);

/**
 * @ref PhidgetDictionary_create() creates an instance of a Phidget channel. Once created the
 * channel may need to be configured to match the physical device and channel index you want to
 * attach to, and then be opened by calling @ref Phidget_open().
 * The Phidget channel handle must be released with @ref PhidgetDictionary_delete().
 *
 * @param[out] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDictionary_create(PhidgetDictionaryHandle *ch);

/**
 * @ref PhidgetDictionary_delete() releases a Phidget channel handle created with @ref
 * PhidgetDictionary_create().
 * If the channel is open when @ref PhidgetDictionary_delete() is called, it will be closed.
 *
 * @param[out] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDictionary_delete(PhidgetDictionaryHandle *ch);

/**
 * Adds a new key value pair to the dictionary. It is an error if the key already exits.
 *
 * @param[in] ch The channel handle
 * @param[in] key The key to add
 * @param[in] value The value to add
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDictionary_add(PhidgetDictionaryHandle ch, const char *key,
  const char *value);

/**
 * Removes every key from the dictionary
 *
 * @param[in] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDictionary_removeAll(PhidgetDictionaryHandle ch);

/**
 * Gets the value associated with the given key from the dictionary
 *
 * @param[in] ch The channel handle
 * @param[in] key The key whose value is desired
 * @param[out] value The buffer to store the value in
 * @param[in] valueLen The length of the value buffer
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDictionary_get(PhidgetDictionaryHandle ch, const char *key,
  char *value, size_t valueLen);

/**
 * Removes the key from the dictionary
 *
 * @param[in] ch The channel handle
 * @param[in] key The key to remove
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDictionary_remove(PhidgetDictionaryHandle ch,
  const char *key);

/**
 * Scans the keys in the dictionary, indexed by `start` or the first key in the dictionary if start
 * is `NULL` or an empty String.
 *
 * *   The result is formated as a newline seperated list of keys
 * *   The list begins at the key following the start key
 * *   The list might not contain all of the keys in the dictionary
 * *   To continue scanning, call the method again with the last entry from the previous result
 * *   When all of the keys have been scanned, a zero length string is returned
 * *   Keys added during the scan may be missed, and keys deleted during the scan may be
 *     included
 *
 * @param[in] ch The channel handle
 * @param[in] start The key to start the scan from (or the first key if null)
 * @param[out] keyList The buffer to store the key list in
 * @param[in] keyListLen The length of the result buffer
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDictionary_scan(PhidgetDictionaryHandle ch,
  const char *start, char *keyList, size_t keyListLen);

/**
 * Sets the value of a key, or creates the key value pair if the key does not already exist.
 *
 * @param[in] ch The channel handle
 * @param[in] key The key to set
 * @param[in] value The value to set
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDictionary_set(PhidgetDictionaryHandle ch, const char *key,
  const char *value);

/**
 * Updates a key value pair in the dictionary. It is an error if the key does not exist.
 *
 * @param[in] ch The channel handle
 * @param[in] key The key to update
 * @param[in] value The value to set
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDictionary_update(PhidgetDictionaryHandle ch,
  const char *key, const char *value);

/**
 * @brief Callback function type for PhidgetDictionary_setOnAddHandler().
 *
 * @param[in] ch The channel handle
 * @param[in] ctx Pointer to the user context
 * @param[in] key The key that was added
 * @param[in] value The value of the new key
 */
typedef void (CCONV *PhidgetDictionary_OnAddCallback)(PhidgetDictionaryHandle ch, void *ctx,
  const char *key, const char *value);

/**
 * Occurs when a new key value pair is added to the dictionary.
 *
 * @param[in] ch The channel handle
 * @param[in] fptr The event handler callback function
 * @param[in] ctx User supplied context pointer
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDictionary_setOnAddHandler(PhidgetDictionaryHandle ch,
  PhidgetDictionary_OnAddCallback fptr, void *ctx);

/**
 * @brief Callback function type for PhidgetDictionary_setOnRemoveHandler().
 *
 * @param[in] ch The channel handle
 * @param[in] ctx Pointer to the user context
 * @param[in] key The key that was removed
 */
typedef void (CCONV *PhidgetDictionary_OnRemoveCallback)(PhidgetDictionaryHandle ch, void *ctx,
  const char *key);

/**
 * Occurs when a key is removed from the dictionary.
 *
 * @param[in] ch The channel handle
 * @param[in] fptr The event handler callback function
 * @param[in] ctx User supplied context pointer
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDictionary_setOnRemoveHandler(PhidgetDictionaryHandle ch,
  PhidgetDictionary_OnRemoveCallback fptr, void *ctx);

/**
 * @brief Callback function type for PhidgetDictionary_setOnUpdateHandler().
 *
 * @param[in] ch The channel handle
 * @param[in] ctx Pointer to the user context
 * @param[in] key The key whose value was updated
 * @param[in] value The new value
 */
typedef void (CCONV *PhidgetDictionary_OnUpdateCallback)(PhidgetDictionaryHandle ch, void *ctx,
  const char *key, const char *value);

/**
 * Occurs when a change is made to a key value pair in the dictionary.
 *
 * @param[in] ch The channel handle
 * @param[in] fptr The event handler callback function
 * @param[in] ctx User supplied context pointer
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDictionary_setOnUpdateHandler(PhidgetDictionaryHandle ch,
  PhidgetDictionary_OnUpdateCallback fptr, void *ctx);

/** @} */ /* PhidgetDictionary */

/**
 * @defgroup PhidgetDigitalInput DigitalInput
 * @brief The Digital Input class is used to monitor the state of Phidget digital inputs. Use
 *     digital inputs to monitor the state of buttons, switches, or switch-to-ground sensors.
 * @{
 */

/**
 * The Digital Input class is used to monitor the state of Phidget digital inputs. Use digital
 * inputs to monitor the state of buttons, switches, or switch-to-ground sensors.
 */
typedef struct _PhidgetDigitalInput *PhidgetDigitalInputHandle;

/**
 * @ref PhidgetDigitalInput_create() creates an instance of a Phidget channel. Once created the
 * channel may need to be configured to match the physical device and channel index you want to
 * attach to, and then be opened by calling @ref Phidget_open().
 * The Phidget channel handle must be released with @ref PhidgetDigitalInput_delete().
 *
 * @param[out] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDigitalInput_create(PhidgetDigitalInputHandle *ch);

/**
 * @ref PhidgetDigitalInput_delete() releases a Phidget channel handle created with @ref
 * PhidgetDigitalInput_create().
 * If the channel is open when @ref PhidgetDigitalInput_delete() is called, it will be closed.
 *
 * @param[out] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDigitalInput_delete(PhidgetDigitalInputHandle *ch);

/**
 * @brief The voltage value
 *
 * The voltage used to communicate with and power the external device.
 *
 * @param[in] ch The channel handle
 * @param[in] dataAdapterVoltage The voltage value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDigitalInput_setDataAdapterVoltage(PhidgetDigitalInputHandle ch,
  Phidget_DataAdapterVoltage dataAdapterVoltage);

/**
 * @brief The voltage value
 *
 * The voltage used to communicate with and power the external device.
 *
 * @param[in] ch The channel handle
 * @param[out] dataAdapterVoltage The voltage value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDigitalInput_getDataAdapterVoltage(PhidgetDigitalInputHandle ch,
  Phidget_DataAdapterVoltage *dataAdapterVoltage);

/**
 * @brief The input mode value
 *
 * The input polarity mode for your channel.
 *
 * *   See your device's User Guide for more information about what value to chooose for the
 *     `InputMode`
 *
 * @param[in] ch The channel handle
 * @param[in] inputMode The input mode value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDigitalInput_setInputMode(PhidgetDigitalInputHandle ch,
  Phidget_InputMode inputMode);

/**
 * @brief The input mode value
 *
 * The input polarity mode for your channel.
 *
 * *   See your device's User Guide for more information about what value to chooose for the
 *     `InputMode`
 *
 * @param[in] ch The channel handle
 * @param[out] inputMode The input mode value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDigitalInput_getInputMode(PhidgetDigitalInputHandle ch,
  Phidget_InputMode *inputMode);

/**
 * @brief The power supply value
 *
 * Choose the power supply voltage.
 *
 * *   Set this to the voltage specified in the attached sensor's data sheet to power it.
 * *   Set to @ref POWER_SUPPLY_OFF to turn off the supply to save power.
 *
 * @param[in] ch The channel handle
 * @param[in] powerSupply The power supply value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDigitalInput_setPowerSupply(PhidgetDigitalInputHandle ch,
  Phidget_PowerSupply powerSupply);

/**
 * @brief The power supply value
 *
 * Choose the power supply voltage.
 *
 * *   Set this to the voltage specified in the attached sensor's data sheet to power it.
 * *   Set to @ref POWER_SUPPLY_OFF to turn off the supply to save power.
 *
 * @param[in] ch The channel handle
 * @param[out] powerSupply The power supply value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDigitalInput_getPowerSupply(PhidgetDigitalInputHandle ch,
  Phidget_PowerSupply *powerSupply);

/**
 * @brief The state value
 *
 * The most recent state value that the channel has reported.
 *
 * @param[in] ch The channel handle
 * @param[out] state The state value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDigitalInput_getState(PhidgetDigitalInputHandle ch,
  int *state);

/**
 * @brief Callback function type for PhidgetDigitalInput_setOnStateChangeHandler().
 *
 * @param[in] ch The channel handle
 * @param[in] ctx Pointer to the user context
 * @param[in] state The state value
 */
typedef void (CCONV *PhidgetDigitalInput_OnStateChangeCallback)(PhidgetDigitalInputHandle ch, void *ctx,
  int state);

/**
 * This event will occur when the state of the digital input has changed.
 *
 * *   The value will either be 0 or 1 (true or false).
 *
 * @param[in] ch The channel handle
 * @param[in] fptr The event handler callback function
 * @param[in] ctx User supplied context pointer
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDigitalInput_setOnStateChangeHandler(PhidgetDigitalInputHandle ch,
  PhidgetDigitalInput_OnStateChangeCallback fptr, void *ctx);

/** @} */ /* PhidgetDigitalInput */

/**
 * @defgroup PhidgetDigitalOutput DigitalOutput
 * @brief The Digital Output class is used to control digital logic outputs and LED outputs on
 *     Phidgets boards.
 * @{
 */

/**
 * The Digital Output class is used to control digital logic outputs and LED outputs on Phidgets
 * boards.
 */
typedef struct _PhidgetDigitalOutput *PhidgetDigitalOutputHandle;

/**
 * @ref PhidgetDigitalOutput_create() creates an instance of a Phidget channel. Once created the
 * channel may need to be configured to match the physical device and channel index you want to
 * attach to, and then be opened by calling @ref Phidget_open().
 * The Phidget channel handle must be released with @ref PhidgetDigitalOutput_delete().
 *
 * @param[out] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDigitalOutput_create(PhidgetDigitalOutputHandle *ch);

/**
 * @ref PhidgetDigitalOutput_delete() releases a Phidget channel handle created with @ref
 * PhidgetDigitalOutput_create().
 * If the channel is open when @ref PhidgetDigitalOutput_delete() is called, it will be closed.
 *
 * @param[out] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDigitalOutput_delete(PhidgetDigitalOutputHandle *ch);

/**
 * Enables the **failsafe** feature for the channel, with the specified **failsafe time**.
 *
 * Enabling the failsafe feature starts a recurring **failsafe timer** for the channel. Once the
 * failsafe is enabled, the timer must be reset within the specified time or the channel will enter
 * a **failsafe state**. For Digital Output channels, this will set the output State to FALSE. The
 * failsafe timer can be reset by using any of the following API calls:
 *
 * *   @ref PhidgetDigitalOutput_setDutyCycle()
 * *   @ref PhidgetDigitalOutput_setState()
 * *   @ref PhidgetDigitalOutput_setFrequency()
 * *   @ref PhidgetDigitalOutput_resetFailsafe()
 *
 * For more information about failsafe, visit our [Failsafe
 * Guide](https://www.phidgets.com/docs/Failsafe_Guide).
 *
 * @param[in] ch The channel handle
 * @param[in] failsafeTime Failsafe timeout in milliseconds
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDigitalOutput_enableFailsafe(PhidgetDigitalOutputHandle ch,
  uint32_t failsafeTime);

/**
 * Resets the failsafe timer, if one has been set. See @ref PhidgetDigitalOutput_enableFailsafe()
 * for details.
 *
 * This function will fail if no failsafe timer has been set for the channel.
 *
 * @param[in] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDigitalOutput_resetFailsafe(PhidgetDigitalOutputHandle ch);

/**
 * @brief The voltage value
 *
 * The voltage used to communicate with and power the external device.
 *
 * @param[in] ch The channel handle
 * @param[in] dataAdapterVoltage The voltage value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDigitalOutput_setDataAdapterVoltage(PhidgetDigitalOutputHandle ch,
  Phidget_DataAdapterVoltage dataAdapterVoltage);

/**
 * @brief The voltage value
 *
 * The voltage used to communicate with and power the external device.
 *
 * @param[in] ch The channel handle
 * @param[out] dataAdapterVoltage The voltage value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDigitalOutput_getDataAdapterVoltage(PhidgetDigitalOutputHandle ch,
  Phidget_DataAdapterVoltage *dataAdapterVoltage);

/**
 * @brief The duty cycle value
 *
 * The `DutyCycle` represents the fraction of time the output is on (high).
 *
 * *   A `DutyCycle` of 1.0 translates to a high output, a `DutyCycle` of 0 translates to a low
 *     output.
 * *   A `DutyCycle` of 0.5 translates to an output that is high half the time, which results in
 *     an average output voltage of (output voltage x 0.5)
 * *   You can use the `DutyCycle` to create a dimming effect on LEDs.
 *
 * @param[in] ch The channel handle
 * @param[in] dutyCycle The duty cycle value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDigitalOutput_setDutyCycle(PhidgetDigitalOutputHandle ch,
  double dutyCycle);

/**
 * @brief The duty cycle value
 *
 * The `DutyCycle` represents the fraction of time the output is on (high).
 *
 * *   A `DutyCycle` of 1.0 translates to a high output, a `DutyCycle` of 0 translates to a low
 *     output.
 * *   A `DutyCycle` of 0.5 translates to an output that is high half the time, which results in
 *     an average output voltage of (output voltage x 0.5)
 * *   You can use the `DutyCycle` to create a dimming effect on LEDs.
 *
 * @param[in] ch The channel handle
 * @param[in] dutyCycle The duty cycle value
 * @param[in] fptr Asynchronous completion callback
 * @param[in] ctx User supplied context pointer
 */
PHIDGET22_API void CCONV PhidgetDigitalOutput_setDutyCycle_async(PhidgetDigitalOutputHandle ch,
  double dutyCycle, Phidget_AsyncCallback fptr, void *ctx);

/**
 * @brief The duty cycle value
 *
 * The `DutyCycle` represents the fraction of time the output is on (high).
 *
 * *   A `DutyCycle` of 1.0 translates to a high output, a `DutyCycle` of 0 translates to a low
 *     output.
 * *   A `DutyCycle` of 0.5 translates to an output that is high half the time, which results in
 *     an average output voltage of (output voltage x 0.5)
 * *   You can use the `DutyCycle` to create a dimming effect on LEDs.
 *
 * @param[in] ch The channel handle
 * @param[out] dutyCycle The duty cycle value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDigitalOutput_getDutyCycle(PhidgetDigitalOutputHandle ch,
  double *dutyCycle);

/**
 * @brief The duty cycle value
 *
 * The minimum value that `DutyCycle` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minDutyCycle The duty cycle value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDigitalOutput_getMinDutyCycle(PhidgetDigitalOutputHandle ch,
  double *minDutyCycle);

/**
 * @brief The duty cycle value
 *
 * The maximum value that `DutyCycle` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxDutyCycle The duty cycle value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDigitalOutput_getMaxDutyCycle(PhidgetDigitalOutputHandle ch,
  double *maxDutyCycle);

/**
 * @brief The failsafe time
 *
 * The minimum value that `failsafeTime` can be set to when calling @ref
 * PhidgetDigitalOutput_enableFailsafe().
 *
 * @param[in] ch The channel handle
 * @param[out] minFailsafeTime The failsafe time
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDigitalOutput_getMinFailsafeTime(PhidgetDigitalOutputHandle ch,
  uint32_t *minFailsafeTime);

/**
 * @brief The failsafe time
 *
 * The maximum value that `failsafeTime` can be set to when calling @ref
 * PhidgetDigitalOutput_enableFailsafe().
 *
 * @param[in] ch The channel handle
 * @param[out] maxFailsafeTime The failsafe time
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDigitalOutput_getMaxFailsafeTime(PhidgetDigitalOutputHandle ch,
  uint32_t *maxFailsafeTime);

/**
 * @brief The PWM frequency
 *
 * The `Frequency` parameter sets the PWM frequency for all frequency-settable PWM outputs on the
 * board.
 *
 * @param[in] ch The channel handle
 * @param[in] frequency The PWM frequency
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDigitalOutput_setFrequency(PhidgetDigitalOutputHandle ch,
  double frequency);

/**
 * @brief The PWM frequency
 *
 * The `Frequency` parameter sets the PWM frequency for all frequency-settable PWM outputs on the
 * board.
 *
 * @param[in] ch The channel handle
 * @param[in] frequency The PWM frequency
 * @param[in] fptr Asynchronous completion callback
 * @param[in] ctx User supplied context pointer
 */
PHIDGET22_API void CCONV PhidgetDigitalOutput_setFrequency_async(PhidgetDigitalOutputHandle ch,
  double frequency, Phidget_AsyncCallback fptr, void *ctx);

/**
 * @brief The PWM frequency
 *
 * The `Frequency` parameter sets the PWM frequency for all frequency-settable PWM outputs on the
 * board.
 *
 * @param[in] ch The channel handle
 * @param[out] frequency The PWM frequency
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDigitalOutput_getFrequency(PhidgetDigitalOutputHandle ch,
  double *frequency);

/**
 * @brief The frequency
 *
 * The minimum value that `Frequency` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minFrequency The frequency
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDigitalOutput_getMinFrequency(PhidgetDigitalOutputHandle ch,
  double *minFrequency);

/**
 * @brief The frequency
 *
 * The maximum value that `Frequency` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxFrequency The frequency
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDigitalOutput_getMaxFrequency(PhidgetDigitalOutputHandle ch,
  double *maxFrequency);

/**
 * @brief The current limit value
 *
 * The `LEDCurrentLimit` is the maximum amount of current that the controller will provide to the
 * output.
 *
 * *   Reference the data sheet of the LED you are using before setting this value.
 *
 * @param[in] ch The channel handle
 * @param[in] LEDCurrentLimit The current limit value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDigitalOutput_setLEDCurrentLimit(PhidgetDigitalOutputHandle ch,
  double LEDCurrentLimit);

/**
 * @brief The current limit value
 *
 * The `LEDCurrentLimit` is the maximum amount of current that the controller will provide to the
 * output.
 *
 * *   Reference the data sheet of the LED you are using before setting this value.
 *
 * @param[in] ch The channel handle
 * @param[in] LEDCurrentLimit The current limit value
 * @param[in] fptr Asynchronous completion callback
 * @param[in] ctx User supplied context pointer
 */
PHIDGET22_API void CCONV PhidgetDigitalOutput_setLEDCurrentLimit_async(PhidgetDigitalOutputHandle ch,
  double LEDCurrentLimit, Phidget_AsyncCallback fptr, void *ctx);

/**
 * @brief The current limit value
 *
 * The `LEDCurrentLimit` is the maximum amount of current that the controller will provide to the
 * output.
 *
 * *   Reference the data sheet of the LED you are using before setting this value.
 *
 * @param[in] ch The channel handle
 * @param[out] LEDCurrentLimit The current limit value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDigitalOutput_getLEDCurrentLimit(PhidgetDigitalOutputHandle ch,
  double *LEDCurrentLimit);

/**
 * @brief The current limit value
 *
 * The minimum value that `LEDCurrentLimit` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minLEDCurrentLimit The current limit value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDigitalOutput_getMinLEDCurrentLimit(PhidgetDigitalOutputHandle ch,
  double *minLEDCurrentLimit);

/**
 * @brief The current limit value
 *
 * The maximum value that `LEDCurrentLimit` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxLEDCurrentLimit The current limit value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDigitalOutput_getMaxLEDCurrentLimit(PhidgetDigitalOutputHandle ch,
  double *maxLEDCurrentLimit);

/**
 * @brief The forward voltage value
 *
 * The `LEDForwardVoltage` is the voltage that will be available to your LED.
 *
 * *   Reference the data sheet of the LED you are using before setting this value. Choose the
 *     `LEDForwardVoltage` that is closest to the forward voltage specified in the data sheet.
 * *   This forward voltage is shared for all channels on this device. Setting the
 *     LEDForwardVoltage on any channel will set the LEDForwardVoltage for all channels on the
 *     device.
 *
 * @param[in] ch The channel handle
 * @param[in] LEDForwardVoltage The forward voltage value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDigitalOutput_setLEDForwardVoltage(PhidgetDigitalOutputHandle ch,
  PhidgetDigitalOutput_LEDForwardVoltage LEDForwardVoltage);

/**
 * @brief The forward voltage value
 *
 * The `LEDForwardVoltage` is the voltage that will be available to your LED.
 *
 * *   Reference the data sheet of the LED you are using before setting this value. Choose the
 *     `LEDForwardVoltage` that is closest to the forward voltage specified in the data sheet.
 * *   This forward voltage is shared for all channels on this device. Setting the
 *     LEDForwardVoltage on any channel will set the LEDForwardVoltage for all channels on the
 *     device.
 *
 * @param[in] ch The channel handle
 * @param[out] LEDForwardVoltage The forward voltage value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDigitalOutput_getLEDForwardVoltage(PhidgetDigitalOutputHandle ch,
  PhidgetDigitalOutput_LEDForwardVoltage *LEDForwardVoltage);

/**
 * @brief The state value
 *
 * The `State` will indicate whether the output is high (TRUE) or low (FALSE).
 *
 * *   If a `DutyCycle` has been set, the state will return as TRUE if the DutyCycle is above
 *     0.5, or FALSE otherwise.
 *
 * @param[in] ch The channel handle
 * @param[in] state The state value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDigitalOutput_setState(PhidgetDigitalOutputHandle ch,
  int state);

/**
 * @brief The state value
 *
 * The `State` will indicate whether the output is high (TRUE) or low (FALSE).
 *
 * *   If a `DutyCycle` has been set, the state will return as TRUE if the DutyCycle is above
 *     0.5, or FALSE otherwise.
 *
 * @param[in] ch The channel handle
 * @param[in] state The state value
 * @param[in] fptr Asynchronous completion callback
 * @param[in] ctx User supplied context pointer
 */
PHIDGET22_API void CCONV PhidgetDigitalOutput_setState_async(PhidgetDigitalOutputHandle ch, int state,
  Phidget_AsyncCallback fptr, void *ctx);

/**
 * @brief The state value
 *
 * The `State` will indicate whether the output is high (TRUE) or low (FALSE).
 *
 * *   If a `DutyCycle` has been set, the state will return as TRUE if the DutyCycle is above
 *     0.5, or FALSE otherwise.
 *
 * @param[in] ch The channel handle
 * @param[out] state The state value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDigitalOutput_getState(PhidgetDigitalOutputHandle ch,
  int *state);

/** @} */ /* PhidgetDigitalOutput */

/**
 * @defgroup PhidgetDistanceSensor DistanceSensor
 * @brief The Distance Sensor class gathers data from the distance sensor on a Phidget board.
 * @{
 */

/**
 * The Distance Sensor class gathers data from the distance sensor on a Phidget board.
 *
 * If you're using a simple 0-5V sensor that does not have its own firmware, use the VoltageInput or
 * VoltageRatioInput class instead, as specified for your device.
 */
typedef struct _PhidgetDistanceSensor *PhidgetDistanceSensorHandle;

/**
 * @ref PhidgetDistanceSensor_create() creates an instance of a Phidget channel. Once created the
 * channel may need to be configured to match the physical device and channel index you want to
 * attach to, and then be opened by calling @ref Phidget_open().
 * The Phidget channel handle must be released with @ref PhidgetDistanceSensor_delete().
 *
 * @param[out] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDistanceSensor_create(PhidgetDistanceSensorHandle *ch);

/**
 * @ref PhidgetDistanceSensor_delete() releases a Phidget channel handle created with @ref
 * PhidgetDistanceSensor_create().
 * If the channel is open when @ref PhidgetDistanceSensor_delete() is called, it will be closed.
 *
 * @param[out] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDistanceSensor_delete(PhidgetDistanceSensorHandle *ch);

/**
 * The most recent reflection values that the channel has reported.
 *
 * *   The distance values will always be between @ref PhidgetDistanceSensor_getMinDistance()
 *     and @ref PhidgetDistanceSensor_getMaxDistance().
 * *   The closest reflection will be placed at index 0 of the distances array, and the furthest
 *     reflection at index 7
 * *   The amplitude values are relative amplitudes of the reflections that are normalized to an
 *     arbitrary scale.
 *
 * @param[in] ch The channel handle
 * @param[out] distances The reflection values
 * @param[out] amplitudes The amplitude values
 * @param[out] count The number of reflections
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDistanceSensor_getSonarReflections(PhidgetDistanceSensorHandle ch,
  uint32_t (*distances)[8], uint32_t (*amplitudes)[8], uint32_t *count);

/**
 * @brief The data interval value
 *
 * The `DataInterval` is the time that must elapse before the channel will fire another event.
 *
 * *   The data interval is bounded by @ref PhidgetDistanceSensor_getMinDataInterval() and @ref
 *     PhidgetDistanceSensor_getMaxDataInterval().
 * *   The timing between events can also be affected by the `DistanceChangeTrigger`.
 *
 * @param[in] ch The channel handle
 * @param[in] dataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDistanceSensor_setDataInterval(PhidgetDistanceSensorHandle ch,
  uint32_t dataInterval);

/**
 * @brief The data interval value
 *
 * The `DataInterval` is the time that must elapse before the channel will fire another event.
 *
 * *   The data interval is bounded by @ref PhidgetDistanceSensor_getMinDataInterval() and @ref
 *     PhidgetDistanceSensor_getMaxDataInterval().
 * *   The timing between events can also be affected by the `DistanceChangeTrigger`.
 *
 * @param[in] ch The channel handle
 * @param[out] dataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDistanceSensor_getDataInterval(PhidgetDistanceSensorHandle ch,
  uint32_t *dataInterval);

/**
 * @brief The data interval value
 *
 * The minimum value that `DataInterval` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minDataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDistanceSensor_getMinDataInterval(PhidgetDistanceSensorHandle ch,
  uint32_t *minDataInterval);

/**
 * @brief The data interval value
 *
 * The maximum value that `DataInterval` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxDataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDistanceSensor_getMaxDataInterval(PhidgetDistanceSensorHandle ch,
  uint32_t *maxDataInterval);

/**
 * @brief The data rate for the channel
 *
 * The `DataRate` is the frequency of events from the device.
 *
 * *   The data rate is bounded by @ref PhidgetDistanceSensor_getMinDataRate() and @ref
 *     PhidgetDistanceSensor_getMaxDataRate().
 * *   Changing `DataRate` will change the channel's `DataInterval` to a corresponding value,
 *     rounded to the nearest integer number of milliseconds.
 * *   The timing between events can also affected by the change trigger.
 *
 * @param[in] ch The channel handle
 * @param[in] dataRate The data rate for the channel
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDistanceSensor_setDataRate(PhidgetDistanceSensorHandle ch,
  double dataRate);

/**
 * @brief The data rate for the channel
 *
 * The `DataRate` is the frequency of events from the device.
 *
 * *   The data rate is bounded by @ref PhidgetDistanceSensor_getMinDataRate() and @ref
 *     PhidgetDistanceSensor_getMaxDataRate().
 * *   Changing `DataRate` will change the channel's `DataInterval` to a corresponding value,
 *     rounded to the nearest integer number of milliseconds.
 * *   The timing between events can also affected by the change trigger.
 *
 * @param[in] ch The channel handle
 * @param[out] dataRate The data rate for the channel
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDistanceSensor_getDataRate(PhidgetDistanceSensorHandle ch,
  double *dataRate);

/**
 * @brief The data rate value
 *
 * The minimum value that `DataRate` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minDataRate The data rate value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDistanceSensor_getMinDataRate(PhidgetDistanceSensorHandle ch,
  double *minDataRate);

/**
 * @brief The data rate value
 *
 * The maximum value that `DataRate` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxDataRate The data rate value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDistanceSensor_getMaxDataRate(PhidgetDistanceSensorHandle ch,
  double *maxDataRate);

/**
 * @brief The distance value
 *
 * The most recent distance value that the channel has reported.
 *
 * *   This value will always be between @ref PhidgetDistanceSensor_getMinDistance() and @ref
 *     PhidgetDistanceSensor_getMaxDistance().
 *
 * @param[in] ch The channel handle
 * @param[out] distance The distance value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDistanceSensor_getDistance(PhidgetDistanceSensorHandle ch,
  uint32_t *distance);

/**
 * @brief The distance value
 *
 * The minimum distance that a event will report.
 *
 * @param[in] ch The channel handle
 * @param[out] minDistance The distance value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDistanceSensor_getMinDistance(PhidgetDistanceSensorHandle ch,
  uint32_t *minDistance);

/**
 * @brief The distance value
 *
 * The maximum distance that a event will report.
 *
 * @param[in] ch The channel handle
 * @param[out] maxDistance The distance value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDistanceSensor_getMaxDistance(PhidgetDistanceSensorHandle ch,
  uint32_t *maxDistance);

/**
 * @brief The change trigger value
 *
 * The channel will not issue an event until the distance value has changed by the amount specified
 * by the `DistanceChangeTrigger`.
 *
 * *   Setting the `DistanceChangeTrigger` to 0 will result in the channel firing events every
 *     `DataInterval`. This is useful for applications that implement their own data filtering,
 *
 * @param[in] ch The channel handle
 * @param[in] distanceChangeTrigger The change trigger value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDistanceSensor_setDistanceChangeTrigger(PhidgetDistanceSensorHandle ch,
  uint32_t distanceChangeTrigger);

/**
 * @brief The change trigger value
 *
 * The channel will not issue an event until the distance value has changed by the amount specified
 * by the `DistanceChangeTrigger`.
 *
 * *   Setting the `DistanceChangeTrigger` to 0 will result in the channel firing events every
 *     `DataInterval`. This is useful for applications that implement their own data filtering,
 *
 * @param[in] ch The channel handle
 * @param[out] distanceChangeTrigger The change trigger value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDistanceSensor_getDistanceChangeTrigger(PhidgetDistanceSensorHandle ch,
  uint32_t *distanceChangeTrigger);

/**
 * @brief The change trigger value
 *
 * The minimum value that `DistanceChangeTrigger` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minDistanceChangeTrigger The change trigger value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDistanceSensor_getMinDistanceChangeTrigger(PhidgetDistanceSensorHandle ch,
  uint32_t *minDistanceChangeTrigger);

/**
 * @brief The change trigger value
 *
 * The maximum value that `DistanceChangeTrigger` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxDistanceChangeTrigger The change trigger value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDistanceSensor_getMaxDistanceChangeTrigger(PhidgetDistanceSensorHandle ch,
  uint32_t *maxDistanceChangeTrigger);

/**
 * @brief The quiet mode value
 *
 * When set to true, the device will operate more quietly.
 *
 * *   The measurable range is reduced when operating in quiet mode.
 *
 * @param[in] ch The channel handle
 * @param[in] sonarQuietMode The quiet mode value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDistanceSensor_setSonarQuietMode(PhidgetDistanceSensorHandle ch,
  int sonarQuietMode);

/**
 * @brief The quiet mode value
 *
 * When set to true, the device will operate more quietly.
 *
 * *   The measurable range is reduced when operating in quiet mode.
 *
 * @param[in] ch The channel handle
 * @param[out] sonarQuietMode The quiet mode value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDistanceSensor_getSonarQuietMode(PhidgetDistanceSensorHandle ch,
  int *sonarQuietMode);

/**
 * @brief Callback function type for PhidgetDistanceSensor_setOnDistanceChangeHandler().
 *
 * @param[in] ch The channel handle
 * @param[in] ctx Pointer to the user context
 * @param[in] distance The current distance
 */
typedef void (CCONV *PhidgetDistanceSensor_OnDistanceChangeCallback)(PhidgetDistanceSensorHandle ch,
  void *ctx, uint32_t distance);

/**
 * The most recent distance value the channel has measured will be reported in this event, which
 * occurs when the `DataInterval` has elapsed.
 *
 * *   If a `DistanceChangeTrigger` has been set to a non-zero value, the @ref
 *     PhidgetDistanceSensor_setOnDistanceChangeHandler() event will not occur until the distance
 *     has changed by at least the `DistanceChangeTrigger` value.
 *
 * @param[in] ch The channel handle
 * @param[in] fptr The event handler callback function
 * @param[in] ctx User supplied context pointer
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDistanceSensor_setOnDistanceChangeHandler(PhidgetDistanceSensorHandle ch,
  PhidgetDistanceSensor_OnDistanceChangeCallback fptr, void *ctx);

/**
 * @brief Callback function type for PhidgetDistanceSensor_setOnSonarReflectionsUpdateHandler().
 *
 * @param[in] ch The channel handle
 * @param[in] ctx Pointer to the user context
 * @param[in] distances The reflection values
 * @param[in] amplitudes The amplitude values
 * @param[in] count The number of reflections detected
 */
typedef void (CCONV *PhidgetDistanceSensor_OnSonarReflectionsUpdateCallback)(PhidgetDistanceSensorHandle ch,
  void *ctx, const uint32_t distances[8], const uint32_t amplitudes[8], uint32_t count);

/**
 * The most recent reflections the channel has detected will be reported in this event, which occurs
 * when the `DataInterval` has elapsed.
 *
 * *   If a `DistanceChangeTrigger` has been set to a non-zero value, the @ref
 *     PhidgetDistanceSensor_setOnSonarReflectionsUpdateHandler() event will not occur until the
 *     distance has changed by at least the `DistanceChangeTrigger` value.
 * *   The closest reflection will be placed at index 0 of the _distances_ array, and the
 *     furthest reflection at index 7.
 * *   If you are only interested in the closest reflection, you can simply use the @ref
 *     PhidgetDistanceSensor_setOnDistanceChangeHandler() event.
 * *   The values reported as amplitudes are relative amplitudes of the reflections that are
 *     normalized to an arbitrary scale.
 *
 * @param[in] ch The channel handle
 * @param[in] fptr The event handler callback function
 * @param[in] ctx User supplied context pointer
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDistanceSensor_setOnSonarReflectionsUpdateHandler(PhidgetDistanceSensorHandle ch,
  PhidgetDistanceSensor_OnSonarReflectionsUpdateCallback fptr, void *ctx);

/** @} */ /* PhidgetDistanceSensor */

/**
 * @defgroup PhidgetEncoder Encoder
 * @brief The Encoder class is used to read position data from quadrature encoders in order to
 *     track linear or rotary movement. If the device supports an index pin as a reference point,
 *     you can also access it through this class.
 * @{
 */

/**
 * The Encoder class is used to read position data from quadrature encoders in order to track linear
 * or rotary movement. If the device supports an index pin as a reference point, you can also access
 * it through this class.
 */
typedef struct _PhidgetEncoder *PhidgetEncoderHandle;

/**
 * @ref PhidgetEncoder_create() creates an instance of a Phidget channel. Once created the channel
 * may need to be configured to match the physical device and channel index you want to attach to,
 * and then be opened by calling @ref Phidget_open().
 * The Phidget channel handle must be released with @ref PhidgetEncoder_delete().
 *
 * @param[out] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetEncoder_create(PhidgetEncoderHandle *ch);

/**
 * @ref PhidgetEncoder_delete() releases a Phidget channel handle created with @ref
 * PhidgetEncoder_create().
 * If the channel is open when @ref PhidgetEncoder_delete() is called, it will be closed.
 *
 * @param[out] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetEncoder_delete(PhidgetEncoderHandle *ch);

/**
 * @brief The data interval value
 *
 * The `DataInterval` is the time that must elapse before the channel will fire another @ref
 * PhidgetEncoder_setOnPositionChangeHandler() event.
 *
 * *   The data interval is bounded by @ref PhidgetEncoder_getMinDataInterval() and @ref
 *     PhidgetEncoder_getMaxDataInterval().
 * *   The timing between @ref PhidgetEncoder_setOnPositionChangeHandler() events can also be
 *     affected by the `PositionChangeTrigger`.
 *
 * @param[in] ch The channel handle
 * @param[in] dataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetEncoder_setDataInterval(PhidgetEncoderHandle ch,
  uint32_t dataInterval);

/**
 * @brief The data interval value
 *
 * The `DataInterval` is the time that must elapse before the channel will fire another @ref
 * PhidgetEncoder_setOnPositionChangeHandler() event.
 *
 * *   The data interval is bounded by @ref PhidgetEncoder_getMinDataInterval() and @ref
 *     PhidgetEncoder_getMaxDataInterval().
 * *   The timing between @ref PhidgetEncoder_setOnPositionChangeHandler() events can also be
 *     affected by the `PositionChangeTrigger`.
 *
 * @param[in] ch The channel handle
 * @param[out] dataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetEncoder_getDataInterval(PhidgetEncoderHandle ch,
  uint32_t *dataInterval);

/**
 * @brief The data interval value
 *
 * The minimum value that `DataInterval` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minDataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetEncoder_getMinDataInterval(PhidgetEncoderHandle ch,
  uint32_t *minDataInterval);

/**
 * @brief The data interval value
 *
 * The maximum value that `DataInterval` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxDataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetEncoder_getMaxDataInterval(PhidgetEncoderHandle ch,
  uint32_t *maxDataInterval);

/**
 * @brief The data rate for the channel
 *
 * The `DataRate` is the frequency of events from the device.
 *
 * *   The data rate is bounded by @ref PhidgetEncoder_getMinDataRate() and @ref
 *     PhidgetEncoder_getMaxDataRate().
 * *   Changing `DataRate` will change the channel's `DataInterval` to a corresponding value,
 *     rounded to the nearest integer number of milliseconds.
 * *   The timing between events can also affected by the change trigger.
 *
 * @param[in] ch The channel handle
 * @param[in] dataRate The data rate for the channel
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetEncoder_setDataRate(PhidgetEncoderHandle ch,
  double dataRate);

/**
 * @brief The data rate for the channel
 *
 * The `DataRate` is the frequency of events from the device.
 *
 * *   The data rate is bounded by @ref PhidgetEncoder_getMinDataRate() and @ref
 *     PhidgetEncoder_getMaxDataRate().
 * *   Changing `DataRate` will change the channel's `DataInterval` to a corresponding value,
 *     rounded to the nearest integer number of milliseconds.
 * *   The timing between events can also affected by the change trigger.
 *
 * @param[in] ch The channel handle
 * @param[out] dataRate The data rate for the channel
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetEncoder_getDataRate(PhidgetEncoderHandle ch,
  double *dataRate);

/**
 * @brief The data rate value
 *
 * The minimum value that `DataRate` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minDataRate The data rate value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetEncoder_getMinDataRate(PhidgetEncoderHandle ch,
  double *minDataRate);

/**
 * @brief The data rate value
 *
 * The maximum value that `DataRate` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxDataRate The data rate value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetEncoder_getMaxDataRate(PhidgetEncoderHandle ch,
  double *maxDataRate);

/**
 * @brief The enabled value
 *
 * The enabled state of the encoder.
 *
 * @param[in] ch The channel handle
 * @param[in] enabled The enabled value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetEncoder_setEnabled(PhidgetEncoderHandle ch, int enabled);

/**
 * @brief The enabled value
 *
 * The enabled state of the encoder.
 *
 * @param[in] ch The channel handle
 * @param[out] enabled The enabled value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetEncoder_getEnabled(PhidgetEncoderHandle ch, int *enabled);

/**
 * @brief The index position value
 *
 * The most recent position of the index channel calculated by the Phidgets library.
 *
 * *   The index channel will usually pulse once per rotation.
 * *   Setting the encoder position will move the index position the same amount so their
 *     relative position stays the same.
 * *   Index position is tracked locally as the last position at which the index was triggered.
 *     Setting position will only affect the local copy of the index position value. This means that
 *     index positions seen by multiple network applications may not agree.
 *
 * @param[in] ch The channel handle
 * @param[out] indexPosition The index position value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetEncoder_getIndexPosition(PhidgetEncoderHandle ch,
  int64_t *indexPosition);

/**
 * @brief The IO mode value.
 *
 * The encoder interface mode. Match the mode to the type of encoder you have attached.
 *
 * *   It is recommended to only change this when the encoder disabled in order to avoid
 *     unexpected results.
 *
 * @param[in] ch The channel handle
 * @param[in] IOMode The IO mode value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetEncoder_setIOMode(PhidgetEncoderHandle ch,
  Phidget_EncoderIOMode IOMode);

/**
 * @brief The IO mode value.
 *
 * The encoder interface mode. Match the mode to the type of encoder you have attached.
 *
 * *   It is recommended to only change this when the encoder disabled in order to avoid
 *     unexpected results.
 *
 * @param[in] ch The channel handle
 * @param[out] IOMode The IO mode value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetEncoder_getIOMode(PhidgetEncoderHandle ch,
  Phidget_EncoderIOMode *IOMode);

/**
 * @brief The position value
 *
 * The most recent position value calculated by the Phidgets library.
 *
 * *   Position counts quadrature edges within a quadrature cycle. This means there are four
 *     counts per full quadrature cycle.
 * *   Position is tracked locally as the total position change from the time the channel is
 *     opened. Setting position will only affect the local copy of the position value. This means
 *     that positions seen by multiple network applications may not agree.
 *
 * @param[in] ch The channel handle
 * @param[in] position The position value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetEncoder_setPosition(PhidgetEncoderHandle ch,
  int64_t position);

/**
 * @brief The position value
 *
 * The most recent position value calculated by the Phidgets library.
 *
 * *   Position counts quadrature edges within a quadrature cycle. This means there are four
 *     counts per full quadrature cycle.
 * *   Position is tracked locally as the total position change from the time the channel is
 *     opened. Setting position will only affect the local copy of the position value. This means
 *     that positions seen by multiple network applications may not agree.
 *
 * @param[in] ch The channel handle
 * @param[out] position The position value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetEncoder_getPosition(PhidgetEncoderHandle ch,
  int64_t *position);

/**
 * @brief The change trigger value
 *
 * The channel will not issue a @ref PhidgetEncoder_setOnPositionChangeHandler() event until the
 * position value has changed by the amount specified by the `PositionChangeTrigger`.
 *
 * *   Setting the `PositionChangeTrigger` to 0 will result in the channel firing events every
 *     `DataInterval`. This is useful for applications that implement their own data filtering
 *
 * @param[in] ch The channel handle
 * @param[in] positionChangeTrigger The change trigger value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetEncoder_setPositionChangeTrigger(PhidgetEncoderHandle ch,
  uint32_t positionChangeTrigger);

/**
 * @brief The change trigger value
 *
 * The channel will not issue a @ref PhidgetEncoder_setOnPositionChangeHandler() event until the
 * position value has changed by the amount specified by the `PositionChangeTrigger`.
 *
 * *   Setting the `PositionChangeTrigger` to 0 will result in the channel firing events every
 *     `DataInterval`. This is useful for applications that implement their own data filtering
 *
 * @param[in] ch The channel handle
 * @param[out] positionChangeTrigger The change trigger value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetEncoder_getPositionChangeTrigger(PhidgetEncoderHandle ch,
  uint32_t *positionChangeTrigger);

/**
 * @brief The change trigger value
 *
 * The minimum value that `PositionChangeTrigger` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minPositionChangeTrigger The change trigger value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetEncoder_getMinPositionChangeTrigger(PhidgetEncoderHandle ch,
  uint32_t *minPositionChangeTrigger);

/**
 * @brief The change trigger value
 *
 * The maximum value that `PositionChangeTrigger` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxPositionChangeTrigger The change trigger value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetEncoder_getMaxPositionChangeTrigger(PhidgetEncoderHandle ch,
  uint32_t *maxPositionChangeTrigger);

/**
 * @brief Callback function type for PhidgetEncoder_setOnPositionChangeHandler().
 *
 * @param[in] ch The channel handle
 * @param[in] ctx Pointer to the user context
 * @param[in] positionChange The amount the position changed since the last change event
 * @param[in] timeChange The time elapsed since the last change event in milliseconds
 * @param[in] indexTriggered True if the index was passed since the last change event
 */
typedef void (CCONV *PhidgetEncoder_OnPositionChangeCallback)(PhidgetEncoderHandle ch, void *ctx,
  int positionChange, double timeChange, int indexTriggered);

/**
 * The most recent position change and time change the channel has measured will be reported in this
 * event, which occurs when the `DataInterval` has elapsed.
 *
 * *   If a `PositionChangeTrigger` has been set to a non-zero value, the @ref
 *     PhidgetEncoder_setOnPositionChangeHandler() event will not occur until the position has
 *     changed by at least the `PositionChangeTrigger` value.
 *
 * @param[in] ch The channel handle
 * @param[in] fptr The event handler callback function
 * @param[in] ctx User supplied context pointer
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetEncoder_setOnPositionChangeHandler(PhidgetEncoderHandle ch,
  PhidgetEncoder_OnPositionChangeCallback fptr, void *ctx);

/** @} */ /* PhidgetEncoder */

/**
 * @defgroup PhidgetFirmwareUpgrade FirmwareUpgrade
 * @private
 * @{
 */

/**
 * @private
 */
typedef struct _PhidgetFirmwareUpgrade *PhidgetFirmwareUpgradeHandle;

/**
 * @ref PhidgetFirmwareUpgrade_create() creates an instance of a Phidget channel. Once created the
 * channel may need to be configured to match the physical device and channel index you want to
 * attach to, and then be opened by calling @ref Phidget_open().
 * The Phidget channel handle must be released with @ref PhidgetFirmwareUpgrade_delete().
 *
 * @param[out] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetFirmwareUpgrade_create(PhidgetFirmwareUpgradeHandle *ch);

/**
 * @ref PhidgetFirmwareUpgrade_delete() releases a Phidget channel handle created with @ref
 * PhidgetFirmwareUpgrade_create().
 * If the channel is open when @ref PhidgetFirmwareUpgrade_delete() is called, it will be closed.
 *
 * @param[out] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetFirmwareUpgrade_delete(PhidgetFirmwareUpgradeHandle *ch);

/**
 * Sends firmware data to the device being upgraded.
 *
 * @private
 * @param[in] ch The channel handle
 * @param[in] data Data being sent in the firmware update
 * @param[in] dataLen Length of the data being sent
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetFirmwareUpgrade_sendFirmware(PhidgetFirmwareUpgradeHandle ch,
  const uint8_t *data, size_t dataLen);

/**
 * @brief Device ID
 *
 * The Device ID of the actual device being upgraded.
 *
 * @private
 * @param[in] ch The channel handle
 * @param[out] actualDeviceID Device ID
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetFirmwareUpgrade_getActualDeviceID(PhidgetFirmwareUpgradeHandle ch,
  Phidget_DeviceID *actualDeviceID);

/**
 * @brief Name of the device
 *
 * The name of the actual device being upgraded.
 *
 * @private
 * @param[in] ch The channel handle
 * @param[out] actualDeviceName Name of the device
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetFirmwareUpgrade_getActualDeviceName(PhidgetFirmwareUpgradeHandle ch,
  const char **actualDeviceName);

/**
 * @brief Device SKU
 *
 * The SKU of the actual device being upgraded.
 *
 * @private
 * @param[in] ch The channel handle
 * @param[out] actualDeviceSKU Device SKU
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetFirmwareUpgrade_getActualDeviceSKU(PhidgetFirmwareUpgradeHandle ch,
  const char **actualDeviceSKU);

/**
 * @brief Firmware version
 *
 * The firmware version of the actual device being upgraded.
 *
 * @private
 * @param[in] ch The channel handle
 * @param[out] actualDeviceVersion Firmware version
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetFirmwareUpgrade_getActualDeviceVersion(PhidgetFirmwareUpgradeHandle ch,
  int *actualDeviceVersion);

/**
 * @brief Device VINT ID
 *
 * The VINT ID of the actual device being upgraded.
 *
 * @private
 * @param[in] ch The channel handle
 * @param[out] actualDeviceVINTID Device VINT ID
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetFirmwareUpgrade_getActualDeviceVINTID(PhidgetFirmwareUpgradeHandle ch,
  uint32_t *actualDeviceVINTID);

/**
 * @brief Firmware update progress
 *
 * The progress of the firmware update, ranging from 0 to 1.
 *
 * @private
 * @param[in] ch The channel handle
 * @param[out] progress Firmware update progress
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetFirmwareUpgrade_getProgress(PhidgetFirmwareUpgradeHandle ch,
  double *progress);

/**
 * @brief Callback function type for PhidgetFirmwareUpgrade_setOnProgressChangeHandler().
 *
 * @private
 * @param[in] ch The channel handle
 * @param[in] ctx Pointer to the user context
 * @param[in] progress The progress, range is 0-1
 */
typedef void (CCONV *PhidgetFirmwareUpgrade_OnProgressChangeCallback)(PhidgetFirmwareUpgradeHandle ch,
  void *ctx, double progress);

/**
 * Occurs on firmware upgrade progress.
 *
 * @private
 * @param[in] ch The channel handle
 * @param[in] fptr The event handler callback function
 * @param[in] ctx User supplied context pointer
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetFirmwareUpgrade_setOnProgressChangeHandler(PhidgetFirmwareUpgradeHandle ch,
  PhidgetFirmwareUpgrade_OnProgressChangeCallback fptr, void *ctx);

/** @} */ /* PhidgetFirmwareUpgrade */

/**
 * @defgroup PhidgetFrequencyCounter FrequencyCounter
 * @brief The Frequency Counter class is used to measure the frequency of pulses in an
 *     electronic signal, or to count the pulses in the signal. Such signals can come from other
 *     electronics, or certain sensors that have a pulse output.
 * @{
 */

/**
 * The Frequency Counter class is used to measure the frequency of pulses in an electronic signal,
 * or to count the pulses in the signal. Such signals can come from other electronics, or certain
 * sensors that have a pulse output.
 */
typedef struct _PhidgetFrequencyCounter *PhidgetFrequencyCounterHandle;

/**
 * @ref PhidgetFrequencyCounter_create() creates an instance of a Phidget channel. Once created the
 * channel may need to be configured to match the physical device and channel index you want to
 * attach to, and then be opened by calling @ref Phidget_open().
 * The Phidget channel handle must be released with @ref PhidgetFrequencyCounter_delete().
 *
 * @param[out] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetFrequencyCounter_create(PhidgetFrequencyCounterHandle *ch);

/**
 * @ref PhidgetFrequencyCounter_delete() releases a Phidget channel handle created with @ref
 * PhidgetFrequencyCounter_create().
 * If the channel is open when @ref PhidgetFrequencyCounter_delete() is called, it will be closed.
 *
 * @param[out] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetFrequencyCounter_delete(PhidgetFrequencyCounterHandle *ch);

/**
 * Resets the @ref PhidgetFrequencyCounter_getCount() and @ref
 * PhidgetFrequencyCounter_getTimeElapsed().
 *
 * *   For best results, reset should be called when the channel is disabled.
 *
 * @param[in] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetFrequencyCounter_reset(PhidgetFrequencyCounterHandle ch);

/**
 * @brief The count value
 *
 * The most recent count value the channel has reported.
 *
 * *   The count represents the total number of pulses since the the channel was opened, or last
 *     reset.
 *
 * @param[in] ch The channel handle
 * @param[out] count The count value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetFrequencyCounter_getCount(PhidgetFrequencyCounterHandle ch,
  uint64_t *count);

/**
 * @brief The data interval value
 *
 * The `DataInterval` is the time that must elapse before the channel will fire another @ref
 * PhidgetFrequencyCounter_setOnCountChangeHandler() / @ref
 * PhidgetFrequencyCounter_setOnFrequencyChangeHandler() event.
 *
 * *   The data interval is bounded by @ref PhidgetFrequencyCounter_getMinDataInterval() and
 *     @ref PhidgetFrequencyCounter_getMaxDataInterval().
 *
 * @param[in] ch The channel handle
 * @param[in] dataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetFrequencyCounter_setDataInterval(PhidgetFrequencyCounterHandle ch,
  uint32_t dataInterval);

/**
 * @brief The data interval value
 *
 * The `DataInterval` is the time that must elapse before the channel will fire another @ref
 * PhidgetFrequencyCounter_setOnCountChangeHandler() / @ref
 * PhidgetFrequencyCounter_setOnFrequencyChangeHandler() event.
 *
 * *   The data interval is bounded by @ref PhidgetFrequencyCounter_getMinDataInterval() and
 *     @ref PhidgetFrequencyCounter_getMaxDataInterval().
 *
 * @param[in] ch The channel handle
 * @param[out] dataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetFrequencyCounter_getDataInterval(PhidgetFrequencyCounterHandle ch,
  uint32_t *dataInterval);

/**
 * @brief The data interval value
 *
 * The minimum value that `DataInterval` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minDataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetFrequencyCounter_getMinDataInterval(PhidgetFrequencyCounterHandle ch,
  uint32_t *minDataInterval);

/**
 * @brief The data interval value
 *
 * The maximum value that `DataInterval` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxDataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetFrequencyCounter_getMaxDataInterval(PhidgetFrequencyCounterHandle ch,
  uint32_t *maxDataInterval);

/**
 * @brief The data rate for the channel
 *
 * The `DataRate` is the frequency of events from the device.
 *
 * *   The data rate is bounded by @ref PhidgetFrequencyCounter_getMinDataRate() and @ref
 *     PhidgetFrequencyCounter_getMaxDataRate().
 * *   Changing `DataRate` will change the channel's `DataInterval` to a corresponding value,
 *     rounded to the nearest integer number of milliseconds.
 * *   The timing between events can also affected by the change trigger.
 *
 * @param[in] ch The channel handle
 * @param[in] dataRate The data rate for the channel
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetFrequencyCounter_setDataRate(PhidgetFrequencyCounterHandle ch,
  double dataRate);

/**
 * @brief The data rate for the channel
 *
 * The `DataRate` is the frequency of events from the device.
 *
 * *   The data rate is bounded by @ref PhidgetFrequencyCounter_getMinDataRate() and @ref
 *     PhidgetFrequencyCounter_getMaxDataRate().
 * *   Changing `DataRate` will change the channel's `DataInterval` to a corresponding value,
 *     rounded to the nearest integer number of milliseconds.
 * *   The timing between events can also affected by the change trigger.
 *
 * @param[in] ch The channel handle
 * @param[out] dataRate The data rate for the channel
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetFrequencyCounter_getDataRate(PhidgetFrequencyCounterHandle ch,
  double *dataRate);

/**
 * @brief The data rate value
 *
 * The minimum value that `DataRate` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minDataRate The data rate value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetFrequencyCounter_getMinDataRate(PhidgetFrequencyCounterHandle ch,
  double *minDataRate);

/**
 * @brief The data rate value
 *
 * The maximum value that `DataRate` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxDataRate The data rate value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetFrequencyCounter_getMaxDataRate(PhidgetFrequencyCounterHandle ch,
  double *maxDataRate);

/**
 * @brief The enabled value
 *
 * Enables or disables the channel.
 *
 * *   When a channel is disabled, it will not longer register counts, therefore the @ref
 *     PhidgetFrequencyCounter_getTimeElapsed() and @ref PhidgetFrequencyCounter_getCount() will not
 *     be updated until the channel is re-enabled.
 *
 * @param[in] ch The channel handle
 * @param[in] enabled The enabled value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetFrequencyCounter_setEnabled(PhidgetFrequencyCounterHandle ch,
  int enabled);

/**
 * @brief The enabled value
 *
 * Enables or disables the channel.
 *
 * *   When a channel is disabled, it will not longer register counts, therefore the @ref
 *     PhidgetFrequencyCounter_getTimeElapsed() and @ref PhidgetFrequencyCounter_getCount() will not
 *     be updated until the channel is re-enabled.
 *
 * @param[in] ch The channel handle
 * @param[out] enabled The enabled value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetFrequencyCounter_getEnabled(PhidgetFrequencyCounterHandle ch,
  int *enabled);

/**
 * @brief The filter value
 *
 * Determines the signal type that the channel responds to.
 *
 * *   The filter type is chosen based on the type of input signal. See the @ref
 *     PhidgetFrequencyCounter_FilterType entry under Enumerations for more information.
 *
 * @param[in] ch The channel handle
 * @param[in] filterType The filter value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetFrequencyCounter_setFilterType(PhidgetFrequencyCounterHandle ch,
  PhidgetFrequencyCounter_FilterType filterType);

/**
 * @brief The filter value
 *
 * Determines the signal type that the channel responds to.
 *
 * *   The filter type is chosen based on the type of input signal. See the @ref
 *     PhidgetFrequencyCounter_FilterType entry under Enumerations for more information.
 *
 * @param[in] ch The channel handle
 * @param[out] filterType The filter value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetFrequencyCounter_getFilterType(PhidgetFrequencyCounterHandle ch,
  PhidgetFrequencyCounter_FilterType *filterType);

/**
 * @brief The frequency value
 *
 * The most recent frequency value that the channel has reported.
 *
 * *   This value will always be between 0 Hz and @ref
 *     PhidgetFrequencyCounter_getMaxFrequency().
 *
 * @param[in] ch The channel handle
 * @param[out] frequency The frequency value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetFrequencyCounter_getFrequency(PhidgetFrequencyCounterHandle ch,
  double *frequency);

/**
 * @brief The frequency value
 *
 * The maximum value the @ref PhidgetFrequencyCounter_setOnFrequencyChangeHandler() event will
 * report.
 *
 * @param[in] ch The channel handle
 * @param[out] maxFrequency The frequency value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetFrequencyCounter_getMaxFrequency(PhidgetFrequencyCounterHandle ch,
  double *maxFrequency);

/**
 * @brief The frequency cutoff value
 *
 * The frequency at which zero hertz is assumed.
 *
 * *   This means any frequency at or below the `FrequencyCutoff` value will be reported as 0
 *     Hz.
 * *   This property is stored locally, so other users who have this Phidget open over a network
 *     connection won't see the effects of your selected cutoff.
 *
 * @param[in] ch The channel handle
 * @param[in] frequencyCutoff The frequency cutoff value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetFrequencyCounter_setFrequencyCutoff(PhidgetFrequencyCounterHandle ch,
  double frequencyCutoff);

/**
 * @brief The frequency cutoff value
 *
 * The frequency at which zero hertz is assumed.
 *
 * *   This means any frequency at or below the `FrequencyCutoff` value will be reported as 0
 *     Hz.
 * *   This property is stored locally, so other users who have this Phidget open over a network
 *     connection won't see the effects of your selected cutoff.
 *
 * @param[in] ch The channel handle
 * @param[out] frequencyCutoff The frequency cutoff value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetFrequencyCounter_getFrequencyCutoff(PhidgetFrequencyCounterHandle ch,
  double *frequencyCutoff);

/**
 * @brief The frequency value
 *
 * The minimum value that `FrequencyCutoff` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minFrequencyCutoff The frequency value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetFrequencyCounter_getMinFrequencyCutoff(PhidgetFrequencyCounterHandle ch,
  double *minFrequencyCutoff);

/**
 * @brief The frequency value
 *
 * The maximum value that `FrequencyCutoff` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxFrequencyCutoff The frequency value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetFrequencyCounter_getMaxFrequencyCutoff(PhidgetFrequencyCounterHandle ch,
  double *maxFrequencyCutoff);

/**
 * @brief The input mode value
 *
 * The input polarity mode for your channel.
 *
 * *   See your device's User Guide for more information about what value to chooose for the
 *     `InputMode`
 *
 * @param[in] ch The channel handle
 * @param[in] inputMode The input mode value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetFrequencyCounter_setInputMode(PhidgetFrequencyCounterHandle ch,
  Phidget_InputMode inputMode);

/**
 * @brief The input mode value
 *
 * The input polarity mode for your channel.
 *
 * *   See your device's User Guide for more information about what value to chooose for the
 *     `InputMode`
 *
 * @param[in] ch The channel handle
 * @param[out] inputMode The input mode value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetFrequencyCounter_getInputMode(PhidgetFrequencyCounterHandle ch,
  Phidget_InputMode *inputMode);

/**
 * @brief The power supply value
 *
 * Choose the power supply voltage.
 *
 * *   Set this to the voltage specified in the attached sensor's data sheet to power it.
 * *   Set to @ref POWER_SUPPLY_OFF to turn off the supply to save power.
 *
 * @param[in] ch The channel handle
 * @param[in] powerSupply The power supply value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetFrequencyCounter_setPowerSupply(PhidgetFrequencyCounterHandle ch,
  Phidget_PowerSupply powerSupply);

/**
 * @brief The power supply value
 *
 * Choose the power supply voltage.
 *
 * *   Set this to the voltage specified in the attached sensor's data sheet to power it.
 * *   Set to @ref POWER_SUPPLY_OFF to turn off the supply to save power.
 *
 * @param[in] ch The channel handle
 * @param[out] powerSupply The power supply value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetFrequencyCounter_getPowerSupply(PhidgetFrequencyCounterHandle ch,
  Phidget_PowerSupply *powerSupply);

/**
 * @brief The time value
 *
 * The amount of time the frequency counter has been enabled for.
 *
 * *   This property complements @ref PhidgetFrequencyCounter_getCount(), the total number of
 *     pulses detected since the channel was opened, or last reset.
 *
 * @param[in] ch The channel handle
 * @param[out] timeElapsed The time value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetFrequencyCounter_getTimeElapsed(PhidgetFrequencyCounterHandle ch,
  double *timeElapsed);

/**
 * @brief Callback function type for PhidgetFrequencyCounter_setOnCountChangeHandler().
 *
 * @param[in] ch The channel handle
 * @param[in] ctx Pointer to the user context
 * @param[in] counts The pulse count of the signal
 * @param[in] timeChange The change in elapsed time since the last change
 */
typedef void (CCONV *PhidgetFrequencyCounter_OnCountChangeCallback)(PhidgetFrequencyCounterHandle ch,
  void *ctx, uint64_t counts, double timeChange);

/**
 * The most recent values the channel has measured will be reported in this event, which occurs when
 * the `DataInterval` has elapsed.
 *
 * @param[in] ch The channel handle
 * @param[in] fptr The event handler callback function
 * @param[in] ctx User supplied context pointer
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetFrequencyCounter_setOnCountChangeHandler(PhidgetFrequencyCounterHandle ch,
  PhidgetFrequencyCounter_OnCountChangeCallback fptr, void *ctx);

/**
 * @brief Callback function type for PhidgetFrequencyCounter_setOnFrequencyChangeHandler().
 *
 * @param[in] ch The channel handle
 * @param[in] ctx Pointer to the user context
 * @param[in] frequency The calculated frequency of the signal
 */
typedef void (CCONV *PhidgetFrequencyCounter_OnFrequencyChangeCallback)(PhidgetFrequencyCounterHandle ch,
  void *ctx, double frequency);

/**
 * The most recent frequency value the channel has measured will be reported in this event, which
 * occurs when the `DataInterval` has elapsed.
 *
 * @param[in] ch The channel handle
 * @param[in] fptr The event handler callback function
 * @param[in] ctx User supplied context pointer
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetFrequencyCounter_setOnFrequencyChangeHandler(PhidgetFrequencyCounterHandle ch,
  PhidgetFrequencyCounter_OnFrequencyChangeCallback fptr, void *ctx);

/** @} */ /* PhidgetFrequencyCounter */

/**
 * @defgroup PhidgetGeneric Generic
 * @private
 * @{
 */

/**
 * @private
 */
typedef struct _PhidgetGeneric *PhidgetGenericHandle;

/**
 * @ref PhidgetGeneric_create() creates an instance of a Phidget channel. Once created the channel
 * may need to be configured to match the physical device and channel index you want to attach to,
 * and then be opened by calling @ref Phidget_open().
 * The Phidget channel handle must be released with @ref PhidgetGeneric_delete().
 *
 * @param[out] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetGeneric_create(PhidgetGenericHandle *ch);

/**
 * @ref PhidgetGeneric_delete() releases a Phidget channel handle created with @ref
 * PhidgetGeneric_create().
 * If the channel is open when @ref PhidgetGeneric_delete() is called, it will be closed.
 *
 * @param[out] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetGeneric_delete(PhidgetGenericHandle *ch);

/** @} */ /* PhidgetGeneric */

/**
 * @defgroup PhidgetGPS GPS
 * @brief The GPS class is used to configure and gather data from Phidgets GPS sensors, and
 *     gives you access to variables from GPS data packets.
 * @{
 */

/**
 * The GPS class is used to configure and gather data from Phidgets GPS sensors, and gives you
 * access to variables from GPS data packets.
 */
typedef struct _PhidgetGPS *PhidgetGPSHandle;

/**
 * @ref PhidgetGPS_create() creates an instance of a Phidget channel. Once created the channel may
 * need to be configured to match the physical device and channel index you want to attach to, and
 * then be opened by calling @ref Phidget_open().
 * The Phidget channel handle must be released with @ref PhidgetGPS_delete().
 *
 * @param[out] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetGPS_create(PhidgetGPSHandle *ch);

/**
 * @ref PhidgetGPS_delete() releases a Phidget channel handle created with @ref PhidgetGPS_create().
 * If the channel is open when @ref PhidgetGPS_delete() is called, it will be closed.
 *
 * @param[out] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetGPS_delete(PhidgetGPSHandle *ch);

/**
 * @brief Altitude of the GPS
 *
 * The altitude above mean sea level in meters.
 *
 * @param[in] ch The channel handle
 * @param[out] altitude Altitude of the GPS
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetGPS_getAltitude(PhidgetGPSHandle ch, double *altitude);

/**
 * @brief Date of last position
 *
 * The UTC date of the last received position.
 *
 * @param[in] ch The channel handle
 * @param[out] date Date of last position
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetGPS_getDate(PhidgetGPSHandle ch, PhidgetGPS_Date *date);

/**
 * @brief Heading of the GPS
 *
 * The current true course over ground of the GPS
 *
 * @param[in] ch The channel handle
 * @param[out] heading Heading of the GPS
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetGPS_getHeading(PhidgetGPSHandle ch, double *heading);

/**
 * @brief Latitude of the GPS
 *
 * The latitude of the GPS in degrees
 *
 * @param[in] ch The channel handle
 * @param[out] latitude Latitude of the GPS
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetGPS_getLatitude(PhidgetGPSHandle ch, double *latitude);

/**
 * @brief Longtidue of the GPS
 *
 * The longitude of the GPS.
 *
 * @param[in] ch The channel handle
 * @param[out] longitude Longtidue of the GPS
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetGPS_getLongitude(PhidgetGPSHandle ch, double *longitude);

/**
 * @brief NMEA Data structure
 *
 * The NMEA data structure.
 *
 * @param[in] ch The channel handle
 * @param[out] NMEAData NMEA Data structure
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetGPS_getNMEAData(PhidgetGPSHandle ch,
  PhidgetGPS_NMEAData *NMEAData);

/**
 * @brief Status of the position fix
 *
 * The status of the position fix
 *
 * *   True if a fix is available and latitude, longitude, and altitude can be read. False if
 *     the fix is not available.
 *
 * @param[in] ch The channel handle
 * @param[out] positionFixState Status of the position fix
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetGPS_getPositionFixState(PhidgetGPSHandle ch,
  int *positionFixState);

/**
 * @brief Current time
 *
 * The current UTC time of the GPS
 *
 * @param[in] ch The channel handle
 * @param[out] time Current time
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetGPS_getTime(PhidgetGPSHandle ch, PhidgetGPS_Time *time);

/**
 * @brief Velocity of the GPS
 *
 * The current speed over ground of the GPS.
 *
 * @param[in] ch The channel handle
 * @param[out] velocity Velocity of the GPS
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetGPS_getVelocity(PhidgetGPSHandle ch, double *velocity);

/**
 * @brief Callback function type for PhidgetGPS_setOnHeadingChangeHandler().
 *
 * @param[in] ch The channel handle
 * @param[in] ctx Pointer to the user context
 * @param[in] heading The current heading
 * @param[in] velocity The current velocity
 */
typedef void (CCONV *PhidgetGPS_OnHeadingChangeCallback)(PhidgetGPSHandle ch, void *ctx, double heading,
  double velocity);

/**
 * The most recent heading and velocity values will be reported in this event, which occurs when the
 * GPS heading changes.
 *
 * @param[in] ch The channel handle
 * @param[in] fptr The event handler callback function
 * @param[in] ctx User supplied context pointer
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetGPS_setOnHeadingChangeHandler(PhidgetGPSHandle ch,
  PhidgetGPS_OnHeadingChangeCallback fptr, void *ctx);

/**
 * @brief Callback function type for PhidgetGPS_setOnPositionChangeHandler().
 *
 * @param[in] ch The channel handle
 * @param[in] ctx Pointer to the user context
 * @param[in] latitude The current latitude
 * @param[in] longitude The current longitude
 * @param[in] altitude The current altitude
 */
typedef void (CCONV *PhidgetGPS_OnPositionChangeCallback)(PhidgetGPSHandle ch, void *ctx, double latitude,
  double longitude, double altitude);

/**
 * The most recent values the channel has measured will be reported in this event, which occurs when
 * the GPS position changes.
 *
 * @param[in] ch The channel handle
 * @param[in] fptr The event handler callback function
 * @param[in] ctx User supplied context pointer
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetGPS_setOnPositionChangeHandler(PhidgetGPSHandle ch,
  PhidgetGPS_OnPositionChangeCallback fptr, void *ctx);

/**
 * @brief Callback function type for PhidgetGPS_setOnPositionFixStateChangeHandler().
 *
 * @param[in] ch The channel handle
 * @param[in] ctx Pointer to the user context
 * @param[in] positionFixState The state of the position fix. True indicates a fix is obtained.
 *     False indicates no fix found
 */
typedef void (CCONV *PhidgetGPS_OnPositionFixStateChangeCallback)(PhidgetGPSHandle ch, void *ctx,
  int positionFixState);

/**
 * Occurs when a position fix is obtained or lost.
 *
 * @param[in] ch The channel handle
 * @param[in] fptr The event handler callback function
 * @param[in] ctx User supplied context pointer
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetGPS_setOnPositionFixStateChangeHandler(PhidgetGPSHandle ch,
  PhidgetGPS_OnPositionFixStateChangeCallback fptr, void *ctx);

/** @} */ /* PhidgetGPS */

/**
 * @defgroup PhidgetGyroscope Gyroscope
 * @brief The Gyroscope class reports rotational data from the Phidget containing a gyroscope
 *     chip for use in your code. Phidget gyroscopes usually have multiple sensors, each oriented in
 *     a different axis, so multiple dimensions of heading can be recorded.
 * @{
 */

/**
 * The Gyroscope class reports rotational data from the Phidget containing a gyroscope chip for use
 * in your code. Phidget gyroscopes usually have multiple sensors, each oriented in a different
 * axis, so multiple dimensions of heading can be recorded.
 *
 * If the Phidget you're using also has an accelerometer and a magnetometer, you may want to use the
 * Spatial classin order to get all of the data at the same time, in a single event.
 */
typedef struct _PhidgetGyroscope *PhidgetGyroscopeHandle;

/**
 * @ref PhidgetGyroscope_create() creates an instance of a Phidget channel. Once created the channel
 * may need to be configured to match the physical device and channel index you want to attach to,
 * and then be opened by calling @ref Phidget_open().
 * The Phidget channel handle must be released with @ref PhidgetGyroscope_delete().
 *
 * @param[out] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetGyroscope_create(PhidgetGyroscopeHandle *ch);

/**
 * @ref PhidgetGyroscope_delete() releases a Phidget channel handle created with @ref
 * PhidgetGyroscope_create().
 * If the channel is open when @ref PhidgetGyroscope_delete() is called, it will be closed.
 *
 * @param[out] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetGyroscope_delete(PhidgetGyroscopeHandle *ch);

/**
 * Re-zeros the gyroscope in 1-2 seconds.
 *
 * *   The device must be stationary when zeroing.
 * *   The angular rate will be reported as 0.0°/s while zeroing.
 * *   Zeroing the gyroscope is a method of compensating for the drift that is inherent to all
 *     gyroscopes. See your device's User Guide for more information on dealing with drift.
 *
 * @param[in] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetGyroscope_zero(PhidgetGyroscopeHandle ch);

/**
 * @brief The last reported angular rate
 *
 * The most recent angular rate value that the channel has reported.
 *
 * *   This value will always be between @ref PhidgetGyroscope_getMinAngularRate() and @ref
 *     PhidgetGyroscope_getMaxAngularRate().
 *
 * @param[in] ch The channel handle
 * @param[out] angularRate The last reported angular rate
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetGyroscope_getAngularRate(PhidgetGyroscopeHandle ch,
  double (*angularRate)[3]);

/**
 * @brief The angular rate values
 *
 * The minimum value the @ref PhidgetGyroscope_setOnAngularRateUpdateHandler() event will report.
 *
 * @param[in] ch The channel handle
 * @param[out] minAngularRate The angular rate values
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetGyroscope_getMinAngularRate(PhidgetGyroscopeHandle ch,
  double (*minAngularRate)[3]);

/**
 * @brief The angular rate values
 *
 * The maximum value the @ref PhidgetGyroscope_setOnAngularRateUpdateHandler() event will report.
 *
 * @param[in] ch The channel handle
 * @param[out] maxAngularRate The angular rate values
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetGyroscope_getMaxAngularRate(PhidgetGyroscopeHandle ch,
  double (*maxAngularRate)[3]);

/**
 * @brief Axis count value
 *
 * The number of axes the channel can measure angular rate on.
 *
 * *   See your device's User Guide for more information about the number of axes and their
 *     orientation.
 *
 * @param[in] ch The channel handle
 * @param[out] axisCount Axis count value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetGyroscope_getAxisCount(PhidgetGyroscopeHandle ch,
  int *axisCount);

/**
 * @brief The data interval value
 *
 * The `DataInterval` is the time that must elapse before the channel will fire another @ref
 * PhidgetGyroscope_setOnAngularRateUpdateHandler() event.
 *
 * *   The data interval is bounded by @ref PhidgetGyroscope_getMinDataInterval() and @ref
 *     PhidgetGyroscope_getMaxDataInterval().
 *
 * @param[in] ch The channel handle
 * @param[in] dataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetGyroscope_setDataInterval(PhidgetGyroscopeHandle ch,
  uint32_t dataInterval);

/**
 * @brief The data interval value
 *
 * The `DataInterval` is the time that must elapse before the channel will fire another @ref
 * PhidgetGyroscope_setOnAngularRateUpdateHandler() event.
 *
 * *   The data interval is bounded by @ref PhidgetGyroscope_getMinDataInterval() and @ref
 *     PhidgetGyroscope_getMaxDataInterval().
 *
 * @param[in] ch The channel handle
 * @param[out] dataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetGyroscope_getDataInterval(PhidgetGyroscopeHandle ch,
  uint32_t *dataInterval);

/**
 * @brief The data interval value
 *
 * The minimum value that `DataInterval` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minDataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetGyroscope_getMinDataInterval(PhidgetGyroscopeHandle ch,
  uint32_t *minDataInterval);

/**
 * @brief The data interval value
 *
 * The maximum value that `DataInterval` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxDataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetGyroscope_getMaxDataInterval(PhidgetGyroscopeHandle ch,
  uint32_t *maxDataInterval);

/**
 * @brief The data rate for the channel
 *
 * The `DataRate` is the frequency of events from the device.
 *
 * *   The data rate is bounded by @ref PhidgetGyroscope_getMinDataRate() and @ref
 *     PhidgetGyroscope_getMaxDataRate().
 * *   Changing `DataRate` will change the channel's `DataInterval` to a corresponding value,
 *     rounded to the nearest integer number of milliseconds.
 * *   The timing between events can also affected by the change trigger.
 *
 * @param[in] ch The channel handle
 * @param[in] dataRate The data rate for the channel
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetGyroscope_setDataRate(PhidgetGyroscopeHandle ch,
  double dataRate);

/**
 * @brief The data rate for the channel
 *
 * The `DataRate` is the frequency of events from the device.
 *
 * *   The data rate is bounded by @ref PhidgetGyroscope_getMinDataRate() and @ref
 *     PhidgetGyroscope_getMaxDataRate().
 * *   Changing `DataRate` will change the channel's `DataInterval` to a corresponding value,
 *     rounded to the nearest integer number of milliseconds.
 * *   The timing between events can also affected by the change trigger.
 *
 * @param[in] ch The channel handle
 * @param[out] dataRate The data rate for the channel
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetGyroscope_getDataRate(PhidgetGyroscopeHandle ch,
  double *dataRate);

/**
 * @brief The data rate value
 *
 * The minimum value that `DataRate` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minDataRate The data rate value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetGyroscope_getMinDataRate(PhidgetGyroscopeHandle ch,
  double *minDataRate);

/**
 * @brief The data rate value
 *
 * The maximum value that `DataRate` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxDataRate The data rate value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetGyroscope_getMaxDataRate(PhidgetGyroscopeHandle ch,
  double *maxDataRate);

/**
 * @brief Whether self-heating temperature stabilization is enabled
 *
 * Set to TRUE to enable the temperature stabilization feature of this device. This enables onboard
 * heating elements to bring the board up to a known temperature to minimize ambient temerature
 * effects on the sensor's reading. You can leave this setting FALSE to conserve power consumption.
 *
 * If you enable heating, it is strongly recommended to keep the board in its enclosure to keep it
 * insulated from moving air.
 *
 * This property is shared by any and all spatial-related objects on this device (Accelerometer,
 * Gyroscope, Magnetometer, Spatial)
 *
 * @param[in] ch The channel handle
 * @param[in] heatingEnabled Whether self-heating temperature stabilization is enabled
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetGyroscope_setHeatingEnabled(PhidgetGyroscopeHandle ch,
  int heatingEnabled);

/**
 * @brief Whether self-heating temperature stabilization is enabled
 *
 * Set to TRUE to enable the temperature stabilization feature of this device. This enables onboard
 * heating elements to bring the board up to a known temperature to minimize ambient temerature
 * effects on the sensor's reading. You can leave this setting FALSE to conserve power consumption.
 *
 * If you enable heating, it is strongly recommended to keep the board in its enclosure to keep it
 * insulated from moving air.
 *
 * This property is shared by any and all spatial-related objects on this device (Accelerometer,
 * Gyroscope, Magnetometer, Spatial)
 *
 * @param[in] ch The channel handle
 * @param[out] heatingEnabled Whether self-heating temperature stabilization is enabled
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetGyroscope_getHeatingEnabled(PhidgetGyroscopeHandle ch,
  int *heatingEnabled);

/**
 * @brief The sensor precision value
 *
 * Selects between high/low precision sensing chips.
 *
 * @private
 * @param[in] ch The channel handle
 * @param[in] precision The sensor precision value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetGyroscope_setPrecision(PhidgetGyroscopeHandle ch,
  Phidget_SpatialPrecision precision);

/**
 * @brief The sensor precision value
 *
 * Selects between high/low precision sensing chips.
 *
 * @private
 * @param[in] ch The channel handle
 * @param[out] precision The sensor precision value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetGyroscope_getPrecision(PhidgetGyroscopeHandle ch,
  Phidget_SpatialPrecision *precision);

/**
 * @brief The timestamp value
 *
 * The most recent timestamp value that the channel has reported. This is an extremely accurate time
 * measurement streamed from the device.
 *
 * *   If your application requires a time measurement, you should use this value over a local
 *     software timestamp.
 *
 * @param[in] ch The channel handle
 * @param[out] timestamp The timestamp value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetGyroscope_getTimestamp(PhidgetGyroscopeHandle ch,
  double *timestamp);

/**
 * @brief Callback function type for PhidgetGyroscope_setOnAngularRateUpdateHandler().
 *
 * @param[in] ch The channel handle
 * @param[in] ctx Pointer to the user context
 * @param[in] angularRate The angular rate values
 * @param[in] timestamp The timestamp value
 */
typedef void (CCONV *PhidgetGyroscope_OnAngularRateUpdateCallback)(PhidgetGyroscopeHandle ch, void *ctx,
  const double angularRate[3], double timestamp);

/**
 * The most recent angular rate and timestamp values the channel has measured will be reported in
 * this event, which occurs when the `DataInterval` has elapsed.
 *
 * @param[in] ch The channel handle
 * @param[in] fptr The event handler callback function
 * @param[in] ctx User supplied context pointer
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetGyroscope_setOnAngularRateUpdateHandler(PhidgetGyroscopeHandle ch,
  PhidgetGyroscope_OnAngularRateUpdateCallback fptr, void *ctx);

/** @} */ /* PhidgetGyroscope */

/**
 * @defgroup PhidgetHub Hub
 * @brief The hub class allows you to control power to VINT hub ports.
 * @{
 */

/**
 * The hub class allows you to control power to VINT hub ports.
 */
typedef struct _PhidgetHub *PhidgetHubHandle;

/**
 * @ref PhidgetHub_create() creates an instance of a Phidget channel. Once created the channel may
 * need to be configured to match the physical device and channel index you want to attach to, and
 * then be opened by calling @ref Phidget_open().
 * The Phidget channel handle must be released with @ref PhidgetHub_delete().
 *
 * @param[out] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetHub_create(PhidgetHubHandle *ch);

/**
 * @ref PhidgetHub_delete() releases a Phidget channel handle created with @ref PhidgetHub_create().
 * If the channel is open when @ref PhidgetHub_delete() is called, it will be closed.
 *
 * @param[out] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetHub_delete(PhidgetHubHandle *ch);

/**
 * Writes ADC calibration values to a VINT Hub. Used for manufacturing.
 *
 * @private
 * @param[in] ch The channel handle
 * @param[in] voltageInputGain Voltage input gains
 * @param[in] voltageRatioGain Voltage ratio gains
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetHub_setADCCalibrationValues(PhidgetHubHandle ch,
  const double voltageInputGain[6], const double voltageRatioGain[6]);

/**
 * Writes ADC calibration values to a VINT Hub. Used for manufacturing.
 *
 * @private
 * @param[in] ch The channel handle
 * @param[in] voltageInputOffset Voltage input offsets
 * @param[in] voltageInputOffsetLen Voltage input offsets array length
 * @param[in] voltageInputGain Voltage input gains
 * @param[in] voltageInputGainLen Voltage input gains array length
 * @param[in] voltageRatioOffset Voltage ratio offsets
 * @param[in] voltageRatioOffsetLen Voltage ratio offsets array length
 * @param[in] voltageRatioGain Voltage ratio gains
 * @param[in] voltageRatioGainLen Voltage ratio gains array length
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetHub_setADCCalibrationValues2(PhidgetHubHandle ch,
  const double *voltageInputOffset, size_t voltageInputOffsetLen, const double *voltageInputGain,
  size_t voltageInputGainLen, const double *voltageRatioOffset, size_t voltageRatioOffsetLen,
  const double *voltageRatioGain, size_t voltageRatioGainLen);

/**
 * Sets a flag on this hub port which forces the next VINT devices plugged in to stay in firmware
 * upgrade mode.
 *
 * @private
 * @param[in] ch The channel handle
 * @param[in] port The port the device is plugged into
 * @param[in] timeout The time to leave the flag set for
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetHub_setFirmwareUpgradeFlag(PhidgetHubHandle ch, int port,
  uint32_t timeout);

/**
 * Enables / disables Auto Set Speed on the hub port. When enabled, and a supported VINT device is
 * attached, the **HubPortSpeed** will automatically be set to the fastest reliable speed. This is
 * enabled by default on supported VINT Hubs.
 *
 * @param[in] ch The channel handle
 * @param[in] port The Hub port
 * @param[in] state The AutoSetSpeed state
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetHub_setPortAutoSetSpeed(PhidgetHubHandle ch, int port,
  int state);

/**
 * The max communication speed of a high-speed capable VINT Port.
 *
 * @param[in] ch The channel handle
 * @param[in] port The Hub port
 * @param[out] state The max speed
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetHub_getPortMaxSpeed(PhidgetHubHandle ch, int port,
  uint32_t *state);

/**
 * Gets the mode of the selected hub port. VINT devices will not show up when the port is in
 * digital/analog mode.
 *
 * @param[in] ch The channel handle
 * @param[in] port The port being read
 * @param[out] mode The mode the port is in
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetHub_getPortMode(PhidgetHubHandle ch, int port,
  PhidgetHub_PortMode *mode);

/**
 * Sets the mode of the selected port. This could be used to set a port back to VINT mode if it was
 * left in digital/analog mode.
 *
 * @param[in] ch The channel handle
 * @param[in] port The port being set
 * @param[in] mode The mode the port is being set to
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetHub_setPortMode(PhidgetHubHandle ch, int port,
  PhidgetHub_PortMode mode);

/**
 * Gets the VINT Hub Port power state
 *
 * @param[in] ch The channel handle
 * @param[in] port The Hub port
 * @param[out] state The power state
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetHub_getPortPower(PhidgetHubHandle ch, int port,
  int *state);

/**
 * Controls power to the VINT Hub Port.
 *
 * @param[in] ch The channel handle
 * @param[in] port The Hub port
 * @param[in] state The power state
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetHub_setPortPower(PhidgetHubHandle ch, int port, int state);

/**
 * Indicates that this VINT Port support Auto Set Speed.
 *
 * @param[in] ch The channel handle
 * @param[in] port The Hub port
 * @param[out] state The supported state
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetHub_getPortSupportsAutoSetSpeed(PhidgetHubHandle ch,
  int port, int *state);

/**
 * Indicates that the communication speed of this VINT port can be set.
 *
 * @param[in] ch The channel handle
 * @param[in] port The Hub port
 * @param[out] state The supported state
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetHub_getPortSupportsSetSpeed(PhidgetHubHandle ch, int port,
  int *state);

/** @} */ /* PhidgetHub */

/**
 * @defgroup PhidgetHumiditySensor HumiditySensor
 * @brief The Humidity Sensor class gathers relative humidity data from the Phidget and makes it
 *     available to your code.
 * @{
 */

/**
 * The Humidity Sensor class gathers relative humidity data from the Phidget and makes it available
 * to your code.
 *
 * If you're using a simple 0-5V sensor that does not have its own firmware, use the VoltageInput or
 * VoltageRatioInput class instead, as specified for your device.
 */
typedef struct _PhidgetHumiditySensor *PhidgetHumiditySensorHandle;

/**
 * @ref PhidgetHumiditySensor_create() creates an instance of a Phidget channel. Once created the
 * channel may need to be configured to match the physical device and channel index you want to
 * attach to, and then be opened by calling @ref Phidget_open().
 * The Phidget channel handle must be released with @ref PhidgetHumiditySensor_delete().
 *
 * @param[out] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetHumiditySensor_create(PhidgetHumiditySensorHandle *ch);

/**
 * @ref PhidgetHumiditySensor_delete() releases a Phidget channel handle created with @ref
 * PhidgetHumiditySensor_create().
 * If the channel is open when @ref PhidgetHumiditySensor_delete() is called, it will be closed.
 *
 * @param[out] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetHumiditySensor_delete(PhidgetHumiditySensorHandle *ch);

/**
 * @brief The data interval value
 *
 * The `DataInterval` is the time that must elapse before the channel will fire another @ref
 * PhidgetHumiditySensor_setOnHumidityChangeHandler() event.
 *
 * *   The data interval is bounded by @ref PhidgetHumiditySensor_getMinDataInterval() and @ref
 *     PhidgetHumiditySensor_getMaxDataInterval().
 * *   The timing between @ref PhidgetHumiditySensor_setOnHumidityChangeHandler() events can
 *     also be affected by the `HumidityChangeTrigger`.
 *
 * @param[in] ch The channel handle
 * @param[in] dataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetHumiditySensor_setDataInterval(PhidgetHumiditySensorHandle ch,
  uint32_t dataInterval);

/**
 * @brief The data interval value
 *
 * The `DataInterval` is the time that must elapse before the channel will fire another @ref
 * PhidgetHumiditySensor_setOnHumidityChangeHandler() event.
 *
 * *   The data interval is bounded by @ref PhidgetHumiditySensor_getMinDataInterval() and @ref
 *     PhidgetHumiditySensor_getMaxDataInterval().
 * *   The timing between @ref PhidgetHumiditySensor_setOnHumidityChangeHandler() events can
 *     also be affected by the `HumidityChangeTrigger`.
 *
 * @param[in] ch The channel handle
 * @param[out] dataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetHumiditySensor_getDataInterval(PhidgetHumiditySensorHandle ch,
  uint32_t *dataInterval);

/**
 * @brief The data interval value
 *
 * The minimum value that `DataInterval` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minDataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetHumiditySensor_getMinDataInterval(PhidgetHumiditySensorHandle ch,
  uint32_t *minDataInterval);

/**
 * @brief The data interval value
 *
 * The maximum value that `DataInterval` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxDataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetHumiditySensor_getMaxDataInterval(PhidgetHumiditySensorHandle ch,
  uint32_t *maxDataInterval);

/**
 * @brief The data rate for the channel
 *
 * The `DataRate` is the frequency of events from the device.
 *
 * *   The data rate is bounded by @ref PhidgetHumiditySensor_getMinDataRate() and @ref
 *     PhidgetHumiditySensor_getMaxDataRate().
 * *   Changing `DataRate` will change the channel's `DataInterval` to a corresponding value,
 *     rounded to the nearest integer number of milliseconds.
 * *   The timing between events can also affected by the change trigger.
 *
 * @param[in] ch The channel handle
 * @param[in] dataRate The data rate for the channel
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetHumiditySensor_setDataRate(PhidgetHumiditySensorHandle ch,
  double dataRate);

/**
 * @brief The data rate for the channel
 *
 * The `DataRate` is the frequency of events from the device.
 *
 * *   The data rate is bounded by @ref PhidgetHumiditySensor_getMinDataRate() and @ref
 *     PhidgetHumiditySensor_getMaxDataRate().
 * *   Changing `DataRate` will change the channel's `DataInterval` to a corresponding value,
 *     rounded to the nearest integer number of milliseconds.
 * *   The timing between events can also affected by the change trigger.
 *
 * @param[in] ch The channel handle
 * @param[out] dataRate The data rate for the channel
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetHumiditySensor_getDataRate(PhidgetHumiditySensorHandle ch,
  double *dataRate);

/**
 * @brief The data rate value
 *
 * The minimum value that `DataRate` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minDataRate The data rate value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetHumiditySensor_getMinDataRate(PhidgetHumiditySensorHandle ch,
  double *minDataRate);

/**
 * @brief The data rate value
 *
 * The maximum value that `DataRate` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxDataRate The data rate value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetHumiditySensor_getMaxDataRate(PhidgetHumiditySensorHandle ch,
  double *maxDataRate);

/**
 * @brief The humidity value
 *
 * The most recent humidity value that the channel has reported.
 *
 * *   This value will always be between @ref PhidgetHumiditySensor_getMinHumidity() and @ref
 *     PhidgetHumiditySensor_getMaxHumidity().
 *
 * @param[in] ch The channel handle
 * @param[out] humidity The humidity value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetHumiditySensor_getHumidity(PhidgetHumiditySensorHandle ch,
  double *humidity);

/**
 * @brief The humidity value
 *
 * The minimum value that the @ref PhidgetHumiditySensor_setOnHumidityChangeHandler() event will
 * report.
 *
 * @param[in] ch The channel handle
 * @param[out] minHumidity The humidity value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetHumiditySensor_getMinHumidity(PhidgetHumiditySensorHandle ch,
  double *minHumidity);

/**
 * @brief The humidity value
 *
 * The maximum value that the @ref PhidgetHumiditySensor_setOnHumidityChangeHandler() event will
 * report.
 *
 * @param[in] ch The channel handle
 * @param[out] maxHumidity The humidity value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetHumiditySensor_getMaxHumidity(PhidgetHumiditySensorHandle ch,
  double *maxHumidity);

/**
 * @brief The change trigger value
 *
 * The channel will not issue a @ref PhidgetHumiditySensor_setOnHumidityChangeHandler() event until
 * the humidity value has changed by the amount specified by the `HumidityChangeTrigger`.
 *
 * *   Setting the `HumidityChangeTrigger` to 0 will result in the channel firing events every
 *     `DataInterval`. This is useful for applications that implement their own data filtering.
 *
 * @param[in] ch The channel handle
 * @param[in] humidityChangeTrigger The change trigger value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetHumiditySensor_setHumidityChangeTrigger(PhidgetHumiditySensorHandle ch,
  double humidityChangeTrigger);

/**
 * @brief The change trigger value
 *
 * The channel will not issue a @ref PhidgetHumiditySensor_setOnHumidityChangeHandler() event until
 * the humidity value has changed by the amount specified by the `HumidityChangeTrigger`.
 *
 * *   Setting the `HumidityChangeTrigger` to 0 will result in the channel firing events every
 *     `DataInterval`. This is useful for applications that implement their own data filtering.
 *
 * @param[in] ch The channel handle
 * @param[out] humidityChangeTrigger The change trigger value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetHumiditySensor_getHumidityChangeTrigger(PhidgetHumiditySensorHandle ch,
  double *humidityChangeTrigger);

/**
 * @brief The change trigger value
 *
 * The minimum value that `HumidityChangeTrigger` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minHumidityChangeTrigger The change trigger value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetHumiditySensor_getMinHumidityChangeTrigger(PhidgetHumiditySensorHandle ch,
  double *minHumidityChangeTrigger);

/**
 * @brief The change trigger value
 *
 * The maximum value that `HumidityChangeTrigger` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxHumidityChangeTrigger The change trigger value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetHumiditySensor_getMaxHumidityChangeTrigger(PhidgetHumiditySensorHandle ch,
  double *maxHumidityChangeTrigger);

/**
 * @brief Callback function type for PhidgetHumiditySensor_setOnHumidityChangeHandler().
 *
 * @param[in] ch The channel handle
 * @param[in] ctx Pointer to the user context
 * @param[in] humidity The ambient relative humidity
 */
typedef void (CCONV *PhidgetHumiditySensor_OnHumidityChangeCallback)(PhidgetHumiditySensorHandle ch,
  void *ctx, double humidity);

/**
 * The most recent humidity value the channel has measured will be reported in this event, which
 * occurs when the `DataInterval` has elapsed.
 *
 * *   If a `HumidityChangeTrigger` has been set to a non-zero value, the @ref
 *     PhidgetHumiditySensor_setOnHumidityChangeHandler() event will not occur until the humidity
 *     has changed by at least the `HumidityChangeTrigger` value.
 *
 * @param[in] ch The channel handle
 * @param[in] fptr The event handler callback function
 * @param[in] ctx User supplied context pointer
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetHumiditySensor_setOnHumidityChangeHandler(PhidgetHumiditySensorHandle ch,
  PhidgetHumiditySensor_OnHumidityChangeCallback fptr, void *ctx);

/** @} */ /* PhidgetHumiditySensor */

/**
 * @defgroup PhidgetIR IR
 * @brief The Infrared Remote class lets you read and transmit command codes from infrared
 *     remotes that the majority of household appliances use. You can use this class to construct
 *     and transmit commands from scratch, or learn and retransmit codes from the remote controller
 *     of your appliance.
 * @{
 */

/**
 * The Infrared Remote class lets you read and transmit command codes from infrared remotes that the
 * majority of household appliances use. You can use this class to construct and transmit commands
 * from scratch, or learn and retransmit codes from the remote controller of your appliance.
 */
typedef struct _PhidgetIR *PhidgetIRHandle;

/**
 * @ref PhidgetIR_create() creates an instance of a Phidget channel. Once created the channel may
 * need to be configured to match the physical device and channel index you want to attach to, and
 * then be opened by calling @ref Phidget_open().
 * The Phidget channel handle must be released with @ref PhidgetIR_delete().
 *
 * @param[out] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetIR_create(PhidgetIRHandle *ch);

/**
 * @ref PhidgetIR_delete() releases a Phidget channel handle created with @ref PhidgetIR_create().
 * If the channel is open when @ref PhidgetIR_delete() is called, it will be closed.
 *
 * @param[out] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetIR_delete(PhidgetIRHandle *ch);

/**
 * The last code the channel has received.
 *
 * *   The code is represented by a hexadecimal string (array of bytes).
 *
 * @param[in] ch The channel handle
 * @param[out] code The last received code
 * @param[in] codeLen length of `code` \- should be at least as long as @ref
 *     IR_MAX_CODE_STR_LENGTH
 * @param[out] bitCount length of the received code in bits
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetIR_getLastCode(PhidgetIRHandle ch, char *code,
  size_t codeLen, uint32_t *bitCount);

/**
 * The last code the channel has learned.
 *
 * *   The code is represented by a hexadecimal string (array of bytes).
 * *   The `codeInfo` structure holds data that describes the learned code.
 *
 * @param[in] ch The channel handle
 * @param[out] code The last learned code
 * @param[in] codeLen length of `code` \- should be at least as long as @ref
 *     IR_MAX_CODE_STR_LENGTH
 * @param[out] codeInfo contains the data for characterizing the code
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetIR_getLastLearnedCode(PhidgetIRHandle ch, char *code,
  size_t codeLen, PhidgetIR_CodeInfo *codeInfo);

/**
 * Transmits a code
 *
 * *   `code` data is transmitted MSBit first.
 * *   MSByte is in array index 0 of `code`
 * *   LSBit is right justified, therefore, MSBit may be in bit position 0-7 (of array index 0)
 *     depending on the bit count.
 *
 * @param[in] ch The channel handle
 * @param[in] code code data
 * @param[in] codeInfo contains the data for characterizing the code
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetIR_transmit(PhidgetIRHandle ch, const char *code,
  PhidgetIR_CodeInfo *codeInfo);

/**
 * Transmits **raw** data as a series of pulses and spaces.
 *
 * *   `data` must start and end with a pulse.
 *     *   Each element is a positive time in μs
 * *   `dataLength` has a maximum length of 200, however, streams should be kept must shorter
 *     than this (less than 100ms between gaps).
 *
 * *   `dataLength` must be an odd number
 *
 * *   Leave `carrierFrequency` as 0 for default.
 *
 * *   `carrierFrequency` has a range of 10kHz - 1MHz
 *
 * *   Leave `dutyCycle` as 0 for default
 *
 * *   `dutyCycle` can have a value between 0.1 and 0.5
 *
 * *   Specifying a `gap` will guarantee a gap time (no transmitting) after data is sent.
 *
 * *   gap time is in μs
 * *   gap time can be set to 0
 *
 * @param[in] ch The channel handle
 * @param[in] data data to send
 * @param[in] dataLen length of the data array
 * @param[in] carrierFrequency carrier frequency in Hz
 * @param[in] dutyCycle the duty cycle
 * @param[in] gap the gap time in μs
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetIR_transmitRaw(PhidgetIRHandle ch, const uint32_t *data,
  size_t dataLen, uint32_t carrierFrequency, double dutyCycle, uint32_t gap);

/**
 * Transmits a repeat of the last transmited code.
 *
 * *   Depending on the CodeInfo structure, this may be a retransmission of the code itself, or
 *     there may be a special repeat code.
 *
 * @param[in] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetIR_transmitRepeat(PhidgetIRHandle ch);

/**
 * @brief Callback function type for PhidgetIR_setOnCodeHandler().
 *
 * @param[in] ch The channel handle
 * @param[in] ctx Pointer to the user context
 * @param[in] code The code string
 * @param[in] bitCount The length of the received code in bits
 * @param[in] isRepeat 'true' if a repeat is detected
 */
typedef void (CCONV *PhidgetIR_OnCodeCallback)(PhidgetIRHandle ch, void *ctx, const char *code,
  uint32_t bitCount, int isRepeat);

/**
 * This event is fired every time a code is received and correctly decoded.
 *
 * *   The code is represented by a hexadecimal string (array of bytes) with a length of 1/4 of
 *     `bitCount`.
 * *   The MSBit is considered to be the first bit received and will be in array index 0 of
 *     `code`
 * *   Repeat will be true if a repeat is detected (either timing wise or via a repeat code)
 *
 * *   False repeasts can happen if two separate button presses happen close together
 *
 * @param[in] ch The channel handle
 * @param[in] fptr The event handler callback function
 * @param[in] ctx User supplied context pointer
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetIR_setOnCodeHandler(PhidgetIRHandle ch,
  PhidgetIR_OnCodeCallback fptr, void *ctx);

/**
 * @brief Callback function type for PhidgetIR_setOnLearnHandler().
 *
 * @param[in] ch The channel handle
 * @param[in] ctx Pointer to the user context
 * @param[in] code The code string
 * @param[in] codeInfo Contains the data for characterizing the code
 */
typedef void (CCONV *PhidgetIR_OnLearnCallback)(PhidgetIRHandle ch, void *ctx, const char *code,
  PhidgetIR_CodeInfo *codeInfo);

/**
 * This event fires when a button has been held down long enough for the channel to have learned the
 * CodeInfo values
 *
 * *   A code is usually learned after 1 second, or after 4 repeats.
 *
 * @param[in] ch The channel handle
 * @param[in] fptr The event handler callback function
 * @param[in] ctx User supplied context pointer
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetIR_setOnLearnHandler(PhidgetIRHandle ch,
  PhidgetIR_OnLearnCallback fptr, void *ctx);

/**
 * @brief Callback function type for PhidgetIR_setOnRawDataHandler().
 *
 * @param[in] ch The channel handle
 * @param[in] ctx Pointer to the user context
 * @param[in] data The data being received
 * @param[in] dataLen The length of the data being received
 */
typedef void (CCONV *PhidgetIR_OnRawDataCallback)(PhidgetIRHandle ch, void *ctx, const uint32_t *data,
  size_t dataLen);

/**
 * This event will fire every time the channel gets more data
 *
 * *   This will happen at most once every 8ms.
 *
 * @param[in] ch The channel handle
 * @param[in] fptr The event handler callback function
 * @param[in] ctx User supplied context pointer
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetIR_setOnRawDataHandler(PhidgetIRHandle ch,
  PhidgetIR_OnRawDataCallback fptr, void *ctx);

#define IR_RAWDATA_LONGSPACE 0xffffffff /**< The value for a long space in raw data */
#define IR_MAX_CODE_BIT_COUNT 0x80      /**< Maximum bit count for sent / received data */
#define IR_MAX_CODE_STR_LENGTH 0x21     /**< Maximum bit count for sent / received data */

/** @} */ /* PhidgetIR */

/**
 * @defgroup PhidgetLCD LCD
 * @brief The LCD class allows you to control various liquid crystal displays. It offers control
 *     of displayed text as well as screen settings and custom character creation.
 * @{
 */

/**
 * The LCD class allows you to control various liquid crystal displays. It offers control of
 * displayed text as well as screen settings and custom character creation.
 */
typedef struct _PhidgetLCD *PhidgetLCDHandle;

/**
 * @ref PhidgetLCD_create() creates an instance of a Phidget channel. Once created the channel may
 * need to be configured to match the physical device and channel index you want to attach to, and
 * then be opened by calling @ref Phidget_open().
 * The Phidget channel handle must be released with @ref PhidgetLCD_delete().
 *
 * @param[out] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLCD_create(PhidgetLCDHandle *ch);

/**
 * @ref PhidgetLCD_delete() releases a Phidget channel handle created with @ref PhidgetLCD_create().
 * If the channel is open when @ref PhidgetLCD_delete() is called, it will be closed.
 *
 * @param[out] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLCD_delete(PhidgetLCDHandle *ch);

/**
 * Create a bitmap and select a character to represent it. Now, when you use the specific character,
 * the bitmap will show in it's place.
 *
 * @param[in] ch The channel handle
 * @param[in] font The font the character belongs to
 * @param[in] character The character to be changed, in a null-terminated string
 * @param[in] bitmap Bitmap array
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLCD_setCharacterBitmap(PhidgetLCDHandle ch,
  PhidgetLCD_Font font, const char *character, const uint8_t *bitmap);

/**
 * Create a bitmap and select a character to represent it. Now, when you use the specific character,
 * the bitmap will show in it's place.
 *
 * @param[in] ch The channel handle
 * @param[in] font The font the character belongs to
 * @param[in] character The character to be changed, in a null-terminated string
 * @param[in] bitmap Bitmap array
 * @param[in] fptr Asynchronous completion callback
 * @param[in] ctx User supplied context pointer
 */
PHIDGET22_API void CCONV PhidgetLCD_setCharacterBitmap_async(PhidgetLCDHandle ch, PhidgetLCD_Font font,
  const char *character, const uint8_t *bitmap, Phidget_AsyncCallback fptr, void *ctx);

/**
 * The maximum number of characters that can fit on the frame buffer for the specified font.
 *
 * @param[in] ch The channel handle
 * @param[in] font The specified font
 * @param[out] maxCharacters The maximum number of characters for the font
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLCD_getMaxCharacters(PhidgetLCDHandle ch,
  PhidgetLCD_Font font, int *maxCharacters);

/**
 * Clears all pixels in the current frame buffer.
 *
 * *   Changes made to the frame buffer must be flushed to the LCD screen using @ref
 *     PhidgetLCD_flush().
 *
 * @param[in] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLCD_clear(PhidgetLCDHandle ch);

/**
 * Clears all pixels in the current frame buffer.
 *
 * *   Changes made to the frame buffer must be flushed to the LCD screen using @ref
 *     PhidgetLCD_flush().
 *
 * @param[in] ch The channel handle
 * @param[in] fptr Asynchronous completion callback
 * @param[in] ctx User supplied context pointer
 */
PHIDGET22_API void CCONV PhidgetLCD_clear_async(PhidgetLCDHandle ch, Phidget_AsyncCallback fptr,
  void *ctx);

/**
 * Copies all pixels from a specified rectangular region to another.
 *
 * @param[in] ch The channel handle
 * @param[in] sourceFramebuffer Index number of the frame buffer containing the source rectangle
 * @param[in] destFramebuffer Index number of the frame buffer containing the destination
 *     rectangle
 * @param[in] sourceX1 X coordinate of upper left corner of source rectangle
 * @param[in] sourceY1 Y coordinate of upper left corner of source rectangle
 * @param[in] sourceX2 X coordinate of bottom right corner of source rectangle
 * @param[in] sourceY2 Y coordinate of bottom right corner of source rectangle
 * @param[in] destX X coordinate of upper left corner of destination rectangle
 * @param[in] destY Y coordinate of upper left corner of destination rectangle
 * @param[in] inverted If true, copied pixels are inverted
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLCD_copy(PhidgetLCDHandle ch, int sourceFramebuffer,
  int destFramebuffer, int sourceX1, int sourceY1, int sourceX2, int sourceY2, int destX, int destY,
  int inverted);

/**
 * Copies all pixels from a specified rectangular region to another.
 *
 * @param[in] ch The channel handle
 * @param[in] sourceFramebuffer Index number of the frame buffer containing the source rectangle
 * @param[in] destFramebuffer Index number of the frame buffer containing the destination
 *     rectangle
 * @param[in] sourceX1 X coordinate of upper left corner of source rectangle
 * @param[in] sourceY1 Y coordinate of upper left corner of source rectangle
 * @param[in] sourceX2 X coordinate of bottom right corner of source rectangle
 * @param[in] sourceY2 Y coordinate of bottom right corner of source rectangle
 * @param[in] destX X coordinate of upper left corner of destination rectangle
 * @param[in] destY Y coordinate of upper left corner of destination rectangle
 * @param[in] inverted If true, copied pixels are inverted
 * @param[in] fptr Asynchronous completion callback
 * @param[in] ctx User supplied context pointer
 */
PHIDGET22_API void CCONV PhidgetLCD_copy_async(PhidgetLCDHandle ch, int sourceFramebuffer,
  int destFramebuffer, int sourceX1, int sourceY1, int sourceX2, int sourceY2, int destX, int destY,
  int inverted, Phidget_AsyncCallback fptr, void *ctx);

/**
 * Draws a straight line in the current frame buffer between two specified points
 *
 * *   Changes made to the frame buffer must be flushed to the LCD screen using @ref
 *     PhidgetLCD_flush().
 *
 * @param[in] ch The channel handle
 * @param[in] x1 X coordinate of the first point
 * @param[in] y1 Y coordinate of the first point
 * @param[in] x2 X coordinate of the second point
 * @param[in] y2 Y coordinate of the second point
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLCD_drawLine(PhidgetLCDHandle ch, int x1, int y1, int x2,
  int y2);

/**
 * Draws a straight line in the current frame buffer between two specified points
 *
 * *   Changes made to the frame buffer must be flushed to the LCD screen using @ref
 *     PhidgetLCD_flush().
 *
 * @param[in] ch The channel handle
 * @param[in] x1 X coordinate of the first point
 * @param[in] y1 Y coordinate of the first point
 * @param[in] x2 X coordinate of the second point
 * @param[in] y2 Y coordinate of the second point
 * @param[in] fptr Asynchronous completion callback
 * @param[in] ctx User supplied context pointer
 */
PHIDGET22_API void CCONV PhidgetLCD_drawLine_async(PhidgetLCDHandle ch, int x1, int y1, int x2, int y2,
  Phidget_AsyncCallback fptr, void *ctx);

/**
 * Draws, erases, or inverts a single specified pixel.
 *
 * *   Changes made to the frame buffer must be flushed to the LCD screen using @ref
 *     PhidgetLCD_flush().
 *
 * @param[in] ch The channel handle
 * @param[in] x The X coordinate of the pixel
 * @param[in] y The Y coordinate of the pixel
 * @param[in] pixelState The new state of the pixel
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLCD_drawPixel(PhidgetLCDHandle ch, int x, int y,
  PhidgetLCD_PixelState pixelState);

/**
 * Draws, erases, or inverts a single specified pixel.
 *
 * *   Changes made to the frame buffer must be flushed to the LCD screen using @ref
 *     PhidgetLCD_flush().
 *
 * @param[in] ch The channel handle
 * @param[in] x The X coordinate of the pixel
 * @param[in] y The Y coordinate of the pixel
 * @param[in] pixelState The new state of the pixel
 * @param[in] fptr Asynchronous completion callback
 * @param[in] ctx User supplied context pointer
 */
PHIDGET22_API void CCONV PhidgetLCD_drawPixel_async(PhidgetLCDHandle ch, int x, int y,
  PhidgetLCD_PixelState pixelState, Phidget_AsyncCallback fptr, void *ctx);

/**
 * Draws a rectangle in the current frame buffer using the specified points
 *
 * *   Changes made to the frame buffer must be flushed to the LCD screen using @ref
 *     PhidgetLCD_flush().
 *
 * @param[in] ch The channel handle
 * @param[in] x1 The X coordinate of the top-left corner of the rectangle
 * @param[in] y1 The Y coordinate of the top-left corner of the rectangle
 * @param[in] x2 The X coordinate of the bottom-right corner of the rectangle
 * @param[in] y2 The Y coordinate of the bottom-right corner of the rectangle
 * @param[in] filled If true, the rectangle will be solid. If false, just a single pixel outline
 * @param[in] inverted If true, clears the region instead of drawing
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLCD_drawRect(PhidgetLCDHandle ch, int x1, int y1, int x2,
  int y2, int filled, int inverted);

/**
 * Draws a rectangle in the current frame buffer using the specified points
 *
 * *   Changes made to the frame buffer must be flushed to the LCD screen using @ref
 *     PhidgetLCD_flush().
 *
 * @param[in] ch The channel handle
 * @param[in] x1 The X coordinate of the top-left corner of the rectangle
 * @param[in] y1 The Y coordinate of the top-left corner of the rectangle
 * @param[in] x2 The X coordinate of the bottom-right corner of the rectangle
 * @param[in] y2 The Y coordinate of the bottom-right corner of the rectangle
 * @param[in] filled If true, the rectangle will be solid. If false, just a single pixel outline
 * @param[in] inverted If true, clears the region instead of drawing
 * @param[in] fptr Asynchronous completion callback
 * @param[in] ctx User supplied context pointer
 */
PHIDGET22_API void CCONV PhidgetLCD_drawRect_async(PhidgetLCDHandle ch, int x1, int y1, int x2, int y2,
  int filled, int inverted, Phidget_AsyncCallback fptr, void *ctx);

/**
 * Flushes the buffered LCD contents to the LCD screen.
 *
 * @param[in] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLCD_flush(PhidgetLCDHandle ch);

/**
 * Flushes the buffered LCD contents to the LCD screen.
 *
 * @param[in] ch The channel handle
 * @param[in] fptr Asynchronous completion callback
 * @param[in] ctx User supplied context pointer
 */
PHIDGET22_API void CCONV PhidgetLCD_flush_async(PhidgetLCDHandle ch, Phidget_AsyncCallback fptr,
  void *ctx);

/**
 * Gets the size of the specified font.
 *
 * @param[in] ch The channel handle
 * @param[in] font The specified font
 * @param[out] width The width of the font
 * @param[out] height The height of the font
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLCD_getFontSize(PhidgetLCDHandle ch, PhidgetLCD_Font font,
  int *width, int *height);

/**
 * Sets the size of the specified font.
 *
 * @param[in] ch The channel handle
 * @param[in] font The specified font
 * @param[in] width The width of the font
 * @param[in] height The height of the font
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLCD_setFontSize(PhidgetLCDHandle ch, PhidgetLCD_Font font,
  int width, int height);

/**
 * Initializes the Text LCD display
 *
 * @param[in] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLCD_initialize(PhidgetLCDHandle ch);

/**
 * Writes the specified frame buffer to flash memory
 *
 * *   Use sparingly. The flash memory is only designed to be written to 10,000 times before it
 *     may become unusable. This method can only be called one time each time the channel is opened.
 *
 * @param[in] ch The channel handle
 * @param[in] frameBuffer The frame buffer to be saved
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLCD_saveFrameBuffer(PhidgetLCDHandle ch, int frameBuffer);

/**
 * Writes the specified frame buffer to flash memory
 *
 * *   Use sparingly. The flash memory is only designed to be written to 10,000 times before it
 *     may become unusable. This method can only be called one time each time the channel is opened.
 *
 * @param[in] ch The channel handle
 * @param[in] frameBuffer The frame buffer to be saved
 * @param[in] fptr Asynchronous completion callback
 * @param[in] ctx User supplied context pointer
 */
PHIDGET22_API void CCONV PhidgetLCD_saveFrameBuffer_async(PhidgetLCDHandle ch, int frameBuffer,
  Phidget_AsyncCallback fptr, void *ctx);

/**
 * Draws a bitmap to the current frame buffer at the given location.
 *
 * *   Each byte in the array represents one pixel in row-major order.
 * *   Changes made to the frame buffer must be flushed to the LCD screen using @ref
 *     PhidgetLCD_flush().
 *
 * @param[in] ch The channel handle
 * @param[in] xPosition The X coordinate of the bitmap
 * @param[in] yPosition The Y coordinate of the bitmap
 * @param[in] xSize The length of each row in the bitmap
 * @param[in] ySize The number of rows in the bitmap
 * @param[in] bitmap The bitmap to be drawn
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLCD_writeBitmap(PhidgetLCDHandle ch, int xPosition,
  int yPosition, int xSize, int ySize, const uint8_t *bitmap);

/**
 * Draws a bitmap to the current frame buffer at the given location.
 *
 * *   Each byte in the array represents one pixel in row-major order.
 * *   Changes made to the frame buffer must be flushed to the LCD screen using @ref
 *     PhidgetLCD_flush().
 *
 * @param[in] ch The channel handle
 * @param[in] xPosition The X coordinate of the bitmap
 * @param[in] yPosition The Y coordinate of the bitmap
 * @param[in] xSize The length of each row in the bitmap
 * @param[in] ySize The number of rows in the bitmap
 * @param[in] bitmap The bitmap to be drawn
 * @param[in] fptr Asynchronous completion callback
 * @param[in] ctx User supplied context pointer
 */
PHIDGET22_API void CCONV PhidgetLCD_writeBitmap_async(PhidgetLCDHandle ch, int xPosition, int yPosition,
  int xSize, int ySize, const uint8_t *bitmap, Phidget_AsyncCallback fptr, void *ctx);

/**
 * Writes text to the current frame buffer at the specified location
 *
 * *   Changes made to the frame buffer must be flushed to the LCD screen using @ref
 *     PhidgetLCD_flush().
 *
 * @param[in] ch The channel handle
 * @param[in] font The font of the text
 * @param[in] xPosition The X position of the start of the text string
 * @param[in] yPosition The Y position of the start of the text string
 * @param[in] text The text to be written
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLCD_writeText(PhidgetLCDHandle ch, PhidgetLCD_Font font,
  int xPosition, int yPosition, const char *text);

/**
 * Writes text to the current frame buffer at the specified location
 *
 * *   Changes made to the frame buffer must be flushed to the LCD screen using @ref
 *     PhidgetLCD_flush().
 *
 * @param[in] ch The channel handle
 * @param[in] font The font of the text
 * @param[in] xPosition The X position of the start of the text string
 * @param[in] yPosition The Y position of the start of the text string
 * @param[in] text The text to be written
 * @param[in] fptr Asynchronous completion callback
 * @param[in] ctx User supplied context pointer
 */
PHIDGET22_API void CCONV PhidgetLCD_writeText_async(PhidgetLCDHandle ch, PhidgetLCD_Font font,
  int xPosition, int yPosition, const char *text, Phidget_AsyncCallback fptr, void *ctx);

/**
 * @brief Allows setting the LCD to flush the screen automatically
 *
 * Set to true to automatically flush the LCD screen after every message that writes to the LCD.
 *
 * @param[in] ch The channel handle
 * @param[in] autoFlush The auto-flush state
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLCD_setAutoFlush(PhidgetLCDHandle ch, int autoFlush);

/**
 * @brief Allows setting the LCD to flush the screen automatically
 *
 * Set to true to automatically flush the LCD screen after every message that writes to the LCD.
 *
 * @param[in] ch The channel handle
 * @param[out] autoFlush The auto-flush state
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLCD_getAutoFlush(PhidgetLCDHandle ch, int *autoFlush);

/**
 * @brief The backlight value
 *
 * The `Backlight` affects the brightness of the LCD screen.
 *
 * *   `Backlight` is bounded by @ref PhidgetLCD_getMinBacklight() and @ref
 *     PhidgetLCD_getMaxBacklight().
 *
 * @param[in] ch The channel handle
 * @param[in] backlight The backlight value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLCD_setBacklight(PhidgetLCDHandle ch, double backlight);

/**
 * @brief The backlight value
 *
 * The `Backlight` affects the brightness of the LCD screen.
 *
 * *   `Backlight` is bounded by @ref PhidgetLCD_getMinBacklight() and @ref
 *     PhidgetLCD_getMaxBacklight().
 *
 * @param[in] ch The channel handle
 * @param[out] backlight The backlight value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLCD_getBacklight(PhidgetLCDHandle ch, double *backlight);

/**
 * @brief The backlight value
 *
 * The minimum value that `Backlight` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minBacklight The backlight value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLCD_getMinBacklight(PhidgetLCDHandle ch,
  double *minBacklight);

/**
 * @brief The backlight value
 *
 * The maximum value that `Backlight` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxBacklight The backlight value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLCD_getMaxBacklight(PhidgetLCDHandle ch,
  double *maxBacklight);

/**
 * @brief The contrast value
 *
 * Contrast level of the text or graphic pixels.
 *
 * *   A higher contrast will make the image darker.
 * *   `Contrast` is bounded by @ref PhidgetLCD_getMinContrast() and @ref
 *     PhidgetLCD_getMaxContrast().
 *
 * @param[in] ch The channel handle
 * @param[in] contrast The contrast value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLCD_setContrast(PhidgetLCDHandle ch, double contrast);

/**
 * @brief The contrast value
 *
 * Contrast level of the text or graphic pixels.
 *
 * *   A higher contrast will make the image darker.
 * *   `Contrast` is bounded by @ref PhidgetLCD_getMinContrast() and @ref
 *     PhidgetLCD_getMaxContrast().
 *
 * @param[in] ch The channel handle
 * @param[out] contrast The contrast value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLCD_getContrast(PhidgetLCDHandle ch, double *contrast);

/**
 * @brief The contrast value.
 *
 * The minimum value that `Contrast` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minContrast The contrast value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLCD_getMinContrast(PhidgetLCDHandle ch,
  double *minContrast);

/**
 * @brief The contrast value.
 *
 * The maximum value that `Contrast` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxContrast The contrast value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLCD_getMaxContrast(PhidgetLCDHandle ch,
  double *maxContrast);

/**
 * @brief The cursor blink mode
 *
 * When `CursorBlink` is true, the device will cause the cursor to periodically blink.
 *
 * @param[in] ch The channel handle
 * @param[in] cursorBlink The cursor blink mode
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLCD_setCursorBlink(PhidgetLCDHandle ch, int cursorBlink);

/**
 * @brief The cursor blink mode
 *
 * When `CursorBlink` is true, the device will cause the cursor to periodically blink.
 *
 * @param[in] ch The channel handle
 * @param[out] cursorBlink The cursor blink mode
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLCD_getCursorBlink(PhidgetLCDHandle ch, int *cursorBlink);

/**
 * @brief The cursor on value
 *
 * When `CursorOn` is true, the device will underline to the cursor position.
 *
 * @param[in] ch The channel handle
 * @param[in] cursorOn The cursor on value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLCD_setCursorOn(PhidgetLCDHandle ch, int cursorOn);

/**
 * @brief The cursor on value
 *
 * When `CursorOn` is true, the device will underline to the cursor position.
 *
 * @param[in] ch The channel handle
 * @param[out] cursorOn The cursor on value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLCD_getCursorOn(PhidgetLCDHandle ch, int *cursorOn);

/**
 * @brief The current frame buffer
 *
 * The frame buffer that is currently being used.
 *
 * *   Commands sent to the device are performed on this buffer.
 *
 * @param[in] ch The channel handle
 * @param[in] frameBuffer The current frame buffer
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLCD_setFrameBuffer(PhidgetLCDHandle ch, int frameBuffer);

/**
 * @brief The current frame buffer
 *
 * The frame buffer that is currently being used.
 *
 * *   Commands sent to the device are performed on this buffer.
 *
 * @param[in] ch The channel handle
 * @param[in] frameBuffer The current frame buffer
 * @param[in] fptr Asynchronous completion callback
 * @param[in] ctx User supplied context pointer
 */
PHIDGET22_API void CCONV PhidgetLCD_setFrameBuffer_async(PhidgetLCDHandle ch, int frameBuffer,
  Phidget_AsyncCallback fptr, void *ctx);

/**
 * @brief The current frame buffer
 *
 * The frame buffer that is currently being used.
 *
 * *   Commands sent to the device are performed on this buffer.
 *
 * @param[in] ch The channel handle
 * @param[out] frameBuffer The current frame buffer
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLCD_getFrameBuffer(PhidgetLCDHandle ch, int *frameBuffer);

/**
 * @brief The height value
 *
 * The height of the LCD screen attached to the channel.
 *
 * @param[in] ch The channel handle
 * @param[out] height The height value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLCD_getHeight(PhidgetLCDHandle ch, int *height);

/**
 * @brief The screen size
 *
 * The size of the LCD screen attached to the channel.
 *
 * @param[in] ch The channel handle
 * @param[in] screenSize The screen size
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLCD_setScreenSize(PhidgetLCDHandle ch,
  PhidgetLCD_ScreenSize screenSize);

/**
 * @brief The screen size
 *
 * The size of the LCD screen attached to the channel.
 *
 * @param[in] ch The channel handle
 * @param[out] screenSize The screen size
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLCD_getScreenSize(PhidgetLCDHandle ch,
  PhidgetLCD_ScreenSize *screenSize);

/**
 * @brief The sleep status
 *
 * The on/off state of `Sleeping`. Putting the device to sleep turns off the display and backlight
 * in order to save power.
 *
 * *   The device will still take commands while asleep, and will wake up if the screen is
 *     flushed, or if the contrast or backlight are changed.
 * *   When the device wakes up, it will return to its last known state, taking into account any
 *     changes that happened while asleep.
 *
 * @param[in] ch The channel handle
 * @param[in] sleeping The sleep status
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLCD_setSleeping(PhidgetLCDHandle ch, int sleeping);

/**
 * @brief The sleep status
 *
 * The on/off state of `Sleeping`. Putting the device to sleep turns off the display and backlight
 * in order to save power.
 *
 * *   The device will still take commands while asleep, and will wake up if the screen is
 *     flushed, or if the contrast or backlight are changed.
 * *   When the device wakes up, it will return to its last known state, taking into account any
 *     changes that happened while asleep.
 *
 * @param[in] ch The channel handle
 * @param[out] sleeping The sleep status
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLCD_getSleeping(PhidgetLCDHandle ch, int *sleeping);

/**
 * @brief The width value
 *
 * The width of the LCD screen attached to the channel.
 *
 * @param[in] ch The channel handle
 * @param[out] width The width value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLCD_getWidth(PhidgetLCDHandle ch, int *width);

/** @} */ /* PhidgetLCD */

/**
 * @defgroup PhidgetLEDArray LEDArray
 * @brief The LED Array class is used to control addressable LEDs, providing full control over
 *     color, brightness, and more.
 * @{
 */

/**
 * The LED Array class is used to control addressable LEDs, providing full control over color,
 * brightness, and more.
 */
typedef struct _PhidgetLEDArray *PhidgetLEDArrayHandle;

/**
 * @ref PhidgetLEDArray_create() creates an instance of a Phidget channel. Once created the channel
 * may need to be configured to match the physical device and channel index you want to attach to,
 * and then be opened by calling @ref Phidget_open().
 * The Phidget channel handle must be released with @ref PhidgetLEDArray_delete().
 *
 * @param[out] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLEDArray_create(PhidgetLEDArrayHandle *ch);

/**
 * @ref PhidgetLEDArray_delete() releases a Phidget channel handle created with @ref
 * PhidgetLEDArray_create().
 * If the channel is open when @ref PhidgetLEDArray_delete() is called, it will be closed.
 *
 * @param[out] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLEDArray_delete(PhidgetLEDArrayHandle *ch);

/**
 * Display an animation. For more information, visit our [LEDArray API
 * Guide](https://www.phidgets.com/docs/LEDArray_API_Guide#Animations).
 *
 * @param[in] ch The channel handle
 * @param[in] animationID The ID of the animation
 * @param[in] pattern The LED pattern to animate
 * @param[in] patternLen The number of stages in the animation
 * @param[in] animation The animation parameters
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLEDArray_setAnimation(PhidgetLEDArrayHandle ch,
  int32_t animationID, const PhidgetLEDArray_Color *pattern, size_t patternLen,
  PhidgetLEDArray_Animation *animation);

/**
 * Turn off all LEDs. Any active animations will be stopped. For more information, visit our
 * [LEDArray API Guide](https://www.phidgets.com/docs/LEDArray_API_Guide#Clear).
 *
 * @param[in] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLEDArray_clearLEDs(PhidgetLEDArrayHandle ch);

/**
 * Set the color of a single of LED
 *
 * @param[in] ch The channel handle
 * @param[in] address The address of the LED
 * @param[in] color The color
 * @param[in] fadeTime The time to fade from the previous state in milliseconds
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLEDArray_setLED(PhidgetLEDArrayHandle ch, uint32_t address,
  PhidgetLEDArray_Color *color, uint32_t fadeTime);

/**
 * Set the colors of a segment of LEDs
 *
 * @param[in] ch The channel handle
 * @param[in] startAddress The address of the first LED in the segment
 * @param[in] endAddress The address of the last LED in the segment
 * @param[in] leds The color pattern. This will be repeated or truncated as necessary to fill
 *     the space between startAddress and endAddress
 * @param[in] ledsLen The number of bytes being sent
 * @param[in] fadeTime The time to fade from the previous state in milliseconds
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLEDArray_setLEDs(PhidgetLEDArrayHandle ch,
  uint32_t startAddress, uint32_t endAddress, const PhidgetLEDArray_Color *leds, size_t ledsLen,
  uint32_t fadeTime);

/**
 * Set the colors of a segment of LEDs
 *
 * @param[in] ch The channel handle
 * @param[in] startAddress The address of the first LED in the segment
 * @param[in] endAddress The address of the last LED in the segment
 * @param[in] leds The color pattern. This will be repeated or truncated as necessary to fill
 *     the space between startAddress and endAddress
 * @param[in] ledsLen The number of bytes being sent
 * @param[in] fadeTime The time to fade from the previous state in milliseconds
 * @param[in] fptr Asynchronous completion callback
 * @param[in] ctx User supplied context pointer
 */
PHIDGET22_API void CCONV PhidgetLEDArray_setLEDs_async(PhidgetLEDArrayHandle ch, uint32_t startAddress,
  uint32_t endAddress, const PhidgetLEDArray_Color *leds, size_t ledsLen, uint32_t fadeTime,
  Phidget_AsyncCallback fptr, void *ctx);

/**
 * Disable the specified animation.
 *
 * @param[in] ch The channel handle
 * @param[in] animationID The ID of the animation to disable
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLEDArray_stopAnimation(PhidgetLEDArrayHandle ch,
  int32_t animationID);

/**
 * Restart all animations at the same time.
 *
 * @param[in] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLEDArray_synchronizeAnimations(PhidgetLEDArrayHandle ch);

/**
 * @brief Lowest LED address
 *
 * The lowest LED address.
 *
 * @param[in] ch The channel handle
 * @param[out] minAddress Lowest LED address
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLEDArray_getMinAddress(PhidgetLEDArrayHandle ch,
  uint32_t *minAddress);

/**
 * @brief Highest LED address
 *
 * The highest LED address. When using a `ColorOrder` with a white component (e.g., RGBW), this is
 * reduced to 1535.
 *
 * @param[in] ch The channel handle
 * @param[out] maxAddress Highest LED address
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLEDArray_getMaxAddress(PhidgetLEDArrayHandle ch,
  uint32_t *maxAddress);

/**
 * @brief Lowest AnimationID
 *
 * The lowest AnimationID.
 *
 * @param[in] ch The channel handle
 * @param[out] minAnimationID Lowest AnimationID
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLEDArray_getMinAnimationID(PhidgetLEDArrayHandle ch,
  int32_t *minAnimationID);

/**
 * @brief Highest AnimationID
 *
 * The highest AnimationID.
 *
 * @param[in] ch The channel handle
 * @param[out] maxAnimationID Highest AnimationID
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLEDArray_getMaxAnimationID(PhidgetLEDArrayHandle ch,
  int32_t *maxAnimationID);

/**
 * @brief Minimum pattern count
 *
 * The minimum size of the LEDArrayColor array when using animations.
 *
 * @param[in] ch The channel handle
 * @param[out] minAnimationPatternCount Minimum pattern count
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLEDArray_getMinAnimationPatternCount(PhidgetLEDArrayHandle ch,
  uint32_t *minAnimationPatternCount);

/**
 * @brief Maximum pattern count
 *
 * The maximum size of the LEDArrayColor array when using animations. When using a `ColorOrder` with
 * a white component (e.g., RGBW), this is reduced to 96.
 *
 * @param[in] ch The channel handle
 * @param[out] maxAnimationPatternCount Maximum pattern count
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLEDArray_getMaxAnimationPatternCount(PhidgetLEDArrayHandle ch,
  uint32_t *maxAnimationPatternCount);

/**
 * @brief Brightness value
 *
 * The brightness value will apply to all LEDs. For more information, visit our [LEDArray API
 * Guide](https://www.phidgets.com/docs/LEDArray_API_Guide#Brightness).
 *
 * @param[in] ch The channel handle
 * @param[in] brightness Brightness value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLEDArray_setBrightness(PhidgetLEDArrayHandle ch,
  double brightness);

/**
 * @brief Brightness value
 *
 * The brightness value will apply to all LEDs. For more information, visit our [LEDArray API
 * Guide](https://www.phidgets.com/docs/LEDArray_API_Guide#Brightness).
 *
 * @param[in] ch The channel handle
 * @param[out] brightness Brightness value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLEDArray_getBrightness(PhidgetLEDArrayHandle ch,
  double *brightness);

/**
 * @brief Minimum brightness
 *
 * The minimum brightness.
 *
 * @param[in] ch The channel handle
 * @param[out] minBrightness Minimum brightness
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLEDArray_getMinBrightness(PhidgetLEDArrayHandle ch,
  double *minBrightness);

/**
 * @brief Maximum brightness
 *
 * The maximum brightness.
 *
 * @param[in] ch The channel handle
 * @param[out] maxBrightness Maximum brightness
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLEDArray_getMaxBrightness(PhidgetLEDArrayHandle ch,
  double *maxBrightness);

/**
 * @brief LED Color Order
 *
 * Specify the order of colors expected by your LEDs. For more information, visit our [LEDArray API
 * Guide](https://www.phidgets.com/docs/LEDArray_API_Guide#Color_Order).
 *
 * @param[in] ch The channel handle
 * @param[in] colorOrder LED Color Order
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLEDArray_setColorOrder(PhidgetLEDArrayHandle ch,
  PhidgetLEDArray_ColorOrder colorOrder);

/**
 * @brief LED Color Order
 *
 * Specify the order of colors expected by your LEDs. For more information, visit our [LEDArray API
 * Guide](https://www.phidgets.com/docs/LEDArray_API_Guide#Color_Order).
 *
 * @param[in] ch The channel handle
 * @param[out] colorOrder LED Color Order
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLEDArray_getColorOrder(PhidgetLEDArrayHandle ch,
  PhidgetLEDArray_ColorOrder *colorOrder);

/**
 * @brief Minimum fade time
 *
 * The minimum fade time.
 *
 * @param[in] ch The channel handle
 * @param[out] minFadeTime Minimum fade time
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLEDArray_getMinFadeTime(PhidgetLEDArrayHandle ch,
  uint32_t *minFadeTime);

/**
 * @brief Maximum fade time
 *
 * The maximum fade time.
 *
 * @param[in] ch The channel handle
 * @param[out] maxFadeTime Maximum fade time
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLEDArray_getMaxFadeTime(PhidgetLEDArrayHandle ch,
  uint32_t *maxFadeTime);

/**
 * @brief Gamma value
 *
 * The gamma value to apply to brightnesses. PC monitors typically to use 2.2. For more information,
 * visit our [LEDArray API Guide](https://www.phidgets.com/docs/LEDArray_API_Guide#Gamma).
 *
 * @param[in] ch The channel handle
 * @param[in] gamma Gamma value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLEDArray_setGamma(PhidgetLEDArrayHandle ch, double gamma);

/**
 * @brief Gamma value
 *
 * The gamma value to apply to brightnesses. PC monitors typically to use 2.2. For more information,
 * visit our [LEDArray API Guide](https://www.phidgets.com/docs/LEDArray_API_Guide#Gamma).
 *
 * @param[in] ch The channel handle
 * @param[out] gamma Gamma value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLEDArray_getGamma(PhidgetLEDArrayHandle ch, double *gamma);

/**
 * @brief Minimum gamma
 *
 * The minimum value gamma can be set to. Gamma values less than 1 are unsuitable for most
 * applications.
 *
 * @param[in] ch The channel handle
 * @param[out] minGamma Minimum gamma
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLEDArray_getMinGamma(PhidgetLEDArrayHandle ch,
  double *minGamma);

/**
 * @brief Maximum gamma
 *
 * The maximum value that gamma can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxGamma Maximum gamma
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLEDArray_getMaxGamma(PhidgetLEDArrayHandle ch,
  double *maxGamma);

/**
 * @brief Minimum size of the LED array
 *
 * The minimum size of the LEDArrayColor array when using @ref PhidgetLEDArray_setLED() or @ref
 * PhidgetLEDArray_setLEDs().
 *
 * @param[in] ch The channel handle
 * @param[out] minLEDCount Minimum size of the LED array
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLEDArray_getMinLEDCount(PhidgetLEDArrayHandle ch,
  uint32_t *minLEDCount);

/**
 * @brief Maximum size of the LED array
 *
 * The maximum size of the LEDArrayColor array when using @ref PhidgetLEDArray_setLED() or @ref
 * PhidgetLEDArray_setLEDs(). When using a `ColorOrder` with a white component (e.g., RGBW), this is
 * reduced to 1536.
 *
 * @param[in] ch The channel handle
 * @param[out] maxLEDCount Maximum size of the LED array
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLEDArray_getMaxLEDCount(PhidgetLEDArrayHandle ch,
  uint32_t *maxLEDCount);

/**
 * @brief Control power to all LEDs
 *
 * Control power to all LEDs. For more information, visit our [LEDArray API
 * Guide](https://www.phidgets.com/docs/LEDArray_API_Guide#PowerEnabled).
 *
 * @param[in] ch The channel handle
 * @param[in] powerEnabled Control power to all LEDs
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLEDArray_setPowerEnabled(PhidgetLEDArrayHandle ch,
  int powerEnabled);

/**
 * @brief Control power to all LEDs
 *
 * Control power to all LEDs. For more information, visit our [LEDArray API
 * Guide](https://www.phidgets.com/docs/LEDArray_API_Guide#PowerEnabled).
 *
 * @param[in] ch The channel handle
 * @param[out] powerEnabled Control power to all LEDs
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLEDArray_getPowerEnabled(PhidgetLEDArrayHandle ch,
  int *powerEnabled);

/** @} */ /* PhidgetLEDArray */

/**
 * @defgroup PhidgetLightSensor LightSensor
 * @brief The Light Sensor class gathers data from the light sensor on a Phidget board.
 * @{
 */

/**
 * The Light Sensor class gathers data from the light sensor on a Phidget board.
 *
 * If you're using a simple 0-5V sensor that does not have its own firmware, use the VoltageInput or
 * VoltageRatioInput class instead, as specified for your device.
 */
typedef struct _PhidgetLightSensor *PhidgetLightSensorHandle;

/**
 * @ref PhidgetLightSensor_create() creates an instance of a Phidget channel. Once created the
 * channel may need to be configured to match the physical device and channel index you want to
 * attach to, and then be opened by calling @ref Phidget_open().
 * The Phidget channel handle must be released with @ref PhidgetLightSensor_delete().
 *
 * @param[out] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLightSensor_create(PhidgetLightSensorHandle *ch);

/**
 * @ref PhidgetLightSensor_delete() releases a Phidget channel handle created with @ref
 * PhidgetLightSensor_create().
 * If the channel is open when @ref PhidgetLightSensor_delete() is called, it will be closed.
 *
 * @param[out] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLightSensor_delete(PhidgetLightSensorHandle *ch);

/**
 * @brief The data interval value
 *
 * The `DataInterval` is the time that must elapse before the channel will fire another @ref
 * PhidgetLightSensor_setOnIlluminanceChangeHandler() event.
 *
 * *   The data interval is bounded by @ref PhidgetLightSensor_getMinDataInterval() and @ref
 *     PhidgetLightSensor_getMaxDataInterval().
 * *   The timing between @ref PhidgetLightSensor_setOnIlluminanceChangeHandler() events can
 *     also be affected by the `IlluminanceChangeTrigger`.
 *
 * @param[in] ch The channel handle
 * @param[in] dataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLightSensor_setDataInterval(PhidgetLightSensorHandle ch,
  uint32_t dataInterval);

/**
 * @brief The data interval value
 *
 * The `DataInterval` is the time that must elapse before the channel will fire another @ref
 * PhidgetLightSensor_setOnIlluminanceChangeHandler() event.
 *
 * *   The data interval is bounded by @ref PhidgetLightSensor_getMinDataInterval() and @ref
 *     PhidgetLightSensor_getMaxDataInterval().
 * *   The timing between @ref PhidgetLightSensor_setOnIlluminanceChangeHandler() events can
 *     also be affected by the `IlluminanceChangeTrigger`.
 *
 * @param[in] ch The channel handle
 * @param[out] dataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLightSensor_getDataInterval(PhidgetLightSensorHandle ch,
  uint32_t *dataInterval);

/**
 * @brief The data interval value
 *
 * The minimum value that `DataInterval` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minDataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLightSensor_getMinDataInterval(PhidgetLightSensorHandle ch,
  uint32_t *minDataInterval);

/**
 * @brief The data interval value
 *
 * The maximum value that `DataInterval` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxDataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLightSensor_getMaxDataInterval(PhidgetLightSensorHandle ch,
  uint32_t *maxDataInterval);

/**
 * @brief The data rate for the channel
 *
 * The `DataRate` is the frequency of events from the device.
 *
 * *   The data rate is bounded by @ref PhidgetLightSensor_getMinDataRate() and @ref
 *     PhidgetLightSensor_getMaxDataRate().
 * *   Changing `DataRate` will change the channel's `DataInterval` to a corresponding value,
 *     rounded to the nearest integer number of milliseconds.
 * *   The timing between events can also affected by the change trigger.
 *
 * @param[in] ch The channel handle
 * @param[in] dataRate The data rate for the channel
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLightSensor_setDataRate(PhidgetLightSensorHandle ch,
  double dataRate);

/**
 * @brief The data rate for the channel
 *
 * The `DataRate` is the frequency of events from the device.
 *
 * *   The data rate is bounded by @ref PhidgetLightSensor_getMinDataRate() and @ref
 *     PhidgetLightSensor_getMaxDataRate().
 * *   Changing `DataRate` will change the channel's `DataInterval` to a corresponding value,
 *     rounded to the nearest integer number of milliseconds.
 * *   The timing between events can also affected by the change trigger.
 *
 * @param[in] ch The channel handle
 * @param[out] dataRate The data rate for the channel
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLightSensor_getDataRate(PhidgetLightSensorHandle ch,
  double *dataRate);

/**
 * @brief The data rate value
 *
 * The minimum value that `DataRate` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minDataRate The data rate value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLightSensor_getMinDataRate(PhidgetLightSensorHandle ch,
  double *minDataRate);

/**
 * @brief The data rate value
 *
 * The maximum value that `DataRate` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxDataRate The data rate value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLightSensor_getMaxDataRate(PhidgetLightSensorHandle ch,
  double *maxDataRate);

/**
 * @brief The illuminance value
 *
 * The most recent illuminance value that the channel has reported.
 *
 * *   This value will always be between @ref PhidgetLightSensor_getMinIlluminance() and @ref
 *     PhidgetLightSensor_getMaxIlluminance().
 *
 * @param[in] ch The channel handle
 * @param[out] illuminance The illuminance value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLightSensor_getIlluminance(PhidgetLightSensorHandle ch,
  double *illuminance);

/**
 * @brief The illuminance value
 *
 * The minimum value the @ref PhidgetLightSensor_setOnIlluminanceChangeHandler() event will report.
 *
 * @param[in] ch The channel handle
 * @param[out] minIlluminance The illuminance value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLightSensor_getMinIlluminance(PhidgetLightSensorHandle ch,
  double *minIlluminance);

/**
 * @brief The illuminance value
 *
 * The maximum value the @ref PhidgetLightSensor_setOnIlluminanceChangeHandler() event will report.
 *
 * @param[in] ch The channel handle
 * @param[out] maxIlluminance The illuminance value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLightSensor_getMaxIlluminance(PhidgetLightSensorHandle ch,
  double *maxIlluminance);

/**
 * @brief The change trigger value
 *
 * The channel will not issue a @ref PhidgetLightSensor_setOnIlluminanceChangeHandler() event until
 * the illuminance value has changed by the amount specified by the `IlluminanceChangeTrigger`.
 *
 * *   Setting the `IlluminanceChangeTrigger` to 0 will result in the channel firing events
 *     every `DataInterval`. This is useful for applications that implement their own data filtering
 *
 * @param[in] ch The channel handle
 * @param[in] illuminanceChangeTrigger The change trigger value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLightSensor_setIlluminanceChangeTrigger(PhidgetLightSensorHandle ch,
  double illuminanceChangeTrigger);

/**
 * @brief The change trigger value
 *
 * The channel will not issue a @ref PhidgetLightSensor_setOnIlluminanceChangeHandler() event until
 * the illuminance value has changed by the amount specified by the `IlluminanceChangeTrigger`.
 *
 * *   Setting the `IlluminanceChangeTrigger` to 0 will result in the channel firing events
 *     every `DataInterval`. This is useful for applications that implement their own data filtering
 *
 * @param[in] ch The channel handle
 * @param[out] illuminanceChangeTrigger The change trigger value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLightSensor_getIlluminanceChangeTrigger(PhidgetLightSensorHandle ch,
  double *illuminanceChangeTrigger);

/**
 * @brief The change trigger value
 *
 * The minimum value that `IlluminanceChangeTrigger` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minIlluminanceChangeTrigger The change trigger value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLightSensor_getMinIlluminanceChangeTrigger(PhidgetLightSensorHandle ch,
  double *minIlluminanceChangeTrigger);

/**
 * @brief The change trigger value
 *
 * The maximum value that `IlluminanceChangeTrigger` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxIlluminanceChangeTrigger The change trigger value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLightSensor_getMaxIlluminanceChangeTrigger(PhidgetLightSensorHandle ch,
  double *maxIlluminanceChangeTrigger);

/**
 * @brief Callback function type for PhidgetLightSensor_setOnIlluminanceChangeHandler().
 *
 * @param[in] ch The channel handle
 * @param[in] ctx Pointer to the user context
 * @param[in] illuminance The current illuminance
 */
typedef void (CCONV *PhidgetLightSensor_OnIlluminanceChangeCallback)(PhidgetLightSensorHandle ch,
  void *ctx, double illuminance);

/**
 * The most recent illuminance value the channel has measured will be reported in this event, which
 * occurs when the `DataInterval` has elapsed.
 *
 * *   If a `IlluminanceChangeTrigger` has been set to a non-zero value, the @ref
 *     PhidgetLightSensor_setOnIlluminanceChangeHandler() event will not occur until the illuminance
 *     has changed by at least the `IlluminanceChangeTrigger` value.
 *
 * @param[in] ch The channel handle
 * @param[in] fptr The event handler callback function
 * @param[in] ctx User supplied context pointer
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLightSensor_setOnIlluminanceChangeHandler(PhidgetLightSensorHandle ch,
  PhidgetLightSensor_OnIlluminanceChangeCallback fptr, void *ctx);

/** @} */ /* PhidgetLightSensor */

/**
 * @defgroup PhidgetMagnetometer Magnetometer
 * @brief The Magnetometer class gathers magnetic compass data from Phidget boards. Phidget
 *     magnetometers usually have multiple sensors, each oriented in a different axis, so multiple
 *     dimensions of compass bearing can be recorded.
 * @{
 */

/**
 * The Magnetometer class gathers magnetic compass data from Phidget boards. Phidget magnetometers
 * usually have multiple sensors, each oriented in a different axis, so multiple dimensions of
 * compass bearing can be recorded.
 *
 * If the Phidget you're using also has a gyroscope and an accelerometer, you may want to use the
 * Spatial class in order to get all of the data at the same time, in a single event.
 */
typedef struct _PhidgetMagnetometer *PhidgetMagnetometerHandle;

/**
 * @ref PhidgetMagnetometer_create() creates an instance of a Phidget channel. Once created the
 * channel may need to be configured to match the physical device and channel index you want to
 * attach to, and then be opened by calling @ref Phidget_open().
 * The Phidget channel handle must be released with @ref PhidgetMagnetometer_delete().
 *
 * @param[out] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMagnetometer_create(PhidgetMagnetometerHandle *ch);

/**
 * @ref PhidgetMagnetometer_delete() releases a Phidget channel handle created with @ref
 * PhidgetMagnetometer_create().
 * If the channel is open when @ref PhidgetMagnetometer_delete() is called, it will be closed.
 *
 * @param[out] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMagnetometer_delete(PhidgetMagnetometerHandle *ch);

/**
 * Calibrate your device for the environment it will be used in.
 *
 * *   Due to physical location, hard and soft iron offsets, and even bias errors, your device
 *     should be calibrated. We have created a calibration program that will provide you with the
 *     `MagnetometerCorrectionParameters` for your specific situation. See your device's User Guide
 *     for more information.
 *
 * @param[in] ch The channel handle
 * @param[in] magneticField Ambient magnetic field value
 * @param[in] offset0 Provided by calibration program
 * @param[in] offset1 Provided by calibration program
 * @param[in] offset2 Provided by calibration program
 * @param[in] gain0 Provided by calibration program
 * @param[in] gain1 Provided by calibration program
 * @param[in] gain2 Provided by calibration program
 * @param[in] T0 Provided by calibration program
 * @param[in] T1 Provided by calibration program
 * @param[in] T2 Provided by calibration program
 * @param[in] T3 Provided by calibration program
 * @param[in] T4 Provided by calibration program
 * @param[in] T5 Provided by calibration program
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMagnetometer_setCorrectionParameters(PhidgetMagnetometerHandle ch,
  double magneticField, double offset0, double offset1, double offset2, double gain0, double gain1,
  double gain2, double T0, double T1, double T2, double T3, double T4, double T5);

/**
 * Resets the `MagnetometerCorrectionParameters` to their default values.
 *
 * *   Due to physical location, hard and soft iron offsets, and even bias errors, your device
 *     should be calibrated. We have created a calibration program that will provide you with the
 *     `MagnetometerCorrectionParameters` for your specific situation. See your device's User Guide
 *     for more information.
 *
 * @param[in] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMagnetometer_resetCorrectionParameters(PhidgetMagnetometerHandle ch);

/**
 * Saves the `MagnetometerCorrectionParameters`.
 *
 * *   Due to physical location, hard and soft iron offsets, and even bias errors, your device
 *     should be calibrated. We have created a calibration program that will provide you with the
 *     `MagnetometerCorrectionParameters` for your specific situation. See your device's User Guide
 *     for more information.
 *
 * @param[in] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMagnetometer_saveCorrectionParameters(PhidgetMagnetometerHandle ch);

/**
 * @brief The axis count value
 *
 * The number of axes the channel can measure field strength on.
 *
 * *   See your device's User Guide for more information about the number of axes and their
 *     orientation.
 *
 * @param[in] ch The channel handle
 * @param[out] axisCount The axis count value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMagnetometer_getAxisCount(PhidgetMagnetometerHandle ch,
  int *axisCount);

/**
 * @brief The data interval value
 *
 * The `DataInterval` is the time that must elapse before the channel will fire another @ref
 * PhidgetMagnetometer_setOnMagneticFieldChangeHandler() event.
 *
 * *   The data interval is bounded by @ref PhidgetMagnetometer_getMinDataInterval() and @ref
 *     PhidgetMagnetometer_getMaxDataInterval().
 * *   The timing between @ref PhidgetMagnetometer_setOnMagneticFieldChangeHandler() events can
 *     also be affected by the `MagneticFieldChangeTrigger`.
 *
 * @param[in] ch The channel handle
 * @param[in] dataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMagnetometer_setDataInterval(PhidgetMagnetometerHandle ch,
  uint32_t dataInterval);

/**
 * @brief The data interval value
 *
 * The `DataInterval` is the time that must elapse before the channel will fire another @ref
 * PhidgetMagnetometer_setOnMagneticFieldChangeHandler() event.
 *
 * *   The data interval is bounded by @ref PhidgetMagnetometer_getMinDataInterval() and @ref
 *     PhidgetMagnetometer_getMaxDataInterval().
 * *   The timing between @ref PhidgetMagnetometer_setOnMagneticFieldChangeHandler() events can
 *     also be affected by the `MagneticFieldChangeTrigger`.
 *
 * @param[in] ch The channel handle
 * @param[out] dataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMagnetometer_getDataInterval(PhidgetMagnetometerHandle ch,
  uint32_t *dataInterval);

/**
 * @brief The data interval value
 *
 * The minimum value that `DataInterval` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minDataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMagnetometer_getMinDataInterval(PhidgetMagnetometerHandle ch,
  uint32_t *minDataInterval);

/**
 * @brief The data interval value
 *
 * The maximum value that `DataInterval` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxDataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMagnetometer_getMaxDataInterval(PhidgetMagnetometerHandle ch,
  uint32_t *maxDataInterval);

/**
 * @brief The data rate for the channel
 *
 * The `DataRate` is the frequency of events from the device.
 *
 * *   The data rate is bounded by @ref PhidgetMagnetometer_getMinDataRate() and @ref
 *     PhidgetMagnetometer_getMaxDataRate().
 * *   Changing `DataRate` will change the channel's `DataInterval` to a corresponding value,
 *     rounded to the nearest integer number of milliseconds.
 * *   The timing between events can also affected by the change trigger.
 *
 * @param[in] ch The channel handle
 * @param[in] dataRate The data rate for the channel
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMagnetometer_setDataRate(PhidgetMagnetometerHandle ch,
  double dataRate);

/**
 * @brief The data rate for the channel
 *
 * The `DataRate` is the frequency of events from the device.
 *
 * *   The data rate is bounded by @ref PhidgetMagnetometer_getMinDataRate() and @ref
 *     PhidgetMagnetometer_getMaxDataRate().
 * *   Changing `DataRate` will change the channel's `DataInterval` to a corresponding value,
 *     rounded to the nearest integer number of milliseconds.
 * *   The timing between events can also affected by the change trigger.
 *
 * @param[in] ch The channel handle
 * @param[out] dataRate The data rate for the channel
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMagnetometer_getDataRate(PhidgetMagnetometerHandle ch,
  double *dataRate);

/**
 * @brief The data rate value
 *
 * The minimum value that `DataRate` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minDataRate The data rate value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMagnetometer_getMinDataRate(PhidgetMagnetometerHandle ch,
  double *minDataRate);

/**
 * @brief The data rate value
 *
 * The maximum value that `DataRate` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxDataRate The data rate value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMagnetometer_getMaxDataRate(PhidgetMagnetometerHandle ch,
  double *maxDataRate);

/**
 * @brief Whether self-heating temperature stabilization is enabled
 *
 * Set to TRUE to enable the temperature stabilization feature of this device. This enables onboard
 * heating elements to bring the board up to a known temperature to minimize ambient temerature
 * effects on the sensor's reading. You can leave this setting FALSE to conserve power consumption.
 *
 * If you enable heating, it is strongly recommended to keep the board in its enclosure to keep it
 * insulated from moving air.
 *
 * This property is shared by any and all spatial-related objects on this device (Accelerometer,
 * Gyroscope, Magnetometer, Spatial)
 *
 * @param[in] ch The channel handle
 * @param[in] heatingEnabled Whether self-heating temperature stabilization is enabled
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMagnetometer_setHeatingEnabled(PhidgetMagnetometerHandle ch,
  int heatingEnabled);

/**
 * @brief Whether self-heating temperature stabilization is enabled
 *
 * Set to TRUE to enable the temperature stabilization feature of this device. This enables onboard
 * heating elements to bring the board up to a known temperature to minimize ambient temerature
 * effects on the sensor's reading. You can leave this setting FALSE to conserve power consumption.
 *
 * If you enable heating, it is strongly recommended to keep the board in its enclosure to keep it
 * insulated from moving air.
 *
 * This property is shared by any and all spatial-related objects on this device (Accelerometer,
 * Gyroscope, Magnetometer, Spatial)
 *
 * @param[in] ch The channel handle
 * @param[out] heatingEnabled Whether self-heating temperature stabilization is enabled
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMagnetometer_getHeatingEnabled(PhidgetMagnetometerHandle ch,
  int *heatingEnabled);

/**
 * @brief The channel's measured MagneticField
 *
 * The most recent field strength value that the channel has reported.
 *
 * *   This value will always be between @ref PhidgetMagnetometer_getMinMagneticField() and @ref
 *     PhidgetMagnetometer_getMaxMagneticField().
 *
 * @param[in] ch The channel handle
 * @param[out] magneticField The channel's measured MagneticField
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMagnetometer_getMagneticField(PhidgetMagnetometerHandle ch,
  double (*magneticField)[3]);

/**
 * @brief The field strength value
 *
 * The minimum value the @ref PhidgetMagnetometer_setOnMagneticFieldChangeHandler() event will
 * report.Any readings outside this range will result in a @ref EEPHIDGET_SATURATION event. This
 * check is done after calibration values have been applied, which will affect your magnetometer's
 * range accordingly.
 *
 * @param[in] ch The channel handle
 * @param[out] minMagneticField The field strength value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMagnetometer_getMinMagneticField(PhidgetMagnetometerHandle ch,
  double (*minMagneticField)[3]);

/**
 * @brief The field strength value
 *
 * The maximum value the @ref PhidgetMagnetometer_setOnMagneticFieldChangeHandler() event will
 * report.Any readings outside this range will result in a @ref EEPHIDGET_SATURATION event. This
 * check is done after calibration values have been applied, which will affect your magnetometer's
 * range accordingly.
 *
 * @param[in] ch The channel handle
 * @param[out] maxMagneticField The field strength value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMagnetometer_getMaxMagneticField(PhidgetMagnetometerHandle ch,
  double (*maxMagneticField)[3]);

/**
 * @brief The change trigger value
 *
 * The channel will not issue a @ref PhidgetMagnetometer_setOnMagneticFieldChangeHandler() event
 * until the field strength value has changed by the amount specified by the
 * `MagneticFieldChangeTrigger`.
 *
 * *   Setting the `MagneticFieldChangeTrigger` to 0 will result in the channel firing events
 *     every `DataInterval`. This is useful for applications that implement their own data filtering
 *
 * @param[in] ch The channel handle
 * @param[in] magneticFieldChangeTrigger The change trigger value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMagnetometer_setMagneticFieldChangeTrigger(PhidgetMagnetometerHandle ch,
  double magneticFieldChangeTrigger);

/**
 * @brief The change trigger value
 *
 * The channel will not issue a @ref PhidgetMagnetometer_setOnMagneticFieldChangeHandler() event
 * until the field strength value has changed by the amount specified by the
 * `MagneticFieldChangeTrigger`.
 *
 * *   Setting the `MagneticFieldChangeTrigger` to 0 will result in the channel firing events
 *     every `DataInterval`. This is useful for applications that implement their own data filtering
 *
 * @param[in] ch The channel handle
 * @param[out] magneticFieldChangeTrigger The change trigger value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMagnetometer_getMagneticFieldChangeTrigger(PhidgetMagnetometerHandle ch,
  double *magneticFieldChangeTrigger);

/**
 * @brief The change trigger value
 *
 * The minimum value that `MagneticFieldChangeTrigger` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minMagneticFieldChangeTrigger The change trigger value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMagnetometer_getMinMagneticFieldChangeTrigger(PhidgetMagnetometerHandle ch,
  double *minMagneticFieldChangeTrigger);

/**
 * @brief The change trigger value
 *
 * The maximum value that `MagneticFieldChangeTrigger` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxMagneticFieldChangeTrigger The change trigger value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMagnetometer_getMaxMagneticFieldChangeTrigger(PhidgetMagnetometerHandle ch,
  double *maxMagneticFieldChangeTrigger);

/**
 * @brief The timestamp value
 *
 * The most recent timestamp value that the channel has reported. This is an extremely accurate time
 * measurement streamed from the device.
 *
 * *   If your application requires a time measurement, you should use this value over a local
 *     software timestamp.
 *
 * @param[in] ch The channel handle
 * @param[out] timestamp The timestamp value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMagnetometer_getTimestamp(PhidgetMagnetometerHandle ch,
  double *timestamp);

/**
 * @brief Callback function type for PhidgetMagnetometer_setOnMagneticFieldChangeHandler().
 *
 * @param[in] ch The channel handle
 * @param[in] ctx Pointer to the user context
 * @param[in] magneticField The magnetic field values
 * @param[in] timestamp The timestamp value
 */
typedef void (CCONV *PhidgetMagnetometer_OnMagneticFieldChangeCallback)(PhidgetMagnetometerHandle ch,
  void *ctx, const double magneticField[3], double timestamp);

/**
 * The most recent magnetic field values the channel has measured will be reported in this event,
 * which occurs when the `DataInterval` has elapsed.
 *
 * *   If a `MagneticFieldChangeTrigger` has been set to a non-zero value, the @ref
 *     PhidgetMagnetometer_setOnMagneticFieldChangeHandler() event will not occur until the field
 *     strength has changed by at least the `MagneticFieldChangeTrigger` value.
 *
 * @param[in] ch The channel handle
 * @param[in] fptr The event handler callback function
 * @param[in] ctx User supplied context pointer
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMagnetometer_setOnMagneticFieldChangeHandler(PhidgetMagnetometerHandle ch,
  PhidgetMagnetometer_OnMagneticFieldChangeCallback fptr, void *ctx);

/** @} */ /* PhidgetMagnetometer */

/**
 * @defgroup PhidgetMotorPositionController MotorPositionController
 * @brief The Motor Position Controller class controlls the position, velocity and acceleration
 *     of the attached motor. It also contains various other control and monitoring functions that
 *     aid in the control of the motor.
 * @{
 */

/**
 * The Motor Position Controller class controlls the position, velocity and acceleration of the
 * attached motor. It also contains various other control and monitoring functions that aid in the
 * control of the motor.
 *
 * For specifics on how to use this class, we recommend watching our video on the [Phidget Motor
 * Position Controller](https://www.youtube.com/watch?v=0cQlxNd7dk4) class.
 */
typedef struct _PhidgetMotorPositionController *PhidgetMotorPositionControllerHandle;

/**
 * @ref PhidgetMotorPositionController_create() creates an instance of a Phidget channel. Once
 * created the channel may need to be configured to match the physical device and channel index you
 * want to attach to, and then be opened by calling @ref Phidget_open().
 * The Phidget channel handle must be released with @ref PhidgetMotorPositionController_delete().
 *
 * @param[out] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_create(PhidgetMotorPositionControllerHandle *ch);

/**
 * @ref PhidgetMotorPositionController_delete() releases a Phidget channel handle created with @ref
 * PhidgetMotorPositionController_create().
 * If the channel is open when @ref PhidgetMotorPositionController_delete() is called, it will be
 * closed.
 *
 * @param[out] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_delete(PhidgetMotorPositionControllerHandle *ch);

/**
 * Enables the **failsafe** feature for the channel, with the specified **failsafe time**.
 *
 * Enabling the failsafe feature starts a recurring **failsafe timer** for the channel. Once the
 * failsafe is enabled, the timer must be reset within the specified time or the channel will enter
 * a **failsafe state**. For Motor Position Controller channels, this will cut power to the motor,
 * allowing it to coast (freewheel) instead. The failsafe timer can be reset by using any API call
 * **_except_** for the following:
 *
 * *   @ref PhidgetMotorPositionController_setRescaleFactor()
 * *   @ref PhidgetMotorPositionController_addPositionOffset()
 * *   @ref PhidgetMotorPositionController_setNormalizePID()
 * *   'get' API calls
 *
 * For more information about failsafe, visit our [Failsafe
 * Guide](https://www.phidgets.com/docs/Failsafe_Guide).
 *
 * @param[in] ch The channel handle
 * @param[in] failsafeTime Failsafe timeout in milliseconds
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_enableFailsafe(PhidgetMotorPositionControllerHandle ch,
  uint32_t failsafeTime);

/**
 * Adds an offset (positive or negative) to the current position. Useful for zeroing position.
 *
 * @param[in] ch The channel handle
 * @param[in] positionOffset Amount to offset the position by
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_addPositionOffset(PhidgetMotorPositionControllerHandle ch,
  double positionOffset);

/**
 * Resets the failsafe timer, if one has been set. See @ref
 * PhidgetMotorPositionController_enableFailsafe() for details.
 *
 * This function will fail if no failsafe timer has been set for the channel.
 *
 * @param[in] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_resetFailsafe(PhidgetMotorPositionControllerHandle ch);

/**
 * @brief The acceleration value
 *
 * The rate at which the controller can change the motor's velocity.
 *
 * *   Use the `RescaleFactor` to convert the units of this property to more intuitive units,
 *     such as rotations or degrees.
 *
 * For more information about `Acceleration`, visit our [MotorPositionController API
 * Guide](https://www.phidgets.com/docs/MotorPositionController_API_Guide#Acceleration)
 *
 * @param[in] ch The channel handle
 * @param[in] acceleration The acceleration value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_setAcceleration(PhidgetMotorPositionControllerHandle ch,
  double acceleration);

/**
 * @brief The acceleration value
 *
 * The rate at which the controller can change the motor's velocity.
 *
 * *   Use the `RescaleFactor` to convert the units of this property to more intuitive units,
 *     such as rotations or degrees.
 *
 * For more information about `Acceleration`, visit our [MotorPositionController API
 * Guide](https://www.phidgets.com/docs/MotorPositionController_API_Guide#Acceleration)
 *
 * @param[in] ch The channel handle
 * @param[out] acceleration The acceleration value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_getAcceleration(PhidgetMotorPositionControllerHandle ch,
  double *acceleration);

/**
 * @brief The acceleration value.
 *
 * The minimum value that `Acceleration` can be set to.
 *
 * *   Use the `RescaleFactor` to convert the units of this property to more intuitive units,
 *     such as rotations or degrees.
 *
 * @param[in] ch The channel handle
 * @param[out] minAcceleration The acceleration value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_getMinAcceleration(PhidgetMotorPositionControllerHandle ch,
  double *minAcceleration);

/**
 * @brief The acceleration value.
 *
 * The maximum value that `Acceleration` can be set to.
 *
 * *   Use the `RescaleFactor` to convert the units of this property to more intuitive units,
 *     such as rotations or degrees.
 *
 * @param[in] ch The channel handle
 * @param[out] maxAcceleration The acceleration value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_getMaxAcceleration(PhidgetMotorPositionControllerHandle ch,
  double *maxAcceleration);

/**
 * @brief The active current limit value
 *
 * The current limit that the controller is actively following. The `SurgeCurrentLimit`,
 * `CurrentLimit`, and temperature will impact this value.
 *
 * @param[in] ch The channel handle
 * @param[out] activeCurrentLimit The active current limit value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_getActiveCurrentLimit(PhidgetMotorPositionControllerHandle ch,
  double *activeCurrentLimit);

/**
 * @brief Motor current limit
 *
 * The controller will limit the current through the motor to the `CurrentLimit` value.
 *
 * For more information about `CurrentLimit`, visit our [MotorPositionController API
 * Guide](https://www.phidgets.com/docs/MotorPositionController_API_Guide#Current_Limit)
 *
 * @param[in] ch The channel handle
 * @param[in] currentLimit Motor current limit
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_setCurrentLimit(PhidgetMotorPositionControllerHandle ch,
  double currentLimit);

/**
 * @brief Motor current limit
 *
 * The controller will limit the current through the motor to the `CurrentLimit` value.
 *
 * For more information about `CurrentLimit`, visit our [MotorPositionController API
 * Guide](https://www.phidgets.com/docs/MotorPositionController_API_Guide#Current_Limit)
 *
 * @param[in] ch The channel handle
 * @param[out] currentLimit Motor current limit
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_getCurrentLimit(PhidgetMotorPositionControllerHandle ch,
  double *currentLimit);

/**
 * @brief Minimum current limit
 *
 * The minimum current limit that can be set for the device.
 *
 * @param[in] ch The channel handle
 * @param[out] minCurrentLimit Minimum current limit
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_getMinCurrentLimit(PhidgetMotorPositionControllerHandle ch,
  double *minCurrentLimit);

/**
 * @brief Maximum current limit
 *
 * The maximum current limit that can be set for the device.
 *
 * @param[in] ch The channel handle
 * @param[out] maxCurrentLimit Maximum current limit
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_getMaxCurrentLimit(PhidgetMotorPositionControllerHandle ch,
  double *maxCurrentLimit);

/**
 * @brief Current Regulator Gain
 *
 * Depending on power supply voltage and motor coil inductance, current through the motor can change
 * relatively slowly or extremely rapidly. A physically larger DC Motor will typically have a lower
 * inductance, requiring a higher current regulator gain. A higher power supply voltage will result
 * in motor current changing more rapidly, requiring a higher current regulator gain. If the current
 * regulator gain is too small, spikes in current will occur, causing large variations in torque,
 * and possibly damaging the motor controller. If the current regulator gain is too high, the
 * current will jitter, causing the motor to sound 'rough', especially when changing directions.
 * Each DC Motor we sell specifies a suitable current regulator gain.
 *
 * @param[in] ch The channel handle
 * @param[in] currentRegulatorGain Current Regulator Gain
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_setCurrentRegulatorGain(PhidgetMotorPositionControllerHandle ch,
  double currentRegulatorGain);

/**
 * @brief Current Regulator Gain
 *
 * Depending on power supply voltage and motor coil inductance, current through the motor can change
 * relatively slowly or extremely rapidly. A physically larger DC Motor will typically have a lower
 * inductance, requiring a higher current regulator gain. A higher power supply voltage will result
 * in motor current changing more rapidly, requiring a higher current regulator gain. If the current
 * regulator gain is too small, spikes in current will occur, causing large variations in torque,
 * and possibly damaging the motor controller. If the current regulator gain is too high, the
 * current will jitter, causing the motor to sound 'rough', especially when changing directions.
 * Each DC Motor we sell specifies a suitable current regulator gain.
 *
 * @param[in] ch The channel handle
 * @param[out] currentRegulatorGain Current Regulator Gain
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_getCurrentRegulatorGain(PhidgetMotorPositionControllerHandle ch,
  double *currentRegulatorGain);

/**
 * @brief Minimum current regulator gain
 *
 * The minimum current regulator gain for the device.
 *
 * @param[in] ch The channel handle
 * @param[out] minCurrentRegulatorGain Minimum current regulator gain
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_getMinCurrentRegulatorGain(PhidgetMotorPositionControllerHandle ch,
  double *minCurrentRegulatorGain);

/**
 * @brief Maximum current regulator gain
 *
 * The maximum current regulator gain for the device.
 *
 * @param[in] ch The channel handle
 * @param[out] maxCurrentRegulatorGain Maximum current regulator gain
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_getMaxCurrentRegulatorGain(PhidgetMotorPositionControllerHandle ch,
  double *maxCurrentRegulatorGain);

/**
 * @brief The data interval value
 *
 * The `DataInterval` is the time that must elapse before the channel will fire another @ref
 * PhidgetMotorPositionController_setOnPositionChangeHandler() / @ref
 * PhidgetMotorPositionController_setOnDutyCycleUpdateHandler() event.
 *
 * *   The data interval is bounded by @ref PhidgetMotorPositionController_getMinDataInterval()
 *     and @ref PhidgetMotorPositionController_getMaxDataInterval().
 *
 * @param[in] ch The channel handle
 * @param[in] dataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_setDataInterval(PhidgetMotorPositionControllerHandle ch,
  uint32_t dataInterval);

/**
 * @brief The data interval value
 *
 * The `DataInterval` is the time that must elapse before the channel will fire another @ref
 * PhidgetMotorPositionController_setOnPositionChangeHandler() / @ref
 * PhidgetMotorPositionController_setOnDutyCycleUpdateHandler() event.
 *
 * *   The data interval is bounded by @ref PhidgetMotorPositionController_getMinDataInterval()
 *     and @ref PhidgetMotorPositionController_getMaxDataInterval().
 *
 * @param[in] ch The channel handle
 * @param[out] dataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_getDataInterval(PhidgetMotorPositionControllerHandle ch,
  uint32_t *dataInterval);

/**
 * @brief The data interval value
 *
 * The minimum value that `DataInterval` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minDataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_getMinDataInterval(PhidgetMotorPositionControllerHandle ch,
  uint32_t *minDataInterval);

/**
 * @brief The data interval value
 *
 * The maximum value that `DataInterval` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxDataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_getMaxDataInterval(PhidgetMotorPositionControllerHandle ch,
  uint32_t *maxDataInterval);

/**
 * @brief The data rate for the channel
 *
 * The `DataRate` is the frequency of events from the device.
 *
 * *   The data rate is bounded by @ref PhidgetMotorPositionController_getMinDataRate() and @ref
 *     PhidgetMotorPositionController_getMaxDataRate().
 * *   Changing `DataRate` will change the channel's `DataInterval` to a corresponding value,
 *     rounded to the nearest integer number of milliseconds.
 * *   The timing between events can also affected by the change trigger.
 *
 * @param[in] ch The channel handle
 * @param[in] dataRate The data rate for the channel
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_setDataRate(PhidgetMotorPositionControllerHandle ch,
  double dataRate);

/**
 * @brief The data rate for the channel
 *
 * The `DataRate` is the frequency of events from the device.
 *
 * *   The data rate is bounded by @ref PhidgetMotorPositionController_getMinDataRate() and @ref
 *     PhidgetMotorPositionController_getMaxDataRate().
 * *   Changing `DataRate` will change the channel's `DataInterval` to a corresponding value,
 *     rounded to the nearest integer number of milliseconds.
 * *   The timing between events can also affected by the change trigger.
 *
 * @param[in] ch The channel handle
 * @param[out] dataRate The data rate for the channel
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_getDataRate(PhidgetMotorPositionControllerHandle ch,
  double *dataRate);

/**
 * @brief The data rate value
 *
 * The minimum value that `DataRate` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minDataRate The data rate value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_getMinDataRate(PhidgetMotorPositionControllerHandle ch,
  double *minDataRate);

/**
 * @brief The data rate value
 *
 * The maximum value that `DataRate` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxDataRate The data rate value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_getMaxDataRate(PhidgetMotorPositionControllerHandle ch,
  double *maxDataRate);

/**
 * @brief The dead band value
 *
 * `DeadBand` specifies a a region around the `TargetPosition` (`TargetPosition` \+/\- `DeadBand`)
 * where control of the motor is relaxed.
 *
 * *   Use the `RescaleFactor` to convert the units of this property to more intuitive units,
 *     such as rotations or degrees.
 *
 * For more information about `DeadBand`, visit our [MotorPositionController API
 * Guide](https://www.phidgets.com/docs/MotorPositionController_API_Guide#Deadband)
 *
 * @param[in] ch The channel handle
 * @param[in] deadBand The dead band value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_setDeadBand(PhidgetMotorPositionControllerHandle ch,
  double deadBand);

/**
 * @brief The dead band value
 *
 * `DeadBand` specifies a a region around the `TargetPosition` (`TargetPosition` \+/\- `DeadBand`)
 * where control of the motor is relaxed.
 *
 * *   Use the `RescaleFactor` to convert the units of this property to more intuitive units,
 *     such as rotations or degrees.
 *
 * For more information about `DeadBand`, visit our [MotorPositionController API
 * Guide](https://www.phidgets.com/docs/MotorPositionController_API_Guide#Deadband)
 *
 * @param[in] ch The channel handle
 * @param[out] deadBand The dead band value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_getDeadBand(PhidgetMotorPositionControllerHandle ch,
  double *deadBand);

/**
 * @brief The duty cycle value.
 *
 * The most recent @ref PhidgetMotorPositionController_getDutyCycle() value that the controller has
 * reported.
 *
 * *   This value will be between -1 and 1 where a sign change (±) is indicitave of a direction
 *     change.
 * *   @ref PhidgetMotorPositionController_getDutyCycle() is an indication of the average
 *     voltage across the motor. At a constant load, an increase in @ref
 *     PhidgetMotorPositionController_getDutyCycle() indicates an increase in motor speed.
 *
 * For more information about @ref PhidgetMotorPositionController_getDutyCycle(), visit our
 * [MotorPositionController API
 * Guide](https://www.phidgets.com/docs/MotorPositionController_API_Guide#Duty_Cycle)
 *
 * @param[in] ch The channel handle
 * @param[out] dutyCycle The duty cycle value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_getDutyCycle(PhidgetMotorPositionControllerHandle ch,
  double *dutyCycle);

/**
 * @brief The engaged value.
 *
 * When engaged, the motor has the ability to be positioned. When disengaged, the controller will
 * stop powering to your motor, it will instead be in a freewheel state.
 *
 * For more information about `Engaged`, visit our [MotorPositionController API
 * Guide](https://www.phidgets.com/docs/MotorPositionController_API_Guide#Engage_Motor)
 *
 * @param[in] ch The channel handle
 * @param[in] engaged The engaged value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_setEngaged(PhidgetMotorPositionControllerHandle ch,
  int engaged);

/**
 * @brief The engaged value.
 *
 * When engaged, the motor has the ability to be positioned. When disengaged, the controller will
 * stop powering to your motor, it will instead be in a freewheel state.
 *
 * For more information about `Engaged`, visit our [MotorPositionController API
 * Guide](https://www.phidgets.com/docs/MotorPositionController_API_Guide#Engage_Motor)
 *
 * @param[in] ch The channel handle
 * @param[out] engaged The engaged value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_getEngaged(PhidgetMotorPositionControllerHandle ch,
  int *engaged);

/**
 * @brief The expected position value
 *
 * This controller uses trapezoidal motion profiling combined with a PID loop to accurately track
 * position. The @ref PhidgetMotorPositionController_getExpectedPosition() represents the current
 * position the controller is tracking along the trapezoidal motion curve. The error of your PID
 * loop is calculated by taking the difference of @ref PhidgetMotorPositionController_getPosition()
 * and @ref PhidgetMotorPositionController_getExpectedPosition(). You can use this value to verify
 * your controller is working as expected.
 *
 * *   Set `EnableExpectedPosition` to **TRUE** to enable the change event for this property.
 * *   Use the `RescaleFactor` to convert the units of this property to more intuitive units,
 *     such as rotations or degrees.
 *
 * @param[in] ch The channel handle
 * @param[out] expectedPosition The expected position value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_getExpectedPosition(PhidgetMotorPositionControllerHandle ch,
  double *expectedPosition);

/**
 * @brief Enable expected position feedback
 *
 * When enabled, the @ref PhidgetMotorPositionController_getExpectedPosition() will be sent back
 * from the controller.
 *
 * @param[in] ch The channel handle
 * @param[in] enableExpectedPosition Enable expected position feedback
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_setEnableExpectedPosition(PhidgetMotorPositionControllerHandle ch,
  int enableExpectedPosition);

/**
 * @brief Enable expected position feedback
 *
 * When enabled, the @ref PhidgetMotorPositionController_getExpectedPosition() will be sent back
 * from the controller.
 *
 * @param[in] ch The channel handle
 * @param[out] enableExpectedPosition Enable expected position feedback
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_getEnableExpectedPosition(PhidgetMotorPositionControllerHandle ch,
  int *enableExpectedPosition);

/**
 * @brief Enables failsafe braking
 *
 * This setting allows you to choose whether motor will forcibly stop once it enters a **FAILSAFE**
 * state.
 *
 * *   A setting of FALSE will simply stop applying power to the motor, allowing it to spin down
 *     naturally.
 * *   A setting of TRUE will apply braking up to the `FailsafeCurrentLimit`, actively stopping
 *     the motor
 *
 * For more information about `FailsafeBrakingEnabled`, visit our [MotorPositionController API
 * Guide](https://www.phidgets.com/docs/MotorPositionController_API_Guide#Failsafe_Braking_Enabled)
 *
 * @param[in] ch The channel handle
 * @param[in] failsafeBrakingEnabled Enables failsafe braking
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_setFailsafeBrakingEnabled(PhidgetMotorPositionControllerHandle ch,
  int failsafeBrakingEnabled);

/**
 * @brief Enables failsafe braking
 *
 * This setting allows you to choose whether motor will forcibly stop once it enters a **FAILSAFE**
 * state.
 *
 * *   A setting of FALSE will simply stop applying power to the motor, allowing it to spin down
 *     naturally.
 * *   A setting of TRUE will apply braking up to the `FailsafeCurrentLimit`, actively stopping
 *     the motor
 *
 * For more information about `FailsafeBrakingEnabled`, visit our [MotorPositionController API
 * Guide](https://www.phidgets.com/docs/MotorPositionController_API_Guide#Failsafe_Braking_Enabled)
 *
 * @param[in] ch The channel handle
 * @param[out] failsafeBrakingEnabled Enables failsafe braking
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_getFailsafeBrakingEnabled(PhidgetMotorPositionControllerHandle ch,
  int *failsafeBrakingEnabled);

/**
 * @brief The failsafe current limit value
 *
 * When the controller enters a **FAILSAFE** state, the controller will limit the current through
 * the motor to the `FailsafeCurrentLimit` value.
 *
 * For more information about `FailsafeCurrentLimit`, visit our [MotorPositionController API
 * Guide](https://www.phidgets.com/docs/MotorPositionController_API_Guide#Failsafe_Current_Limit)
 *
 * @param[in] ch The channel handle
 * @param[in] failsafeCurrentLimit The failsafe current limit value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_setFailsafeCurrentLimit(PhidgetMotorPositionControllerHandle ch,
  double failsafeCurrentLimit);

/**
 * @brief The failsafe current limit value
 *
 * When the controller enters a **FAILSAFE** state, the controller will limit the current through
 * the motor to the `FailsafeCurrentLimit` value.
 *
 * For more information about `FailsafeCurrentLimit`, visit our [MotorPositionController API
 * Guide](https://www.phidgets.com/docs/MotorPositionController_API_Guide#Failsafe_Current_Limit)
 *
 * @param[in] ch The channel handle
 * @param[out] failsafeCurrentLimit The failsafe current limit value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_getFailsafeCurrentLimit(PhidgetMotorPositionControllerHandle ch,
  double *failsafeCurrentLimit);

/**
 * @brief The failsafe time
 *
 * The minimum value that `failsafeTime` can be set to when calling @ref
 * PhidgetMotorPositionController_enableFailsafe().
 *
 * @param[in] ch The channel handle
 * @param[out] minFailsafeTime The failsafe time
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_getMinFailsafeTime(PhidgetMotorPositionControllerHandle ch,
  uint32_t *minFailsafeTime);

/**
 * @brief The failsafe time
 *
 * The maximum value that `failsafeTime` can be set to when calling @ref
 * PhidgetMotorPositionController_enableFailsafe().
 *
 * @param[in] ch The channel handle
 * @param[out] maxFailsafeTime The failsafe time
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_getMaxFailsafeTime(PhidgetMotorPositionControllerHandle ch,
  uint32_t *maxFailsafeTime);

/**
 * @brief The fan mode
 *
 * The `FanMode` dictates the operating condition of the fan.
 *
 * *   Choose between on, off, or automatic (based on temperature).
 * *   If the `FanMode` is set to automatic, the fan will turn on when the temperature reaches
 *     70°C and it will remain on until the temperature falls below 55°C.
 * *   If the `FanMode` is off, the controller will still turn on the fan if the temperature
 *     reaches 85°C and it will remain on until it falls below 70°C.
 *
 * @param[in] ch The channel handle
 * @param[in] fanMode The fan mode
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_setFanMode(PhidgetMotorPositionControllerHandle ch,
  Phidget_FanMode fanMode);

/**
 * @brief The fan mode
 *
 * The `FanMode` dictates the operating condition of the fan.
 *
 * *   Choose between on, off, or automatic (based on temperature).
 * *   If the `FanMode` is set to automatic, the fan will turn on when the temperature reaches
 *     70°C and it will remain on until the temperature falls below 55°C.
 * *   If the `FanMode` is off, the controller will still turn on the fan if the temperature
 *     reaches 85°C and it will remain on until it falls below 70°C.
 *
 * @param[in] ch The channel handle
 * @param[out] fanMode The fan mode
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_getFanMode(PhidgetMotorPositionControllerHandle ch,
  Phidget_FanMode *fanMode);

/**
 * @brief The inductance of your motor
 *
 * The controller will attempt to measure the inductance of your motor when opened. This value is
 * used to improve control of the motor.
 *
 * *   Set this value during the @ref Phidget_setOnAttachHandler() event to skip motor
 *     characterization (including the audible beeps). You can use a previously saved `Inductance`
 *     value, or information from your motor's datasheet.
 *
 * For more information about `Inductance`, visit our [MotorPositionController API
 * Guide](https://www.phidgets.com/docs/MotorPositionController_API_Guide#Motor_Inductance)
 *
 * @param[in] ch The channel handle
 * @param[in] inductance The inductance of your motor
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_setInductance(PhidgetMotorPositionControllerHandle ch,
  double inductance);

/**
 * @brief The inductance of your motor
 *
 * The controller will attempt to measure the inductance of your motor when opened. This value is
 * used to improve control of the motor.
 *
 * *   Set this value during the @ref Phidget_setOnAttachHandler() event to skip motor
 *     characterization (including the audible beeps). You can use a previously saved `Inductance`
 *     value, or information from your motor's datasheet.
 *
 * For more information about `Inductance`, visit our [MotorPositionController API
 * Guide](https://www.phidgets.com/docs/MotorPositionController_API_Guide#Motor_Inductance)
 *
 * @param[in] ch The channel handle
 * @param[out] inductance The inductance of your motor
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_getInductance(PhidgetMotorPositionControllerHandle ch,
  double *inductance);

/**
 * @brief The motor inductance value
 *
 * The minimum value that `Inductance` can be set to. See `Inductance` for details.
 *
 * @param[in] ch The channel handle
 * @param[out] minInductance The motor inductance value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_getMinInductance(PhidgetMotorPositionControllerHandle ch,
  double *minInductance);

/**
 * @brief The motor inductance value
 *
 * The maximum value that `Inductance` can be set to. See `Inductance` for details.
 *
 * @param[in] ch The channel handle
 * @param[out] maxInductance The motor inductance value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_getMaxInductance(PhidgetMotorPositionControllerHandle ch,
  double *maxInductance);

/**
 * @brief The IO mode value.
 *
 * The encoder interface mode. Match the mode to the type of encoder you have attached.
 *
 * *   It is recommended to only change this when the encoder disabled in order to avoid
 *     unexpected results.
 *
 * @param[in] ch The channel handle
 * @param[in] IOMode The IO mode value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_setIOMode(PhidgetMotorPositionControllerHandle ch,
  Phidget_EncoderIOMode IOMode);

/**
 * @brief The IO mode value.
 *
 * The encoder interface mode. Match the mode to the type of encoder you have attached.
 *
 * *   It is recommended to only change this when the encoder disabled in order to avoid
 *     unexpected results.
 *
 * @param[in] ch The channel handle
 * @param[out] IOMode The IO mode value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_getIOMode(PhidgetMotorPositionControllerHandle ch,
  Phidget_EncoderIOMode *IOMode);

/**
 * @brief The Kd value.
 *
 * Derivative gain constant. A higher `Kd` will help reduce oscillations.
 *
 * For more information about `Kd`, visit our [MotorPositionController API
 * Guide](https://www.phidgets.com/docs/MotorPositionController_API_Guide#Tunings_Constants_(Kp,_Ki,_Kd))
 *
 * @param[in] ch The channel handle
 * @param[in] kd The Kd value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_setKd(PhidgetMotorPositionControllerHandle ch,
  double kd);

/**
 * @brief The Kd value.
 *
 * Derivative gain constant. A higher `Kd` will help reduce oscillations.
 *
 * For more information about `Kd`, visit our [MotorPositionController API
 * Guide](https://www.phidgets.com/docs/MotorPositionController_API_Guide#Tunings_Constants_(Kp,_Ki,_Kd))
 *
 * @param[in] ch The channel handle
 * @param[out] kd The Kd value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_getKd(PhidgetMotorPositionControllerHandle ch,
  double *kd);

/**
 * @brief The Ki value.
 *
 * Integral gain constant. The integral term will help eliminate steady-state error.
 *
 * For more information about `Ki`, visit our [MotorPositionController API
 * Guide](https://www.phidgets.com/docs/MotorPositionController_API_Guide#Tunings_Constants_(Kp,_Ki,_Kd))
 *
 * @param[in] ch The channel handle
 * @param[in] ki The Ki value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_setKi(PhidgetMotorPositionControllerHandle ch,
  double ki);

/**
 * @brief The Ki value.
 *
 * Integral gain constant. The integral term will help eliminate steady-state error.
 *
 * For more information about `Ki`, visit our [MotorPositionController API
 * Guide](https://www.phidgets.com/docs/MotorPositionController_API_Guide#Tunings_Constants_(Kp,_Ki,_Kd))
 *
 * @param[in] ch The channel handle
 * @param[out] ki The Ki value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_getKi(PhidgetMotorPositionControllerHandle ch,
  double *ki);

/**
 * @brief The Kp value.
 *
 * Proportional gain constant. A small `Kp` value will result in a less responsive controller,
 * however, if `Kp` is too high, the system can become unstable.
 *
 * For more information about `Kp`, visit our [MotorPositionController API
 * Guide](https://www.phidgets.com/docs/MotorPositionController_API_Guide#Tunings_Constants_(Kp,_Ki,_Kd))
 *
 * @param[in] ch The channel handle
 * @param[in] kp The Kp value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_setKp(PhidgetMotorPositionControllerHandle ch,
  double kp);

/**
 * @brief The Kp value.
 *
 * Proportional gain constant. A small `Kp` value will result in a less responsive controller,
 * however, if `Kp` is too high, the system can become unstable.
 *
 * For more information about `Kp`, visit our [MotorPositionController API
 * Guide](https://www.phidgets.com/docs/MotorPositionController_API_Guide#Tunings_Constants_(Kp,_Ki,_Kd))
 *
 * @param[in] ch The channel handle
 * @param[out] kp The Kp value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_getKp(PhidgetMotorPositionControllerHandle ch,
  double *kp);

/**
 * @brief Set this parameter to TRUE to adjust PID math to standardized units.
 *
 * Set this parameter to TRUE to adjust PID math to standardized units.
 *
 * @param[in] ch The channel handle
 * @param[in] normalizePID Set this parameter to TRUE to adjust PID math to standardized units
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_setNormalizePID(PhidgetMotorPositionControllerHandle ch,
  int normalizePID);

/**
 * @brief Set this parameter to TRUE to adjust PID math to standardized units.
 *
 * Set this parameter to TRUE to adjust PID math to standardized units.
 *
 * @param[in] ch The channel handle
 * @param[out] normalizePID Set this parameter to TRUE to adjust PID math to standardized units
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_getNormalizePID(PhidgetMotorPositionControllerHandle ch,
  int *normalizePID);

/**
 * @brief The position value
 *
 * The most recent position value that the controller has reported.
 *
 * *   Use the `RescaleFactor` to convert the units of this property to more intuitive units,
 *     such as rotations or degrees.
 *
 * For more information about @ref PhidgetMotorPositionController_getPosition(), visit our
 * [MotorPositionController API
 * Guide](https://www.phidgets.com/docs/MotorPositionController_API_Guide#Position)
 *
 * @param[in] ch The channel handle
 * @param[out] position The position value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_getPosition(PhidgetMotorPositionControllerHandle ch,
  double *position);

/**
 * @brief The position value
 *
 * The minimum value that `TargetPosition` can be set to.
 *
 * *   Use the `RescaleFactor` to convert the units of this property to more intuitive units,
 *     such as rotations or degrees.
 *
 * @param[in] ch The channel handle
 * @param[out] minPosition The position value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_getMinPosition(PhidgetMotorPositionControllerHandle ch,
  double *minPosition);

/**
 * @brief The position value
 *
 * The maximum value that `TargetPosition` can be set to.
 *
 * *   Use the `RescaleFactor` to convert the units of this property to more intuitive units,
 *     such as rotations or degrees.
 *
 * @param[in] ch The channel handle
 * @param[out] maxPosition The position value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_getMaxPosition(PhidgetMotorPositionControllerHandle ch,
  double *maxPosition);

/**
 * @brief The position type selection
 *
 * Determines whether the controller uses the hall effect sensors or an encoder for position
 * information. This setting is locked in once the channel is `Engaged` and cannot be changed until
 * the channel is reset.
 *
 * @param[in] ch The channel handle
 * @param[in] positionType The position type selection
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_setPositionType(PhidgetMotorPositionControllerHandle ch,
  Phidget_PositionType positionType);

/**
 * @brief The position type selection
 *
 * Determines whether the controller uses the hall effect sensors or an encoder for position
 * information. This setting is locked in once the channel is `Engaged` and cannot be changed until
 * the channel is reset.
 *
 * @param[in] ch The channel handle
 * @param[out] positionType The position type selection
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_getPositionType(PhidgetMotorPositionControllerHandle ch,
  Phidget_PositionType *positionType);

/**
 * @brief The rescale factor value
 *
 * Change the units of your parameters so that your application is more intuitive.
 *
 * *   Units for @ref PhidgetMotorPositionController_getPosition(), `TargetPosition`,
 *     `VelocityLimit`, `Acceleration`, and `DeadBand` can be set by the user through the
 *     `RescaleFactor`. The `RescaleFactor` allows you to use more intuitive units such as
 *     rotations, or degrees.
 *
 * For more information about `RescaleFactor`, visit our [MotorPositionController API
 * Guide](https://www.phidgets.com/docs/MotorPositionController_API_Guide#Rescale_Factor)
 *
 * @param[in] ch The channel handle
 * @param[in] rescaleFactor The rescale factor value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_setRescaleFactor(PhidgetMotorPositionControllerHandle ch,
  double rescaleFactor);

/**
 * @brief The rescale factor value
 *
 * Change the units of your parameters so that your application is more intuitive.
 *
 * *   Units for @ref PhidgetMotorPositionController_getPosition(), `TargetPosition`,
 *     `VelocityLimit`, `Acceleration`, and `DeadBand` can be set by the user through the
 *     `RescaleFactor`. The `RescaleFactor` allows you to use more intuitive units such as
 *     rotations, or degrees.
 *
 * For more information about `RescaleFactor`, visit our [MotorPositionController API
 * Guide](https://www.phidgets.com/docs/MotorPositionController_API_Guide#Rescale_Factor)
 *
 * @param[in] ch The channel handle
 * @param[out] rescaleFactor The rescale factor value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_getRescaleFactor(PhidgetMotorPositionControllerHandle ch,
  double *rescaleFactor);

/**
 * @brief The stall velocity value.
 *
 * Before reading this description, it is important to note the difference between the units of
 * `StallVelocity` and @ref PhidgetMotorPositionController_getDutyCycle().
 *
 * *   @ref PhidgetMotorPositionController_getDutyCycle() is a number between -1 and 1 with
 *     units of 'duty cycle'. It simply represents the average voltage across the motor.
 * *   `StallVelocity` represents a real velocity (e.g. m/s, RPM, etc.) and the units are
 *     determined by the `RescaleFactor`. With a `RescaleFactor` of 1, the default units would be in
 *     commutations per second.
 *
 * If the load on your motor is large, your motor may begin rotating more slowly, or even fully
 * stall. Depending on the voltage across your motor, this may result in a large amount of current
 * through both the controller and the motor. In order to prevent damage in these situations, you
 * can use the `StallVelocity` property.
 *
 * The `StallVelocity` should be set to the lowest velocity you would expect from your motor. The
 * controller will then monitor the motor's velocity, as well as the @ref
 * PhidgetMotorPositionController_getDutyCycle(), and prevent a 'dangerous stall' from occuring. If
 * the controller detects a dangerous stall, it will immediately disengage the motor (i.e. `Engaged`
 * will be set to false) and an error will be reported to your program.
 *
 * *   A 'dangerous stall' will occur faster when the @ref
 *     PhidgetMotorPositionController_getDutyCycle() is higher (i.e. when the average voltage across
 *     the motor is higher)
 * *   A 'dangerous stall' will occur faster as (`StallVelocity` \- motor velocity) becomes
 *     larger .
 *
 * Setting `StallVelocity` to 0 will turn off stall protection functionality.
 *
 * @param[in] ch The channel handle
 * @param[in] stallVelocity The stall velocity value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_setStallVelocity(PhidgetMotorPositionControllerHandle ch,
  double stallVelocity);

/**
 * @brief The stall velocity value.
 *
 * Before reading this description, it is important to note the difference between the units of
 * `StallVelocity` and @ref PhidgetMotorPositionController_getDutyCycle().
 *
 * *   @ref PhidgetMotorPositionController_getDutyCycle() is a number between -1 and 1 with
 *     units of 'duty cycle'. It simply represents the average voltage across the motor.
 * *   `StallVelocity` represents a real velocity (e.g. m/s, RPM, etc.) and the units are
 *     determined by the `RescaleFactor`. With a `RescaleFactor` of 1, the default units would be in
 *     commutations per second.
 *
 * If the load on your motor is large, your motor may begin rotating more slowly, or even fully
 * stall. Depending on the voltage across your motor, this may result in a large amount of current
 * through both the controller and the motor. In order to prevent damage in these situations, you
 * can use the `StallVelocity` property.
 *
 * The `StallVelocity` should be set to the lowest velocity you would expect from your motor. The
 * controller will then monitor the motor's velocity, as well as the @ref
 * PhidgetMotorPositionController_getDutyCycle(), and prevent a 'dangerous stall' from occuring. If
 * the controller detects a dangerous stall, it will immediately disengage the motor (i.e. `Engaged`
 * will be set to false) and an error will be reported to your program.
 *
 * *   A 'dangerous stall' will occur faster when the @ref
 *     PhidgetMotorPositionController_getDutyCycle() is higher (i.e. when the average voltage across
 *     the motor is higher)
 * *   A 'dangerous stall' will occur faster as (`StallVelocity` \- motor velocity) becomes
 *     larger .
 *
 * Setting `StallVelocity` to 0 will turn off stall protection functionality.
 *
 * @param[in] ch The channel handle
 * @param[out] stallVelocity The stall velocity value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_getStallVelocity(PhidgetMotorPositionControllerHandle ch,
  double *stallVelocity);

/**
 * @brief The velocity value
 *
 * The lower bound of `StallVelocity`.
 *
 * @param[in] ch The channel handle
 * @param[out] minStallVelocity The velocity value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_getMinStallVelocity(PhidgetMotorPositionControllerHandle ch,
  double *minStallVelocity);

/**
 * @brief The velocity value
 *
 * The upper bound of `StallVelocity`.
 *
 * @param[in] ch The channel handle
 * @param[out] maxStallVelocity The velocity value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_getMaxStallVelocity(PhidgetMotorPositionControllerHandle ch,
  double *maxStallVelocity);

/**
 * @brief The surge current limit value
 *
 * The `SurgeCurrentLimit` allows for increased performance from your motor. The controller will
 * limit the current through your motor to the `SurgeCurrentLimit` briefly, then scale current down
 * to the `CurrentLimit`.
 *
 * *   View @ref PhidgetMotorPositionController_getActiveCurrentLimit() for information about
 *     what current limit the controller is actively following.
 *
 * For more information about `SurgeCurrentLimit`, visit our [MotorPositionController API
 * Guide](https://www.phidgets.com/docs/MotorPositionController_API_Guide#Surge_Current_Limit)
 *
 * @param[in] ch The channel handle
 * @param[in] surgeCurrentLimit The surge current limit value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_setSurgeCurrentLimit(PhidgetMotorPositionControllerHandle ch,
  double surgeCurrentLimit);

/**
 * @brief The surge current limit value
 *
 * The `SurgeCurrentLimit` allows for increased performance from your motor. The controller will
 * limit the current through your motor to the `SurgeCurrentLimit` briefly, then scale current down
 * to the `CurrentLimit`.
 *
 * *   View @ref PhidgetMotorPositionController_getActiveCurrentLimit() for information about
 *     what current limit the controller is actively following.
 *
 * For more information about `SurgeCurrentLimit`, visit our [MotorPositionController API
 * Guide](https://www.phidgets.com/docs/MotorPositionController_API_Guide#Surge_Current_Limit)
 *
 * @param[in] ch The channel handle
 * @param[out] surgeCurrentLimit The surge current limit value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_getSurgeCurrentLimit(PhidgetMotorPositionControllerHandle ch,
  double *surgeCurrentLimit);

/**
 * @brief The surge current value
 *
 * The minimum value that `SurgeCurrentLimit` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minSurgeCurrentLimit The surge current value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_getMinSurgeCurrentLimit(PhidgetMotorPositionControllerHandle ch,
  double *minSurgeCurrentLimit);

/**
 * @brief The surge current value
 *
 * The maximum value that `SurgeCurrentLimit` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxSurgeCurrentLimit The surge current value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_getMaxSurgeCurrentLimit(PhidgetMotorPositionControllerHandle ch,
  double *maxSurgeCurrentLimit);

/**
 * @brief The position value
 *
 * When the controller is engaged and the `TargetPosition` is set, the motor will attempt to reach
 * the `TargetPosition`.
 *
 * *   If the `DeadBand` is non-zero, the final position of the motor may not match the
 *     `TargetPosition`
 * *   Use the `RescaleFactor` to convert the units of this property to more intuitive units,
 *     such as rotations or degrees.
 *
 * For more information about `TargetPosition`, visit our [MotorPositionController API
 * Guide](https://www.phidgets.com/docs/MotorPositionController_API_Guide#Target_Position)
 *
 * @param[in] ch The channel handle
 * @param[in] targetPosition The position value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_setTargetPosition(PhidgetMotorPositionControllerHandle ch,
  double targetPosition);

/**
 * @brief The position value
 *
 * When the controller is engaged and the `TargetPosition` is set, the motor will attempt to reach
 * the `TargetPosition`.
 *
 * *   If the `DeadBand` is non-zero, the final position of the motor may not match the
 *     `TargetPosition`
 * *   Use the `RescaleFactor` to convert the units of this property to more intuitive units,
 *     such as rotations or degrees.
 *
 * For more information about `TargetPosition`, visit our [MotorPositionController API
 * Guide](https://www.phidgets.com/docs/MotorPositionController_API_Guide#Target_Position)
 *
 * @param[in] ch The channel handle
 * @param[in] targetPosition The position value
 * @param[in] fptr Asynchronous completion callback
 * @param[in] ctx User supplied context pointer
 */
PHIDGET22_API void CCONV PhidgetMotorPositionController_setTargetPosition_async(PhidgetMotorPositionControllerHandle ch,
  double targetPosition, Phidget_AsyncCallback fptr, void *ctx);

/**
 * @brief The position value
 *
 * When the controller is engaged and the `TargetPosition` is set, the motor will attempt to reach
 * the `TargetPosition`.
 *
 * *   If the `DeadBand` is non-zero, the final position of the motor may not match the
 *     `TargetPosition`
 * *   Use the `RescaleFactor` to convert the units of this property to more intuitive units,
 *     such as rotations or degrees.
 *
 * For more information about `TargetPosition`, visit our [MotorPositionController API
 * Guide](https://www.phidgets.com/docs/MotorPositionController_API_Guide#Target_Position)
 *
 * @param[in] ch The channel handle
 * @param[out] targetPosition The position value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_getTargetPosition(PhidgetMotorPositionControllerHandle ch,
  double *targetPosition);

/**
 * @brief The velocity value.
 *
 * The controller will attempt to limit the motor's velocity to this value.
 *
 * *   The `VelocityLimit` may be exceeded to track the `TargetPosition` more accurately.
 * *   Use the `RescaleFactor` to convert the units of this property to more intuitive units,
 *     such as rotations or degrees.
 *
 * For more information about `VelocityLimit`, visit our [MotorPositionController API
 * Guide](https://www.phidgets.com/docs/MotorPositionController_API_Guide#Velocity_Limit)
 *
 * @param[in] ch The channel handle
 * @param[in] velocityLimit The velocity value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_setVelocityLimit(PhidgetMotorPositionControllerHandle ch,
  double velocityLimit);

/**
 * @brief The velocity value.
 *
 * The controller will attempt to limit the motor's velocity to this value.
 *
 * *   The `VelocityLimit` may be exceeded to track the `TargetPosition` more accurately.
 * *   Use the `RescaleFactor` to convert the units of this property to more intuitive units,
 *     such as rotations or degrees.
 *
 * For more information about `VelocityLimit`, visit our [MotorPositionController API
 * Guide](https://www.phidgets.com/docs/MotorPositionController_API_Guide#Velocity_Limit)
 *
 * @param[in] ch The channel handle
 * @param[out] velocityLimit The velocity value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_getVelocityLimit(PhidgetMotorPositionControllerHandle ch,
  double *velocityLimit);

/**
 * @brief The velocity value
 *
 * The minimum value that `VelocityLimit` can be set to.
 *
 * *   Use the `RescaleFactor` to convert the units of this property to more intuitive units,
 *     such as rotations or degrees.
 *
 * @param[in] ch The channel handle
 * @param[out] minVelocityLimit The velocity value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_getMinVelocityLimit(PhidgetMotorPositionControllerHandle ch,
  double *minVelocityLimit);

/**
 * @brief The velocity value
 *
 * The maximum value that `VelocityLimit` can be set to.
 *
 * *   Use the `RescaleFactor` to convert the units of this property to more intuitive units,
 *     such as rotations or degrees.
 *
 * @param[in] ch The channel handle
 * @param[out] maxVelocityLimit The velocity value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_getMaxVelocityLimit(PhidgetMotorPositionControllerHandle ch,
  double *maxVelocityLimit);

/**
 * @brief Callback function type for
 *     PhidgetMotorPositionController_setOnDutyCycleUpdateHandler().
 *
 * @param[in] ch The channel handle
 * @param[in] ctx Pointer to the user context
 * @param[in] dutyCycle The duty cycle value
 */
typedef void (CCONV *PhidgetMotorPositionController_OnDutyCycleUpdateCallback)(PhidgetMotorPositionControllerHandle ch,
  void *ctx, double dutyCycle);

/**
 * The most recent duty cycle value will be reported in this event, which occurs when the
 * `DataInterval` has elapsed.
 *
 * *   This event will **always** occur when the `DataInterval` elapses. You can depend on this
 *     event for constant timing when implementing control loops in code. This is the last event to
 *     fire, giving you up-to-date access to all properties.
 *
 * @param[in] ch The channel handle
 * @param[in] fptr The event handler callback function
 * @param[in] ctx User supplied context pointer
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_setOnDutyCycleUpdateHandler(PhidgetMotorPositionControllerHandle ch,
  PhidgetMotorPositionController_OnDutyCycleUpdateCallback fptr, void *ctx);

/**
 * @brief Callback function type for
 *     PhidgetMotorPositionController_setOnExpectedPositionChangeHandler().
 *
 * @param[in] ch The channel handle
 * @param[in] ctx Pointer to the user context
 * @param[in] expectedPosition The expected position value
 */
typedef void (CCONV *PhidgetMotorPositionController_OnExpectedPositionChangeCallback)(PhidgetMotorPositionControllerHandle ch,
  void *ctx, double expectedPosition);

/**
 * The most recent position being tracked by the Position Control loop, which occurs when the
 * `DataInterval` has elapsed.
 *
 * *   Regardless of the `DataInterval`, this event will occur only when the expected position
 *     value has changed from the previous value reported.
 * *   Use the `RescaleFactor` to convert the units of this property to more intuitive units,
 *     such as rotations or degrees.
 *
 * @param[in] ch The channel handle
 * @param[in] fptr The event handler callback function
 * @param[in] ctx User supplied context pointer
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_setOnExpectedPositionChangeHandler(PhidgetMotorPositionControllerHandle ch,
  PhidgetMotorPositionController_OnExpectedPositionChangeCallback fptr, void *ctx);

/**
 * @brief Callback function type for
 *     PhidgetMotorPositionController_setOnPositionChangeHandler().
 *
 * @param[in] ch The channel handle
 * @param[in] ctx Pointer to the user context
 * @param[in] position The position value
 */
typedef void (CCONV *PhidgetMotorPositionController_OnPositionChangeCallback)(PhidgetMotorPositionControllerHandle ch,
  void *ctx, double position);

/**
 * The most recent position value will be reported in this event, which occurs when the
 * `DataInterval` has elapsed.
 *
 * *   Regardless of the `DataInterval`, this event will occur only when the position value has
 *     changed from the previous value reported.
 * *   Use the `RescaleFactor` to convert the units of this property to more intuitive units,
 *     such as rotations or degrees.
 *
 * @param[in] ch The channel handle
 * @param[in] fptr The event handler callback function
 * @param[in] ctx User supplied context pointer
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorPositionController_setOnPositionChangeHandler(PhidgetMotorPositionControllerHandle ch,
  PhidgetMotorPositionController_OnPositionChangeCallback fptr, void *ctx);

/** @} */ /* PhidgetMotorPositionController */

/**
 * @defgroup PhidgetMotorVelocityController MotorVelocityController
 * @brief The Motor Velocity Controller class controls the velocity and acceleration of the
 *     attached motor. It also contains various other control and monitoring functions that aid in
 *     the control of the motor.
 * @{
 */

/**
 * The Motor Velocity Controller class controls the velocity and acceleration of the attached motor.
 * It also contains various other control and monitoring functions that aid in the control of the
 * motor.
 */
typedef struct _PhidgetMotorVelocityController *PhidgetMotorVelocityControllerHandle;

/**
 * @ref PhidgetMotorVelocityController_create() creates an instance of a Phidget channel. Once
 * created the channel may need to be configured to match the physical device and channel index you
 * want to attach to, and then be opened by calling @ref Phidget_open().
 * The Phidget channel handle must be released with @ref PhidgetMotorVelocityController_delete().
 *
 * @param[out] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorVelocityController_create(PhidgetMotorVelocityControllerHandle *ch);

/**
 * @ref PhidgetMotorVelocityController_delete() releases a Phidget channel handle created with @ref
 * PhidgetMotorVelocityController_create().
 * If the channel is open when @ref PhidgetMotorVelocityController_delete() is called, it will be
 * closed.
 *
 * @param[out] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorVelocityController_delete(PhidgetMotorVelocityControllerHandle *ch);

/**
 * Enables the **failsafe** feature for the channel, with the specified **failsafe time**.
 *
 * Enabling the failsafe feature starts a recurring **failsafe timer** for the channel. Once the
 * failsafe is enabled, the timer must be reset within the specified time or the channel will enter
 * a **failsafe state**. For Motor Velocity Controller channels, this will disengage the motor. The
 * failsafe timer can be reset by using any API call **_except_** for the following:
 *
 * *   @ref PhidgetMotorVelocityController_setRescaleFactor()
 * *   'get' API calls
 *
 * For more information about failsafe, visit our [Failsafe
 * Guide](https://www.phidgets.com/docs/Failsafe_Guide).
 *
 * @param[in] ch The channel handle
 * @param[in] failsafeTime Failsafe timeout in milliseconds
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorVelocityController_enableFailsafe(PhidgetMotorVelocityControllerHandle ch,
  uint32_t failsafeTime);

/**
 * Resets the failsafe timer, if one has been set. See @ref
 * PhidgetMotorVelocityController_enableFailsafe() for details.
 *
 * This function will fail if no failsafe timer has been set for the channel.
 *
 * @param[in] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorVelocityController_resetFailsafe(PhidgetMotorVelocityControllerHandle ch);

/**
 * @brief The acceleration value
 *
 * The rate at which the controller can change the motor's velocity.
 *
 * *   Use the `RescaleFactor` to convert the units of this property to more intuitive units,
 *     such as rotations or degrees.
 *
 * For more information about `Acceleration`, visit our [MotorVelocityController API
 * Guide](https://www.phidgets.com/docs/MotorVelocityController_API_Guide#Acceleration)
 *
 * @param[in] ch The channel handle
 * @param[in] acceleration The acceleration value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorVelocityController_setAcceleration(PhidgetMotorVelocityControllerHandle ch,
  double acceleration);

/**
 * @brief The acceleration value
 *
 * The rate at which the controller can change the motor's velocity.
 *
 * *   Use the `RescaleFactor` to convert the units of this property to more intuitive units,
 *     such as rotations or degrees.
 *
 * For more information about `Acceleration`, visit our [MotorVelocityController API
 * Guide](https://www.phidgets.com/docs/MotorVelocityController_API_Guide#Acceleration)
 *
 * @param[in] ch The channel handle
 * @param[out] acceleration The acceleration value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorVelocityController_getAcceleration(PhidgetMotorVelocityControllerHandle ch,
  double *acceleration);

/**
 * @brief The acceleration value.
 *
 * The minimum value that `Acceleration` can be set to.
 *
 * *   Use the `RescaleFactor` to convert the units of this property to more intuitive units,
 *     such as rotations or degrees.
 *
 * @param[in] ch The channel handle
 * @param[out] minAcceleration The acceleration value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorVelocityController_getMinAcceleration(PhidgetMotorVelocityControllerHandle ch,
  double *minAcceleration);

/**
 * @brief The acceleration value.
 *
 * The maximum value that `Acceleration` can be set to.
 *
 * *   Use the `RescaleFactor` to convert the units of this property to more intuitive units,
 *     such as rotations or degrees.
 *
 * @param[in] ch The channel handle
 * @param[out] maxAcceleration The acceleration value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorVelocityController_getMaxAcceleration(PhidgetMotorVelocityControllerHandle ch,
  double *maxAcceleration);

/**
 * @brief The active current limit value
 *
 * The current limit that the controller is actively following. The `SurgeCurrentLimit`,
 * `CurrentLimit`, and temperature will impact this value.
 *
 * @param[in] ch The channel handle
 * @param[out] activeCurrentLimit The active current limit value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorVelocityController_getActiveCurrentLimit(PhidgetMotorVelocityControllerHandle ch,
  double *activeCurrentLimit);

/**
 * @brief Motor current limit
 *
 * The controller will limit the current through the motor to the `CurrentLimit` value.
 *
 * *   View @ref PhidgetMotorVelocityController_getActiveCurrentLimit() for information about
 *     what current limit the controller is actively following.
 *
 * For more information about `CurrentLimit`, visit our [MotorVelocityController API
 * Guide](https://www.phidgets.com/docs/MotorVelocityController_API_Guide#Current_Limit)
 *
 * @param[in] ch The channel handle
 * @param[in] currentLimit Motor current limit
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorVelocityController_setCurrentLimit(PhidgetMotorVelocityControllerHandle ch,
  double currentLimit);

/**
 * @brief Motor current limit
 *
 * The controller will limit the current through the motor to the `CurrentLimit` value.
 *
 * *   View @ref PhidgetMotorVelocityController_getActiveCurrentLimit() for information about
 *     what current limit the controller is actively following.
 *
 * For more information about `CurrentLimit`, visit our [MotorVelocityController API
 * Guide](https://www.phidgets.com/docs/MotorVelocityController_API_Guide#Current_Limit)
 *
 * @param[in] ch The channel handle
 * @param[out] currentLimit Motor current limit
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorVelocityController_getCurrentLimit(PhidgetMotorVelocityControllerHandle ch,
  double *currentLimit);

/**
 * @brief Minimum current limit
 *
 * The minimum current limit that can be set for the device.
 *
 * @param[in] ch The channel handle
 * @param[out] minCurrentLimit Minimum current limit
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorVelocityController_getMinCurrentLimit(PhidgetMotorVelocityControllerHandle ch,
  double *minCurrentLimit);

/**
 * @brief Maximum current limit
 *
 * The maximum current limit that can be set for the device.
 *
 * @param[in] ch The channel handle
 * @param[out] maxCurrentLimit Maximum current limit
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorVelocityController_getMaxCurrentLimit(PhidgetMotorVelocityControllerHandle ch,
  double *maxCurrentLimit);

/**
 * @brief The data interval value
 *
 * The `DataInterval` is the time that must elapse before the channel will fire another @ref
 * PhidgetMotorVelocityController_setOnVelocityChangeHandler() / @ref
 * PhidgetMotorVelocityController_setOnDutyCycleUpdateHandler() event.
 *
 * *   The data interval is bounded by @ref PhidgetMotorVelocityController_getMinDataInterval()
 *     and @ref PhidgetMotorVelocityController_getMaxDataInterval().
 *
 * @param[in] ch The channel handle
 * @param[in] dataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorVelocityController_setDataInterval(PhidgetMotorVelocityControllerHandle ch,
  uint32_t dataInterval);

/**
 * @brief The data interval value
 *
 * The `DataInterval` is the time that must elapse before the channel will fire another @ref
 * PhidgetMotorVelocityController_setOnVelocityChangeHandler() / @ref
 * PhidgetMotorVelocityController_setOnDutyCycleUpdateHandler() event.
 *
 * *   The data interval is bounded by @ref PhidgetMotorVelocityController_getMinDataInterval()
 *     and @ref PhidgetMotorVelocityController_getMaxDataInterval().
 *
 * @param[in] ch The channel handle
 * @param[out] dataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorVelocityController_getDataInterval(PhidgetMotorVelocityControllerHandle ch,
  uint32_t *dataInterval);

/**
 * @brief The data interval value
 *
 * The minimum value that `DataInterval` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minDataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorVelocityController_getMinDataInterval(PhidgetMotorVelocityControllerHandle ch,
  uint32_t *minDataInterval);

/**
 * @brief The data interval value
 *
 * The maximum value that `DataInterval` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxDataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorVelocityController_getMaxDataInterval(PhidgetMotorVelocityControllerHandle ch,
  uint32_t *maxDataInterval);

/**
 * @brief The data rate for the channel
 *
 * The `DataRate` is the frequency of events from the device.
 *
 * *   The data rate is bounded by @ref PhidgetMotorVelocityController_getMinDataRate() and @ref
 *     PhidgetMotorVelocityController_getMaxDataRate().
 * *   Changing `DataRate` will change the channel's `DataInterval` to a corresponding value,
 *     rounded to the nearest integer number of milliseconds.
 * *   The timing between events can also affected by the change trigger.
 *
 * @param[in] ch The channel handle
 * @param[in] dataRate The data rate for the channel
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorVelocityController_setDataRate(PhidgetMotorVelocityControllerHandle ch,
  double dataRate);

/**
 * @brief The data rate for the channel
 *
 * The `DataRate` is the frequency of events from the device.
 *
 * *   The data rate is bounded by @ref PhidgetMotorVelocityController_getMinDataRate() and @ref
 *     PhidgetMotorVelocityController_getMaxDataRate().
 * *   Changing `DataRate` will change the channel's `DataInterval` to a corresponding value,
 *     rounded to the nearest integer number of milliseconds.
 * *   The timing between events can also affected by the change trigger.
 *
 * @param[in] ch The channel handle
 * @param[out] dataRate The data rate for the channel
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorVelocityController_getDataRate(PhidgetMotorVelocityControllerHandle ch,
  double *dataRate);

/**
 * @brief The data rate value
 *
 * The minimum value that `DataRate` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minDataRate The data rate value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorVelocityController_getMinDataRate(PhidgetMotorVelocityControllerHandle ch,
  double *minDataRate);

/**
 * @brief The data rate value
 *
 * The maximum value that `DataRate` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxDataRate The data rate value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorVelocityController_getMaxDataRate(PhidgetMotorVelocityControllerHandle ch,
  double *maxDataRate);

/**
 * @brief The dead band value
 *
 * This parameter specifies a minimum @ref PhidgetMotorVelocityController_getVelocity() below which
 * your system will relax if the `TargetVelocity` is set to 0, to prevent unwanted jitter.
 *
 * *   Use the `RescaleFactor` to convert the units of this property to more intuitive units,
 *     such as rotations or degrees.
 *
 * For more information about `DeadBand`, visit our [MotorVelocityController API
 * Guide](https://www.phidgets.com/docs/MotorVelocityController_API_Guide#Deadband)
 *
 * @param[in] ch The channel handle
 * @param[in] deadBand The dead band value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorVelocityController_setDeadBand(PhidgetMotorVelocityControllerHandle ch,
  double deadBand);

/**
 * @brief The dead band value
 *
 * This parameter specifies a minimum @ref PhidgetMotorVelocityController_getVelocity() below which
 * your system will relax if the `TargetVelocity` is set to 0, to prevent unwanted jitter.
 *
 * *   Use the `RescaleFactor` to convert the units of this property to more intuitive units,
 *     such as rotations or degrees.
 *
 * For more information about `DeadBand`, visit our [MotorVelocityController API
 * Guide](https://www.phidgets.com/docs/MotorVelocityController_API_Guide#Deadband)
 *
 * @param[in] ch The channel handle
 * @param[out] deadBand The dead band value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorVelocityController_getDeadBand(PhidgetMotorVelocityControllerHandle ch,
  double *deadBand);

/**
 * @brief The duty cycle value.
 *
 * The most recent @ref PhidgetMotorVelocityController_getDutyCycle() value that the controller has
 * reported.
 *
 * *   This value will be between -1 and 1 where a sign change (±) is indicitave of a direction
 *     change.
 * *   @ref PhidgetMotorVelocityController_getDutyCycle() is an indication of the average
 *     voltage across the motor. At a constant load, an increase in @ref
 *     PhidgetMotorVelocityController_getDutyCycle() indicates an increase in motor speed.
 *
 * For more information about @ref PhidgetMotorVelocityController_getDutyCycle(), visit our
 * [MotorVelocityController API
 * Guide](https://www.phidgets.com/docs/MotorVelocityController_API_Guide#Duty_Cycle)
 *
 * @param[in] ch The channel handle
 * @param[out] dutyCycle The duty cycle value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorVelocityController_getDutyCycle(PhidgetMotorVelocityControllerHandle ch,
  double *dutyCycle);

/**
 * @brief The engaged value.
 *
 * When engaged, the controller has the ability to be controlled. When disengaged, the controller
 * will stop powering to your motor, it will instead be in a freewheel state.
 *
 * For more information about `Engaged`, visit our [MotorVelocityController API
 * Guide](https://www.phidgets.com/docs/MotorVelocityController_API_Guide#Engage_Motor)
 *
 * @param[in] ch The channel handle
 * @param[in] engaged The engaged value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorVelocityController_setEngaged(PhidgetMotorVelocityControllerHandle ch,
  int engaged);

/**
 * @brief The engaged value.
 *
 * When engaged, the controller has the ability to be controlled. When disengaged, the controller
 * will stop powering to your motor, it will instead be in a freewheel state.
 *
 * For more information about `Engaged`, visit our [MotorVelocityController API
 * Guide](https://www.phidgets.com/docs/MotorVelocityController_API_Guide#Engage_Motor)
 *
 * @param[in] ch The channel handle
 * @param[out] engaged The engaged value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorVelocityController_getEngaged(PhidgetMotorVelocityControllerHandle ch,
  int *engaged);

/**
 * @brief The expected velocity value
 *
 * This controller uses trapezoidal motion profiling combined with a PID loop to accurately track
 * velocity. The @ref PhidgetMotorVelocityController_getExpectedVelocity() represents the current
 * velocity the controller is tracking along the trapezoidal motion curve. The error of your PID
 * loop is calculated by taking the difference of @ref PhidgetMotorVelocityController_getVelocity()
 * and @ref PhidgetMotorVelocityController_getExpectedVelocity(). You can use this value to verify
 * your controller is working as expected.
 *
 * *   Set `EnableExpectedVelocity` to **TRUE** to enable the change event for this property.
 * *   Use the `RescaleFactor` to convert the units of this property to more intuitive units,
 *     such as rotations or degrees.
 *
 * @param[in] ch The channel handle
 * @param[out] expectedVelocity The expected velocity value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorVelocityController_getExpectedVelocity(PhidgetMotorVelocityControllerHandle ch,
  double *expectedVelocity);

/**
 * @brief Enable expected velocity feedback
 *
 * When enabled, the @ref PhidgetMotorVelocityController_getExpectedVelocity() will be sent back
 * from the controller.
 *
 * @param[in] ch The channel handle
 * @param[in] enableExpectedVelocity Enable expected velocity feedback
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorVelocityController_setEnableExpectedVelocity(PhidgetMotorVelocityControllerHandle ch,
  int enableExpectedVelocity);

/**
 * @brief Enable expected velocity feedback
 *
 * When enabled, the @ref PhidgetMotorVelocityController_getExpectedVelocity() will be sent back
 * from the controller.
 *
 * @param[in] ch The channel handle
 * @param[out] enableExpectedVelocity Enable expected velocity feedback
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorVelocityController_getEnableExpectedVelocity(PhidgetMotorVelocityControllerHandle ch,
  int *enableExpectedVelocity);

/**
 * @brief Enables failsafe braking
 *
 * This setting allows you to choose whether motor will forcibly stop once it enters a **FAILSAFE**
 * state.
 *
 * *   A setting of FALSE will simply stop applying power to the motor, allowing it to spin down
 *     naturally.
 * *   A setting of TRUE will apply braking up to the `FailsafeCurrentLimit`, actively stopping
 *     the motor
 *
 * For more information about `FailsafeBrakingEnabled`, visit our [MotorVelocityController API
 * Guide](https://www.phidgets.com/docs/MotorVelocityController_API_Guide#Failsafe_Braking_Enabled)
 *
 * @param[in] ch The channel handle
 * @param[in] failsafeBrakingEnabled Enables failsafe braking
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorVelocityController_setFailsafeBrakingEnabled(PhidgetMotorVelocityControllerHandle ch,
  int failsafeBrakingEnabled);

/**
 * @brief Enables failsafe braking
 *
 * This setting allows you to choose whether motor will forcibly stop once it enters a **FAILSAFE**
 * state.
 *
 * *   A setting of FALSE will simply stop applying power to the motor, allowing it to spin down
 *     naturally.
 * *   A setting of TRUE will apply braking up to the `FailsafeCurrentLimit`, actively stopping
 *     the motor
 *
 * For more information about `FailsafeBrakingEnabled`, visit our [MotorVelocityController API
 * Guide](https://www.phidgets.com/docs/MotorVelocityController_API_Guide#Failsafe_Braking_Enabled)
 *
 * @param[in] ch The channel handle
 * @param[out] failsafeBrakingEnabled Enables failsafe braking
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorVelocityController_getFailsafeBrakingEnabled(PhidgetMotorVelocityControllerHandle ch,
  int *failsafeBrakingEnabled);

/**
 * @brief The failsafe current limit value
 *
 * When the controller enters a **FAILSAFE** state, the controller will limit the current through
 * the motor to the `FailsafeCurrentLimit` value.
 *
 * For more information about `FailsafeCurrentLimit`, visit our [MotorVelocityController API
 * Guide](https://www.phidgets.com/docs/MotorVelocityController_API_Guide#Failsafe_Current_Limit)
 *
 * @param[in] ch The channel handle
 * @param[in] failsafeCurrentLimit The failsafe current limit value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorVelocityController_setFailsafeCurrentLimit(PhidgetMotorVelocityControllerHandle ch,
  double failsafeCurrentLimit);

/**
 * @brief The failsafe current limit value
 *
 * When the controller enters a **FAILSAFE** state, the controller will limit the current through
 * the motor to the `FailsafeCurrentLimit` value.
 *
 * For more information about `FailsafeCurrentLimit`, visit our [MotorVelocityController API
 * Guide](https://www.phidgets.com/docs/MotorVelocityController_API_Guide#Failsafe_Current_Limit)
 *
 * @param[in] ch The channel handle
 * @param[out] failsafeCurrentLimit The failsafe current limit value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorVelocityController_getFailsafeCurrentLimit(PhidgetMotorVelocityControllerHandle ch,
  double *failsafeCurrentLimit);

/**
 * @brief The failsafe time
 *
 * The minimum value that `failsafeTime` can be set to when calling @ref
 * PhidgetMotorVelocityController_enableFailsafe().
 *
 * @param[in] ch The channel handle
 * @param[out] minFailsafeTime The failsafe time
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorVelocityController_getMinFailsafeTime(PhidgetMotorVelocityControllerHandle ch,
  uint32_t *minFailsafeTime);

/**
 * @brief The failsafe time
 *
 * The maximum value that `failsafeTime` can be set to when calling @ref
 * PhidgetMotorVelocityController_enableFailsafe().
 *
 * @param[in] ch The channel handle
 * @param[out] maxFailsafeTime The failsafe time
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorVelocityController_getMaxFailsafeTime(PhidgetMotorVelocityControllerHandle ch,
  uint32_t *maxFailsafeTime);

/**
 * @brief The inductance of your motor
 *
 * The controller will attempt to measure the inductance of your motor when opened. This value is
 * used to improve control of the motor.
 *
 * *   Set this value during the @ref Phidget_setOnAttachHandler() event to skip motor
 *     characterization (including the audible beeps). You can use a previously saved `Inductance`
 *     value, or information from your motor's datasheet.
 *
 * For more information about `Inductance`, visit our [MotorVelocityController API
 * Guide](https://www.phidgets.com/docs/MotorVelocityController_API_Guide#Motor_Inductance)
 *
 * @param[in] ch The channel handle
 * @param[in] inductance The inductance of your motor
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorVelocityController_setInductance(PhidgetMotorVelocityControllerHandle ch,
  double inductance);

/**
 * @brief The inductance of your motor
 *
 * The controller will attempt to measure the inductance of your motor when opened. This value is
 * used to improve control of the motor.
 *
 * *   Set this value during the @ref Phidget_setOnAttachHandler() event to skip motor
 *     characterization (including the audible beeps). You can use a previously saved `Inductance`
 *     value, or information from your motor's datasheet.
 *
 * For more information about `Inductance`, visit our [MotorVelocityController API
 * Guide](https://www.phidgets.com/docs/MotorVelocityController_API_Guide#Motor_Inductance)
 *
 * @param[in] ch The channel handle
 * @param[out] inductance The inductance of your motor
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorVelocityController_getInductance(PhidgetMotorVelocityControllerHandle ch,
  double *inductance);

/**
 * @brief The motor inductance value
 *
 * The minimum value that `Inductance` can be set to. See `Inductance` for details.
 *
 * @param[in] ch The channel handle
 * @param[out] minInductance The motor inductance value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorVelocityController_getMinInductance(PhidgetMotorVelocityControllerHandle ch,
  double *minInductance);

/**
 * @brief The motor inductance value
 *
 * The maximum value that `Inductance` can be set to. See `Inductance` for details.
 *
 * @param[in] ch The channel handle
 * @param[out] maxInductance The motor inductance value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorVelocityController_getMaxInductance(PhidgetMotorVelocityControllerHandle ch,
  double *maxInductance);

/**
 * @brief The Kd value.
 *
 * Derivative gain constant. A higher `Kd` will help reduce oscillations.
 *
 * For more information about `Kd`, visit our [MotorVelocityController API
 * Guide](https://www.phidgets.com/docs/MotorVelocityController_API_Guide#Tunings_Constants_(Kp,_Ki,_Kd))
 *
 * @param[in] ch The channel handle
 * @param[in] kd The Kd value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorVelocityController_setKd(PhidgetMotorVelocityControllerHandle ch,
  double kd);

/**
 * @brief The Kd value.
 *
 * Derivative gain constant. A higher `Kd` will help reduce oscillations.
 *
 * For more information about `Kd`, visit our [MotorVelocityController API
 * Guide](https://www.phidgets.com/docs/MotorVelocityController_API_Guide#Tunings_Constants_(Kp,_Ki,_Kd))
 *
 * @param[in] ch The channel handle
 * @param[out] kd The Kd value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorVelocityController_getKd(PhidgetMotorVelocityControllerHandle ch,
  double *kd);

/**
 * @brief The Ki value.
 *
 * Integral gain constant. The integral term will help eliminate steady-state error.
 *
 * For more information about `Ki`, visit our [MotorVelocityController API
 * Guide](https://www.phidgets.com/docs/MotorVelocityController_API_Guide#Tunings_Constants_(Kp,_Ki,_Kd))
 *
 * @param[in] ch The channel handle
 * @param[in] ki The Ki value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorVelocityController_setKi(PhidgetMotorVelocityControllerHandle ch,
  double ki);

/**
 * @brief The Ki value.
 *
 * Integral gain constant. The integral term will help eliminate steady-state error.
 *
 * For more information about `Ki`, visit our [MotorVelocityController API
 * Guide](https://www.phidgets.com/docs/MotorVelocityController_API_Guide#Tunings_Constants_(Kp,_Ki,_Kd))
 *
 * @param[in] ch The channel handle
 * @param[out] ki The Ki value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorVelocityController_getKi(PhidgetMotorVelocityControllerHandle ch,
  double *ki);

/**
 * @brief The Kp value.
 *
 * Proportional gain constant. A small `Kp` value will result in a less responsive controller,
 * however, if `Kp` is too high, the system can become unstable.
 *
 * For more information about `Kp`, visit our [MotorVelocityController API
 * Guide](https://www.phidgets.com/docs/MotorVelocityController_API_Guide#Tunings_Constants_(Kp,_Ki,_Kd))
 *
 * @param[in] ch The channel handle
 * @param[in] kp The Kp value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorVelocityController_setKp(PhidgetMotorVelocityControllerHandle ch,
  double kp);

/**
 * @brief The Kp value.
 *
 * Proportional gain constant. A small `Kp` value will result in a less responsive controller,
 * however, if `Kp` is too high, the system can become unstable.
 *
 * For more information about `Kp`, visit our [MotorVelocityController API
 * Guide](https://www.phidgets.com/docs/MotorVelocityController_API_Guide#Tunings_Constants_(Kp,_Ki,_Kd))
 *
 * @param[in] ch The channel handle
 * @param[out] kp The Kp value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorVelocityController_getKp(PhidgetMotorVelocityControllerHandle ch,
  double *kp);

/**
 * @brief The position type selection
 *
 * Determines whether the controller uses the hall effect sensors or an encoder for velocity
 * information. This setting is locked in once the channel is `Engaged` and cannot be changed until
 * the channel is reset.
 *
 * @param[in] ch The channel handle
 * @param[in] positionType The position type selection
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorVelocityController_setPositionType(PhidgetMotorVelocityControllerHandle ch,
  Phidget_PositionType positionType);

/**
 * @brief The position type selection
 *
 * Determines whether the controller uses the hall effect sensors or an encoder for velocity
 * information. This setting is locked in once the channel is `Engaged` and cannot be changed until
 * the channel is reset.
 *
 * @param[in] ch The channel handle
 * @param[out] positionType The position type selection
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorVelocityController_getPositionType(PhidgetMotorVelocityControllerHandle ch,
  Phidget_PositionType *positionType);

/**
 * @brief The rescale factor value
 *
 * Change the units of your parameters so that your application is more intuitive.
 *
 * *   Units for `Acceleration`, `DeadBand`, @ref
 *     PhidgetMotorVelocityController_getExpectedVelocity(), `TargetVelocity`, and @ref
 *     PhidgetMotorVelocityController_getVelocity() can be set by the user through the
 *     `RescaleFactor`. The `RescaleFactor` allows you to use more intuitive units such as
 *     rotations, or degrees.
 *
 * For more information about `RescaleFactor`, visit our [MotorVelocityController API
 * Guide](https://www.phidgets.com/docs/MotorVelocityController_API_Guide#Rescale_Factor)
 *
 * @param[in] ch The channel handle
 * @param[in] rescaleFactor The rescale factor value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorVelocityController_setRescaleFactor(PhidgetMotorVelocityControllerHandle ch,
  double rescaleFactor);

/**
 * @brief The rescale factor value
 *
 * Change the units of your parameters so that your application is more intuitive.
 *
 * *   Units for `Acceleration`, `DeadBand`, @ref
 *     PhidgetMotorVelocityController_getExpectedVelocity(), `TargetVelocity`, and @ref
 *     PhidgetMotorVelocityController_getVelocity() can be set by the user through the
 *     `RescaleFactor`. The `RescaleFactor` allows you to use more intuitive units such as
 *     rotations, or degrees.
 *
 * For more information about `RescaleFactor`, visit our [MotorVelocityController API
 * Guide](https://www.phidgets.com/docs/MotorVelocityController_API_Guide#Rescale_Factor)
 *
 * @param[in] ch The channel handle
 * @param[out] rescaleFactor The rescale factor value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorVelocityController_getRescaleFactor(PhidgetMotorVelocityControllerHandle ch,
  double *rescaleFactor);

/**
 * @brief The stall velocity value.
 *
 * Before reading this description, it is important to note the difference between the units of
 * `StallVelocity` and @ref PhidgetMotorVelocityController_getDutyCycle().
 *
 * *   @ref PhidgetMotorVelocityController_getDutyCycle() is a number between -1 and 1 with
 *     units of 'duty cycle'. It simply represents the average voltage across the motor.
 * *   `StallVelocity` represents a real velocity (e.g. m/s, RPM, etc.) and the units are
 *     determined by the `RescaleFactor`. With a `RescaleFactor` of 1, the default units would be in
 *     commutations per second.
 *
 * If the load on your motor is large, your motor may begin rotating more slowly, or even fully
 * stall. Depending on the voltage across your motor, this may result in a large amount of current
 * through both the controller and the motor. In order to prevent damage in these situations, you
 * can use the `StallVelocity` property.
 *
 * The `StallVelocity` should be set to the lowest velocity you would expect from your motor. The
 * controller will then monitor the motor's velocity, as well as the @ref
 * PhidgetMotorVelocityController_getDutyCycle(), and prevent a 'dangerous stall' from occuring. If
 * the controller detects a dangerous stall, it will immediately disengage the motor (i.e. `Engaged`
 * will be set to false) and an error will be reported to your program.
 *
 * *   A 'dangerous stall' will occur faster when the @ref
 *     PhidgetMotorVelocityController_getDutyCycle() is higher (i.e. when the average voltage across
 *     the motor is higher)
 * *   A 'dangerous stall' will occur faster as (`StallVelocity` \- motor velocity) becomes
 *     larger .
 *
 * Setting `StallVelocity` to 0 will turn off stall protection functionality.
 *
 * @param[in] ch The channel handle
 * @param[in] stallVelocity The stall velocity value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorVelocityController_setStallVelocity(PhidgetMotorVelocityControllerHandle ch,
  double stallVelocity);

/**
 * @brief The stall velocity value.
 *
 * Before reading this description, it is important to note the difference between the units of
 * `StallVelocity` and @ref PhidgetMotorVelocityController_getDutyCycle().
 *
 * *   @ref PhidgetMotorVelocityController_getDutyCycle() is a number between -1 and 1 with
 *     units of 'duty cycle'. It simply represents the average voltage across the motor.
 * *   `StallVelocity` represents a real velocity (e.g. m/s, RPM, etc.) and the units are
 *     determined by the `RescaleFactor`. With a `RescaleFactor` of 1, the default units would be in
 *     commutations per second.
 *
 * If the load on your motor is large, your motor may begin rotating more slowly, or even fully
 * stall. Depending on the voltage across your motor, this may result in a large amount of current
 * through both the controller and the motor. In order to prevent damage in these situations, you
 * can use the `StallVelocity` property.
 *
 * The `StallVelocity` should be set to the lowest velocity you would expect from your motor. The
 * controller will then monitor the motor's velocity, as well as the @ref
 * PhidgetMotorVelocityController_getDutyCycle(), and prevent a 'dangerous stall' from occuring. If
 * the controller detects a dangerous stall, it will immediately disengage the motor (i.e. `Engaged`
 * will be set to false) and an error will be reported to your program.
 *
 * *   A 'dangerous stall' will occur faster when the @ref
 *     PhidgetMotorVelocityController_getDutyCycle() is higher (i.e. when the average voltage across
 *     the motor is higher)
 * *   A 'dangerous stall' will occur faster as (`StallVelocity` \- motor velocity) becomes
 *     larger .
 *
 * Setting `StallVelocity` to 0 will turn off stall protection functionality.
 *
 * @param[in] ch The channel handle
 * @param[out] stallVelocity The stall velocity value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorVelocityController_getStallVelocity(PhidgetMotorVelocityControllerHandle ch,
  double *stallVelocity);

/**
 * @brief The velocity value
 *
 * The lower bound of `StallVelocity`.
 *
 * @param[in] ch The channel handle
 * @param[out] minStallVelocity The velocity value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorVelocityController_getMinStallVelocity(PhidgetMotorVelocityControllerHandle ch,
  double *minStallVelocity);

/**
 * @brief The velocity value
 *
 * The upper bound of `StallVelocity`.
 *
 * @param[in] ch The channel handle
 * @param[out] maxStallVelocity The velocity value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorVelocityController_getMaxStallVelocity(PhidgetMotorVelocityControllerHandle ch,
  double *maxStallVelocity);

/**
 * @brief The surge current limit value
 *
 * The `SurgeCurrentLimit` allows for increased performance from your motor. The controller will
 * limit the current through your motor to the `SurgeCurrentLimit` briefly, then scale current down
 * to the `CurrentLimit`.
 *
 * *   View @ref PhidgetMotorVelocityController_getActiveCurrentLimit() for information about
 *     what current limit the controller is actively following.
 *
 * For more information about `SurgeCurrentLimit`, visit our [MotorVelocityController API
 * Guide](https://www.phidgets.com/docs/MotorVelocityController_API_Guide#Surge_Current_Limit)
 *
 * @param[in] ch The channel handle
 * @param[in] surgeCurrentLimit The surge current limit value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorVelocityController_setSurgeCurrentLimit(PhidgetMotorVelocityControllerHandle ch,
  double surgeCurrentLimit);

/**
 * @brief The surge current limit value
 *
 * The `SurgeCurrentLimit` allows for increased performance from your motor. The controller will
 * limit the current through your motor to the `SurgeCurrentLimit` briefly, then scale current down
 * to the `CurrentLimit`.
 *
 * *   View @ref PhidgetMotorVelocityController_getActiveCurrentLimit() for information about
 *     what current limit the controller is actively following.
 *
 * For more information about `SurgeCurrentLimit`, visit our [MotorVelocityController API
 * Guide](https://www.phidgets.com/docs/MotorVelocityController_API_Guide#Surge_Current_Limit)
 *
 * @param[in] ch The channel handle
 * @param[out] surgeCurrentLimit The surge current limit value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorVelocityController_getSurgeCurrentLimit(PhidgetMotorVelocityControllerHandle ch,
  double *surgeCurrentLimit);

/**
 * @brief The surge current value
 *
 * The minimum value that `SurgeCurrentLimit` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minSurgeCurrentLimit The surge current value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorVelocityController_getMinSurgeCurrentLimit(PhidgetMotorVelocityControllerHandle ch,
  double *minSurgeCurrentLimit);

/**
 * @brief The surge current value
 *
 * The maximum value that `SurgeCurrentLimit` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxSurgeCurrentLimit The surge current value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorVelocityController_getMaxSurgeCurrentLimit(PhidgetMotorVelocityControllerHandle ch,
  double *maxSurgeCurrentLimit);

/**
 * @brief The velocity value.
 *
 * When moving, the motor velocity will be limited by this value.
 *
 * *   Use the `RescaleFactor` to convert the units of this property to more intuitive units,
 *     such as rotations or degrees.
 *
 * For more information about `TargetVelocity`, visit our [MotorVelocityController API
 * Guide](https://www.phidgets.com/docs/MotorVelocityController_API_Guide#Target_Velocity)
 *
 * @param[in] ch The channel handle
 * @param[in] targetVelocity The velocity value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorVelocityController_setTargetVelocity(PhidgetMotorVelocityControllerHandle ch,
  double targetVelocity);

/**
 * @brief The velocity value.
 *
 * When moving, the motor velocity will be limited by this value.
 *
 * *   Use the `RescaleFactor` to convert the units of this property to more intuitive units,
 *     such as rotations or degrees.
 *
 * For more information about `TargetVelocity`, visit our [MotorVelocityController API
 * Guide](https://www.phidgets.com/docs/MotorVelocityController_API_Guide#Target_Velocity)
 *
 * @param[in] ch The channel handle
 * @param[out] targetVelocity The velocity value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorVelocityController_getTargetVelocity(PhidgetMotorVelocityControllerHandle ch,
  double *targetVelocity);

/**
 * @brief The velocity value
 *
 * The minimum value that `TargetVelocity` can be set to.
 *
 * *   Use the `RescaleFactor` to convert the units of this property to more intuitive units,
 *     such as rotations or degrees.
 *
 * @param[in] ch The channel handle
 * @param[out] minTargetVelocity The velocity value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorVelocityController_getMinTargetVelocity(PhidgetMotorVelocityControllerHandle ch,
  double *minTargetVelocity);

/**
 * @brief The velocity value
 *
 * The maximum value that `TargetVelocity` can be set to.
 *
 * *   Use the `RescaleFactor` to convert the units of this property to more intuitive units,
 *     such as rotations or degrees.
 *
 * @param[in] ch The channel handle
 * @param[out] maxTargetVelocity The velocity value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorVelocityController_getMaxTargetVelocity(PhidgetMotorVelocityControllerHandle ch,
  double *maxTargetVelocity);

/**
 * @brief The velocity value
 *
 * The most recent velocity value that the controller has reported.
 *
 * *   Use the `RescaleFactor` to convert the units of this property to more intuitive units,
 *     such as rotations or degrees.
 *
 * @param[in] ch The channel handle
 * @param[out] velocity The velocity value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorVelocityController_getVelocity(PhidgetMotorVelocityControllerHandle ch,
  double *velocity);

/**
 * @brief Callback function type for
 *     PhidgetMotorVelocityController_setOnDutyCycleUpdateHandler().
 *
 * @param[in] ch The channel handle
 * @param[in] ctx Pointer to the user context
 * @param[in] dutyCycle The duty cycle value
 */
typedef void (CCONV *PhidgetMotorVelocityController_OnDutyCycleUpdateCallback)(PhidgetMotorVelocityControllerHandle ch,
  void *ctx, double dutyCycle);

/**
 * The most recent duty cycle value will be reported in this event, which occurs when the
 * `DataInterval` has elapsed.
 *
 * *   This event will **always** occur when the `DataInterval` elapses. You can depend on this
 *     event for constant timing when implementing control loops in code. This is the last event to
 *     fire, giving you up-to-date access to all properties.
 *
 * @param[in] ch The channel handle
 * @param[in] fptr The event handler callback function
 * @param[in] ctx User supplied context pointer
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorVelocityController_setOnDutyCycleUpdateHandler(PhidgetMotorVelocityControllerHandle ch,
  PhidgetMotorVelocityController_OnDutyCycleUpdateCallback fptr, void *ctx);

/**
 * @brief Callback function type for
 *     PhidgetMotorVelocityController_setOnExpectedVelocityChangeHandler().
 *
 * @param[in] ch The channel handle
 * @param[in] ctx Pointer to the user context
 * @param[in] expectedVelocity The expected velocity value
 */
typedef void (CCONV *PhidgetMotorVelocityController_OnExpectedVelocityChangeCallback)(PhidgetMotorVelocityControllerHandle ch,
  void *ctx, double expectedVelocity);

/**
 * The most recent velocity being tracked by the Velocity Control loop, which occurs when the
 * `DataInterval` has elapsed.
 *
 * *   Regardless of the `DataInterval`, this event will occur only when the velocity value has
 *     changed from the previous value reported.
 * *   Use the `RescaleFactor` to convert the units of this property to more intuitive units,
 *     such as rotations or degrees.
 *
 * @param[in] ch The channel handle
 * @param[in] fptr The event handler callback function
 * @param[in] ctx User supplied context pointer
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorVelocityController_setOnExpectedVelocityChangeHandler(PhidgetMotorVelocityControllerHandle ch,
  PhidgetMotorVelocityController_OnExpectedVelocityChangeCallback fptr, void *ctx);

/**
 * @brief Callback function type for
 *     PhidgetMotorVelocityController_setOnVelocityChangeHandler().
 *
 * @param[in] ch The channel handle
 * @param[in] ctx Pointer to the user context
 * @param[in] velocity The velocity value
 */
typedef void (CCONV *PhidgetMotorVelocityController_OnVelocityChangeCallback)(PhidgetMotorVelocityControllerHandle ch,
  void *ctx, double velocity);

/**
 * The most recent velocity value will be reported in this event, which occurs when the
 * `DataInterval` has elapsed.
 *
 * *   Use the `RescaleFactor` to convert the units of this property to more intuitive units,
 *     such as rotations or degrees.
 *
 * @param[in] ch The channel handle
 * @param[in] fptr The event handler callback function
 * @param[in] ctx User supplied context pointer
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetMotorVelocityController_setOnVelocityChangeHandler(PhidgetMotorVelocityControllerHandle ch,
  PhidgetMotorVelocityController_OnVelocityChangeCallback fptr, void *ctx);

/** @} */ /* PhidgetMotorVelocityController */

/**
 * @defgroup PhidgetPHSensor PHSensor
 * @brief The PH Sensor class gathers data from a pH sensor type Phidget board.
 * @{
 */

/**
 * The PH Sensor class gathers data from a pH sensor type Phidget board.
 *
 * If you're using a simple 0-5V sensor that does not have its own firmware, use the VoltageInput or
 * VoltageRatioInput class instead, as specified for your device.
 */
typedef struct _PhidgetPHSensor *PhidgetPHSensorHandle;

/**
 * @ref PhidgetPHSensor_create() creates an instance of a Phidget channel. Once created the channel
 * may need to be configured to match the physical device and channel index you want to attach to,
 * and then be opened by calling @ref Phidget_open().
 * The Phidget channel handle must be released with @ref PhidgetPHSensor_delete().
 *
 * @param[out] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetPHSensor_create(PhidgetPHSensorHandle *ch);

/**
 * @ref PhidgetPHSensor_delete() releases a Phidget channel handle created with @ref
 * PhidgetPHSensor_create().
 * If the channel is open when @ref PhidgetPHSensor_delete() is called, it will be closed.
 *
 * @param[out] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetPHSensor_delete(PhidgetPHSensorHandle *ch);

/**
 * @brief The temperature of the solution to correct the pH measurement.
 *
 * Set this property to the measured temperature of the solution to correct the slope of the pH
 * conversion for temperature.
 *
 * @param[in] ch The channel handle
 * @param[in] correctionTemperature The temperature of the solution to correct the pH
 *     measurement
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetPHSensor_setCorrectionTemperature(PhidgetPHSensorHandle ch,
  double correctionTemperature);

/**
 * @brief The temperature of the solution to correct the pH measurement.
 *
 * Set this property to the measured temperature of the solution to correct the slope of the pH
 * conversion for temperature.
 *
 * @param[in] ch The channel handle
 * @param[out] correctionTemperature The temperature of the solution to correct the pH
 *     measurement
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetPHSensor_getCorrectionTemperature(PhidgetPHSensorHandle ch,
  double *correctionTemperature);

/**
 * @brief The minimum temperature that can be corrected for.
 *
 * The minimum value that `CorrectionTemperature` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minCorrectionTemperature The minimum temperature that can be corrected for
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetPHSensor_getMinCorrectionTemperature(PhidgetPHSensorHandle ch,
  double *minCorrectionTemperature);

/**
 * @brief The maximum temperature that can be corrected for.
 *
 * The maximum value that `CorrectionTemperature` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxCorrectionTemperature The maximum temperature that can be corrected for
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetPHSensor_getMaxCorrectionTemperature(PhidgetPHSensorHandle ch,
  double *maxCorrectionTemperature);

/**
 * @brief The data interval value
 *
 * The `DataInterval` is the time that must elapse before the channel will fire another @ref
 * PhidgetPHSensor_setOnPHChangeHandler() event.
 *
 * *   The data interval is bounded by @ref PhidgetPHSensor_getMinDataInterval() and @ref
 *     PhidgetPHSensor_getMaxDataInterval().
 * *   The timing between @ref PhidgetPHSensor_setOnPHChangeHandler() events can also be
 *     affected by the `PHChangeTrigger`.
 *
 * @param[in] ch The channel handle
 * @param[in] dataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetPHSensor_setDataInterval(PhidgetPHSensorHandle ch,
  uint32_t dataInterval);

/**
 * @brief The data interval value
 *
 * The `DataInterval` is the time that must elapse before the channel will fire another @ref
 * PhidgetPHSensor_setOnPHChangeHandler() event.
 *
 * *   The data interval is bounded by @ref PhidgetPHSensor_getMinDataInterval() and @ref
 *     PhidgetPHSensor_getMaxDataInterval().
 * *   The timing between @ref PhidgetPHSensor_setOnPHChangeHandler() events can also be
 *     affected by the `PHChangeTrigger`.
 *
 * @param[in] ch The channel handle
 * @param[out] dataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetPHSensor_getDataInterval(PhidgetPHSensorHandle ch,
  uint32_t *dataInterval);

/**
 * @brief The data interval value
 *
 * The minimum value that `DataInterval` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minDataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetPHSensor_getMinDataInterval(PhidgetPHSensorHandle ch,
  uint32_t *minDataInterval);

/**
 * @brief The data interval value
 *
 * The maximum value that `DataInterval` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxDataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetPHSensor_getMaxDataInterval(PhidgetPHSensorHandle ch,
  uint32_t *maxDataInterval);

/**
 * @brief The data rate for the channel
 *
 * The `DataRate` is the frequency of events from the device.
 *
 * *   The data rate is bounded by @ref PhidgetPHSensor_getMinDataRate() and @ref
 *     PhidgetPHSensor_getMaxDataRate().
 * *   Changing `DataRate` will change the channel's `DataInterval` to a corresponding value,
 *     rounded to the nearest integer number of milliseconds.
 * *   The timing between events can also affected by the change trigger.
 *
 * @param[in] ch The channel handle
 * @param[in] dataRate The data rate for the channel
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetPHSensor_setDataRate(PhidgetPHSensorHandle ch,
  double dataRate);

/**
 * @brief The data rate for the channel
 *
 * The `DataRate` is the frequency of events from the device.
 *
 * *   The data rate is bounded by @ref PhidgetPHSensor_getMinDataRate() and @ref
 *     PhidgetPHSensor_getMaxDataRate().
 * *   Changing `DataRate` will change the channel's `DataInterval` to a corresponding value,
 *     rounded to the nearest integer number of milliseconds.
 * *   The timing between events can also affected by the change trigger.
 *
 * @param[in] ch The channel handle
 * @param[out] dataRate The data rate for the channel
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetPHSensor_getDataRate(PhidgetPHSensorHandle ch,
  double *dataRate);

/**
 * @brief The data rate value
 *
 * The minimum value that `DataRate` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minDataRate The data rate value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetPHSensor_getMinDataRate(PhidgetPHSensorHandle ch,
  double *minDataRate);

/**
 * @brief The data rate value
 *
 * The maximum value that `DataRate` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxDataRate The data rate value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetPHSensor_getMaxDataRate(PhidgetPHSensorHandle ch,
  double *maxDataRate);

/**
 * @brief The pH value
 *
 * The most recent pH value that the channel has reported.
 *
 * *   This value will always be between @ref PhidgetPHSensor_getMinPH() and @ref
 *     PhidgetPHSensor_getMaxPH().
 *
 * @param[in] ch The channel handle
 * @param[out] PH The pH value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetPHSensor_getPH(PhidgetPHSensorHandle ch, double *PH);

/**
 * @brief The pH value
 *
 * The minimum value the @ref PhidgetPHSensor_setOnPHChangeHandler() event will report.
 *
 * @param[in] ch The channel handle
 * @param[out] minPH The pH value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetPHSensor_getMinPH(PhidgetPHSensorHandle ch, double *minPH);

/**
 * @brief The pH value
 *
 * The maximum value the @ref PhidgetPHSensor_setOnPHChangeHandler() event will report.
 *
 * @param[in] ch The channel handle
 * @param[out] maxPH The pH value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetPHSensor_getMaxPH(PhidgetPHSensorHandle ch, double *maxPH);

/**
 * @brief The change trigger value
 *
 * The channel will not issue a @ref PhidgetPHSensor_setOnPHChangeHandler() event until the pH value
 * has changed by the amount specified by the `PHChangeTrigger`.
 *
 * *   Setting the `PHChangeTrigger` to 0 will result in the channel firing events every
 *     `DataInterval`. This is useful for applications that implement their own data filtering
 *
 * @param[in] ch The channel handle
 * @param[in] PHChangeTrigger The change trigger value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetPHSensor_setPHChangeTrigger(PhidgetPHSensorHandle ch,
  double PHChangeTrigger);

/**
 * @brief The change trigger value
 *
 * The channel will not issue a @ref PhidgetPHSensor_setOnPHChangeHandler() event until the pH value
 * has changed by the amount specified by the `PHChangeTrigger`.
 *
 * *   Setting the `PHChangeTrigger` to 0 will result in the channel firing events every
 *     `DataInterval`. This is useful for applications that implement their own data filtering
 *
 * @param[in] ch The channel handle
 * @param[out] PHChangeTrigger The change trigger value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetPHSensor_getPHChangeTrigger(PhidgetPHSensorHandle ch,
  double *PHChangeTrigger);

/**
 * @brief The change trigger value
 *
 * The minimum value that `PHChangeTrigger` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minPHChangeTrigger The change trigger value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetPHSensor_getMinPHChangeTrigger(PhidgetPHSensorHandle ch,
  double *minPHChangeTrigger);

/**
 * @brief The change trigger value
 *
 * The maximum value that `PHChangeTrigger` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxPHChangeTrigger The change trigger value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetPHSensor_getMaxPHChangeTrigger(PhidgetPHSensorHandle ch,
  double *maxPHChangeTrigger);

/**
 * @brief Callback function type for PhidgetPHSensor_setOnPHChangeHandler().
 *
 * @param[in] ch The channel handle
 * @param[in] ctx Pointer to the user context
 * @param[in] PH The current pH
 */
typedef void (CCONV *PhidgetPHSensor_OnPHChangeCallback)(PhidgetPHSensorHandle ch, void *ctx,
  double PH);

/**
 * The most recent pH value the channel has measured will be reported in this event, which occurs
 * when the `DataInterval` has elapsed.
 *
 * *   If a `PHChangeTrigger` has been set to a non-zero value, the @ref
 *     PhidgetPHSensor_setOnPHChangeHandler() event will not occur until the pH has changed by at
 *     least the `PHChangeTrigger` value.
 *
 * @param[in] ch The channel handle
 * @param[in] fptr The event handler callback function
 * @param[in] ctx User supplied context pointer
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetPHSensor_setOnPHChangeHandler(PhidgetPHSensorHandle ch,
  PhidgetPHSensor_OnPHChangeCallback fptr, void *ctx);

/** @} */ /* PhidgetPHSensor */

/**
 * @defgroup PhidgetPowerGuard PowerGuard
 * @brief The Power Guard class controls the safety features and thresholds of a programmable
 *     power guard Phidget board.
 * @{
 */

/**
 * The Power Guard class controls the safety features and thresholds of a programmable power guard
 * Phidget board.
 */
typedef struct _PhidgetPowerGuard *PhidgetPowerGuardHandle;

/**
 * @ref PhidgetPowerGuard_create() creates an instance of a Phidget channel. Once created the
 * channel may need to be configured to match the physical device and channel index you want to
 * attach to, and then be opened by calling @ref Phidget_open().
 * The Phidget channel handle must be released with @ref PhidgetPowerGuard_delete().
 *
 * @param[out] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetPowerGuard_create(PhidgetPowerGuardHandle *ch);

/**
 * @ref PhidgetPowerGuard_delete() releases a Phidget channel handle created with @ref
 * PhidgetPowerGuard_create().
 * If the channel is open when @ref PhidgetPowerGuard_delete() is called, it will be closed.
 *
 * @param[out] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetPowerGuard_delete(PhidgetPowerGuardHandle *ch);

/**
 * Enables the **failsafe** feature for the channel, with the specified **failsafe time**.
 *
 * Enabling the failsafe feature starts a recurring **failsafe timer** for the channel. Once the
 * failsafe is enabled, the timer must be reset within the specified time or the channel will enter
 * a **failsafe state**. For Power Guard channels, this will turn off the output. The failsafe timer
 * can be reset by using any of the following API calls:
 *
 * *   @ref PhidgetPowerGuard_setFanMode()
 * *   @ref PhidgetPowerGuard_setOverVoltage()
 * *   @ref PhidgetPowerGuard_setPowerEnabled()
 * *   @ref PhidgetPowerGuard_resetFailsafe()
 *
 * For more information about failsafe, visit our [Failsafe
 * Guide](https://www.phidgets.com/docs/Failsafe_Guide).
 *
 * @param[in] ch The channel handle
 * @param[in] failsafeTime Failsafe timeout in milliseconds
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetPowerGuard_enableFailsafe(PhidgetPowerGuardHandle ch,
  uint32_t failsafeTime);

/**
 * Resets the failsafe timer, if one has been set. See @ref PhidgetPowerGuard_enableFailsafe() for
 * details.
 *
 * This function will fail if no failsafe timer has been set for the channel.
 *
 * @param[in] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetPowerGuard_resetFailsafe(PhidgetPowerGuardHandle ch);

/**
 * @brief The failsafe time
 *
 * The minimum value that `failsafeTime` can be set to when calling @ref
 * PhidgetPowerGuard_enableFailsafe().
 *
 * @param[in] ch The channel handle
 * @param[out] minFailsafeTime The failsafe time
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetPowerGuard_getMinFailsafeTime(PhidgetPowerGuardHandle ch,
  uint32_t *minFailsafeTime);

/**
 * @brief The failsafe time
 *
 * The maximum value that `failsafeTime` can be set to when calling @ref
 * PhidgetPowerGuard_enableFailsafe().
 *
 * @param[in] ch The channel handle
 * @param[out] maxFailsafeTime The failsafe time
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetPowerGuard_getMaxFailsafeTime(PhidgetPowerGuardHandle ch,
  uint32_t *maxFailsafeTime);

/**
 * @brief The fan mode value
 *
 * The `FanMode` dictates the operating condition of the fan.
 *
 * *   Choose between on, off, or automatic (based on temperature).
 * *   If the `FanMode` is set to automatic, the fan will turn on when the temperature reaches
 *     70°C and it will remain on until the temperature falls below 55°C.
 * *   If the `FanMode` is off, the device will still turn on the fan if the temperature reaches
 *     85°C and it will remain on until it falls below 70°C.
 *
 * @param[in] ch The channel handle
 * @param[in] fanMode The fan mode value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetPowerGuard_setFanMode(PhidgetPowerGuardHandle ch,
  Phidget_FanMode fanMode);

/**
 * @brief The fan mode value
 *
 * The `FanMode` dictates the operating condition of the fan.
 *
 * *   Choose between on, off, or automatic (based on temperature).
 * *   If the `FanMode` is set to automatic, the fan will turn on when the temperature reaches
 *     70°C and it will remain on until the temperature falls below 55°C.
 * *   If the `FanMode` is off, the device will still turn on the fan if the temperature reaches
 *     85°C and it will remain on until it falls below 70°C.
 *
 * @param[in] ch The channel handle
 * @param[out] fanMode The fan mode value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetPowerGuard_getFanMode(PhidgetPowerGuardHandle ch,
  Phidget_FanMode *fanMode);

/**
 * @brief The voltage value
 *
 * The device constantly monitors the output voltage, and if it exceeds the `OverVoltage` value, it
 * will disconnect the input from the output.
 *
 * *   This functionality is critical for protecting power supplies from regenerated voltage
 *     coming from motors. Many power supplies assume that a higher than output expected voltage is
 *     related to an internal failure to the power supply, and will permanently disable themselves
 *     to protect the system. A typical safe value is to set OverVoltage to 1-2 volts higher than
 *     the output voltage of the supply. For instance, a 12V supply would be protected by setting
 *     OverVoltage to 13V.
 * *   The device will connect the input to the output again when the voltage drops to
 *     (`OverVoltage` \- 1V)
 *
 * @param[in] ch The channel handle
 * @param[in] overVoltage The voltage value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetPowerGuard_setOverVoltage(PhidgetPowerGuardHandle ch,
  double overVoltage);

/**
 * @brief The voltage value
 *
 * The device constantly monitors the output voltage, and if it exceeds the `OverVoltage` value, it
 * will disconnect the input from the output.
 *
 * *   This functionality is critical for protecting power supplies from regenerated voltage
 *     coming from motors. Many power supplies assume that a higher than output expected voltage is
 *     related to an internal failure to the power supply, and will permanently disable themselves
 *     to protect the system. A typical safe value is to set OverVoltage to 1-2 volts higher than
 *     the output voltage of the supply. For instance, a 12V supply would be protected by setting
 *     OverVoltage to 13V.
 * *   The device will connect the input to the output again when the voltage drops to
 *     (`OverVoltage` \- 1V)
 *
 * @param[in] ch The channel handle
 * @param[out] overVoltage The voltage value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetPowerGuard_getOverVoltage(PhidgetPowerGuardHandle ch,
  double *overVoltage);

/**
 * @brief The voltage value
 *
 * The minimum value that `OverVoltage` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minOverVoltage The voltage value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetPowerGuard_getMinOverVoltage(PhidgetPowerGuardHandle ch,
  double *minOverVoltage);

/**
 * @brief The voltage value
 *
 * The maximum value that `OverVoltage` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxOverVoltage The voltage value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetPowerGuard_getMaxOverVoltage(PhidgetPowerGuardHandle ch,
  double *maxOverVoltage);

/**
 * @brief The power enabled value.
 *
 * When `PowerEnabled` is true, the device will connect the input to the output and begin
 * monitoring.
 *
 * *   The output voltage is constantly monitored and will be automatically disconnected from
 *     the input when the output exceeds the `OverVoltage` value.
 * *   `PowerEnabled` allows the device to operate as a Solid State Relay, powering on or off
 *     all devices connected to the output.
 *
 * @param[in] ch The channel handle
 * @param[in] powerEnabled The power enabled value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetPowerGuard_setPowerEnabled(PhidgetPowerGuardHandle ch,
  int powerEnabled);

/**
 * @brief The power enabled value.
 *
 * When `PowerEnabled` is true, the device will connect the input to the output and begin
 * monitoring.
 *
 * *   The output voltage is constantly monitored and will be automatically disconnected from
 *     the input when the output exceeds the `OverVoltage` value.
 * *   `PowerEnabled` allows the device to operate as a Solid State Relay, powering on or off
 *     all devices connected to the output.
 *
 * @param[in] ch The channel handle
 * @param[out] powerEnabled The power enabled value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetPowerGuard_getPowerEnabled(PhidgetPowerGuardHandle ch,
  int *powerEnabled);

/** @} */ /* PhidgetPowerGuard */

/**
 * @defgroup PhidgetPressureSensor PressureSensor
 * @brief The Pressure Sensor class gathers data from the pressure sensor on a Phidget board.
 * @{
 */

/**
 * The Pressure Sensor class gathers data from the pressure sensor on a Phidget board.
 *
 * If you're using a simple 0-5V sensor that does not have its own firmware, use the VoltageInput or
 * VoltageRatioInput class instead, as specified for your device.
 */
typedef struct _PhidgetPressureSensor *PhidgetPressureSensorHandle;

/**
 * @ref PhidgetPressureSensor_create() creates an instance of a Phidget channel. Once created the
 * channel may need to be configured to match the physical device and channel index you want to
 * attach to, and then be opened by calling @ref Phidget_open().
 * The Phidget channel handle must be released with @ref PhidgetPressureSensor_delete().
 *
 * @param[out] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetPressureSensor_create(PhidgetPressureSensorHandle *ch);

/**
 * @ref PhidgetPressureSensor_delete() releases a Phidget channel handle created with @ref
 * PhidgetPressureSensor_create().
 * If the channel is open when @ref PhidgetPressureSensor_delete() is called, it will be closed.
 *
 * @param[out] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetPressureSensor_delete(PhidgetPressureSensorHandle *ch);

/**
 * @brief The data interval value
 *
 * The `DataInterval` is the time that must elapse before the channel will fire another @ref
 * PhidgetPressureSensor_setOnPressureChangeHandler() event.
 *
 * *   The data interval is bounded by @ref PhidgetPressureSensor_getMinDataInterval() and @ref
 *     PhidgetPressureSensor_getMaxDataInterval().
 * *   The timing between @ref PhidgetPressureSensor_setOnPressureChangeHandler() events can
 *     also be affected by the `PressureChangeTrigger`.
 *
 * @param[in] ch The channel handle
 * @param[in] dataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetPressureSensor_setDataInterval(PhidgetPressureSensorHandle ch,
  uint32_t dataInterval);

/**
 * @brief The data interval value
 *
 * The `DataInterval` is the time that must elapse before the channel will fire another @ref
 * PhidgetPressureSensor_setOnPressureChangeHandler() event.
 *
 * *   The data interval is bounded by @ref PhidgetPressureSensor_getMinDataInterval() and @ref
 *     PhidgetPressureSensor_getMaxDataInterval().
 * *   The timing between @ref PhidgetPressureSensor_setOnPressureChangeHandler() events can
 *     also be affected by the `PressureChangeTrigger`.
 *
 * @param[in] ch The channel handle
 * @param[out] dataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetPressureSensor_getDataInterval(PhidgetPressureSensorHandle ch,
  uint32_t *dataInterval);

/**
 * @brief The data interval value
 *
 * The minimum value that `DataInterval` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minDataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetPressureSensor_getMinDataInterval(PhidgetPressureSensorHandle ch,
  uint32_t *minDataInterval);

/**
 * @brief The data interval value
 *
 * The maximum value that `DataInterval` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxDataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetPressureSensor_getMaxDataInterval(PhidgetPressureSensorHandle ch,
  uint32_t *maxDataInterval);

/**
 * @brief The data rate for the channel
 *
 * The `DataRate` is the frequency of events from the device.
 *
 * *   The data rate is bounded by @ref PhidgetPressureSensor_getMinDataRate() and @ref
 *     PhidgetPressureSensor_getMaxDataRate().
 * *   Changing `DataRate` will change the channel's `DataInterval` to a corresponding value,
 *     rounded to the nearest integer number of milliseconds.
 * *   The timing between events can also affected by the change trigger.
 *
 * @param[in] ch The channel handle
 * @param[in] dataRate The data rate for the channel
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetPressureSensor_setDataRate(PhidgetPressureSensorHandle ch,
  double dataRate);

/**
 * @brief The data rate for the channel
 *
 * The `DataRate` is the frequency of events from the device.
 *
 * *   The data rate is bounded by @ref PhidgetPressureSensor_getMinDataRate() and @ref
 *     PhidgetPressureSensor_getMaxDataRate().
 * *   Changing `DataRate` will change the channel's `DataInterval` to a corresponding value,
 *     rounded to the nearest integer number of milliseconds.
 * *   The timing between events can also affected by the change trigger.
 *
 * @param[in] ch The channel handle
 * @param[out] dataRate The data rate for the channel
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetPressureSensor_getDataRate(PhidgetPressureSensorHandle ch,
  double *dataRate);

/**
 * @brief The data rate value
 *
 * The minimum value that `DataRate` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minDataRate The data rate value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetPressureSensor_getMinDataRate(PhidgetPressureSensorHandle ch,
  double *minDataRate);

/**
 * @brief The data rate value
 *
 * The maximum value that `DataRate` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxDataRate The data rate value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetPressureSensor_getMaxDataRate(PhidgetPressureSensorHandle ch,
  double *maxDataRate);

/**
 * @brief The pressure value
 *
 * The most recent pressure value that the channel has reported.
 *
 * *   This value will always be between @ref PhidgetPressureSensor_getMinPressure() and @ref
 *     PhidgetPressureSensor_getMaxPressure().
 *
 * @param[in] ch The channel handle
 * @param[out] pressure The pressure value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetPressureSensor_getPressure(PhidgetPressureSensorHandle ch,
  double *pressure);

/**
 * @brief The pressure value
 *
 * The minimum value the @ref PhidgetPressureSensor_setOnPressureChangeHandler() event will report.
 *
 * @param[in] ch The channel handle
 * @param[out] minPressure The pressure value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetPressureSensor_getMinPressure(PhidgetPressureSensorHandle ch,
  double *minPressure);

/**
 * @brief The pressure value
 *
 * The maximum value the @ref PhidgetPressureSensor_setOnPressureChangeHandler() event will report.
 *
 * @param[in] ch The channel handle
 * @param[out] maxPressure The pressure value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetPressureSensor_getMaxPressure(PhidgetPressureSensorHandle ch,
  double *maxPressure);

/**
 * @brief The change trigger value
 *
 * The channel will not issue a @ref PhidgetPressureSensor_setOnPressureChangeHandler() event until
 * the pressure value has changed by the amount specified by the `PressureChangeTrigger`.
 *
 * *   Setting the `PressureChangeTrigger` to 0 will result in the channel firing events every
 *     `DataInterval`. This is useful for applications that implement their own data filtering
 *
 * @param[in] ch The channel handle
 * @param[in] pressureChangeTrigger The change trigger value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetPressureSensor_setPressureChangeTrigger(PhidgetPressureSensorHandle ch,
  double pressureChangeTrigger);

/**
 * @brief The change trigger value
 *
 * The channel will not issue a @ref PhidgetPressureSensor_setOnPressureChangeHandler() event until
 * the pressure value has changed by the amount specified by the `PressureChangeTrigger`.
 *
 * *   Setting the `PressureChangeTrigger` to 0 will result in the channel firing events every
 *     `DataInterval`. This is useful for applications that implement their own data filtering
 *
 * @param[in] ch The channel handle
 * @param[out] pressureChangeTrigger The change trigger value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetPressureSensor_getPressureChangeTrigger(PhidgetPressureSensorHandle ch,
  double *pressureChangeTrigger);

/**
 * @brief The change trigger value
 *
 * The minimum value that `PressureChangeTrigger` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minPressureChangeTrigger The change trigger value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetPressureSensor_getMinPressureChangeTrigger(PhidgetPressureSensorHandle ch,
  double *minPressureChangeTrigger);

/**
 * @brief The change trigger value
 *
 * The maximum value that `PressureChangeTrigger` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxPressureChangeTrigger The change trigger value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetPressureSensor_getMaxPressureChangeTrigger(PhidgetPressureSensorHandle ch,
  double *maxPressureChangeTrigger);

/**
 * @brief Callback function type for PhidgetPressureSensor_setOnPressureChangeHandler().
 *
 * @param[in] ch The channel handle
 * @param[in] ctx Pointer to the user context
 * @param[in] pressure The new measured pressure
 */
typedef void (CCONV *PhidgetPressureSensor_OnPressureChangeCallback)(PhidgetPressureSensorHandle ch,
  void *ctx, double pressure);

/**
 * The most recent pressure value the channel has measured will be reported in this event, which
 * occurs when the `DataInterval` has elapsed.
 *
 * *   If a `PressureChangeTrigger` has been set to a non-zero value, the @ref
 *     PhidgetPressureSensor_setOnPressureChangeHandler() event will not occur until the pressure
 *     has changed by at least the `PressureChangeTrigger` value.
 *
 * @param[in] ch The channel handle
 * @param[in] fptr The event handler callback function
 * @param[in] ctx User supplied context pointer
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetPressureSensor_setOnPressureChangeHandler(PhidgetPressureSensorHandle ch,
  PhidgetPressureSensor_OnPressureChangeCallback fptr, void *ctx);

/** @} */ /* PhidgetPressureSensor */

/**
 * @defgroup PhidgetRCServo RCServo
 * @brief The RC Servo class controls the signal being sent to the servo motors from the Phidget
 *     controller in order to control their position. This class provides control of the position,
 *     velocity, acceleration, and supply voltage of the attached servo.
 * @{
 */

/**
 * The RC Servo class controls the signal being sent to the servo motors from the Phidget controller
 * in order to control their position. This class provides control of the position, velocity,
 * acceleration, and supply voltage of the attached servo.
 */
typedef struct _PhidgetRCServo *PhidgetRCServoHandle;

/**
 * @ref PhidgetRCServo_create() creates an instance of a Phidget channel. Once created the channel
 * may need to be configured to match the physical device and channel index you want to attach to,
 * and then be opened by calling @ref Phidget_open().
 * The Phidget channel handle must be released with @ref PhidgetRCServo_delete().
 *
 * @param[out] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetRCServo_create(PhidgetRCServoHandle *ch);

/**
 * @ref PhidgetRCServo_delete() releases a Phidget channel handle created with @ref
 * PhidgetRCServo_create().
 * If the channel is open when @ref PhidgetRCServo_delete() is called, it will be closed.
 *
 * @param[out] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetRCServo_delete(PhidgetRCServoHandle *ch);

/**
 * Enables the **failsafe** feature for the channel, with the specified **failsafe time**.
 *
 * Enabling the failsafe feature starts a recurring **failsafe timer** for the channel. Once the
 * failsafe is enabled, the timer must be reset within the specified time or the channel will enter
 * a **failsafe state**. For RC Servo channels, this will disengage the servo. The failsafe timer
 * can be reset by using any of the following API calls:
 *
 * *   @ref PhidgetRCServo_setAcceleration()
 * *   @ref PhidgetRCServo_setEngaged()
 * *   @ref PhidgetRCServo_setMinPosition()
 * *   @ref PhidgetRCServo_setMaxPosition()
 * *   @ref PhidgetRCServo_setMinPulseWidth()
 * *   @ref PhidgetRCServo_setMaxPulseWidth()
 * *   @ref PhidgetRCServo_setSpeedRampingState()
 * *   @ref PhidgetRCServo_setVelocityLimit()
 * *   @ref PhidgetRCServo_setVoltage()
 * *   @ref PhidgetRCServo_resetFailsafe()
 *
 * For more information about failsafe, visit our [Failsafe
 * Guide](https://www.phidgets.com/docs/Failsafe_Guide).
 *
 * @param[in] ch The channel handle
 * @param[in] failsafeTime Failsafe timeout in milliseconds
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetRCServo_enableFailsafe(PhidgetRCServoHandle ch,
  uint32_t failsafeTime);

/**
 * Resets the failsafe timer, if one has been set. See @ref PhidgetRCServo_enableFailsafe() for
 * details.
 *
 * This function will fail if no failsafe timer has been set for the channel.
 *
 * @param[in] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetRCServo_resetFailsafe(PhidgetRCServoHandle ch);

/**
 * @brief The acceleration value
 *
 * When changing velocity, the RC servo motor will accelerate/decelerate at this rate.
 *
 * *   The acceleration is bounded by @ref PhidgetRCServo_getMaxAcceleration() and @ref
 *     PhidgetRCServo_getMinAcceleration().
 *
 * *   Using the **default settings** this acceleration will correspond acceleration of servo
 *     arm in **degrees/s2**, for many standard RC servos.
 *
 * *   `SpeedRampingState` controls whether or not the acceleration value is actually applied
 *     when trying to reach a target position.
 * *   There is a practical limit on how fast your RC servo motor can accelerate. This is based
 *     on the load and physical design of the motor.
 * *   The units for `TargetPosition`, `VelocityLimit`, and `Acceleration` are configured by
 *     scaling the internal timing (set with `MinPulseWidth` and `MaxPulseWidth`) to a user
 *     specified range with `MinPosition` and `MaxPosition`.
 *
 * See `TargetPosition` for a deeper explanation of how the settings of your RC Servo controller
 * interact to move your servo.
 *
 * @param[in] ch The channel handle
 * @param[in] acceleration The acceleration value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetRCServo_setAcceleration(PhidgetRCServoHandle ch,
  double acceleration);

/**
 * @brief The acceleration value
 *
 * When changing velocity, the RC servo motor will accelerate/decelerate at this rate.
 *
 * *   The acceleration is bounded by @ref PhidgetRCServo_getMaxAcceleration() and @ref
 *     PhidgetRCServo_getMinAcceleration().
 *
 * *   Using the **default settings** this acceleration will correspond acceleration of servo
 *     arm in **degrees/s2**, for many standard RC servos.
 *
 * *   `SpeedRampingState` controls whether or not the acceleration value is actually applied
 *     when trying to reach a target position.
 * *   There is a practical limit on how fast your RC servo motor can accelerate. This is based
 *     on the load and physical design of the motor.
 * *   The units for `TargetPosition`, `VelocityLimit`, and `Acceleration` are configured by
 *     scaling the internal timing (set with `MinPulseWidth` and `MaxPulseWidth`) to a user
 *     specified range with `MinPosition` and `MaxPosition`.
 *
 * See `TargetPosition` for a deeper explanation of how the settings of your RC Servo controller
 * interact to move your servo.
 *
 * @param[in] ch The channel handle
 * @param[out] acceleration The acceleration value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetRCServo_getAcceleration(PhidgetRCServoHandle ch,
  double *acceleration);

/**
 * @brief The acceleration value
 *
 * The minimum value that `Acceleration` can be set to.
 *
 * *   This value depends on `MinPosition`/`MaxPosition` and `MinPulseWidth`/`MaxPulseWidth`
 * .
 *
 * See `TargetPosition` for a deeper explanation of how the settings of your RC Servo controller
 * interact to move your servo.
 *
 * @param[in] ch The channel handle
 * @param[out] minAcceleration The acceleration value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetRCServo_getMinAcceleration(PhidgetRCServoHandle ch,
  double *minAcceleration);

/**
 * @brief The acceleration value
 *
 * The maximum acceleration that `Acceleration` can be set to.
 *
 * *   This value depends on `MinPosition`/`MaxPosition` and `MinPulseWidth`/`MaxPulseWidth`.
 *
 * See `TargetPosition` for a deeper explanation of how the settings of your RC Servo controller
 * interact to move your servo.
 *
 * @param[in] ch The channel handle
 * @param[out] maxAcceleration The acceleration value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetRCServo_getMaxAcceleration(PhidgetRCServoHandle ch,
  double *maxAcceleration);

/**
 * @brief The data interval value
 *
 * The `DataInterval` is the time that must elapse before the channel will fire another @ref
 * PhidgetRCServo_setOnPositionChangeHandler() / @ref PhidgetRCServo_setOnVelocityChangeHandler()
 * event.
 *
 * *   The data interval is bounded by @ref PhidgetRCServo_getMinDataInterval() and @ref
 *     PhidgetRCServo_getMaxDataInterval().
 *
 * @param[in] ch The channel handle
 * @param[in] dataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetRCServo_setDataInterval(PhidgetRCServoHandle ch,
  uint32_t dataInterval);

/**
 * @brief The data interval value
 *
 * The `DataInterval` is the time that must elapse before the channel will fire another @ref
 * PhidgetRCServo_setOnPositionChangeHandler() / @ref PhidgetRCServo_setOnVelocityChangeHandler()
 * event.
 *
 * *   The data interval is bounded by @ref PhidgetRCServo_getMinDataInterval() and @ref
 *     PhidgetRCServo_getMaxDataInterval().
 *
 * @param[in] ch The channel handle
 * @param[out] dataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetRCServo_getDataInterval(PhidgetRCServoHandle ch,
  uint32_t *dataInterval);

/**
 * @brief The data interval value
 *
 * The minimum value that `DataInterval` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minDataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetRCServo_getMinDataInterval(PhidgetRCServoHandle ch,
  uint32_t *minDataInterval);

/**
 * @brief The data interval value
 *
 * The maximum value that `DataInterval` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxDataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetRCServo_getMaxDataInterval(PhidgetRCServoHandle ch,
  uint32_t *maxDataInterval);

/**
 * @brief The data rate for the channel
 *
 * The `DataRate` is the frequency of events from the device.
 *
 * *   The data rate is bounded by @ref PhidgetRCServo_getMinDataRate() and @ref
 *     PhidgetRCServo_getMaxDataRate().
 * *   Changing `DataRate` will change the channel's `DataInterval` to a corresponding value,
 *     rounded to the nearest integer number of milliseconds.
 * *   The timing between events can also affected by the change trigger.
 *
 * @param[in] ch The channel handle
 * @param[in] dataRate The data rate for the channel
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetRCServo_setDataRate(PhidgetRCServoHandle ch,
  double dataRate);

/**
 * @brief The data rate for the channel
 *
 * The `DataRate` is the frequency of events from the device.
 *
 * *   The data rate is bounded by @ref PhidgetRCServo_getMinDataRate() and @ref
 *     PhidgetRCServo_getMaxDataRate().
 * *   Changing `DataRate` will change the channel's `DataInterval` to a corresponding value,
 *     rounded to the nearest integer number of milliseconds.
 * *   The timing between events can also affected by the change trigger.
 *
 * @param[in] ch The channel handle
 * @param[out] dataRate The data rate for the channel
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetRCServo_getDataRate(PhidgetRCServoHandle ch,
  double *dataRate);

/**
 * @brief The data rate value
 *
 * The minimum value that `DataRate` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minDataRate The data rate value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetRCServo_getMinDataRate(PhidgetRCServoHandle ch,
  double *minDataRate);

/**
 * @brief The data rate value
 *
 * The maximum value that `DataRate` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxDataRate The data rate value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetRCServo_getMaxDataRate(PhidgetRCServoHandle ch,
  double *maxDataRate);

/**
 * @brief The engaged value
 *
 * When engaged, a RC servo motor has the ability to be positioned. When disengaged, no commands are
 * sent to the RC servo motor.
 *
 * *   There is no position feedback to the controller, so the RC servo motor will immediately
 *     snap to the `TargetPosition` after being engaged from a disengaged state.
 * *   This property is useful for relaxing a servo once it has reached a given position.
 * *   If you are concerned about tracking position accurately, you should not disengage the
 *     motor while @ref PhidgetRCServo_getIsMoving() is true.
 *
 * @param[in] ch The channel handle
 * @param[in] engaged The engaged value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetRCServo_setEngaged(PhidgetRCServoHandle ch, int engaged);

/**
 * @brief The engaged value
 *
 * When engaged, a RC servo motor has the ability to be positioned. When disengaged, no commands are
 * sent to the RC servo motor.
 *
 * *   There is no position feedback to the controller, so the RC servo motor will immediately
 *     snap to the `TargetPosition` after being engaged from a disengaged state.
 * *   This property is useful for relaxing a servo once it has reached a given position.
 * *   If you are concerned about tracking position accurately, you should not disengage the
 *     motor while @ref PhidgetRCServo_getIsMoving() is true.
 *
 * @param[in] ch The channel handle
 * @param[out] engaged The engaged value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetRCServo_getEngaged(PhidgetRCServoHandle ch, int *engaged);

/**
 * @brief The failsafe time
 *
 * The minimum value that `failsafeTime` can be set to when calling @ref
 * PhidgetRCServo_enableFailsafe().
 *
 * @param[in] ch The channel handle
 * @param[out] minFailsafeTime The failsafe time
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetRCServo_getMinFailsafeTime(PhidgetRCServoHandle ch,
  uint32_t *minFailsafeTime);

/**
 * @brief The failsafe time
 *
 * The maximum value that `failsafeTime` can be set to when calling @ref
 * PhidgetRCServo_enableFailsafe().
 *
 * @param[in] ch The channel handle
 * @param[out] maxFailsafeTime The failsafe time
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetRCServo_getMaxFailsafeTime(PhidgetRCServoHandle ch,
  uint32_t *maxFailsafeTime);

/**
 * @brief The moving value
 *
 * @ref PhidgetRCServo_getIsMoving() returns true if the RC servo motor is currently in motion.
 *
 * *   The controller cannot know if the RC servo motor is physically moving. When @ref
 *     PhidgetRCServo_getIsMoving() is false, it simply means there are no commands in the pipeline
 *     to the RC servo motor.
 *
 * @param[in] ch The channel handle
 * @param[out] isMoving The moving value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetRCServo_getIsMoving(PhidgetRCServoHandle ch,
  int *isMoving);

/**
 * @brief The position value
 *
 * The most recent position of the RC servo motor that the controller has reported.
 *
 * *   This value will always be between `MinPosition` and `MaxPosition`.
 *
 * *   Using the **default settings** this position will correspond to the rotation of the servo
 *     arm in **degrees**, for many standard RC servos.
 *
 * See `TargetPosition` for a deeper explanation of how the settings of your RC Servo controller
 * interact to move your servo.
 *
 * @param[in] ch The channel handle
 * @param[out] position The position value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetRCServo_getPosition(PhidgetRCServoHandle ch,
  double *position);

/**
 * @brief The position value
 *
 * The minimum position that `TargetPosition` can be set to.
 *
 * *   The units for `TargetPosition`, `VelocityLimit`, and `Acceleration` are configured by
 *     scaling the internal timing (set with `MinPulseWidth` and `MaxPulseWidth`) to a user
 *     specified range with `MinPosition` and `MaxPosition`.
 *
 * See `TargetPosition` for a deeper explanation of how the settings of your RC Servo controller
 * interact to move your servo.
 *
 * @param[in] ch The channel handle
 * @param[in] minPosition The position value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetRCServo_setMinPosition(PhidgetRCServoHandle ch,
  double minPosition);

/**
 * @brief The position value
 *
 * The minimum position that `TargetPosition` can be set to.
 *
 * *   The units for `TargetPosition`, `VelocityLimit`, and `Acceleration` are configured by
 *     scaling the internal timing (set with `MinPulseWidth` and `MaxPulseWidth`) to a user
 *     specified range with `MinPosition` and `MaxPosition`.
 *
 * See `TargetPosition` for a deeper explanation of how the settings of your RC Servo controller
 * interact to move your servo.
 *
 * @param[in] ch The channel handle
 * @param[out] minPosition The position value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetRCServo_getMinPosition(PhidgetRCServoHandle ch,
  double *minPosition);

/**
 * @brief The position value
 *
 * The maximum position `TargetPosition` can be set to.
 *
 * *   The units for `TargetPosition`, `VelocityLimit`, and `Acceleration` are configured by
 *     scaling the internal timing (set with `MinPulseWidth` and `MaxPulseWidth`) to a user
 *     specified range with `MinPosition` and `MaxPosition`.
 *
 * See `TargetPosition` for a deeper explanation of how the settings of your RC Servo controller
 * interact to move your servo.
 *
 * @param[in] ch The channel handle
 * @param[in] maxPosition The position value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetRCServo_setMaxPosition(PhidgetRCServoHandle ch,
  double maxPosition);

/**
 * @brief The position value
 *
 * The maximum position `TargetPosition` can be set to.
 *
 * *   The units for `TargetPosition`, `VelocityLimit`, and `Acceleration` are configured by
 *     scaling the internal timing (set with `MinPulseWidth` and `MaxPulseWidth`) to a user
 *     specified range with `MinPosition` and `MaxPosition`.
 *
 * See `TargetPosition` for a deeper explanation of how the settings of your RC Servo controller
 * interact to move your servo.
 *
 * @param[in] ch The channel handle
 * @param[out] maxPosition The position value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetRCServo_getMaxPosition(PhidgetRCServoHandle ch,
  double *maxPosition);

/**
 * @brief The pulse width value
 *
 * The `MinPulseWidth` represents the minimum pulse width that your RC servo motor specifies.
 *
 * *   This value can be found in the data sheet of most RC servo motors.
 * *   The units for `TargetPosition`, `VelocityLimit`, and `Acceleration` are configured by
 *     scaling the internal timing (set with `MinPulseWidth` and `MaxPulseWidth`) to a user
 *     specified range with `MinPosition` and `MaxPosition`.
 *
 * See `TargetPosition` for a deeper explanation of how the settings of your RC Servo controller
 * interact to move your servo.
 *
 * @param[in] ch The channel handle
 * @param[in] minPulseWidth The pulse width value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetRCServo_setMinPulseWidth(PhidgetRCServoHandle ch,
  double minPulseWidth);

/**
 * @brief The pulse width value
 *
 * The `MinPulseWidth` represents the minimum pulse width that your RC servo motor specifies.
 *
 * *   This value can be found in the data sheet of most RC servo motors.
 * *   The units for `TargetPosition`, `VelocityLimit`, and `Acceleration` are configured by
 *     scaling the internal timing (set with `MinPulseWidth` and `MaxPulseWidth`) to a user
 *     specified range with `MinPosition` and `MaxPosition`.
 *
 * See `TargetPosition` for a deeper explanation of how the settings of your RC Servo controller
 * interact to move your servo.
 *
 * @param[in] ch The channel handle
 * @param[out] minPulseWidth The pulse width value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetRCServo_getMinPulseWidth(PhidgetRCServoHandle ch,
  double *minPulseWidth);

/**
 * @brief The pulse width value
 *
 * The `MaxPulseWidth` represents the maximum pulse width that your RC servo motor specifies.
 *
 * *   This value can be found in the data sheet of most RC servo motors.
 * *   The units for `TargetPosition`, `VelocityLimit`, and `Acceleration` are configured by
 *     scaling the internal timing (set with `MinPulseWidth` and `MaxPulseWidth`) to a user
 *     specified range with `MinPosition` and `MaxPosition`.
 *
 * See `TargetPosition` for a deeper explanation of how the settings of your RC Servo controller
 * interact to move your servo.
 *
 * @param[in] ch The channel handle
 * @param[in] maxPulseWidth The pulse width value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetRCServo_setMaxPulseWidth(PhidgetRCServoHandle ch,
  double maxPulseWidth);

/**
 * @brief The pulse width value
 *
 * The `MaxPulseWidth` represents the maximum pulse width that your RC servo motor specifies.
 *
 * *   This value can be found in the data sheet of most RC servo motors.
 * *   The units for `TargetPosition`, `VelocityLimit`, and `Acceleration` are configured by
 *     scaling the internal timing (set with `MinPulseWidth` and `MaxPulseWidth`) to a user
 *     specified range with `MinPosition` and `MaxPosition`.
 *
 * See `TargetPosition` for a deeper explanation of how the settings of your RC Servo controller
 * interact to move your servo.
 *
 * @param[in] ch The channel handle
 * @param[out] maxPulseWidth The pulse width value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetRCServo_getMaxPulseWidth(PhidgetRCServoHandle ch,
  double *maxPulseWidth);

/**
 * @brief The pulse width value
 *
 * The minimum pulse width that `MinPulseWidth` can be set to.
 *
 * See `TargetPosition` for a deeper explanation of how the settings of your RC Servo controller
 * interact to move your servo.
 *
 * @param[in] ch The channel handle
 * @param[out] minPulseWidthLimit The pulse width value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetRCServo_getMinPulseWidthLimit(PhidgetRCServoHandle ch,
  double *minPulseWidthLimit);

/**
 * @brief The pulse width value
 *
 * The maximum pulse width that `MaxPulseWidth` can be set to.
 *
 * See `TargetPosition` for a deeper explanation of how the settings of your RC Servo controller
 * interact to move your servo.
 *
 * @param[in] ch The channel handle
 * @param[out] maxPulseWidthLimit The pulse width value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetRCServo_getMaxPulseWidthLimit(PhidgetRCServoHandle ch,
  double *maxPulseWidthLimit);

/**
 * @brief The speed ramping state value
 *
 * When speed ramping state is enabled, the controller will take the `Acceleration` and
 * `VelocityLimit` properties into account when moving the RC servo motor, usually resulting in
 * smooth motion. If speed ramping state is not enabled, the controller will simply set the RC servo
 * motor to the requested position.
 *
 * @param[in] ch The channel handle
 * @param[in] speedRampingState The speed ramping state value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetRCServo_setSpeedRampingState(PhidgetRCServoHandle ch,
  int speedRampingState);

/**
 * @brief The speed ramping state value
 *
 * When speed ramping state is enabled, the controller will take the `Acceleration` and
 * `VelocityLimit` properties into account when moving the RC servo motor, usually resulting in
 * smooth motion. If speed ramping state is not enabled, the controller will simply set the RC servo
 * motor to the requested position.
 *
 * @param[in] ch The channel handle
 * @param[out] speedRampingState The speed ramping state value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetRCServo_getSpeedRampingState(PhidgetRCServoHandle ch,
  int *speedRampingState);

/**
 * @brief The position value
 *
 * If the RC servo motor is configured and `TargetPosition` is set, the controller will continuously
 * try to reach targeted position.
 *
 * *   The target position is bounded by `MinPosition` and `MaxPosition`.
 *
 * *   Using the **default settings** this position will correspond to the rotation of the servo
 *     arm in **degrees**, for many standard RC servos.
 *
 * *   If the RC servo motor is not engaged, then the position cannot be read.
 * *   The position can still be set while the RC servo motor is not engaged. Once engaged, the
 *     RC servo motor will snap to position, assuming it is not there already.
 * *   The units for `TargetPosition`, `VelocityLimit`, and `Acceleration` are configured by
 *     scaling the internal timing (set with `MinPulseWidth` and `MaxPulseWidth`) to a user
 *     specified range with `MinPosition` and `MaxPosition`.
 *
 * ### Position and Pulse Width
 *
 * *   An RC servo motor's position is controlled using a type of **Pulse Width Modulation**,
 *     sending voltage pulses of a given time span, or **Pulse Width** to the servo.
 * *   The servo translates the **Pulse Width** of the control signal to a corresponding
 *     position of the servo arm.
 * *   Knowing this, a servo's range of motion can be thought of in terms of a `MinPulseWidth`
 *     and a `MaxPulseWidth` corresponding to range of pulse widths that produce the servo arm's
 *     full **range of movement**.
 *
 * *   In Phidget22, you can adjust the `MinPulseWidth` and `MaxPulseWidth` stored by the
 *     library to match the desired **range of movement** you expect from your servo.
 *
 * *   Since directly setting the timing of RC servo pulse widths is not very intuitive for most
 *     purpses, we map these pulse widths to a user-defied _**Minimum**_ and _**Maximum**_
 *     **Position**.This allows you to define the servo's position in terms best suited to your
 *     application, such as degrees, fractions of a rotation, or even some measure of speed for a
 *     continuous-rotation servo.
 * *   By setting the servo's `TargetPosition` to `MaxPosition`, the controller will send pulses
 *     of `MaxPulseWidth` to the servo.
 *     *   Similarly, `MinPosition` will send pulses of `MinPulseWidth` to the servo
 *     *   `MaxPosition` can be set smaller than `MinPosition` to invert movement of the servo, if
 * it helps your application.
 * *   Setting a `TargetPosition` will transate the position between `MinPosition` and
 *     `MaxPosition` to a corresponding **Pulse Width** between `MinPulseWidth` and `MaxPulseWidth`,
 *     in turn sending the servo arm to the desired position.
 * *   Setting `VelocityLimit` and `Acceleration` for your servo will limit the rate of change
 *     of the servo's position in terms of one _**UserUnit**_ per second (or /s2). Here, a
 *     _**UserUnit**_ is whatever distance is maked by the change of the `TargetPosition` by **1.0**
 *
 * ### Adjusting the Servo's Limits
 *
 * *   **To tune your program to a specific servo:**
 *
 * 1.  First adjust the servo's range of motion by setting the `MaxPulseWidth` and `MinPulseWidth`.
 * You can use the default values for these _(or the ones on your servo's datasheet)_ as a starting
 * point.
 * 2.  Send the servo to `MaxPosition` and `MinPosition` to check the results. Repeat steps 1 and 2
 * as nessesarry.
 * 3.  Set the `MaxPosition` and `MinPosition` to match whatever numbers you find best suited to
 * your application.
 *
 * @param[in] ch The channel handle
 * @param[in] targetPosition The position value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetRCServo_setTargetPosition(PhidgetRCServoHandle ch,
  double targetPosition);

/**
 * @brief The position value
 *
 * If the RC servo motor is configured and `TargetPosition` is set, the controller will continuously
 * try to reach targeted position.
 *
 * *   The target position is bounded by `MinPosition` and `MaxPosition`.
 *
 * *   Using the **default settings** this position will correspond to the rotation of the servo
 *     arm in **degrees**, for many standard RC servos.
 *
 * *   If the RC servo motor is not engaged, then the position cannot be read.
 * *   The position can still be set while the RC servo motor is not engaged. Once engaged, the
 *     RC servo motor will snap to position, assuming it is not there already.
 * *   The units for `TargetPosition`, `VelocityLimit`, and `Acceleration` are configured by
 *     scaling the internal timing (set with `MinPulseWidth` and `MaxPulseWidth`) to a user
 *     specified range with `MinPosition` and `MaxPosition`.
 *
 * ### Position and Pulse Width
 *
 * *   An RC servo motor's position is controlled using a type of **Pulse Width Modulation**,
 *     sending voltage pulses of a given time span, or **Pulse Width** to the servo.
 * *   The servo translates the **Pulse Width** of the control signal to a corresponding
 *     position of the servo arm.
 * *   Knowing this, a servo's range of motion can be thought of in terms of a `MinPulseWidth`
 *     and a `MaxPulseWidth` corresponding to range of pulse widths that produce the servo arm's
 *     full **range of movement**.
 *
 * *   In Phidget22, you can adjust the `MinPulseWidth` and `MaxPulseWidth` stored by the
 *     library to match the desired **range of movement** you expect from your servo.
 *
 * *   Since directly setting the timing of RC servo pulse widths is not very intuitive for most
 *     purpses, we map these pulse widths to a user-defied _**Minimum**_ and _**Maximum**_
 *     **Position**.This allows you to define the servo's position in terms best suited to your
 *     application, such as degrees, fractions of a rotation, or even some measure of speed for a
 *     continuous-rotation servo.
 * *   By setting the servo's `TargetPosition` to `MaxPosition`, the controller will send pulses
 *     of `MaxPulseWidth` to the servo.
 *     *   Similarly, `MinPosition` will send pulses of `MinPulseWidth` to the servo
 *     *   `MaxPosition` can be set smaller than `MinPosition` to invert movement of the servo, if
 * it helps your application.
 * *   Setting a `TargetPosition` will transate the position between `MinPosition` and
 *     `MaxPosition` to a corresponding **Pulse Width** between `MinPulseWidth` and `MaxPulseWidth`,
 *     in turn sending the servo arm to the desired position.
 * *   Setting `VelocityLimit` and `Acceleration` for your servo will limit the rate of change
 *     of the servo's position in terms of one _**UserUnit**_ per second (or /s2). Here, a
 *     _**UserUnit**_ is whatever distance is maked by the change of the `TargetPosition` by **1.0**
 *
 * ### Adjusting the Servo's Limits
 *
 * *   **To tune your program to a specific servo:**
 *
 * 1.  First adjust the servo's range of motion by setting the `MaxPulseWidth` and `MinPulseWidth`.
 * You can use the default values for these _(or the ones on your servo's datasheet)_ as a starting
 * point.
 * 2.  Send the servo to `MaxPosition` and `MinPosition` to check the results. Repeat steps 1 and 2
 * as nessesarry.
 * 3.  Set the `MaxPosition` and `MinPosition` to match whatever numbers you find best suited to
 * your application.
 *
 * @param[in] ch The channel handle
 * @param[in] targetPosition The position value
 * @param[in] fptr Asynchronous completion callback
 * @param[in] ctx User supplied context pointer
 */
PHIDGET22_API void CCONV PhidgetRCServo_setTargetPosition_async(PhidgetRCServoHandle ch,
  double targetPosition, Phidget_AsyncCallback fptr, void *ctx);

/**
 * @brief The position value
 *
 * If the RC servo motor is configured and `TargetPosition` is set, the controller will continuously
 * try to reach targeted position.
 *
 * *   The target position is bounded by `MinPosition` and `MaxPosition`.
 *
 * *   Using the **default settings** this position will correspond to the rotation of the servo
 *     arm in **degrees**, for many standard RC servos.
 *
 * *   If the RC servo motor is not engaged, then the position cannot be read.
 * *   The position can still be set while the RC servo motor is not engaged. Once engaged, the
 *     RC servo motor will snap to position, assuming it is not there already.
 * *   The units for `TargetPosition`, `VelocityLimit`, and `Acceleration` are configured by
 *     scaling the internal timing (set with `MinPulseWidth` and `MaxPulseWidth`) to a user
 *     specified range with `MinPosition` and `MaxPosition`.
 *
 * ### Position and Pulse Width
 *
 * *   An RC servo motor's position is controlled using a type of **Pulse Width Modulation**,
 *     sending voltage pulses of a given time span, or **Pulse Width** to the servo.
 * *   The servo translates the **Pulse Width** of the control signal to a corresponding
 *     position of the servo arm.
 * *   Knowing this, a servo's range of motion can be thought of in terms of a `MinPulseWidth`
 *     and a `MaxPulseWidth` corresponding to range of pulse widths that produce the servo arm's
 *     full **range of movement**.
 *
 * *   In Phidget22, you can adjust the `MinPulseWidth` and `MaxPulseWidth` stored by the
 *     library to match the desired **range of movement** you expect from your servo.
 *
 * *   Since directly setting the timing of RC servo pulse widths is not very intuitive for most
 *     purpses, we map these pulse widths to a user-defied _**Minimum**_ and _**Maximum**_
 *     **Position**.This allows you to define the servo's position in terms best suited to your
 *     application, such as degrees, fractions of a rotation, or even some measure of speed for a
 *     continuous-rotation servo.
 * *   By setting the servo's `TargetPosition` to `MaxPosition`, the controller will send pulses
 *     of `MaxPulseWidth` to the servo.
 *     *   Similarly, `MinPosition` will send pulses of `MinPulseWidth` to the servo
 *     *   `MaxPosition` can be set smaller than `MinPosition` to invert movement of the servo, if
 * it helps your application.
 * *   Setting a `TargetPosition` will transate the position between `MinPosition` and
 *     `MaxPosition` to a corresponding **Pulse Width** between `MinPulseWidth` and `MaxPulseWidth`,
 *     in turn sending the servo arm to the desired position.
 * *   Setting `VelocityLimit` and `Acceleration` for your servo will limit the rate of change
 *     of the servo's position in terms of one _**UserUnit**_ per second (or /s2). Here, a
 *     _**UserUnit**_ is whatever distance is maked by the change of the `TargetPosition` by **1.0**
 *
 * ### Adjusting the Servo's Limits
 *
 * *   **To tune your program to a specific servo:**
 *
 * 1.  First adjust the servo's range of motion by setting the `MaxPulseWidth` and `MinPulseWidth`.
 * You can use the default values for these _(or the ones on your servo's datasheet)_ as a starting
 * point.
 * 2.  Send the servo to `MaxPosition` and `MinPosition` to check the results. Repeat steps 1 and 2
 * as nessesarry.
 * 3.  Set the `MaxPosition` and `MinPosition` to match whatever numbers you find best suited to
 * your application.
 *
 * @param[in] ch The channel handle
 * @param[out] targetPosition The position value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetRCServo_getTargetPosition(PhidgetRCServoHandle ch,
  double *targetPosition);

/**
 * @brief The torque value.
 *
 * The `Torque` is a ratio of the maximum available torque.
 *
 * *   The torque is bounded by @ref PhidgetRCServo_getMinTorque() and @ref
 *     PhidgetRCServo_getMaxTorque()
 * *   Increasing the torque will increase the speed and power consumption of the RC servo
 *     motor.
 *
 * @param[in] ch The channel handle
 * @param[in] torque The torque value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetRCServo_setTorque(PhidgetRCServoHandle ch, double torque);

/**
 * @brief The torque value.
 *
 * The `Torque` is a ratio of the maximum available torque.
 *
 * *   The torque is bounded by @ref PhidgetRCServo_getMinTorque() and @ref
 *     PhidgetRCServo_getMaxTorque()
 * *   Increasing the torque will increase the speed and power consumption of the RC servo
 *     motor.
 *
 * @param[in] ch The channel handle
 * @param[out] torque The torque value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetRCServo_getTorque(PhidgetRCServoHandle ch, double *torque);

/**
 * @brief The torque value
 *
 * The minimum value that `Torque` can be set to.
 *
 * *   `Torque` is a ratio of the maximum available torque, therefore the minimum torque is a
 *     unitless constant.
 *
 * @param[in] ch The channel handle
 * @param[out] minTorque The torque value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetRCServo_getMinTorque(PhidgetRCServoHandle ch,
  double *minTorque);

/**
 * @brief The torque value
 *
 * The maximum value that `Torque` can be set to.
 *
 * *   `Torque` is a ratio of the maximum available torque, therefore the minimum torque is a
 *     unitless constant.
 *
 * @param[in] ch The channel handle
 * @param[out] maxTorque The torque value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetRCServo_getMaxTorque(PhidgetRCServoHandle ch,
  double *maxTorque);

/**
 * @brief The velocity value
 *
 * The velocity that the RC servo motor is being driven at.
 *
 * *   A negative value means the RC servo motor is moving towards a lower position.
 * *   The velocity range of the RC servo motor will be from -`VelocityLimit` to
 *     +`VelocityLimit`, depending on direction.
 * *   This is not the actual physical velocity of the RC servo motor.
 *
 * See `TargetPosition` for a deeper explanation of how the settings of your RC Servo controller
 * interact to move your servo.
 *
 * @param[in] ch The channel handle
 * @param[out] velocity The velocity value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetRCServo_getVelocity(PhidgetRCServoHandle ch,
  double *velocity);

/**
 * @brief The velocity value
 *
 * When moving, the RC servo motor velocity will be limited by this value.
 *
 * *   The velocity limit is bounded by @ref PhidgetRCServo_getMinVelocityLimit() and @ref
 *     PhidgetRCServo_getMaxVelocityLimit().
 *
 * *   Using the **default settings** this velocity will correspond to the maximum speed of
 *     rotation of servo arm in **degrees/s**, for many standard RC servos.
 *
 * *   `SpeedRampingState` controls whether or not the velocity limit value is actually applied
 *     when trying to reach a target position.
 * *   The velocity range of the RC servo motor will be from -`VelocityLimit` to
 *     +`VelocityLimit`, depending on direction.
 * *   Note that when this value is set to 0, the RC servo motor will not move.
 * *   There is a practical limit on how fast your servo can rotate, based on the physical
 *     design of the motor.
 * *   The units for `TargetPosition`, `VelocityLimit`, and `Acceleration` are configured by
 *     scaling the internal timing (set with `MinPulseWidth` and `MaxPulseWidth`) to a user
 *     specified range with `MinPosition` and `MaxPosition`.
 *
 * See `TargetPosition` for a deeper explanation of how the settings of your RC Servo controller
 * interact to move your servo.
 *
 * @param[in] ch The channel handle
 * @param[in] velocityLimit The velocity value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetRCServo_setVelocityLimit(PhidgetRCServoHandle ch,
  double velocityLimit);

/**
 * @brief The velocity value
 *
 * When moving, the RC servo motor velocity will be limited by this value.
 *
 * *   The velocity limit is bounded by @ref PhidgetRCServo_getMinVelocityLimit() and @ref
 *     PhidgetRCServo_getMaxVelocityLimit().
 *
 * *   Using the **default settings** this velocity will correspond to the maximum speed of
 *     rotation of servo arm in **degrees/s**, for many standard RC servos.
 *
 * *   `SpeedRampingState` controls whether or not the velocity limit value is actually applied
 *     when trying to reach a target position.
 * *   The velocity range of the RC servo motor will be from -`VelocityLimit` to
 *     +`VelocityLimit`, depending on direction.
 * *   Note that when this value is set to 0, the RC servo motor will not move.
 * *   There is a practical limit on how fast your servo can rotate, based on the physical
 *     design of the motor.
 * *   The units for `TargetPosition`, `VelocityLimit`, and `Acceleration` are configured by
 *     scaling the internal timing (set with `MinPulseWidth` and `MaxPulseWidth`) to a user
 *     specified range with `MinPosition` and `MaxPosition`.
 *
 * See `TargetPosition` for a deeper explanation of how the settings of your RC Servo controller
 * interact to move your servo.
 *
 * @param[in] ch The channel handle
 * @param[out] velocityLimit The velocity value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetRCServo_getVelocityLimit(PhidgetRCServoHandle ch,
  double *velocityLimit);

/**
 * @brief The velocity value
 *
 * The minimum velocity `VelocityLimit` can be set to.
 *
 * See `TargetPosition` for a deeper explanation of how the settings of your RC Servo controller
 * interact to move your servo.
 *
 * @param[in] ch The channel handle
 * @param[out] minVelocityLimit The velocity value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetRCServo_getMinVelocityLimit(PhidgetRCServoHandle ch,
  double *minVelocityLimit);

/**
 * @brief The velocity value
 *
 * The maximum velocity `VelocityLimit` can be set to. This value depends on
 * `MinPosition`/`MaxPosition` and `MinPulseWidth`/`MaxPulseWidth`.
 *
 * See `TargetPosition` for a deeper explanation of how the settings of your RC Servo controller
 * interact to move your servo.
 *
 * @param[in] ch The channel handle
 * @param[out] maxVelocityLimit The velocity value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetRCServo_getMaxVelocityLimit(PhidgetRCServoHandle ch,
  double *maxVelocityLimit);

/**
 * @brief The voltage value
 *
 * The supply voltage for the RC servo motor.
 *
 * *   If your controller supports multiple RC servo motors, every motor will have the same
 *     supply voltage. It is not possible to set individual supply voltages.
 *
 * @param[in] ch The channel handle
 * @param[in] voltage The voltage value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetRCServo_setVoltage(PhidgetRCServoHandle ch,
  PhidgetRCServo_Voltage voltage);

/**
 * @brief The voltage value
 *
 * The supply voltage for the RC servo motor.
 *
 * *   If your controller supports multiple RC servo motors, every motor will have the same
 *     supply voltage. It is not possible to set individual supply voltages.
 *
 * @param[in] ch The channel handle
 * @param[out] voltage The voltage value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetRCServo_getVoltage(PhidgetRCServoHandle ch,
  PhidgetRCServo_Voltage *voltage);

/**
 * @brief Callback function type for PhidgetRCServo_setOnPositionChangeHandler().
 *
 * @param[in] ch The channel handle
 * @param[in] ctx Pointer to the user context
 * @param[in] position The position value
 */
typedef void (CCONV *PhidgetRCServo_OnPositionChangeCallback)(PhidgetRCServoHandle ch, void *ctx,
  double position);

/**
 * An event that occurs when the position changes on a RC servo motor.
 *
 * @param[in] ch The channel handle
 * @param[in] fptr The event handler callback function
 * @param[in] ctx User supplied context pointer
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetRCServo_setOnPositionChangeHandler(PhidgetRCServoHandle ch,
  PhidgetRCServo_OnPositionChangeCallback fptr, void *ctx);

/**
 * @brief Callback function type for PhidgetRCServo_setOnTargetPositionReachedHandler().
 *
 * @param[in] ch The channel handle
 * @param[in] ctx Pointer to the user context
 * @param[in] position The position value
 */
typedef void (CCONV *PhidgetRCServo_OnTargetPositionReachedCallback)(PhidgetRCServoHandle ch, void *ctx,
  double position);

/**
 * Occurs when the RC servo motor has reached the `TargetPosition`.
 *
 * *   The controller cannot know if the RC servo motor has physically reached the target
 *     position. When `TargetPosition` is reached, it simply means the controller pulse width output
 *     is matching its target.
 *
 * @param[in] ch The channel handle
 * @param[in] fptr The event handler callback function
 * @param[in] ctx User supplied context pointer
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetRCServo_setOnTargetPositionReachedHandler(PhidgetRCServoHandle ch,
  PhidgetRCServo_OnTargetPositionReachedCallback fptr, void *ctx);

/**
 * @brief Callback function type for PhidgetRCServo_setOnVelocityChangeHandler().
 *
 * @param[in] ch The channel handle
 * @param[in] ctx Pointer to the user context
 * @param[in] velocity The velocity value
 */
typedef void (CCONV *PhidgetRCServo_OnVelocityChangeCallback)(PhidgetRCServoHandle ch, void *ctx,
  double velocity);

/**
 * An event that occurs when the velocity changes on a RC servo motor.
 *
 * @param[in] ch The channel handle
 * @param[in] fptr The event handler callback function
 * @param[in] ctx User supplied context pointer
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetRCServo_setOnVelocityChangeHandler(PhidgetRCServoHandle ch,
  PhidgetRCServo_OnVelocityChangeCallback fptr, void *ctx);

/** @} */ /* PhidgetRCServo */

/**
 * @defgroup PhidgetResistanceInput ResistanceInput
 * @brief The Resistance Input class measures the resistance of a circuit connected to the
 *     Phidget, which is used to read resistance-based sensors such as platinum RTDs.
 * @{
 */

/**
 * The Resistance Input class measures the resistance of a circuit connected to the Phidget, which
 * is used to read resistance-based sensors such as platinum RTDs.
 */
typedef struct _PhidgetResistanceInput *PhidgetResistanceInputHandle;

/**
 * @ref PhidgetResistanceInput_create() creates an instance of a Phidget channel. Once created the
 * channel may need to be configured to match the physical device and channel index you want to
 * attach to, and then be opened by calling @ref Phidget_open().
 * The Phidget channel handle must be released with @ref PhidgetResistanceInput_delete().
 *
 * @param[out] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetResistanceInput_create(PhidgetResistanceInputHandle *ch);

/**
 * @ref PhidgetResistanceInput_delete() releases a Phidget channel handle created with @ref
 * PhidgetResistanceInput_create().
 * If the channel is open when @ref PhidgetResistanceInput_delete() is called, it will be closed.
 *
 * @param[out] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetResistanceInput_delete(PhidgetResistanceInputHandle *ch);

/**
 * @brief The data interval value
 *
 * The `DataInterval` is the time that must elapse before the channel will fire another @ref
 * PhidgetResistanceInput_setOnResistanceChangeHandler() event.
 *
 * *   The data interval is bounded by @ref PhidgetResistanceInput_getMinDataInterval() and @ref
 *     PhidgetResistanceInput_getMaxDataInterval().
 * *   The timing between @ref PhidgetResistanceInput_setOnResistanceChangeHandler() events can
 *     also be affected by the `ResistanceChangeTrigger`.
 *
 * @param[in] ch The channel handle
 * @param[in] dataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetResistanceInput_setDataInterval(PhidgetResistanceInputHandle ch,
  uint32_t dataInterval);

/**
 * @brief The data interval value
 *
 * The `DataInterval` is the time that must elapse before the channel will fire another @ref
 * PhidgetResistanceInput_setOnResistanceChangeHandler() event.
 *
 * *   The data interval is bounded by @ref PhidgetResistanceInput_getMinDataInterval() and @ref
 *     PhidgetResistanceInput_getMaxDataInterval().
 * *   The timing between @ref PhidgetResistanceInput_setOnResistanceChangeHandler() events can
 *     also be affected by the `ResistanceChangeTrigger`.
 *
 * @param[in] ch The channel handle
 * @param[out] dataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetResistanceInput_getDataInterval(PhidgetResistanceInputHandle ch,
  uint32_t *dataInterval);

/**
 * @brief The data interval value
 *
 * The minimum value that `DataInterval` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minDataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetResistanceInput_getMinDataInterval(PhidgetResistanceInputHandle ch,
  uint32_t *minDataInterval);

/**
 * @brief The data interval value
 *
 * The maximum value that `DataInterval` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxDataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetResistanceInput_getMaxDataInterval(PhidgetResistanceInputHandle ch,
  uint32_t *maxDataInterval);

/**
 * @brief The data rate for the channel
 *
 * The `DataRate` is the frequency of events from the device.
 *
 * *   The data rate is bounded by @ref PhidgetResistanceInput_getMinDataRate() and @ref
 *     PhidgetResistanceInput_getMaxDataRate().
 * *   Changing `DataRate` will change the channel's `DataInterval` to a corresponding value,
 *     rounded to the nearest integer number of milliseconds.
 * *   The timing between events can also affected by the change trigger.
 *
 * @param[in] ch The channel handle
 * @param[in] dataRate The data rate for the channel
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetResistanceInput_setDataRate(PhidgetResistanceInputHandle ch,
  double dataRate);

/**
 * @brief The data rate for the channel
 *
 * The `DataRate` is the frequency of events from the device.
 *
 * *   The data rate is bounded by @ref PhidgetResistanceInput_getMinDataRate() and @ref
 *     PhidgetResistanceInput_getMaxDataRate().
 * *   Changing `DataRate` will change the channel's `DataInterval` to a corresponding value,
 *     rounded to the nearest integer number of milliseconds.
 * *   The timing between events can also affected by the change trigger.
 *
 * @param[in] ch The channel handle
 * @param[out] dataRate The data rate for the channel
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetResistanceInput_getDataRate(PhidgetResistanceInputHandle ch,
  double *dataRate);

/**
 * @brief The data rate value
 *
 * The minimum value that `DataRate` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minDataRate The data rate value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetResistanceInput_getMinDataRate(PhidgetResistanceInputHandle ch,
  double *minDataRate);

/**
 * @brief The data rate value
 *
 * The maximum value that `DataRate` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxDataRate The data rate value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetResistanceInput_getMaxDataRate(PhidgetResistanceInputHandle ch,
  double *maxDataRate);

/**
 * @brief The resistance value
 *
 * The most recent resistance value that the channel has reported.
 *
 * *   This value will always be between @ref PhidgetResistanceInput_getMinResistance() and @ref
 *     PhidgetResistanceInput_getMaxResistance().
 * *   The @ref PhidgetResistanceInput_getResistance() value will change when the device is also
 *     being used as a temperature sensor. This is a side effect of increasing accuracy on the
 *     temperature channel.
 *
 * @param[in] ch The channel handle
 * @param[out] resistance The resistance value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetResistanceInput_getResistance(PhidgetResistanceInputHandle ch,
  double *resistance);

/**
 * @brief The minimum resistance
 *
 * The minimum value the @ref PhidgetResistanceInput_setOnResistanceChangeHandler() event will
 * report.
 *
 * *   When the device is also being used as a TemperatureSensor the @ref
 *     PhidgetResistanceInput_getMinResistance() and @ref PhidgetResistanceInput_getMaxResistance()
 *     will not represent the true input range. This is a side effect of increasing accuracy on the
 *     temperature channel.
 *
 * @param[in] ch The channel handle
 * @param[out] minResistance The minimum resistance
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetResistanceInput_getMinResistance(PhidgetResistanceInputHandle ch,
  double *minResistance);

/**
 * @brief The resistance value
 *
 * The maximum value the @ref PhidgetResistanceInput_setOnResistanceChangeHandler() event will
 * report.
 *
 * @param[in] ch The channel handle
 * @param[out] maxResistance The resistance value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetResistanceInput_getMaxResistance(PhidgetResistanceInputHandle ch,
  double *maxResistance);

/**
 * @brief The change trigger value
 *
 * The channel will not issue a @ref PhidgetResistanceInput_setOnResistanceChangeHandler() event
 * until the resistance value has changed by the amount specified by the `ResistanceChangeTrigger`.
 *
 * *   Setting the `ResistanceChangeTrigger` to 0 will result in the channel firing events every
 *     `DataInterval`. This is useful for applications that implement their own data filtering
 *
 * @param[in] ch The channel handle
 * @param[in] resistanceChangeTrigger The change trigger value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetResistanceInput_setResistanceChangeTrigger(PhidgetResistanceInputHandle ch,
  double resistanceChangeTrigger);

/**
 * @brief The change trigger value
 *
 * The channel will not issue a @ref PhidgetResistanceInput_setOnResistanceChangeHandler() event
 * until the resistance value has changed by the amount specified by the `ResistanceChangeTrigger`.
 *
 * *   Setting the `ResistanceChangeTrigger` to 0 will result in the channel firing events every
 *     `DataInterval`. This is useful for applications that implement their own data filtering
 *
 * @param[in] ch The channel handle
 * @param[out] resistanceChangeTrigger The change trigger value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetResistanceInput_getResistanceChangeTrigger(PhidgetResistanceInputHandle ch,
  double *resistanceChangeTrigger);

/**
 * @brief The change trigger value
 *
 * The minimum value that the `ResistanceChangeTrigger` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minResistanceChangeTrigger The change trigger value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetResistanceInput_getMinResistanceChangeTrigger(PhidgetResistanceInputHandle ch,
  double *minResistanceChangeTrigger);

/**
 * @brief The change trigger value
 *
 * The maximum value that `ResistanceChangeTrigger` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxResistanceChangeTrigger The change trigger value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetResistanceInput_getMaxResistanceChangeTrigger(PhidgetResistanceInputHandle ch,
  double *maxResistanceChangeTrigger);

/**
 * @brief Wire setup value
 *
 * Select the RTD wiring configuration.
 *
 * *   More information about RTD wiring can be found in the user guide.
 *
 * @param[in] ch The channel handle
 * @param[in] RTDWireSetup Wire setup value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetResistanceInput_setRTDWireSetup(PhidgetResistanceInputHandle ch,
  Phidget_RTDWireSetup RTDWireSetup);

/**
 * @brief Wire setup value
 *
 * Select the RTD wiring configuration.
 *
 * *   More information about RTD wiring can be found in the user guide.
 *
 * @param[in] ch The channel handle
 * @param[out] RTDWireSetup Wire setup value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetResistanceInput_getRTDWireSetup(PhidgetResistanceInputHandle ch,
  Phidget_RTDWireSetup *RTDWireSetup);

/**
 * @brief Callback function type for PhidgetResistanceInput_setOnResistanceChangeHandler().
 *
 * @param[in] ch The channel handle
 * @param[in] ctx Pointer to the user context
 * @param[in] resistance The resistance value
 */
typedef void (CCONV *PhidgetResistanceInput_OnResistanceChangeCallback)(PhidgetResistanceInputHandle ch,
  void *ctx, double resistance);

/**
 * The most recent resistance value the channel has measured will be reported in this event, which
 * occurs when the `DataInterval` has elapsed.
 *
 * *   If a `ResistanceChangeTrigger` has been set to a non-zero value, the @ref
 *     PhidgetResistanceInput_setOnResistanceChangeHandler() event will not occur until the
 *     resistance has changed by at least the `ResistanceChangeTrigger` value.
 *
 * @param[in] ch The channel handle
 * @param[in] fptr The event handler callback function
 * @param[in] ctx User supplied context pointer
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetResistanceInput_setOnResistanceChangeHandler(PhidgetResistanceInputHandle ch,
  PhidgetResistanceInput_OnResistanceChangeCallback fptr, void *ctx);

/** @} */ /* PhidgetResistanceInput */

/**
 * @defgroup PhidgetRFID RFID
 * @brief The RFID class provides methods for Phidget RFID boards to read and write (if writing
 *     is supported) to RFID tags.
 * @{
 */

/**
 * The RFID class provides methods for Phidget RFID boards to read and write (if writing is
 * supported) to RFID tags.
 */
typedef struct _PhidgetRFID *PhidgetRFIDHandle;

/**
 * @ref PhidgetRFID_create() creates an instance of a Phidget channel. Once created the channel may
 * need to be configured to match the physical device and channel index you want to attach to, and
 * then be opened by calling @ref Phidget_open().
 * The Phidget channel handle must be released with @ref PhidgetRFID_delete().
 *
 * @param[out] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetRFID_create(PhidgetRFIDHandle *ch);

/**
 * @ref PhidgetRFID_delete() releases a Phidget channel handle created with @ref
 * PhidgetRFID_create().
 * If the channel is open when @ref PhidgetRFID_delete() is called, it will be closed.
 *
 * @param[out] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetRFID_delete(PhidgetRFIDHandle *ch);

/**
 * Gets the most recently detected tag's data, even if that tag is no longer within read range.
 *
 * *   Only valid after at least one tag has been detected.
 *
 * @param[in] ch The channel handle
 * @param[out] tagString The data stored on the most recently read tag
 * @param[in] tagStringLen Length of the data from the most recently read tag
 * @param[out] protocol Protocol of the most recently detected tag
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetRFID_getLastTag(PhidgetRFIDHandle ch, char *tagString,
  size_t tagStringLen, PhidgetRFID_Protocol *protocol);

/**
 * Writes data to the tag being currently read by the reader. Not specifying a tag chipset will
 * default to writing T5577-style tags.
 *
 * *   You cannot write to a read-only or locked tag.
 *
 * @param[in] ch The channel handle
 * @param[in] tagString The data to write to the tag
 * @param[in] protocol The communication protocol to use
 * @param[in] lockTag If true, permanently locks the tag so that it cannot be re-written after
 *     this write
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetRFID_write(PhidgetRFIDHandle ch, const char *tagString,
  PhidgetRFID_Protocol protocol, int lockTag);

/**
 * Writes data to the tag being currently read by the reader, with a specified tag chipset.
 *
 * *   You cannot write to a read-only or locked tag.
 *
 * @param[in] ch The channel handle
 * @param[in] tagString The data to write to the tag
 * @param[in] protocol The communication protocol to use
 * @param[in] lockTag If true, permanently locks the tag so that it cannot be re-written after
 *     this write
 * @param[in] chipset The chipset to write for
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetRFID_writeWithChipset(PhidgetRFIDHandle ch,
  const char *tagString, PhidgetRFID_Protocol protocol, int lockTag, PhidgetRFID_Chipset chipset);

/**
 * @brief The state of the antenna
 *
 * The on/off state of the antenna.
 *
 * *   You can turn the antenna off to save power.
 * *   You must turn the antenna on in order to detect and read RFID tags.
 *
 * @param[in] ch The channel handle
 * @param[in] antennaEnabled The state of the antenna
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetRFID_setAntennaEnabled(PhidgetRFIDHandle ch,
  int antennaEnabled);

/**
 * @brief The state of the antenna
 *
 * The on/off state of the antenna.
 *
 * *   You can turn the antenna off to save power.
 * *   You must turn the antenna on in order to detect and read RFID tags.
 *
 * @param[in] ch The channel handle
 * @param[out] antennaEnabled The state of the antenna
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetRFID_getAntennaEnabled(PhidgetRFIDHandle ch,
  int *antennaEnabled);

/**
 * @brief Tag is in range
 *
 * This property is true if a compatibile RFID tag is detected by the reader.
 *
 * *   `TagPresent` will remain true until the tag is out of range and can no longer be
 *     interacted with.
 *
 * @param[in] ch The channel handle
 * @param[out] tagPresent Tag is in range
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetRFID_getTagPresent(PhidgetRFIDHandle ch, int *tagPresent);

/**
 * @brief Callback function type for PhidgetRFID_setOnTagHandler().
 *
 * @param[in] ch The channel handle
 * @param[in] ctx Pointer to the user context
 * @param[in] tag Data from the tag
 * @param[in] protocol Communication protocol of the tag
 */
typedef void (CCONV *PhidgetRFID_OnTagCallback)(PhidgetRFIDHandle ch, void *ctx, const char *tag,
  PhidgetRFID_Protocol protocol);

/**
 * Occurs when an RFID tag is detected.
 *
 * @param[in] ch The channel handle
 * @param[in] fptr The event handler callback function
 * @param[in] ctx User supplied context pointer
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetRFID_setOnTagHandler(PhidgetRFIDHandle ch,
  PhidgetRFID_OnTagCallback fptr, void *ctx);

/**
 * @brief Callback function type for PhidgetRFID_setOnTagLostHandler().
 *
 * @param[in] ch The channel handle
 * @param[in] ctx Pointer to the user context
 * @param[in] tag Data from the lost tag
 * @param[in] protocol Communication protocol of the lost tag
 */
typedef void (CCONV *PhidgetRFID_OnTagLostCallback)(PhidgetRFIDHandle ch, void *ctx, const char *tag,
  PhidgetRFID_Protocol protocol);

/**
 * Occurs when an RFID tag that was being read is no longer seen by the reader. Typically this
 * indicates the tag has been removed from the read range, though it could also happen due to
 * interference from multiple tags entering the read range at the same time.
 *
 * @param[in] ch The channel handle
 * @param[in] fptr The event handler callback function
 * @param[in] ctx User supplied context pointer
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetRFID_setOnTagLostHandler(PhidgetRFIDHandle ch,
  PhidgetRFID_OnTagLostCallback fptr, void *ctx);

/** @} */ /* PhidgetRFID */

/**
 * @defgroup PhidgetSoundSensor SoundSensor
 * @brief The Sound Sensor class gathers data from the sound sensor on a Phidget board.
 * @{
 */

/**
 * The Sound Sensor class gathers data from the sound sensor on a Phidget board.
 *
 * If you're using a simple 0-5V sensor that does not have its own firmware, use the VoltageInput or
 * VoltageRatioInput class instead, as specified for your device.
 */
typedef struct _PhidgetSoundSensor *PhidgetSoundSensorHandle;

/**
 * @ref PhidgetSoundSensor_create() creates an instance of a Phidget channel. Once created the
 * channel may need to be configured to match the physical device and channel index you want to
 * attach to, and then be opened by calling @ref Phidget_open().
 * The Phidget channel handle must be released with @ref PhidgetSoundSensor_delete().
 *
 * @param[out] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetSoundSensor_create(PhidgetSoundSensorHandle *ch);

/**
 * @ref PhidgetSoundSensor_delete() releases a Phidget channel handle created with @ref
 * PhidgetSoundSensor_create().
 * If the channel is open when @ref PhidgetSoundSensor_delete() is called, it will be closed.
 *
 * @param[out] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetSoundSensor_delete(PhidgetSoundSensorHandle *ch);

/**
 * @brief The data interval value
 *
 * The `DataInterval` is the time that must elapse before the channel will fire another @ref
 * PhidgetSoundSensor_setOnSPLChangeHandler() event.
 *
 * *   The data interval is bounded by @ref PhidgetSoundSensor_getMinDataInterval() and @ref
 *     PhidgetSoundSensor_getMaxDataInterval().
 * *   The timing between @ref PhidgetSoundSensor_setOnSPLChangeHandler() events can also be
 *     affected by the `SPLChangeTrigger`.
 *
 * @param[in] ch The channel handle
 * @param[in] dataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetSoundSensor_setDataInterval(PhidgetSoundSensorHandle ch,
  uint32_t dataInterval);

/**
 * @brief The data interval value
 *
 * The `DataInterval` is the time that must elapse before the channel will fire another @ref
 * PhidgetSoundSensor_setOnSPLChangeHandler() event.
 *
 * *   The data interval is bounded by @ref PhidgetSoundSensor_getMinDataInterval() and @ref
 *     PhidgetSoundSensor_getMaxDataInterval().
 * *   The timing between @ref PhidgetSoundSensor_setOnSPLChangeHandler() events can also be
 *     affected by the `SPLChangeTrigger`.
 *
 * @param[in] ch The channel handle
 * @param[out] dataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetSoundSensor_getDataInterval(PhidgetSoundSensorHandle ch,
  uint32_t *dataInterval);

/**
 * @brief The data interval value
 *
 * The minimum value that `DataInterval` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minDataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetSoundSensor_getMinDataInterval(PhidgetSoundSensorHandle ch,
  uint32_t *minDataInterval);

/**
 * @brief The data interval value
 *
 * The maximum value that `DataInterval` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxDataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetSoundSensor_getMaxDataInterval(PhidgetSoundSensorHandle ch,
  uint32_t *maxDataInterval);

/**
 * @brief The data rate for the channel
 *
 * The `DataRate` is the frequency of events from the device.
 *
 * *   The data rate is bounded by @ref PhidgetSoundSensor_getMinDataRate() and @ref
 *     PhidgetSoundSensor_getMaxDataRate().
 * *   Changing `DataRate` will change the channel's `DataInterval` to a corresponding value,
 *     rounded to the nearest integer number of milliseconds.
 * *   The timing between events can also affected by the change trigger.
 *
 * @param[in] ch The channel handle
 * @param[in] dataRate The data rate for the channel
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetSoundSensor_setDataRate(PhidgetSoundSensorHandle ch,
  double dataRate);

/**
 * @brief The data rate for the channel
 *
 * The `DataRate` is the frequency of events from the device.
 *
 * *   The data rate is bounded by @ref PhidgetSoundSensor_getMinDataRate() and @ref
 *     PhidgetSoundSensor_getMaxDataRate().
 * *   Changing `DataRate` will change the channel's `DataInterval` to a corresponding value,
 *     rounded to the nearest integer number of milliseconds.
 * *   The timing between events can also affected by the change trigger.
 *
 * @param[in] ch The channel handle
 * @param[out] dataRate The data rate for the channel
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetSoundSensor_getDataRate(PhidgetSoundSensorHandle ch,
  double *dataRate);

/**
 * @brief The data rate value
 *
 * The minimum value that `DataRate` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minDataRate The data rate value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetSoundSensor_getMinDataRate(PhidgetSoundSensorHandle ch,
  double *minDataRate);

/**
 * @brief The data rate value
 *
 * The maximum value that `DataRate` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxDataRate The data rate value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetSoundSensor_getMaxDataRate(PhidgetSoundSensorHandle ch,
  double *maxDataRate);

/**
 * @brief The dB value
 *
 * The most recent dB SPL value that has been calculated.
 *
 * *   This value is bounded by @ref PhidgetSoundSensor_getMaxdB().
 *
 * @param[in] ch The channel handle
 * @param[out] dB The dB value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetSoundSensor_getdB(PhidgetSoundSensorHandle ch, double *dB);

/**
 * @brief The dBA value
 *
 * The most recent dBA SPL value that has been calculated.
 *
 * *   The dBA SPL value is calculated by applying a A-weighted filter to the @ref
 *     PhidgetSoundSensor_getOctaves() data.
 *
 * @param[in] ch The channel handle
 * @param[out] dBA The dBA value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetSoundSensor_getdBA(PhidgetSoundSensorHandle ch,
  double *dBA);

/**
 * @brief The dBC value
 *
 * The most recent dBC SPL value that has been calculated.
 *
 * *   The dBC SPL value is calculated by applying a C-weighted filter to the @ref
 *     PhidgetSoundSensor_getOctaves() data.
 *
 * @param[in] ch The channel handle
 * @param[out] dBC The dBC value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetSoundSensor_getdBC(PhidgetSoundSensorHandle ch,
  double *dBC);

/**
 * @brief The dB value
 *
 * The maximum value the @ref PhidgetSoundSensor_setOnSPLChangeHandler() event will report.
 *
 * @param[in] ch The channel handle
 * @param[out] maxdB The dB value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetSoundSensor_getMaxdB(PhidgetSoundSensorHandle ch,
  double *maxdB);

/**
 * @brief The noise floor value.
 *
 * The minimum SPL value that the channel can accurately measure.
 *
 * *   Input SPLs below this level will not produce an output from the microphone.
 *
 * @param[in] ch The channel handle
 * @param[out] noiseFloor The noise floor value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetSoundSensor_getNoiseFloor(PhidgetSoundSensorHandle ch,
  double *noiseFloor);

/**
 * @brief The octave values
 *
 * The unweighted value of each frequency band.
 *
 * *   The following frequency bands are represented:
 *
 * *   octaves\[0\] = 31.5 Hz
 * *   octaves\[1\] = 63 Hz
 * *   octaves\[2\] = 125 Hz
 * *   octaves\[3\] = 250 Hz
 * *   octaves\[4\] = 500 Hz
 * *   octaves\[5\] = 1 kHz
 * *   octaves\[6\] = 2 kHz
 * *   octaves\[7\] = 4 kHz
 * *   octaves\[8\] = 8 kHz
 * *   octaves\[9\] = 16 kHz
 *
 * @param[in] ch The channel handle
 * @param[out] octaves The octave values
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetSoundSensor_getOctaves(PhidgetSoundSensorHandle ch,
  double (*octaves)[10]);

/**
 * @brief The change trigger value
 *
 * The channel will not issue a @ref PhidgetSoundSensor_setOnSPLChangeHandler() event until the @ref
 * PhidgetSoundSensor_getdB() value has changed by the amount specified by the `SPLChangeTrigger`.
 *
 * *   Setting the `SPLChangeTrigger` to 0 will result in the channel firing events every
 *     `DataInterval`. This is useful for applications that implement their own data filtering
 *
 * @param[in] ch The channel handle
 * @param[in] SPLChangeTrigger The change trigger value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetSoundSensor_setSPLChangeTrigger(PhidgetSoundSensorHandle ch,
  double SPLChangeTrigger);

/**
 * @brief The change trigger value
 *
 * The channel will not issue a @ref PhidgetSoundSensor_setOnSPLChangeHandler() event until the @ref
 * PhidgetSoundSensor_getdB() value has changed by the amount specified by the `SPLChangeTrigger`.
 *
 * *   Setting the `SPLChangeTrigger` to 0 will result in the channel firing events every
 *     `DataInterval`. This is useful for applications that implement their own data filtering
 *
 * @param[in] ch The channel handle
 * @param[out] SPLChangeTrigger The change trigger value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetSoundSensor_getSPLChangeTrigger(PhidgetSoundSensorHandle ch,
  double *SPLChangeTrigger);

/**
 * @brief The change trigger value
 *
 * The minimum value that `SPLChangeTrigger` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minSPLChangeTrigger The change trigger value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetSoundSensor_getMinSPLChangeTrigger(PhidgetSoundSensorHandle ch,
  double *minSPLChangeTrigger);

/**
 * @brief The change trigger value
 *
 * The maximum value that `SPLChangeTrigger` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxSPLChangeTrigger The change trigger value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetSoundSensor_getMaxSPLChangeTrigger(PhidgetSoundSensorHandle ch,
  double *maxSPLChangeTrigger);

/**
 * @brief The range value.
 *
 * When selecting a range, first decide how sensitive you want the microphone to be. Select a
 * smaller range when you want more sensitivity from the microphone.
 *
 * *   If a @ref EEPHIDGET_SATURATION event occurrs, increase the range.
 *
 * @param[in] ch The channel handle
 * @param[in] SPLRange The range value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetSoundSensor_setSPLRange(PhidgetSoundSensorHandle ch,
  PhidgetSoundSensor_SPLRange SPLRange);

/**
 * @brief The range value.
 *
 * When selecting a range, first decide how sensitive you want the microphone to be. Select a
 * smaller range when you want more sensitivity from the microphone.
 *
 * *   If a @ref EEPHIDGET_SATURATION event occurrs, increase the range.
 *
 * @param[in] ch The channel handle
 * @param[out] SPLRange The range value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetSoundSensor_getSPLRange(PhidgetSoundSensorHandle ch,
  PhidgetSoundSensor_SPLRange *SPLRange);

/**
 * @brief Callback function type for PhidgetSoundSensor_setOnSPLChangeHandler().
 *
 * @param[in] ch The channel handle
 * @param[in] ctx Pointer to the user context
 * @param[in] dB The dB SPL value
 * @param[in] dBA The dBA SPL value
 * @param[in] dBC The dBC SPL value
 * @param[in] octaves The dB SPL value for each band
 */
typedef void (CCONV *PhidgetSoundSensor_OnSPLChangeCallback)(PhidgetSoundSensorHandle ch, void *ctx,
  double dB, double dBA, double dBC, const double octaves[10]);

/**
 * The most recent SPL values the channel has measured will be reported in this event, which occurs
 * when the `DataInterval` has elapsed.
 *
 * *   If a `SPLChangeTrigger` has been set to a non-zero value, the @ref
 *     PhidgetSoundSensor_setOnSPLChangeHandler() event will not occur until the @ref
 *     PhidgetSoundSensor_getdB() SPL value has changed by at least the `SPLChangeTrigger` value.
 * *   The dB SPL value is calculated from the @ref PhidgetSoundSensor_getOctaves() data.
 * *   The dBA SPL value is calculated by applying a A-weighted filter to the @ref
 *     PhidgetSoundSensor_getOctaves() data.
 * *   The dBC SPL value is calculated by applying a C-weighted filter to the @ref
 *     PhidgetSoundSensor_getOctaves() data.
 * *   The following frequency bands are represented:
 *
 * *   octaves\[0\] = 31.5 Hz
 * *   octaves\[1\] = 63 Hz
 * *   octaves\[2\] = 125 Hz
 * *   octaves\[3\] = 250 Hz
 * *   octaves\[4\] = 500 Hz
 * *   octaves\[5\] = 1 kHz
 * *   octaves\[6\] = 2 kHz
 * *   octaves\[7\] = 4 kHz
 * *   octaves\[8\] = 8 kHz
 * *   octaves\[9\] = 16 kHz
 *
 * @param[in] ch The channel handle
 * @param[in] fptr The event handler callback function
 * @param[in] ctx User supplied context pointer
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetSoundSensor_setOnSPLChangeHandler(PhidgetSoundSensorHandle ch,
  PhidgetSoundSensor_OnSPLChangeCallback fptr, void *ctx);

/** @} */ /* PhidgetSoundSensor */

/**
 * @defgroup PhidgetSpatial Spatial
 * @brief The Spatial class simultaneously gathers data from the acceleromter, gyroscope and
 *     magnetometer on a Phidget board.
 * @{
 */

/**
 * The Spatial class simultaneously gathers data from the acceleromter, gyroscope and magnetometer
 * on a Phidget board.
 *
 * You can also use the individual classes for these sensors if you want to handle the data in
 * separate events.
 */
typedef struct _PhidgetSpatial *PhidgetSpatialHandle;

/**
 * @ref PhidgetSpatial_create() creates an instance of a Phidget channel. Once created the channel
 * may need to be configured to match the physical device and channel index you want to attach to,
 * and then be opened by calling @ref Phidget_open().
 * The Phidget channel handle must be released with @ref PhidgetSpatial_delete().
 *
 * @param[out] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetSpatial_create(PhidgetSpatialHandle *ch);

/**
 * @ref PhidgetSpatial_delete() releases a Phidget channel handle created with @ref
 * PhidgetSpatial_create().
 * If the channel is open when @ref PhidgetSpatial_delete() is called, it will be closed.
 *
 * @param[out] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetSpatial_delete(PhidgetSpatialHandle *ch);

/**
 * Calibrate your device for the environment it will be used in.
 *
 * *   Setting these parameters will allow you to tune the AHRS algorithm on the device to your
 *     specific application.
 *
 * @param[in] ch The channel handle
 * @param[in] angularVelocityThreshold The maximum angular velocity reading where the device is
 *     assumed to be "at rest"
 * @param[in] angularVelocityDeltaThreshold The acceptable amount of change in angular velocity
 *     between measurements before movement is assumed
 * @param[in] accelerationThreshold The maximum acceleration applied to the device (minus
 *     gravity) where it is assumed to be "at rest". This is also the maximum acceleration allowable
 *     before the device stops correcting to the acceleration vector
 * @param[in] magTime The time it will take to correct the heading 95% of the way to aligning
 *     with the compass (in seconds),up to 15 degrees of error. Beyond 15 degrees, this is the time
 *     it will take for the bearing to move 45 degrees towards the compass reading. Remember you can
 *     zero the algorithm at any time to instantly realign the spatial with acceleration and
 *     magnetic field vectors regardless of magnitude
 * @param[in] accelTime The time it will take to correct the pitch and roll 95% of the way to
 *     aligning with the accelerometer (in seconds)
 * @param[in] biasTime The time it will take to have the gyro biases settle to within 95% of the
 *     measured steady state (in seconds)
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetSpatial_setAHRSParameters(PhidgetSpatialHandle ch,
  double angularVelocityThreshold, double angularVelocityDeltaThreshold, double accelerationThreshold,
  double magTime, double accelTime, double biasTime);

/**
 * Calibrate your device for the environment it will be used in.
 *
 * *   Due to physical location, hard and soft iron offsets, and even bias errors, your device
 *     should be calibrated. We have created a calibration program that will provide you with the
 *     `MagnetometerCorrectionParameters` for your specific situation. See your device's User Guide
 *     for more information.
 *
 * @param[in] ch The channel handle
 * @param[in] magneticField Ambient magnetic field value
 * @param[in] offset0 Provided by calibration program
 * @param[in] offset1 Provided by calibration program
 * @param[in] offset2 Provided by calibration program
 * @param[in] gain0 Provided by calibration program
 * @param[in] gain1 Provided by calibration program
 * @param[in] gain2 Provided by calibration program
 * @param[in] T0 Provided by calibration program
 * @param[in] T1 Provided by calibration program
 * @param[in] T2 Provided by calibration program
 * @param[in] T3 Provided by calibration program
 * @param[in] T4 Provided by calibration program
 * @param[in] T5 Provided by calibration program
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetSpatial_setMagnetometerCorrectionParameters(PhidgetSpatialHandle ch,
  double magneticField, double offset0, double offset1, double offset2, double gain0, double gain1,
  double gain2, double T0, double T1, double T2, double T3, double T4, double T5);

/**
 * Resets the `MagnetometerCorrectionParameters` to their default values.
 *
 * *   Due to physical location, hard and soft iron offsets, and even bias errors, your device
 *     should be calibrated. We have created a calibration program that will provide you with the
 *     `MagnetometerCorrectionParameters` for your specific situation. See your device's User Guide
 *     for more information.
 *
 * @param[in] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetSpatial_resetMagnetometerCorrectionParameters(PhidgetSpatialHandle ch);

/**
 * Saves the `MagnetometerCorrectionParameters`.
 *
 * *   Due to physical location, hard and soft iron offsets, and even bias errors, your device
 *     should be calibrated. We have created a calibration program that will provide you with the
 *     `MagnetometerCorrectionParameters` for your specific situation. See your device's User Guide
 *     for more information.
 *
 * @param[in] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetSpatial_saveMagnetometerCorrectionParameters(PhidgetSpatialHandle ch);

/**
 * Zeros the AHRS algorithm.
 *
 * @param[in] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetSpatial_zeroAlgorithm(PhidgetSpatialHandle ch);

/**
 * Re-zeros the gyroscope in 1-2 seconds.
 *
 * *   The device must be stationary when zeroing.
 * *   The angular rate will be reported as 0.0°/s while zeroing.
 * *   Zeroing the gyroscope is a method of compensating for the drift that is inherent to all
 *     gyroscopes. See your device's User Guide for more information on dealing with drift.
 *
 * @param[in] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetSpatial_zeroGyro(PhidgetSpatialHandle ch);

/**
 * @brief The minimum acceleration value
 *
 * The minimum acceleration the sensor will measure.
 *
 * @param[in] ch The channel handle
 * @param[out] minAcceleration The minimum acceleration value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetSpatial_getMinAcceleration(PhidgetSpatialHandle ch,
  double (*minAcceleration)[3]);

/**
 * @brief The maximum acceleration values
 *
 * The maximum acceleration the sensor will measure.
 *
 * @param[in] ch The channel handle
 * @param[out] maxAcceleration The maximum acceleration values
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetSpatial_getMaxAcceleration(PhidgetSpatialHandle ch,
  double (*maxAcceleration)[3]);

/**
 * @brief The sensor algorithm
 *
 * Selects the IMU/AHRS algorithm.
 *
 * @param[in] ch The channel handle
 * @param[in] algorithm The sensor algorithm
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetSpatial_setAlgorithm(PhidgetSpatialHandle ch,
  Phidget_SpatialAlgorithm algorithm);

/**
 * @brief The sensor algorithm
 *
 * Selects the IMU/AHRS algorithm.
 *
 * @param[in] ch The channel handle
 * @param[out] algorithm The sensor algorithm
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetSpatial_getAlgorithm(PhidgetSpatialHandle ch,
  Phidget_SpatialAlgorithm *algorithm);

/**
 * @brief The AHRS algorithm magnetometer gain
 *
 * Sets the gain for the magnetometer in the AHRS algorithm. Lower gains reduce sensor noise while
 * slowing response time.
 *
 * @param[in] ch The channel handle
 * @param[in] algorithmMagnetometerGain The AHRS algorithm magnetometer gain
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetSpatial_setAlgorithmMagnetometerGain(PhidgetSpatialHandle ch,
  double algorithmMagnetometerGain);

/**
 * @brief The AHRS algorithm magnetometer gain
 *
 * Sets the gain for the magnetometer in the AHRS algorithm. Lower gains reduce sensor noise while
 * slowing response time.
 *
 * @param[in] ch The channel handle
 * @param[out] algorithmMagnetometerGain The AHRS algorithm magnetometer gain
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetSpatial_getAlgorithmMagnetometerGain(PhidgetSpatialHandle ch,
  double *algorithmMagnetometerGain);

/**
 * @brief The angular rate values
 *
 * The minimum angular rate the sensor will measure.
 *
 * @param[in] ch The channel handle
 * @param[out] minAngularRate The angular rate values
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetSpatial_getMinAngularRate(PhidgetSpatialHandle ch,
  double (*minAngularRate)[3]);

/**
 * @brief The angular rate values
 *
 * The maximum angular rate the sensor will measure.
 *
 * @param[in] ch The channel handle
 * @param[out] maxAngularRate The angular rate values
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetSpatial_getMaxAngularRate(PhidgetSpatialHandle ch,
  double (*maxAngularRate)[3]);

/**
 * @brief The data interval value
 *
 * The `DataInterval` is the time that must elapse before the channel will fire another @ref
 * PhidgetSpatial_setOnSpatialDataHandler() event.
 *
 * *   The data interval is bounded by @ref PhidgetSpatial_getMinDataInterval() and @ref
 *     PhidgetSpatial_getMaxDataInterval().
 *
 * @param[in] ch The channel handle
 * @param[in] dataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetSpatial_setDataInterval(PhidgetSpatialHandle ch,
  uint32_t dataInterval);

/**
 * @brief The data interval value
 *
 * The `DataInterval` is the time that must elapse before the channel will fire another @ref
 * PhidgetSpatial_setOnSpatialDataHandler() event.
 *
 * *   The data interval is bounded by @ref PhidgetSpatial_getMinDataInterval() and @ref
 *     PhidgetSpatial_getMaxDataInterval().
 *
 * @param[in] ch The channel handle
 * @param[out] dataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetSpatial_getDataInterval(PhidgetSpatialHandle ch,
  uint32_t *dataInterval);

/**
 * @brief The data interval value
 *
 * The minimum value that `DataInterval` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minDataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetSpatial_getMinDataInterval(PhidgetSpatialHandle ch,
  uint32_t *minDataInterval);

/**
 * @brief The data interval value
 *
 * The maximum value that `DataInterval` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxDataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetSpatial_getMaxDataInterval(PhidgetSpatialHandle ch,
  uint32_t *maxDataInterval);

/**
 * @brief The data rate for the channel
 *
 * The `DataRate` is the frequency of events from the device.
 *
 * *   The data rate is bounded by @ref PhidgetSpatial_getMinDataRate() and @ref
 *     PhidgetSpatial_getMaxDataRate().
 * *   Changing `DataRate` will change the channel's `DataInterval` to a corresponding value,
 *     rounded to the nearest integer number of milliseconds.
 * *   The timing between events can also affected by the change trigger.
 *
 * @param[in] ch The channel handle
 * @param[in] dataRate The data rate for the channel
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetSpatial_setDataRate(PhidgetSpatialHandle ch,
  double dataRate);

/**
 * @brief The data rate for the channel
 *
 * The `DataRate` is the frequency of events from the device.
 *
 * *   The data rate is bounded by @ref PhidgetSpatial_getMinDataRate() and @ref
 *     PhidgetSpatial_getMaxDataRate().
 * *   Changing `DataRate` will change the channel's `DataInterval` to a corresponding value,
 *     rounded to the nearest integer number of milliseconds.
 * *   The timing between events can also affected by the change trigger.
 *
 * @param[in] ch The channel handle
 * @param[out] dataRate The data rate for the channel
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetSpatial_getDataRate(PhidgetSpatialHandle ch,
  double *dataRate);

/**
 * @brief The data rate value
 *
 * The minimum value that `DataRate` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minDataRate The data rate value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetSpatial_getMinDataRate(PhidgetSpatialHandle ch,
  double *minDataRate);

/**
 * @brief The data rate value
 *
 * The maximum value that `DataRate` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxDataRate The data rate value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetSpatial_getMaxDataRate(PhidgetSpatialHandle ch,
  double *maxDataRate);

/**
 * @brief Gets the latest device orientation in the form of Euler angles.
 *
 * Gets the latest device orientation in the form of Euler angles. (Pitch, roll, and yaw)
 *
 * @param[in] ch The channel handle
 * @param[out] eulerAngles Gets the latest device orientation in the form of Euler angles
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetSpatial_getEulerAngles(PhidgetSpatialHandle ch,
  PhidgetSpatial_SpatialEulerAngles *eulerAngles);

/**
 * @brief Whether self-heating temperature stabilization is enabled
 *
 * Set to TRUE to enable the temperature stabilization feature of this device. This enables on-board
 * heating elements to bring the board up to a known temperature to minimize ambient temperature
 * effects on the sensor's reading. You can leave this setting FALSE to conserve power consumption.
 *
 * If you enable heating, it is strongly recommended to keep the board in its enclosure to keep it
 * insulated from moving air.
 *
 * This property is shared by any and all spatial-related objects on this device (Accelerometer,
 * Gyroscope, Magnetometer, Spatial)
 *
 * @param[in] ch The channel handle
 * @param[in] heatingEnabled Whether self-heating temperature stabilization is enabled
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetSpatial_setHeatingEnabled(PhidgetSpatialHandle ch,
  int heatingEnabled);

/**
 * @brief Whether self-heating temperature stabilization is enabled
 *
 * Set to TRUE to enable the temperature stabilization feature of this device. This enables on-board
 * heating elements to bring the board up to a known temperature to minimize ambient temperature
 * effects on the sensor's reading. You can leave this setting FALSE to conserve power consumption.
 *
 * If you enable heating, it is strongly recommended to keep the board in its enclosure to keep it
 * insulated from moving air.
 *
 * This property is shared by any and all spatial-related objects on this device (Accelerometer,
 * Gyroscope, Magnetometer, Spatial)
 *
 * @param[in] ch The channel handle
 * @param[out] heatingEnabled Whether self-heating temperature stabilization is enabled
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetSpatial_getHeatingEnabled(PhidgetSpatialHandle ch,
  int *heatingEnabled);

/**
 * @brief The field strength value
 *
 * The minimum field strength the sensor will measure.
 *
 * @param[in] ch The channel handle
 * @param[out] minMagneticField The field strength value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetSpatial_getMinMagneticField(PhidgetSpatialHandle ch,
  double (*minMagneticField)[3]);

/**
 * @brief The field strength value
 *
 * The maximum field strength the sensor will measure.
 *
 * @param[in] ch The channel handle
 * @param[out] maxMagneticField The field strength value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetSpatial_getMaxMagneticField(PhidgetSpatialHandle ch,
  double (*maxMagneticField)[3]);

/**
 * @brief The sensor precision value
 *
 * Selects between high/low precision sensing chips.
 *
 * @private
 * @param[in] ch The channel handle
 * @param[in] precision The sensor precision value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetSpatial_setPrecision(PhidgetSpatialHandle ch,
  Phidget_SpatialPrecision precision);

/**
 * @brief The sensor precision value
 *
 * Selects between high/low precision sensing chips.
 *
 * @private
 * @param[in] ch The channel handle
 * @param[out] precision The sensor precision value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetSpatial_getPrecision(PhidgetSpatialHandle ch,
  Phidget_SpatialPrecision *precision);

/**
 * @brief Gets the latest AHRS/IMU quaternion sent from the device.
 *
 * Gets the latest AHRS/IMU quaternion sent from the device.
 *
 * @param[in] ch The channel handle
 * @param[out] quaternion Gets the latest AHRS/IMU quaternion sent from the device
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetSpatial_getQuaternion(PhidgetSpatialHandle ch,
  PhidgetSpatial_SpatialQuaternion *quaternion);

/**
 * @brief Callback function type for PhidgetSpatial_setOnAlgorithmDataHandler().
 *
 * @param[in] ch The channel handle
 * @param[in] ctx Pointer to the user context
 * @param[in] quaternion The quaternion value - \[x, y, z, w\]
 * @param[in] timestamp The timestamp value
 */
typedef void (CCONV *PhidgetSpatial_OnAlgorithmDataCallback)(PhidgetSpatialHandle ch, void *ctx,
  const double quaternion[4], double timestamp);

/**
 * The most recent IMU/AHRS Quaternion will be reported in this event, which occurs when the
 * `DataInterval` has elapsed.
 *
 * @param[in] ch The channel handle
 * @param[in] fptr The event handler callback function
 * @param[in] ctx User supplied context pointer
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetSpatial_setOnAlgorithmDataHandler(PhidgetSpatialHandle ch,
  PhidgetSpatial_OnAlgorithmDataCallback fptr, void *ctx);

/**
 * @brief Callback function type for PhidgetSpatial_setOnSpatialDataHandler().
 *
 * @param[in] ch The channel handle
 * @param[in] ctx Pointer to the user context
 * @param[in] acceleration The acceleration vaulues
 * @param[in] angularRate The angular rate values
 * @param[in] magneticField The field strength values
 * @param[in] timestamp The timestamp value
 */
typedef void (CCONV *PhidgetSpatial_OnSpatialDataCallback)(PhidgetSpatialHandle ch, void *ctx,
  const double acceleration[3], const double angularRate[3], const double magneticField[3],
  double timestamp);

/**
 * The most recent values that your channel has measured will be reported in this event, which
 * occurs when the `DataInterval` has elapsed.
 *
 * @param[in] ch The channel handle
 * @param[in] fptr The event handler callback function
 * @param[in] ctx User supplied context pointer
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetSpatial_setOnSpatialDataHandler(PhidgetSpatialHandle ch,
  PhidgetSpatial_OnSpatialDataCallback fptr, void *ctx);

/** @} */ /* PhidgetSpatial */

/**
 * @defgroup PhidgetStepper Stepper
 * @brief The Stepper class powers and controls the stepper motor connected to the Phidget
 *     controller, allowing you to change the position, velocity, acceleration, and current limit.
 * @{
 */

/**
 * The Stepper class powers and controls the stepper motor connected to the Phidget controller,
 * allowing you to change the position, velocity, acceleration, and current limit.
 */
typedef struct _PhidgetStepper *PhidgetStepperHandle;

/**
 * @ref PhidgetStepper_create() creates an instance of a Phidget channel. Once created the channel
 * may need to be configured to match the physical device and channel index you want to attach to,
 * and then be opened by calling @ref Phidget_open().
 * The Phidget channel handle must be released with @ref PhidgetStepper_delete().
 *
 * @param[out] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetStepper_create(PhidgetStepperHandle *ch);

/**
 * @ref PhidgetStepper_delete() releases a Phidget channel handle created with @ref
 * PhidgetStepper_create().
 * If the channel is open when @ref PhidgetStepper_delete() is called, it will be closed.
 *
 * @param[out] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetStepper_delete(PhidgetStepperHandle *ch);

/**
 * Enables the **failsafe** feature for the channel, with the specified **failsafe time**.
 *
 * Enabling the failsafe feature starts a recurring **failsafe timer** for the channel. Once the
 * failsafe is enabled, the timer must be reset within the specified time or the channel will enter
 * a **failsafe state**. For Stepper Motor channels, this will disengage the motor. The failsafe
 * timer can be reset by using any of the following API calls:
 *
 * *   @ref PhidgetStepper_setAcceleration()
 * *   @ref PhidgetStepper_setControlMode()
 * *   @ref PhidgetStepper_setCurrentLimit()
 * *   @ref PhidgetStepper_setDataInterval()
 * *   @ref PhidgetStepper_setDataRate()
 * *   @ref PhidgetStepper_setEngaged()
 * *   @ref PhidgetStepper_setHoldingCurrentLimit()
 * *   @ref PhidgetStepper_setVelocityLimit()
 * *   @ref PhidgetStepper_resetFailsafe()
 *
 * For more information about failsafe, visit our [Failsafe
 * Guide](https://www.phidgets.com/docs/Failsafe_Guide).
 *
 * @param[in] ch The channel handle
 * @param[in] failsafeTime Failsafe timeout in milliseconds
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetStepper_enableFailsafe(PhidgetStepperHandle ch,
  uint32_t failsafeTime);

/**
 * Adds an offset (positive or negative) to the current position and target position.
 *
 * *   This is especially useful for zeroing position.
 *
 * @param[in] ch The channel handle
 * @param[in] positionOffset Amount to offset the position by
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetStepper_addPositionOffset(PhidgetStepperHandle ch,
  double positionOffset);

/**
 * Resets the failsafe timer, if one has been set. See @ref PhidgetStepper_enableFailsafe() for
 * details.
 *
 * This function will fail if no failsafe timer has been set for the channel.
 *
 * @param[in] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetStepper_resetFailsafe(PhidgetStepperHandle ch);

/**
 * @brief The acceleration value
 *
 * The rate at which the controller can change the motor's @ref PhidgetStepper_getVelocity().
 *
 * *   Use the `RescaleFactor` to convert the units of this property into more intuitive units
 *     such as rotations or degrees.
 *
 * For more information about `Acceleration`, visit our [Stepper API
 * Guide](https://www.phidgets.com/docs/Stepper_API_Guide#Acceleration).
 *
 * @param[in] ch The channel handle
 * @param[in] acceleration The acceleration value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetStepper_setAcceleration(PhidgetStepperHandle ch,
  double acceleration);

/**
 * @brief The acceleration value
 *
 * The rate at which the controller can change the motor's @ref PhidgetStepper_getVelocity().
 *
 * *   Use the `RescaleFactor` to convert the units of this property into more intuitive units
 *     such as rotations or degrees.
 *
 * For more information about `Acceleration`, visit our [Stepper API
 * Guide](https://www.phidgets.com/docs/Stepper_API_Guide#Acceleration).
 *
 * @param[in] ch The channel handle
 * @param[out] acceleration The acceleration value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetStepper_getAcceleration(PhidgetStepperHandle ch,
  double *acceleration);

/**
 * @brief The acceleration value
 *
 * The minimum value that `Acceleration` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minAcceleration The acceleration value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetStepper_getMinAcceleration(PhidgetStepperHandle ch,
  double *minAcceleration);

/**
 * @brief The acceleration value
 *
 * The maximum value that `Acceleration` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxAcceleration The acceleration value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetStepper_getMaxAcceleration(PhidgetStepperHandle ch,
  double *maxAcceleration);

/**
 * @brief The control mode value
 *
 * This setting changes how the controller moves your motor.
 *
 * *   In @ref CONTROL_MODE_STEP, a `TargetPosition` is specified and the controller moves the
 *     motor toward the target.
 * *   In @ref CONTROL_MODE_RUN, the controller continuously rotates the motor in a direction
 *     that is specified by the a `VelocityLimit`.
 *
 * For more information about `ControlMode`, visit our [Stepper API
 * Guide](https://www.phidgets.com/docs/Stepper_API_Guide#Control_Mode).
 *
 * @param[in] ch The channel handle
 * @param[in] controlMode The control mode value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetStepper_setControlMode(PhidgetStepperHandle ch,
  PhidgetStepper_ControlMode controlMode);

/**
 * @brief The control mode value
 *
 * This setting changes how the controller moves your motor.
 *
 * *   In @ref CONTROL_MODE_STEP, a `TargetPosition` is specified and the controller moves the
 *     motor toward the target.
 * *   In @ref CONTROL_MODE_RUN, the controller continuously rotates the motor in a direction
 *     that is specified by the a `VelocityLimit`.
 *
 * For more information about `ControlMode`, visit our [Stepper API
 * Guide](https://www.phidgets.com/docs/Stepper_API_Guide#Control_Mode).
 *
 * @param[in] ch The channel handle
 * @param[out] controlMode The control mode value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetStepper_getControlMode(PhidgetStepperHandle ch,
  PhidgetStepper_ControlMode *controlMode);

/**
 * @brief The current limit value
 *
 * The current through the motor will be limited by the `CurrentLimit`.
 *
 * For more information about `CurrentLimit`, visit our [Stepper API
 * Guide](https://www.phidgets.com/docs/Stepper_API_Guide#Current_Limit).
 *
 * @param[in] ch The channel handle
 * @param[in] currentLimit The current limit value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetStepper_setCurrentLimit(PhidgetStepperHandle ch,
  double currentLimit);

/**
 * @brief The current limit value
 *
 * The current through the motor will be limited by the `CurrentLimit`.
 *
 * For more information about `CurrentLimit`, visit our [Stepper API
 * Guide](https://www.phidgets.com/docs/Stepper_API_Guide#Current_Limit).
 *
 * @param[in] ch The channel handle
 * @param[out] currentLimit The current limit value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetStepper_getCurrentLimit(PhidgetStepperHandle ch,
  double *currentLimit);

/**
 * @brief The current limit
 *
 * The minimum value that `CurrentLimit` and `HoldingCurrentLimit` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minCurrentLimit The current limit
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetStepper_getMinCurrentLimit(PhidgetStepperHandle ch,
  double *minCurrentLimit);

/**
 * @brief The current limit
 *
 * The maximum value that `CurrentLimit` and `HoldingCurrentLimit` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxCurrentLimit The current limit
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetStepper_getMaxCurrentLimit(PhidgetStepperHandle ch,
  double *maxCurrentLimit);

/**
 * @brief The data interval value
 *
 * The `DataInterval` is the time that must elapse before the channel will fire another @ref
 * PhidgetStepper_setOnPositionChangeHandler() / @ref PhidgetStepper_setOnVelocityChangeHandler()
 * event.
 *
 * *   The data interval is bounded by @ref PhidgetStepper_getMinDataInterval() and @ref
 *     PhidgetStepper_getMaxDataInterval().
 *
 * @param[in] ch The channel handle
 * @param[in] dataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetStepper_setDataInterval(PhidgetStepperHandle ch,
  uint32_t dataInterval);

/**
 * @brief The data interval value
 *
 * The `DataInterval` is the time that must elapse before the channel will fire another @ref
 * PhidgetStepper_setOnPositionChangeHandler() / @ref PhidgetStepper_setOnVelocityChangeHandler()
 * event.
 *
 * *   The data interval is bounded by @ref PhidgetStepper_getMinDataInterval() and @ref
 *     PhidgetStepper_getMaxDataInterval().
 *
 * @param[in] ch The channel handle
 * @param[out] dataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetStepper_getDataInterval(PhidgetStepperHandle ch,
  uint32_t *dataInterval);

/**
 * @brief The data interval value
 *
 * The minimum value that `DataInterval` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minDataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetStepper_getMinDataInterval(PhidgetStepperHandle ch,
  uint32_t *minDataInterval);

/**
 * @brief The data interval value
 *
 * The maximum value that `DataInterval` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxDataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetStepper_getMaxDataInterval(PhidgetStepperHandle ch,
  uint32_t *maxDataInterval);

/**
 * @brief The data rate for the channel
 *
 * The `DataRate` is the frequency of events from the device.
 *
 * *   The data rate is bounded by @ref PhidgetStepper_getMinDataRate() and @ref
 *     PhidgetStepper_getMaxDataRate().
 * *   Changing `DataRate` will change the channel's `DataInterval` to a corresponding value,
 *     rounded to the nearest integer number of milliseconds.
 * *   The timing between events can also affected by the change trigger.
 *
 * @param[in] ch The channel handle
 * @param[in] dataRate The data rate for the channel
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetStepper_setDataRate(PhidgetStepperHandle ch,
  double dataRate);

/**
 * @brief The data rate for the channel
 *
 * The `DataRate` is the frequency of events from the device.
 *
 * *   The data rate is bounded by @ref PhidgetStepper_getMinDataRate() and @ref
 *     PhidgetStepper_getMaxDataRate().
 * *   Changing `DataRate` will change the channel's `DataInterval` to a corresponding value,
 *     rounded to the nearest integer number of milliseconds.
 * *   The timing between events can also affected by the change trigger.
 *
 * @param[in] ch The channel handle
 * @param[out] dataRate The data rate for the channel
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetStepper_getDataRate(PhidgetStepperHandle ch,
  double *dataRate);

/**
 * @brief The data rate value
 *
 * The minimum value that `DataRate` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minDataRate The data rate value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetStepper_getMinDataRate(PhidgetStepperHandle ch,
  double *minDataRate);

/**
 * @brief The data rate value
 *
 * The maximum value that `DataRate` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxDataRate The data rate value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetStepper_getMaxDataRate(PhidgetStepperHandle ch,
  double *maxDataRate);

/**
 * @brief The engaged state
 *
 * The controller must be engaged in order to move the motor.
 *
 * *   In @ref CONTROL_MODE_STEP, a `TargetPosition` must be defined or the controller will
 *     remain disengaged.
 *
 * *   In @ref CONTROL_MODE_RUN, the controller will activate immediately after engage has been
 *     set to TRUE.
 *
 * For more information about `Engaged`, visit our [Stepper API
 * Guide](https://www.phidgets.com/docs/Stepper_API_Guide#Engage/Disengage).
 *
 * @param[in] ch The channel handle
 * @param[in] engaged The engaged state
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetStepper_setEngaged(PhidgetStepperHandle ch, int engaged);

/**
 * @brief The engaged state
 *
 * The controller must be engaged in order to move the motor.
 *
 * *   In @ref CONTROL_MODE_STEP, a `TargetPosition` must be defined or the controller will
 *     remain disengaged.
 *
 * *   In @ref CONTROL_MODE_RUN, the controller will activate immediately after engage has been
 *     set to TRUE.
 *
 * For more information about `Engaged`, visit our [Stepper API
 * Guide](https://www.phidgets.com/docs/Stepper_API_Guide#Engage/Disengage).
 *
 * @param[in] ch The channel handle
 * @param[out] engaged The engaged state
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetStepper_getEngaged(PhidgetStepperHandle ch, int *engaged);

/**
 * @brief The failsafe time
 *
 * The minimum value that `failsafeTime` can be set to when calling @ref
 * PhidgetStepper_enableFailsafe().
 *
 * @param[in] ch The channel handle
 * @param[out] minFailsafeTime The failsafe time
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetStepper_getMinFailsafeTime(PhidgetStepperHandle ch,
  uint32_t *minFailsafeTime);

/**
 * @brief The failsafe time
 *
 * The maximum value that `failsafeTime` can be set to when calling @ref
 * PhidgetStepper_enableFailsafe().
 *
 * @param[in] ch The channel handle
 * @param[out] maxFailsafeTime The failsafe time
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetStepper_getMaxFailsafeTime(PhidgetStepperHandle ch,
  uint32_t *maxFailsafeTime);

/**
 * @brief The current value
 *
 * The current through the motor will be limited by the `HoldingCurrentLimit` while @ref
 * PhidgetStepper_getIsMoving() is FALSE and `Engaged` is TRUE. If no `HoldingCurrentLimit` is
 * specified, the current through the motor will be limited by the `CurrentLimit` instead.
 *
 * For more information about `HoldingCurrentLimit`, visit our [Stepper API
 * Guide](https://www.phidgets.com/docs/Stepper_API_Guide#Holding_Current_Limit).
 *
 * @param[in] ch The channel handle
 * @param[in] holdingCurrentLimit The current value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetStepper_setHoldingCurrentLimit(PhidgetStepperHandle ch,
  double holdingCurrentLimit);

/**
 * @brief The current value
 *
 * The current through the motor will be limited by the `HoldingCurrentLimit` while @ref
 * PhidgetStepper_getIsMoving() is FALSE and `Engaged` is TRUE. If no `HoldingCurrentLimit` is
 * specified, the current through the motor will be limited by the `CurrentLimit` instead.
 *
 * For more information about `HoldingCurrentLimit`, visit our [Stepper API
 * Guide](https://www.phidgets.com/docs/Stepper_API_Guide#Holding_Current_Limit).
 *
 * @param[in] ch The channel handle
 * @param[out] holdingCurrentLimit The current value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetStepper_getHoldingCurrentLimit(PhidgetStepperHandle ch,
  double *holdingCurrentLimit);

/**
 * @brief The moving state
 *
 * @ref PhidgetStepper_getIsMoving() returns TRUE while the controller is moving the motor.
 *
 * *   The controller receives no feedback from the motor, so this may not always reflect
 *     reality.
 *
 * For more information about @ref PhidgetStepper_getIsMoving(), visit our [Stepper API
 * Guide](https://www.phidgets.com/docs/Stepper_API_Guide#isMoving).
 *
 * @param[in] ch The channel handle
 * @param[out] isMoving The moving state
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetStepper_getIsMoving(PhidgetStepperHandle ch,
  int *isMoving);

/**
 * @brief The position value
 *
 * The most recent Position value reported by the controller.
 *
 * *   Use the `RescaleFactor` to convert the units of this property into more intuitive units
 *     such as rotations or degrees.
 *
 * For more information about @ref PhidgetStepper_getPosition(), visit our [Stepper API
 * Guide](https://www.phidgets.com/docs/Stepper_API_Guide#Motor_Position).
 *
 * @param[in] ch The channel handle
 * @param[out] position The position value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetStepper_getPosition(PhidgetStepperHandle ch,
  double *position);

/**
 * @brief The position value
 *
 * The minimum value that `TargetPosition` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minPosition The position value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetStepper_getMinPosition(PhidgetStepperHandle ch,
  double *minPosition);

/**
 * @brief The position value
 *
 * The maximum value that `TargetPosition` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxPosition The position value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetStepper_getMaxPosition(PhidgetStepperHandle ch,
  double *maxPosition);

/**
 * @brief The rescale factor value
 *
 * Change the units of your parameters so that your application is more intuitive
 *
 * *   View the Specifications tab of your stepper controller to see the default units. Most
 *     controllers have default units of 1/16 steps per count.
 *
 * For more information about `RescaleFactor`, visit our [Stepper API
 * Guide](https://www.phidgets.com/docs/Stepper_API_Guide#Rescale_Factor).
 *
 * @param[in] ch The channel handle
 * @param[in] rescaleFactor The rescale factor value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetStepper_setRescaleFactor(PhidgetStepperHandle ch,
  double rescaleFactor);

/**
 * @brief The rescale factor value
 *
 * Change the units of your parameters so that your application is more intuitive
 *
 * *   View the Specifications tab of your stepper controller to see the default units. Most
 *     controllers have default units of 1/16 steps per count.
 *
 * For more information about `RescaleFactor`, visit our [Stepper API
 * Guide](https://www.phidgets.com/docs/Stepper_API_Guide#Rescale_Factor).
 *
 * @param[in] ch The channel handle
 * @param[out] rescaleFactor The rescale factor value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetStepper_getRescaleFactor(PhidgetStepperHandle ch,
  double *rescaleFactor);

/**
 * @brief The position value
 *
 * The controller will move the motor toward the `TargetPosition` when `Engaged` is TRUE.
 *
 * *   `TargetPosition` is only used when @ref CONTROL_MODE_STEP is selected.
 * *   Use the `RescaleFactor` to convert the units of this property into more intuitive units
 *     such as rotations or degrees.
 *
 * For more information about `TargetPosition`, visit our [Stepper API
 * Guide](https://www.phidgets.com/docs/Stepper_API_Guide#Target_Position).
 *
 * @param[in] ch The channel handle
 * @param[in] targetPosition The position value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetStepper_setTargetPosition(PhidgetStepperHandle ch,
  double targetPosition);

/**
 * @brief The position value
 *
 * The controller will move the motor toward the `TargetPosition` when `Engaged` is TRUE.
 *
 * *   `TargetPosition` is only used when @ref CONTROL_MODE_STEP is selected.
 * *   Use the `RescaleFactor` to convert the units of this property into more intuitive units
 *     such as rotations or degrees.
 *
 * For more information about `TargetPosition`, visit our [Stepper API
 * Guide](https://www.phidgets.com/docs/Stepper_API_Guide#Target_Position).
 *
 * @param[in] ch The channel handle
 * @param[in] targetPosition The position value
 * @param[in] fptr Asynchronous completion callback
 * @param[in] ctx User supplied context pointer
 */
PHIDGET22_API void CCONV PhidgetStepper_setTargetPosition_async(PhidgetStepperHandle ch,
  double targetPosition, Phidget_AsyncCallback fptr, void *ctx);

/**
 * @brief The position value
 *
 * The controller will move the motor toward the `TargetPosition` when `Engaged` is TRUE.
 *
 * *   `TargetPosition` is only used when @ref CONTROL_MODE_STEP is selected.
 * *   Use the `RescaleFactor` to convert the units of this property into more intuitive units
 *     such as rotations or degrees.
 *
 * For more information about `TargetPosition`, visit our [Stepper API
 * Guide](https://www.phidgets.com/docs/Stepper_API_Guide#Target_Position).
 *
 * @param[in] ch The channel handle
 * @param[out] targetPosition The position value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetStepper_getTargetPosition(PhidgetStepperHandle ch,
  double *targetPosition);

/**
 * @brief The velocity value
 *
 * The most recent velocity value that the controller has reported.
 *
 * *   Use the `RescaleFactor` to convert the units of this property into more intuitive units
 *     such as rotations or degrees.
 *
 * For more information about @ref PhidgetStepper_getVelocity(), visit our [Stepper API
 * Guide](https://www.phidgets.com/docs/Stepper_API_Guide#Motor_Velocity).
 *
 * @param[in] ch The channel handle
 * @param[out] velocity The velocity value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetStepper_getVelocity(PhidgetStepperHandle ch,
  double *velocity);

/**
 * @brief Velocity limit
 *
 * The controller will limit the motor's velocity to this value.
 *
 * *   When @ref CONTROL_MODE_STEP is selected, the @ref PhidgetStepper_getMinVelocityLimit()
 *     has a value of 0. This is because the sign (±) of the `TargetPosition` will indicate the
 *     direction.
 * *   When in @ref CONTROL_MODE_RUN, the @ref PhidgetStepper_getMinVelocityLimit() has a value
 *     of -1 * @ref PhidgetStepper_getMaxVelocityLimit(). This is because there is no
 *     `TargetPosition`, so the direction is defined by the sign (±) of the `VelocityLimit`.
 * *   While `VelocityLimit` is listed as a double, it is rounded down to an integer number of
 *     1/16th steps when sent to the board since the board is limited by a minimum unit of 1/16th
 *     steps/s. This is especially important to consider when using different `RescaleFactor` values
 *     where converting to units of, for example, RPM results in 1.5RPM (80 1/16th steps/s) and
 *     1.509375 RPM (80.5 1/16th steps/s) both being sent to the board as 80 1/16th steps/s.
 * *   Use the `RescaleFactor` to convert the units of this property into more intuitive units
 *     such as rotations or degrees.
 *
 * @param[in] ch The channel handle
 * @param[in] velocityLimit Velocity limit
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetStepper_setVelocityLimit(PhidgetStepperHandle ch,
  double velocityLimit);

/**
 * @brief Velocity limit
 *
 * The controller will limit the motor's velocity to this value.
 *
 * *   When @ref CONTROL_MODE_STEP is selected, the @ref PhidgetStepper_getMinVelocityLimit()
 *     has a value of 0. This is because the sign (±) of the `TargetPosition` will indicate the
 *     direction.
 * *   When in @ref CONTROL_MODE_RUN, the @ref PhidgetStepper_getMinVelocityLimit() has a value
 *     of -1 * @ref PhidgetStepper_getMaxVelocityLimit(). This is because there is no
 *     `TargetPosition`, so the direction is defined by the sign (±) of the `VelocityLimit`.
 * *   While `VelocityLimit` is listed as a double, it is rounded down to an integer number of
 *     1/16th steps when sent to the board since the board is limited by a minimum unit of 1/16th
 *     steps/s. This is especially important to consider when using different `RescaleFactor` values
 *     where converting to units of, for example, RPM results in 1.5RPM (80 1/16th steps/s) and
 *     1.509375 RPM (80.5 1/16th steps/s) both being sent to the board as 80 1/16th steps/s.
 * *   Use the `RescaleFactor` to convert the units of this property into more intuitive units
 *     such as rotations or degrees.
 *
 * @param[in] ch The channel handle
 * @param[out] velocityLimit Velocity limit
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetStepper_getVelocityLimit(PhidgetStepperHandle ch,
  double *velocityLimit);

/**
 * @brief The velocity limit value
 *
 * The minimum value that `VelocityLimit` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minVelocityLimit The velocity limit value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetStepper_getMinVelocityLimit(PhidgetStepperHandle ch,
  double *minVelocityLimit);

/**
 * @brief The velocity value
 *
 * The maximum value that `VelocityLimit` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxVelocityLimit The velocity value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetStepper_getMaxVelocityLimit(PhidgetStepperHandle ch,
  double *maxVelocityLimit);

/**
 * @brief Callback function type for PhidgetStepper_setOnPositionChangeHandler().
 *
 * @param[in] ch The channel handle
 * @param[in] ctx Pointer to the user context
 * @param[in] position The current stepper position
 */
typedef void (CCONV *PhidgetStepper_OnPositionChangeCallback)(PhidgetStepperHandle ch, void *ctx,
  double position);

/**
 * The most recent position value will be reported in this event, which occurs when the
 * `DataInterval` has elapsed.
 *
 * *   Use the `RescaleFactor` to convert the units of this property into more intuitive units
 *     such as rotations or degrees.
 *
 * @param[in] ch The channel handle
 * @param[in] fptr The event handler callback function
 * @param[in] ctx User supplied context pointer
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetStepper_setOnPositionChangeHandler(PhidgetStepperHandle ch,
  PhidgetStepper_OnPositionChangeCallback fptr, void *ctx);

/**
 * @brief Callback function type for PhidgetStepper_setOnStoppedHandler().
 *
 * @param[in] ch The channel handle
 * @param[in] ctx Pointer to the user context
 */
typedef void (CCONV *PhidgetStepper_OnStoppedCallback)(PhidgetStepperHandle ch, void *ctx);

/**
 * Occurs when the controller stops moving the motor.
 *
 * *   The controller receives no feedback from the motor, so this may not always reflect
 *     reality.
 *
 * @param[in] ch The channel handle
 * @param[in] fptr The event handler callback function
 * @param[in] ctx User supplied context pointer
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetStepper_setOnStoppedHandler(PhidgetStepperHandle ch,
  PhidgetStepper_OnStoppedCallback fptr, void *ctx);

/**
 * @brief Callback function type for PhidgetStepper_setOnVelocityChangeHandler().
 *
 * @param[in] ch The channel handle
 * @param[in] ctx Pointer to the user context
 * @param[in] velocity Velocity of the stepper. Sign indicates direction
 */
typedef void (CCONV *PhidgetStepper_OnVelocityChangeCallback)(PhidgetStepperHandle ch, void *ctx,
  double velocity);

/**
 * The most recent velocity value will be reported in this event, which occurs when the
 * `DataInterval` has elapsed.
 *
 * *   Use the `RescaleFactor` to convert the units of this property into more intuitive units
 *     such as rotations or degrees.
 *
 * @param[in] ch The channel handle
 * @param[in] fptr The event handler callback function
 * @param[in] ctx User supplied context pointer
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetStepper_setOnVelocityChangeHandler(PhidgetStepperHandle ch,
  PhidgetStepper_OnVelocityChangeCallback fptr, void *ctx);

/** @} */ /* PhidgetStepper */

/**
 * @defgroup PhidgetTemperatureSensor TemperatureSensor
 * @brief The Temperature Sensor class gathers data from the temperature sensor on a Phidget
 *     board. This includes on-board ambient temperature sensors, connected thermocouples or
 *     platinum RTDs, and IR temperature sensors. This class is also used to measure the temperature
 *     on some high-power Phidget boards such as motor controllers for safety reasons.
 * @{
 */

/**
 * The Temperature Sensor class gathers data from the temperature sensor on a Phidget board. This
 * includes on-board ambient temperature sensors, connected thermocouples or platinum RTDs, and IR
 * temperature sensors. This class is also used to measure the temperature on some high-power
 * Phidget boards such as motor controllers for safety reasons.
 *
 * If you're using a simple 0-5V sensor that does not have its own firmware, use the VoltageInput or
 * VoltageRatioInput class instead, as specified for your device.
 */
typedef struct _PhidgetTemperatureSensor *PhidgetTemperatureSensorHandle;

/**
 * @ref PhidgetTemperatureSensor_create() creates an instance of a Phidget channel. Once created the
 * channel may need to be configured to match the physical device and channel index you want to
 * attach to, and then be opened by calling @ref Phidget_open().
 * The Phidget channel handle must be released with @ref PhidgetTemperatureSensor_delete().
 *
 * @param[out] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetTemperatureSensor_create(PhidgetTemperatureSensorHandle *ch);

/**
 * @ref PhidgetTemperatureSensor_delete() releases a Phidget channel handle created with @ref
 * PhidgetTemperatureSensor_create().
 * If the channel is open when @ref PhidgetTemperatureSensor_delete() is called, it will be closed.
 *
 * @param[out] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetTemperatureSensor_delete(PhidgetTemperatureSensorHandle *ch);

/**
 * @brief The data interval value
 *
 * The `DataInterval` is the time that must elapse before the channel will fire another @ref
 * PhidgetTemperatureSensor_setOnTemperatureChangeHandler() event.
 *
 * *   The data interval is bounded by @ref PhidgetTemperatureSensor_getMinDataInterval() and
 *     @ref PhidgetTemperatureSensor_getMaxDataInterval().
 * *   The timing between @ref PhidgetTemperatureSensor_setOnTemperatureChangeHandler() events
 *     can also be affected by the `TemperatureChangeTrigger`.
 *
 * @param[in] ch The channel handle
 * @param[in] dataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetTemperatureSensor_setDataInterval(PhidgetTemperatureSensorHandle ch,
  uint32_t dataInterval);

/**
 * @brief The data interval value
 *
 * The `DataInterval` is the time that must elapse before the channel will fire another @ref
 * PhidgetTemperatureSensor_setOnTemperatureChangeHandler() event.
 *
 * *   The data interval is bounded by @ref PhidgetTemperatureSensor_getMinDataInterval() and
 *     @ref PhidgetTemperatureSensor_getMaxDataInterval().
 * *   The timing between @ref PhidgetTemperatureSensor_setOnTemperatureChangeHandler() events
 *     can also be affected by the `TemperatureChangeTrigger`.
 *
 * @param[in] ch The channel handle
 * @param[out] dataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetTemperatureSensor_getDataInterval(PhidgetTemperatureSensorHandle ch,
  uint32_t *dataInterval);

/**
 * @brief The data interval value
 *
 * The minimum value that `DataInterval` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minDataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetTemperatureSensor_getMinDataInterval(PhidgetTemperatureSensorHandle ch,
  uint32_t *minDataInterval);

/**
 * @brief The data interval value
 *
 * The maximum value that `DataInterval` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxDataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetTemperatureSensor_getMaxDataInterval(PhidgetTemperatureSensorHandle ch,
  uint32_t *maxDataInterval);

/**
 * @brief The data rate for the channel
 *
 * The `DataRate` is the frequency of events from the device.
 *
 * *   The data rate is bounded by @ref PhidgetTemperatureSensor_getMinDataRate() and @ref
 *     PhidgetTemperatureSensor_getMaxDataRate().
 * *   Changing `DataRate` will change the channel's `DataInterval` to a corresponding value,
 *     rounded to the nearest integer number of milliseconds.
 * *   The timing between events can also affected by the change trigger.
 *
 * @param[in] ch The channel handle
 * @param[in] dataRate The data rate for the channel
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetTemperatureSensor_setDataRate(PhidgetTemperatureSensorHandle ch,
  double dataRate);

/**
 * @brief The data rate for the channel
 *
 * The `DataRate` is the frequency of events from the device.
 *
 * *   The data rate is bounded by @ref PhidgetTemperatureSensor_getMinDataRate() and @ref
 *     PhidgetTemperatureSensor_getMaxDataRate().
 * *   Changing `DataRate` will change the channel's `DataInterval` to a corresponding value,
 *     rounded to the nearest integer number of milliseconds.
 * *   The timing between events can also affected by the change trigger.
 *
 * @param[in] ch The channel handle
 * @param[out] dataRate The data rate for the channel
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetTemperatureSensor_getDataRate(PhidgetTemperatureSensorHandle ch,
  double *dataRate);

/**
 * @brief The data rate value
 *
 * The minimum value that `DataRate` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minDataRate The data rate value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetTemperatureSensor_getMinDataRate(PhidgetTemperatureSensorHandle ch,
  double *minDataRate);

/**
 * @brief The data rate value
 *
 * The maximum value that `DataRate` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxDataRate The data rate value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetTemperatureSensor_getMaxDataRate(PhidgetTemperatureSensorHandle ch,
  double *maxDataRate);

/**
 * @brief The RTD type
 *
 * The `RTDType` must correspond to the RTD type you are using in your application.
 *
 * *   If you are unsure which `RTDType` to use, visit your device's User Guide for more
 *     information.
 *
 * @param[in] ch The channel handle
 * @param[in] RTDType The RTD type
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetTemperatureSensor_setRTDType(PhidgetTemperatureSensorHandle ch,
  PhidgetTemperatureSensor_RTDType RTDType);

/**
 * @brief The RTD type
 *
 * The `RTDType` must correspond to the RTD type you are using in your application.
 *
 * *   If you are unsure which `RTDType` to use, visit your device's User Guide for more
 *     information.
 *
 * @param[in] ch The channel handle
 * @param[out] RTDType The RTD type
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetTemperatureSensor_getRTDType(PhidgetTemperatureSensorHandle ch,
  PhidgetTemperatureSensor_RTDType *RTDType);

/**
 * @brief The RTD wire setup
 *
 * The `RTDWireSetup` must correspond to the wire configuration you are using in your application.
 *
 * *   If you are unsure which `RTDWireSetup` to use, visit your device's User Guide for more
 *     information.
 *
 * @param[in] ch The channel handle
 * @param[in] RTDWireSetup The RTD wire setup
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetTemperatureSensor_setRTDWireSetup(PhidgetTemperatureSensorHandle ch,
  Phidget_RTDWireSetup RTDWireSetup);

/**
 * @brief The RTD wire setup
 *
 * The `RTDWireSetup` must correspond to the wire configuration you are using in your application.
 *
 * *   If you are unsure which `RTDWireSetup` to use, visit your device's User Guide for more
 *     information.
 *
 * @param[in] ch The channel handle
 * @param[out] RTDWireSetup The RTD wire setup
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetTemperatureSensor_getRTDWireSetup(PhidgetTemperatureSensorHandle ch,
  Phidget_RTDWireSetup *RTDWireSetup);

/**
 * @brief The temperature value
 *
 * The most recent temperature value that the channel has reported.
 *
 * *   This value will always be between @ref PhidgetTemperatureSensor_getMinTemperature() and
 *     @ref PhidgetTemperatureSensor_getMaxTemperature().
 *
 * @param[in] ch The channel handle
 * @param[out] temperature The temperature value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetTemperatureSensor_getTemperature(PhidgetTemperatureSensorHandle ch,
  double *temperature);

/**
 * @brief The temperature value
 *
 * The minimum value the @ref PhidgetTemperatureSensor_setOnTemperatureChangeHandler() event will
 * report.
 *
 * @param[in] ch The channel handle
 * @param[out] minTemperature The temperature value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetTemperatureSensor_getMinTemperature(PhidgetTemperatureSensorHandle ch,
  double *minTemperature);

/**
 * @brief The temperature value
 *
 * The maximum value the @ref PhidgetTemperatureSensor_setOnTemperatureChangeHandler() event will
 * report.
 *
 * @param[in] ch The channel handle
 * @param[out] maxTemperature The temperature value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetTemperatureSensor_getMaxTemperature(PhidgetTemperatureSensorHandle ch,
  double *maxTemperature);

/**
 * @brief The change trigger value
 *
 * The channel will not issue a @ref PhidgetTemperatureSensor_setOnTemperatureChangeHandler() event
 * until the temperature value has changed by the amount specified by the
 * `TemperatureChangeTrigger`.
 *
 * *   Setting the `TemperatureChangeTrigger` to 0 will result in the channel firing events
 *     every `DataInterval`. This is useful for applications that implement their own data filtering
 *
 * @param[in] ch The channel handle
 * @param[in] temperatureChangeTrigger The change trigger value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetTemperatureSensor_setTemperatureChangeTrigger(PhidgetTemperatureSensorHandle ch,
  double temperatureChangeTrigger);

/**
 * @brief The change trigger value
 *
 * The channel will not issue a @ref PhidgetTemperatureSensor_setOnTemperatureChangeHandler() event
 * until the temperature value has changed by the amount specified by the
 * `TemperatureChangeTrigger`.
 *
 * *   Setting the `TemperatureChangeTrigger` to 0 will result in the channel firing events
 *     every `DataInterval`. This is useful for applications that implement their own data filtering
 *
 * @param[in] ch The channel handle
 * @param[out] temperatureChangeTrigger The change trigger value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetTemperatureSensor_getTemperatureChangeTrigger(PhidgetTemperatureSensorHandle ch,
  double *temperatureChangeTrigger);

/**
 * @brief The change trigger value
 *
 * The minimum value that `TemperatureChangeTrigger` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minTemperatureChangeTrigger The change trigger value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetTemperatureSensor_getMinTemperatureChangeTrigger(PhidgetTemperatureSensorHandle ch,
  double *minTemperatureChangeTrigger);

/**
 * @brief The change trigger value
 *
 * The maximum value that `TemperatureChangeTrigger` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxTemperatureChangeTrigger The change trigger value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetTemperatureSensor_getMaxTemperatureChangeTrigger(PhidgetTemperatureSensorHandle ch,
  double *maxTemperatureChangeTrigger);

/**
 * @brief The thermocouple type
 *
 * The `ThermocoupleType` must correspond to the thermocouple type you are using in your
 * application.
 *
 * *   If you are unsure which `ThermocoupleType` to use, visit the [Thermocouple
 *     Primer](https://www.phidgets.com/docs/Thermocouple_Primer) for more information.
 *
 * @param[in] ch The channel handle
 * @param[in] thermocoupleType The thermocouple type
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetTemperatureSensor_setThermocoupleType(PhidgetTemperatureSensorHandle ch,
  PhidgetTemperatureSensor_ThermocoupleType thermocoupleType);

/**
 * @brief The thermocouple type
 *
 * The `ThermocoupleType` must correspond to the thermocouple type you are using in your
 * application.
 *
 * *   If you are unsure which `ThermocoupleType` to use, visit the [Thermocouple
 *     Primer](https://www.phidgets.com/docs/Thermocouple_Primer) for more information.
 *
 * @param[in] ch The channel handle
 * @param[out] thermocoupleType The thermocouple type
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetTemperatureSensor_getThermocoupleType(PhidgetTemperatureSensorHandle ch,
  PhidgetTemperatureSensor_ThermocoupleType *thermocoupleType);

/**
 * @brief Callback function type for PhidgetTemperatureSensor_setOnTemperatureChangeHandler().
 *
 * @param[in] ch The channel handle
 * @param[in] ctx Pointer to the user context
 * @param[in] temperature The temperature
 */
typedef void (CCONV *PhidgetTemperatureSensor_OnTemperatureChangeCallback)(PhidgetTemperatureSensorHandle ch,
  void *ctx, double temperature);

/**
 * The most recent temperature value the channel has measured will be reported in this event, which
 * occurs when the `DataInterval` has elapsed.
 *
 * *   If a `TemperatureChangeTrigger` has been set to a non-zero value, the @ref
 *     PhidgetTemperatureSensor_setOnTemperatureChangeHandler() event will not occur until the
 *     temperature has changed by at least the `TemperatureChangeTrigger` value.
 *
 * @param[in] ch The channel handle
 * @param[in] fptr The event handler callback function
 * @param[in] ctx User supplied context pointer
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetTemperatureSensor_setOnTemperatureChangeHandler(PhidgetTemperatureSensorHandle ch,
  PhidgetTemperatureSensor_OnTemperatureChangeCallback fptr, void *ctx);

/** @} */ /* PhidgetTemperatureSensor */

/**
 * @defgroup PhidgetVoltageInput VoltageInput
 * @brief The Voltage Input class measures the voltage across the input of a Phidget with a
 *     voltage input. This may be a sensor designed to measure voltage directly, or it could be an
 *     input designed to interface with 0-5V sensors.
 * @{
 */

/**
 * The Voltage Input class measures the voltage across the input of a Phidget with a voltage input.
 * This may be a sensor designed to measure voltage directly, or it could be an input designed to
 * interface with 0-5V sensors.
 *
 * For 0-5V sensors, this class supports conversion to sensor data with units specific to the
 * Phidget sensor being used, to make reading these sensors easy.
 */
typedef struct _PhidgetVoltageInput *PhidgetVoltageInputHandle;

/**
 * @ref PhidgetVoltageInput_create() creates an instance of a Phidget channel. Once created the
 * channel may need to be configured to match the physical device and channel index you want to
 * attach to, and then be opened by calling @ref Phidget_open().
 * The Phidget channel handle must be released with @ref PhidgetVoltageInput_delete().
 *
 * @param[out] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetVoltageInput_create(PhidgetVoltageInputHandle *ch);

/**
 * @ref PhidgetVoltageInput_delete() releases a Phidget channel handle created with @ref
 * PhidgetVoltageInput_create().
 * If the channel is open when @ref PhidgetVoltageInput_delete() is called, it will be closed.
 *
 * @param[out] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetVoltageInput_delete(PhidgetVoltageInputHandle *ch);

/**
 * @brief The data interval value
 *
 * The `DataInterval` is the time that must elapse before the channel will fire another event.
 *
 * *   The data interval is bounded by @ref PhidgetVoltageInput_getMinDataInterval() and @ref
 *     PhidgetVoltageInput_getMaxDataInterval().
 * *   The timing between events can also be affected by the change trigger.
 *
 * @param[in] ch The channel handle
 * @param[in] dataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetVoltageInput_setDataInterval(PhidgetVoltageInputHandle ch,
  uint32_t dataInterval);

/**
 * @brief The data interval value
 *
 * The `DataInterval` is the time that must elapse before the channel will fire another event.
 *
 * *   The data interval is bounded by @ref PhidgetVoltageInput_getMinDataInterval() and @ref
 *     PhidgetVoltageInput_getMaxDataInterval().
 * *   The timing between events can also be affected by the change trigger.
 *
 * @param[in] ch The channel handle
 * @param[out] dataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetVoltageInput_getDataInterval(PhidgetVoltageInputHandle ch,
  uint32_t *dataInterval);

/**
 * @brief The data interval value
 *
 * The minimum value that `DataInterval` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minDataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetVoltageInput_getMinDataInterval(PhidgetVoltageInputHandle ch,
  uint32_t *minDataInterval);

/**
 * @brief The data interval value
 *
 * The maximum value that `DataInterval` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxDataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetVoltageInput_getMaxDataInterval(PhidgetVoltageInputHandle ch,
  uint32_t *maxDataInterval);

/**
 * @brief The data rate for the channel
 *
 * The `DataRate` is the frequency of events from the device.
 *
 * *   The data rate is bounded by @ref PhidgetVoltageInput_getMinDataRate() and @ref
 *     PhidgetVoltageInput_getMaxDataRate().
 * *   Changing `DataRate` will change the channel's `DataInterval` to a corresponding value,
 *     rounded to the nearest integer number of milliseconds.
 * *   The timing between events can also affected by the change trigger.
 *
 * @param[in] ch The channel handle
 * @param[in] dataRate The data rate for the channel
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetVoltageInput_setDataRate(PhidgetVoltageInputHandle ch,
  double dataRate);

/**
 * @brief The data rate for the channel
 *
 * The `DataRate` is the frequency of events from the device.
 *
 * *   The data rate is bounded by @ref PhidgetVoltageInput_getMinDataRate() and @ref
 *     PhidgetVoltageInput_getMaxDataRate().
 * *   Changing `DataRate` will change the channel's `DataInterval` to a corresponding value,
 *     rounded to the nearest integer number of milliseconds.
 * *   The timing between events can also affected by the change trigger.
 *
 * @param[in] ch The channel handle
 * @param[out] dataRate The data rate for the channel
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetVoltageInput_getDataRate(PhidgetVoltageInputHandle ch,
  double *dataRate);

/**
 * @brief The data rate value
 *
 * The minimum value that `DataRate` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minDataRate The data rate value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetVoltageInput_getMinDataRate(PhidgetVoltageInputHandle ch,
  double *minDataRate);

/**
 * @brief The data rate value
 *
 * The maximum value that `DataRate` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxDataRate The data rate value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetVoltageInput_getMaxDataRate(PhidgetVoltageInputHandle ch,
  double *maxDataRate);

/**
 * @brief The power supply value
 *
 * Choose the power supply voltage.
 *
 * *   Set this to the voltage specified in the attached sensor's data sheet to power it.
 * *   Set to @ref POWER_SUPPLY_OFF to turn off the supply to save power.
 *
 * @param[in] ch The channel handle
 * @param[in] powerSupply The power supply value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetVoltageInput_setPowerSupply(PhidgetVoltageInputHandle ch,
  Phidget_PowerSupply powerSupply);

/**
 * @brief The power supply value
 *
 * Choose the power supply voltage.
 *
 * *   Set this to the voltage specified in the attached sensor's data sheet to power it.
 * *   Set to @ref POWER_SUPPLY_OFF to turn off the supply to save power.
 *
 * @param[in] ch The channel handle
 * @param[out] powerSupply The power supply value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetVoltageInput_getPowerSupply(PhidgetVoltageInputHandle ch,
  Phidget_PowerSupply *powerSupply);

/**
 * @brief The sensor type value
 *
 * We sell a variety of analog sensors that do not have their own API, they simply output a voltage
 * that can be converted to a digital value using a specific formula. By matching the `SensorType`
 * to your analog sensor, the correct formula will automatically be applied to data when you get the
 * @ref PhidgetVoltageInput_getSensorValue() or subscribe to the @ref
 * PhidgetVoltageInput_setOnSensorChangeHandler() event.
 *
 * *   The @ref PhidgetVoltageInput_setOnSensorChangeHandler() event has its own change trigger
 *     associated with it: `SensorValueChangeTrigger`.
 * *   Any data from getting the @ref PhidgetVoltageInput_getSensorValue() or subscribing to the
 *     @ref PhidgetVoltageInput_setOnSensorChangeHandler() event will have a @ref
 *     PhidgetVoltageInput_getSensorUnit() associated with it.
 *
 * **Note:** Unlike other properties such as `DeviceSerialNumber` or `Channel`, `SensorType` is set
 * after the device is opened, not before.
 *
 * @param[in] ch The channel handle
 * @param[in] sensorType The sensor type value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetVoltageInput_setSensorType(PhidgetVoltageInputHandle ch,
  PhidgetVoltageInput_SensorType sensorType);

/**
 * @brief The sensor type value
 *
 * We sell a variety of analog sensors that do not have their own API, they simply output a voltage
 * that can be converted to a digital value using a specific formula. By matching the `SensorType`
 * to your analog sensor, the correct formula will automatically be applied to data when you get the
 * @ref PhidgetVoltageInput_getSensorValue() or subscribe to the @ref
 * PhidgetVoltageInput_setOnSensorChangeHandler() event.
 *
 * *   The @ref PhidgetVoltageInput_setOnSensorChangeHandler() event has its own change trigger
 *     associated with it: `SensorValueChangeTrigger`.
 * *   Any data from getting the @ref PhidgetVoltageInput_getSensorValue() or subscribing to the
 *     @ref PhidgetVoltageInput_setOnSensorChangeHandler() event will have a @ref
 *     PhidgetVoltageInput_getSensorUnit() associated with it.
 *
 * **Note:** Unlike other properties such as `DeviceSerialNumber` or `Channel`, `SensorType` is set
 * after the device is opened, not before.
 *
 * @param[in] ch The channel handle
 * @param[out] sensorType The sensor type value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetVoltageInput_getSensorType(PhidgetVoltageInputHandle ch,
  PhidgetVoltageInput_SensorType *sensorType);

/**
 * @brief The sensor unit information corresponding to the @ref
 *     PhidgetVoltageInput_getSensorValue().
 *
 * The unit of measurement that applies to the sensor values of the `SensorType` that has been
 * selected.
 *
 * *   Helps keep track of the type of information being calculated from the voltage input.
 *
 * @param[in] ch The channel handle
 * @param[out] sensorUnit The sensor unit information corresponding to the @ref
 *     PhidgetVoltageInput_getSensorValue()
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetVoltageInput_getSensorUnit(PhidgetVoltageInputHandle ch,
  Phidget_UnitInfo *sensorUnit);

/**
 * @brief The sensor value
 *
 * The most recent sensor value that the channel has reported.
 *
 * *   Use @ref PhidgetVoltageInput_getSensorUnit() to get the measurement units that are
 *     associated with the @ref PhidgetVoltageInput_getSensorValue()
 *
 * @param[in] ch The channel handle
 * @param[out] sensorValue The sensor value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetVoltageInput_getSensorValue(PhidgetVoltageInputHandle ch,
  double *sensorValue);

/**
 * @brief The change trigger value
 *
 * The channel will not issue a @ref PhidgetVoltageInput_setOnSensorChangeHandler() event until the
 * sensor value has changed by the amount specified by the `SensorValueChangeTrigger`.
 *
 * *   Setting the `SensorValueChangeTrigger` to 0 will result in the channel firing events
 *     every `DataInterval`. This is useful for applications that implement their own data filtering
 *
 * @param[in] ch The channel handle
 * @param[in] sensorValueChangeTrigger The change trigger value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetVoltageInput_setSensorValueChangeTrigger(PhidgetVoltageInputHandle ch,
  double sensorValueChangeTrigger);

/**
 * @brief The change trigger value
 *
 * The channel will not issue a @ref PhidgetVoltageInput_setOnSensorChangeHandler() event until the
 * sensor value has changed by the amount specified by the `SensorValueChangeTrigger`.
 *
 * *   Setting the `SensorValueChangeTrigger` to 0 will result in the channel firing events
 *     every `DataInterval`. This is useful for applications that implement their own data filtering
 *
 * @param[in] ch The channel handle
 * @param[out] sensorValueChangeTrigger The change trigger value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetVoltageInput_getSensorValueChangeTrigger(PhidgetVoltageInputHandle ch,
  double *sensorValueChangeTrigger);

/**
 * @brief The voltage value
 *
 * The most recent voltage value that the channel has reported.
 *
 * *   This value will always be between @ref PhidgetVoltageInput_getMinVoltage() and @ref
 *     PhidgetVoltageInput_getMaxVoltage().
 *
 * @param[in] ch The channel handle
 * @param[out] voltage The voltage value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetVoltageInput_getVoltage(PhidgetVoltageInputHandle ch,
  double *voltage);

/**
 * @brief The voltage value
 *
 * The minimum value the @ref PhidgetVoltageInput_setOnVoltageChangeHandler() event will report.
 *
 * @param[in] ch The channel handle
 * @param[out] minVoltage The voltage value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetVoltageInput_getMinVoltage(PhidgetVoltageInputHandle ch,
  double *minVoltage);

/**
 * @brief The voltage value
 *
 * The maximum value the @ref PhidgetVoltageInput_setOnVoltageChangeHandler() event will report.
 *
 * @param[in] ch The channel handle
 * @param[out] maxVoltage The voltage value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetVoltageInput_getMaxVoltage(PhidgetVoltageInputHandle ch,
  double *maxVoltage);

/**
 * @brief The change trigger value
 *
 * The channel will not issue a @ref PhidgetVoltageInput_setOnVoltageChangeHandler() event until the
 * voltage value has changed by the amount specified by the `VoltageChangeTrigger`.
 *
 * *   Setting the `VoltageChangeTrigger` to 0 will result in the channel firing events every
 *     `DataInterval`. This is useful for applications that implement their own data filtering
 *
 * @param[in] ch The channel handle
 * @param[in] voltageChangeTrigger The change trigger value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetVoltageInput_setVoltageChangeTrigger(PhidgetVoltageInputHandle ch,
  double voltageChangeTrigger);

/**
 * @brief The change trigger value
 *
 * The channel will not issue a @ref PhidgetVoltageInput_setOnVoltageChangeHandler() event until the
 * voltage value has changed by the amount specified by the `VoltageChangeTrigger`.
 *
 * *   Setting the `VoltageChangeTrigger` to 0 will result in the channel firing events every
 *     `DataInterval`. This is useful for applications that implement their own data filtering
 *
 * @param[in] ch The channel handle
 * @param[out] voltageChangeTrigger The change trigger value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetVoltageInput_getVoltageChangeTrigger(PhidgetVoltageInputHandle ch,
  double *voltageChangeTrigger);

/**
 * @brief The change trigger value
 *
 * The minimum value that `VoltageChangeTrigger` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minVoltageChangeTrigger The change trigger value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetVoltageInput_getMinVoltageChangeTrigger(PhidgetVoltageInputHandle ch,
  double *minVoltageChangeTrigger);

/**
 * @brief The change trigger value
 *
 * The maximum value that `VoltageChangeTrigger` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxVoltageChangeTrigger The change trigger value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetVoltageInput_getMaxVoltageChangeTrigger(PhidgetVoltageInputHandle ch,
  double *maxVoltageChangeTrigger);

/**
 * @brief The voltage range value
 *
 * The voltage range you choose should allow you to measure the full range of your input signal.
 *
 * *   A larger `VoltageRange` equates to less resolution.
 * *   If a @ref EEPHIDGET_SATURATION event occurs, increase the voltage range.
 *
 * @param[in] ch The channel handle
 * @param[in] voltageRange The voltage range value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetVoltageInput_setVoltageRange(PhidgetVoltageInputHandle ch,
  PhidgetVoltageInput_VoltageRange voltageRange);

/**
 * @brief The voltage range value
 *
 * The voltage range you choose should allow you to measure the full range of your input signal.
 *
 * *   A larger `VoltageRange` equates to less resolution.
 * *   If a @ref EEPHIDGET_SATURATION event occurs, increase the voltage range.
 *
 * @param[in] ch The channel handle
 * @param[out] voltageRange The voltage range value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetVoltageInput_getVoltageRange(PhidgetVoltageInputHandle ch,
  PhidgetVoltageInput_VoltageRange *voltageRange);

/**
 * @brief Callback function type for PhidgetVoltageInput_setOnSensorChangeHandler().
 *
 * @param[in] ch The channel handle
 * @param[in] ctx Pointer to the user context
 * @param[in] sensorValue The sensor value
 * @param[in] sensorUnit The sensor unit information corresponding to the sensor value. *
 *     Helps keep track of the type of information being calculated from the voltage input
 */
typedef void (CCONV *PhidgetVoltageInput_OnSensorChangeCallback)(PhidgetVoltageInputHandle ch, void *ctx,
  double sensorValue, Phidget_UnitInfo *sensorUnit);

/**
 * The most recent sensor value the channel has measured will be reported in this event, which
 * occurs when the `DataInterval` has elapsed.
 *
 * *   If a `SensorValueChangeTrigger` has been set to a non-zero value, the @ref
 *     PhidgetVoltageInput_setOnSensorChangeHandler() event will not occur until the sensor value
 *     has changed by at least the `SensorValueChangeTrigger` value.
 * *   This event only fires when `SensorType` is not set to @ref SENSOR_TYPE_VOLTAGE
 *
 * @param[in] ch The channel handle
 * @param[in] fptr The event handler callback function
 * @param[in] ctx User supplied context pointer
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetVoltageInput_setOnSensorChangeHandler(PhidgetVoltageInputHandle ch,
  PhidgetVoltageInput_OnSensorChangeCallback fptr, void *ctx);

/**
 * @brief Callback function type for PhidgetVoltageInput_setOnVoltageChangeHandler().
 *
 * @param[in] ch The channel handle
 * @param[in] ctx Pointer to the user context
 * @param[in] voltage Measured voltage
 */
typedef void (CCONV *PhidgetVoltageInput_OnVoltageChangeCallback)(PhidgetVoltageInputHandle ch, void *ctx,
  double voltage);

/**
 * The most recent voltage value the channel has measured will be reported in this event, which
 * occurs when the `DataInterval` has elapsed.
 *
 * *   If a `VoltageChangeTrigger` has been set to a non-zero value, the @ref
 *     PhidgetVoltageInput_setOnVoltageChangeHandler() event will not occur until the voltage has
 *     changed by at least the `VoltageChangeTrigger` value.
 * *   If `SensorType` is supported and set to anything other then @ref SENSOR_TYPE_VOLTAGE,
 *     this event will not fire.
 *
 * @param[in] ch The channel handle
 * @param[in] fptr The event handler callback function
 * @param[in] ctx User supplied context pointer
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetVoltageInput_setOnVoltageChangeHandler(PhidgetVoltageInputHandle ch,
  PhidgetVoltageInput_OnVoltageChangeCallback fptr, void *ctx);

/** @} */ /* PhidgetVoltageInput */

/**
 * @defgroup PhidgetVoltageOutput VoltageOutput
 * @brief The Voltage Output class controls the variable DC voltage output on a Phidget board.
 *     This class provides settings for the output voltage as well as various safety controls.
 * @{
 */

/**
 * The Voltage Output class controls the variable DC voltage output on a Phidget board. This class
 * provides settings for the output voltage as well as various safety controls.
 */
typedef struct _PhidgetVoltageOutput *PhidgetVoltageOutputHandle;

/**
 * @ref PhidgetVoltageOutput_create() creates an instance of a Phidget channel. Once created the
 * channel may need to be configured to match the physical device and channel index you want to
 * attach to, and then be opened by calling @ref Phidget_open().
 * The Phidget channel handle must be released with @ref PhidgetVoltageOutput_delete().
 *
 * @param[out] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetVoltageOutput_create(PhidgetVoltageOutputHandle *ch);

/**
 * @ref PhidgetVoltageOutput_delete() releases a Phidget channel handle created with @ref
 * PhidgetVoltageOutput_create().
 * If the channel is open when @ref PhidgetVoltageOutput_delete() is called, it will be closed.
 *
 * @param[out] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetVoltageOutput_delete(PhidgetVoltageOutputHandle *ch);

/**
 * Enables the **failsafe** feature for the channel, with the specified **failsafe time**.
 *
 * Enabling the failsafe feature starts a recurring **failsafe timer** for the channel. Once the
 * failsafe is enabled, the timer must be reset within the specified time or the channel will enter
 * a **failsafe state**. For Voltage Output channels, this will set the output voltage to 0V. The
 * failsafe timer can be reset by using any of the following API calls:
 *
 * *   @ref PhidgetVoltageOutput_setEnabled()
 * *   @ref PhidgetVoltageOutput_setVoltage()
 * *   @ref PhidgetVoltageOutput_setVoltageOutputRange()
 * *   @ref PhidgetVoltageOutput_resetFailsafe()
 *
 * For more information about failsafe, visit our [Failsafe
 * Guide](https://www.phidgets.com/docs/Failsafe_Guide).
 *
 * @param[in] ch The channel handle
 * @param[in] failsafeTime Failsafe timeout in milliseconds
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetVoltageOutput_enableFailsafe(PhidgetVoltageOutputHandle ch,
  uint32_t failsafeTime);

/**
 * Resets the failsafe timer, if one has been set. See @ref PhidgetVoltageOutput_enableFailsafe()
 * for details.
 *
 * This function will fail if no failsafe timer has been set for the channel.
 *
 * @param[in] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetVoltageOutput_resetFailsafe(PhidgetVoltageOutputHandle ch);

/**
 * @brief The enabled value
 *
 * Enable the output voltage by setting `Enabled` to true.
 *
 * *   Disable the output by seting `Enabled` to false to save power.
 *
 * @param[in] ch The channel handle
 * @param[in] enabled The enabled value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetVoltageOutput_setEnabled(PhidgetVoltageOutputHandle ch,
  int enabled);

/**
 * @brief The enabled value
 *
 * Enable the output voltage by setting `Enabled` to true.
 *
 * *   Disable the output by seting `Enabled` to false to save power.
 *
 * @param[in] ch The channel handle
 * @param[out] enabled The enabled value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetVoltageOutput_getEnabled(PhidgetVoltageOutputHandle ch,
  int *enabled);

/**
 * @brief The failsafe time
 *
 * The minimum value that `failsafeTime` can be set to when calling @ref
 * PhidgetVoltageOutput_enableFailsafe().
 *
 * @param[in] ch The channel handle
 * @param[out] minFailsafeTime The failsafe time
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetVoltageOutput_getMinFailsafeTime(PhidgetVoltageOutputHandle ch,
  uint32_t *minFailsafeTime);

/**
 * @brief The failsafe time
 *
 * The maximum value that `failsafeTime` can be set to when calling @ref
 * PhidgetVoltageOutput_enableFailsafe().
 *
 * @param[in] ch The channel handle
 * @param[out] maxFailsafeTime The failsafe time
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetVoltageOutput_getMaxFailsafeTime(PhidgetVoltageOutputHandle ch,
  uint32_t *maxFailsafeTime);

/**
 * @brief The voltage value
 *
 * The voltage value that the channel will output.
 *
 * *   The `Voltage` value is bounded by @ref PhidgetVoltageOutput_getMinVoltage() and @ref
 *     PhidgetVoltageOutput_getMaxVoltage().
 * *   The voltage value will not be output until `Enabled` is set to true.
 *
 * @param[in] ch The channel handle
 * @param[in] voltage The voltage value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetVoltageOutput_setVoltage(PhidgetVoltageOutputHandle ch,
  double voltage);

/**
 * @brief The voltage value
 *
 * The voltage value that the channel will output.
 *
 * *   The `Voltage` value is bounded by @ref PhidgetVoltageOutput_getMinVoltage() and @ref
 *     PhidgetVoltageOutput_getMaxVoltage().
 * *   The voltage value will not be output until `Enabled` is set to true.
 *
 * @param[in] ch The channel handle
 * @param[in] voltage The voltage value
 * @param[in] fptr Asynchronous completion callback
 * @param[in] ctx User supplied context pointer
 */
PHIDGET22_API void CCONV PhidgetVoltageOutput_setVoltage_async(PhidgetVoltageOutputHandle ch,
  double voltage, Phidget_AsyncCallback fptr, void *ctx);

/**
 * @brief The voltage value
 *
 * The voltage value that the channel will output.
 *
 * *   The `Voltage` value is bounded by @ref PhidgetVoltageOutput_getMinVoltage() and @ref
 *     PhidgetVoltageOutput_getMaxVoltage().
 * *   The voltage value will not be output until `Enabled` is set to true.
 *
 * @param[in] ch The channel handle
 * @param[out] voltage The voltage value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetVoltageOutput_getVoltage(PhidgetVoltageOutputHandle ch,
  double *voltage);

/**
 * @brief The voltage value
 *
 * The minimum value that `Voltage` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minVoltage The voltage value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetVoltageOutput_getMinVoltage(PhidgetVoltageOutputHandle ch,
  double *minVoltage);

/**
 * @brief The voltage value
 *
 * The maximum value that `Voltage` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxVoltage The voltage value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetVoltageOutput_getMaxVoltage(PhidgetVoltageOutputHandle ch,
  double *maxVoltage);

/**
 * @brief The output range value
 *
 * Choose a `VoltageOutputRange` that best suits your application.
 *
 * *   Changing the `VoltageOutputRange` will also affect the @ref
 *     PhidgetVoltageOutput_getMinVoltage() and @ref PhidgetVoltageOutput_getMaxVoltage() values.
 *
 * @param[in] ch The channel handle
 * @param[in] voltageOutputRange The output range value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetVoltageOutput_setVoltageOutputRange(PhidgetVoltageOutputHandle ch,
  PhidgetVoltageOutput_VoltageOutputRange voltageOutputRange);

/**
 * @brief The output range value
 *
 * Choose a `VoltageOutputRange` that best suits your application.
 *
 * *   Changing the `VoltageOutputRange` will also affect the @ref
 *     PhidgetVoltageOutput_getMinVoltage() and @ref PhidgetVoltageOutput_getMaxVoltage() values.
 *
 * @param[in] ch The channel handle
 * @param[out] voltageOutputRange The output range value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetVoltageOutput_getVoltageOutputRange(PhidgetVoltageOutputHandle ch,
  PhidgetVoltageOutput_VoltageOutputRange *voltageOutputRange);

/** @} */ /* PhidgetVoltageOutput */

/**
 * @defgroup PhidgetVoltageRatioInput VoltageRatioInput
 * @brief The Voltage Ratio Input class is used for measuring the ratio between the voltage
 *     supplied to and the voltage returned from an attached sensor or device. This is useful for
 *     interfacing with ratiometric sensors or wheatstone bridge based sensors.
 * @{
 */

/**
 * The Voltage Ratio Input class is used for measuring the ratio between the voltage supplied to and
 * the voltage returned from an attached sensor or device. This is useful for interfacing with
 * ratiometric sensors or wheatstone bridge based sensors.
 *
 * For ratiometric sensors, this class supports conversion to sensor data with units specific to the
 * Phidget sensor being used, to make reading these sensors easy.
 */
typedef struct _PhidgetVoltageRatioInput *PhidgetVoltageRatioInputHandle;

/**
 * @ref PhidgetVoltageRatioInput_create() creates an instance of a Phidget channel. Once created the
 * channel may need to be configured to match the physical device and channel index you want to
 * attach to, and then be opened by calling @ref Phidget_open().
 * The Phidget channel handle must be released with @ref PhidgetVoltageRatioInput_delete().
 *
 * @param[out] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetVoltageRatioInput_create(PhidgetVoltageRatioInputHandle *ch);

/**
 * @ref PhidgetVoltageRatioInput_delete() releases a Phidget channel handle created with @ref
 * PhidgetVoltageRatioInput_create().
 * If the channel is open when @ref PhidgetVoltageRatioInput_delete() is called, it will be closed.
 *
 * @param[out] ch The channel handle
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetVoltageRatioInput_delete(PhidgetVoltageRatioInputHandle *ch);

/**
 * @brief The enabled value
 *
 * Enable power to the input and start collecting data by setting `BridgeEnabled` to true.
 *
 * @param[in] ch The channel handle
 * @param[in] bridgeEnabled The enabled value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetVoltageRatioInput_setBridgeEnabled(PhidgetVoltageRatioInputHandle ch,
  int bridgeEnabled);

/**
 * @brief The enabled value
 *
 * Enable power to the input and start collecting data by setting `BridgeEnabled` to true.
 *
 * @param[in] ch The channel handle
 * @param[out] bridgeEnabled The enabled value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetVoltageRatioInput_getBridgeEnabled(PhidgetVoltageRatioInputHandle ch,
  int *bridgeEnabled);

/**
 * @brief The bridge gain value
 *
 * Choose a `BridgeGain` that best suits your application.
 *
 * *   For more information about the range and accuracy of each `BridgeGain` to decide which
 *     best suits your application, see your device's User Guide.
 *
 * @param[in] ch The channel handle
 * @param[in] bridgeGain The bridge gain value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetVoltageRatioInput_setBridgeGain(PhidgetVoltageRatioInputHandle ch,
  PhidgetVoltageRatioInput_BridgeGain bridgeGain);

/**
 * @brief The bridge gain value
 *
 * Choose a `BridgeGain` that best suits your application.
 *
 * *   For more information about the range and accuracy of each `BridgeGain` to decide which
 *     best suits your application, see your device's User Guide.
 *
 * @param[in] ch The channel handle
 * @param[out] bridgeGain The bridge gain value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetVoltageRatioInput_getBridgeGain(PhidgetVoltageRatioInputHandle ch,
  PhidgetVoltageRatioInput_BridgeGain *bridgeGain);

/**
 * @brief The data interval for the channel
 *
 * The `DataInterval` is the time that must elapse before the channel will fire another event.
 *
 * *   The data interval is bounded by @ref PhidgetVoltageRatioInput_getMinDataInterval() and
 *     @ref PhidgetVoltageRatioInput_getMaxDataInterval().
 * *   The timing between events can also be affected by the change trigger.
 *
 * @param[in] ch The channel handle
 * @param[in] dataInterval The data interval for the channel
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetVoltageRatioInput_setDataInterval(PhidgetVoltageRatioInputHandle ch,
  uint32_t dataInterval);

/**
 * @brief The data interval for the channel
 *
 * The `DataInterval` is the time that must elapse before the channel will fire another event.
 *
 * *   The data interval is bounded by @ref PhidgetVoltageRatioInput_getMinDataInterval() and
 *     @ref PhidgetVoltageRatioInput_getMaxDataInterval().
 * *   The timing between events can also be affected by the change trigger.
 *
 * @param[in] ch The channel handle
 * @param[out] dataInterval The data interval for the channel
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetVoltageRatioInput_getDataInterval(PhidgetVoltageRatioInputHandle ch,
  uint32_t *dataInterval);

/**
 * @brief The data interval value
 *
 * The minimum value that `DataInterval` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minDataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetVoltageRatioInput_getMinDataInterval(PhidgetVoltageRatioInputHandle ch,
  uint32_t *minDataInterval);

/**
 * @brief The data interval value
 *
 * The maximum value that `DataInterval` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxDataInterval The data interval value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetVoltageRatioInput_getMaxDataInterval(PhidgetVoltageRatioInputHandle ch,
  uint32_t *maxDataInterval);

/**
 * @brief The data rate for the channel
 *
 * The `DataRate` is the frequency of events from the device.
 *
 * *   The data rate is bounded by @ref PhidgetVoltageRatioInput_getMinDataRate() and @ref
 *     PhidgetVoltageRatioInput_getMaxDataRate().
 * *   Changing `DataRate` will change the channel's `DataInterval` to a corresponding value,
 *     rounded to the nearest integer number of milliseconds.
 * *   The timing between events can also affected by the change trigger.
 *
 * @param[in] ch The channel handle
 * @param[in] dataRate The data rate for the channel
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetVoltageRatioInput_setDataRate(PhidgetVoltageRatioInputHandle ch,
  double dataRate);

/**
 * @brief The data rate for the channel
 *
 * The `DataRate` is the frequency of events from the device.
 *
 * *   The data rate is bounded by @ref PhidgetVoltageRatioInput_getMinDataRate() and @ref
 *     PhidgetVoltageRatioInput_getMaxDataRate().
 * *   Changing `DataRate` will change the channel's `DataInterval` to a corresponding value,
 *     rounded to the nearest integer number of milliseconds.
 * *   The timing between events can also affected by the change trigger.
 *
 * @param[in] ch The channel handle
 * @param[out] dataRate The data rate for the channel
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetVoltageRatioInput_getDataRate(PhidgetVoltageRatioInputHandle ch,
  double *dataRate);

/**
 * @brief The data rate value
 *
 * The minimum value that `DataRate` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minDataRate The data rate value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetVoltageRatioInput_getMinDataRate(PhidgetVoltageRatioInputHandle ch,
  double *minDataRate);

/**
 * @brief The data rate value
 *
 * The maximum value that `DataRate` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxDataRate The data rate value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetVoltageRatioInput_getMaxDataRate(PhidgetVoltageRatioInputHandle ch,
  double *maxDataRate);

/**
 * @brief The sensor type value
 *
 * We sell a variety of analog sensors that do not have their own API, they simply output a voltage
 * that can be converted to a digital value using a specific formula. By matching the `SensorType`
 * to your analog sensor, the correct formula will automatically be applied to data when you get the
 * @ref PhidgetVoltageRatioInput_getSensorValue() or subscribe to the @ref
 * PhidgetVoltageRatioInput_setOnSensorChangeHandler() event.
 *
 * *   The @ref PhidgetVoltageRatioInput_setOnSensorChangeHandler() event has its own change
 *     trigger associated with it: `SensorValueChangeTrigger`.
 * *   Any data from getting the @ref PhidgetVoltageRatioInput_getSensorValue() or subscribing
 *     to the @ref PhidgetVoltageRatioInput_setOnSensorChangeHandler() event will have a @ref
 *     PhidgetVoltageRatioInput_getSensorUnit() associated with it.
 *
 * **Note:** Unlike other properties such as `DeviceSerialNumber` or `Channel`, `SensorType` is set
 * after the device is opened, not before.
 *
 * @param[in] ch The channel handle
 * @param[in] sensorType The sensor type value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetVoltageRatioInput_setSensorType(PhidgetVoltageRatioInputHandle ch,
  PhidgetVoltageRatioInput_SensorType sensorType);

/**
 * @brief The sensor type value
 *
 * We sell a variety of analog sensors that do not have their own API, they simply output a voltage
 * that can be converted to a digital value using a specific formula. By matching the `SensorType`
 * to your analog sensor, the correct formula will automatically be applied to data when you get the
 * @ref PhidgetVoltageRatioInput_getSensorValue() or subscribe to the @ref
 * PhidgetVoltageRatioInput_setOnSensorChangeHandler() event.
 *
 * *   The @ref PhidgetVoltageRatioInput_setOnSensorChangeHandler() event has its own change
 *     trigger associated with it: `SensorValueChangeTrigger`.
 * *   Any data from getting the @ref PhidgetVoltageRatioInput_getSensorValue() or subscribing
 *     to the @ref PhidgetVoltageRatioInput_setOnSensorChangeHandler() event will have a @ref
 *     PhidgetVoltageRatioInput_getSensorUnit() associated with it.
 *
 * **Note:** Unlike other properties such as `DeviceSerialNumber` or `Channel`, `SensorType` is set
 * after the device is opened, not before.
 *
 * @param[in] ch The channel handle
 * @param[out] sensorType The sensor type value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetVoltageRatioInput_getSensorType(PhidgetVoltageRatioInputHandle ch,
  PhidgetVoltageRatioInput_SensorType *sensorType);

/**
 * @brief The sensor unit information corresponding to the @ref
 *     PhidgetVoltageRatioInput_getSensorValue().
 *
 * The unit of measurement that applies to the sensor values of the `SensorType` that has been
 * selected.
 *
 * *   Helps keep track of the type of information being calculated from the voltage ratio
 *     input.
 *
 * @param[in] ch The channel handle
 * @param[out] sensorUnit The sensor unit information corresponding to the @ref
 *     PhidgetVoltageRatioInput_getSensorValue()
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetVoltageRatioInput_getSensorUnit(PhidgetVoltageRatioInputHandle ch,
  Phidget_UnitInfo *sensorUnit);

/**
 * @brief The sensor value
 *
 * The most recent sensor value that the channel has reported.
 *
 * *   Use @ref PhidgetVoltageRatioInput_getSensorUnit() to get the measurement units that are
 *     associated with the @ref PhidgetVoltageRatioInput_getSensorValue()
 *
 * @param[in] ch The channel handle
 * @param[out] sensorValue The sensor value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetVoltageRatioInput_getSensorValue(PhidgetVoltageRatioInputHandle ch,
  double *sensorValue);

/**
 * @brief The change trigger value
 *
 * The channel will not issue a @ref PhidgetVoltageRatioInput_setOnSensorChangeHandler() event until
 * the sensor value has changed by the amount specified by the `SensorValueChangeTrigger`.
 *
 * *   Setting the `SensorValueChangeTrigger` to 0 will result in the channel firing events
 *     every `DataInterval`. This is useful for applications that implement their own data filtering
 *
 * @param[in] ch The channel handle
 * @param[in] sensorValueChangeTrigger The change trigger value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetVoltageRatioInput_setSensorValueChangeTrigger(PhidgetVoltageRatioInputHandle ch,
  double sensorValueChangeTrigger);

/**
 * @brief The change trigger value
 *
 * The channel will not issue a @ref PhidgetVoltageRatioInput_setOnSensorChangeHandler() event until
 * the sensor value has changed by the amount specified by the `SensorValueChangeTrigger`.
 *
 * *   Setting the `SensorValueChangeTrigger` to 0 will result in the channel firing events
 *     every `DataInterval`. This is useful for applications that implement their own data filtering
 *
 * @param[in] ch The channel handle
 * @param[out] sensorValueChangeTrigger The change trigger value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetVoltageRatioInput_getSensorValueChangeTrigger(PhidgetVoltageRatioInputHandle ch,
  double *sensorValueChangeTrigger);

/**
 * @brief The voltage ratio value
 *
 * The most recent voltage ratio value that the channel has reported.
 *
 * *   This value will always be between @ref PhidgetVoltageRatioInput_getMinVoltageRatio() and
 *     @ref PhidgetVoltageRatioInput_getMaxVoltageRatio().
 *
 * @param[in] ch The channel handle
 * @param[out] voltageRatio The voltage ratio value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetVoltageRatioInput_getVoltageRatio(PhidgetVoltageRatioInputHandle ch,
  double *voltageRatio);

/**
 * @brief The voltage ratio value
 *
 * The minimum value the @ref PhidgetVoltageRatioInput_setOnVoltageRatioChangeHandler() event will
 * report.
 *
 * @param[in] ch The channel handle
 * @param[out] minVoltageRatio The voltage ratio value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetVoltageRatioInput_getMinVoltageRatio(PhidgetVoltageRatioInputHandle ch,
  double *minVoltageRatio);

/**
 * @brief The voltage ratio value
 *
 * The maximum value the @ref PhidgetVoltageRatioInput_setOnVoltageRatioChangeHandler() event will
 * report.
 *
 * @param[in] ch The channel handle
 * @param[out] maxVoltageRatio The voltage ratio value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetVoltageRatioInput_getMaxVoltageRatio(PhidgetVoltageRatioInputHandle ch,
  double *maxVoltageRatio);

/**
 * @brief The change trigger value
 *
 * The channel will not issue a @ref PhidgetVoltageRatioInput_setOnVoltageRatioChangeHandler() event
 * until the voltage ratio value has changed by the amount specified by the
 * `VoltageRatioChangeTrigger`.
 *
 * *   Setting the `VoltageRatioChangeTrigger` to 0 will result in the channel firing events
 *     every `DataInterval`. This is useful for applications that implement their own data filtering
 *
 * @param[in] ch The channel handle
 * @param[in] voltageRatioChangeTrigger The change trigger value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetVoltageRatioInput_setVoltageRatioChangeTrigger(PhidgetVoltageRatioInputHandle ch,
  double voltageRatioChangeTrigger);

/**
 * @brief The change trigger value
 *
 * The channel will not issue a @ref PhidgetVoltageRatioInput_setOnVoltageRatioChangeHandler() event
 * until the voltage ratio value has changed by the amount specified by the
 * `VoltageRatioChangeTrigger`.
 *
 * *   Setting the `VoltageRatioChangeTrigger` to 0 will result in the channel firing events
 *     every `DataInterval`. This is useful for applications that implement their own data filtering
 *
 * @param[in] ch The channel handle
 * @param[out] voltageRatioChangeTrigger The change trigger value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetVoltageRatioInput_getVoltageRatioChangeTrigger(PhidgetVoltageRatioInputHandle ch,
  double *voltageRatioChangeTrigger);

/**
 * @brief The change trigger value
 *
 * The minimum value that `VoltageRatioChangeTrigger` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] minVoltageRatioChangeTrigger The change trigger value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetVoltageRatioInput_getMinVoltageRatioChangeTrigger(PhidgetVoltageRatioInputHandle ch,
  double *minVoltageRatioChangeTrigger);

/**
 * @brief The change trigger value
 *
 * The maximum value that `VoltageRatioChangeTrigger` can be set to.
 *
 * @param[in] ch The channel handle
 * @param[out] maxVoltageRatioChangeTrigger The change trigger value
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetVoltageRatioInput_getMaxVoltageRatioChangeTrigger(PhidgetVoltageRatioInputHandle ch,
  double *maxVoltageRatioChangeTrigger);

/**
 * @brief Callback function type for PhidgetVoltageRatioInput_setOnSensorChangeHandler().
 *
 * @param[in] ch The channel handle
 * @param[in] ctx Pointer to the user context
 * @param[in] sensorValue The sensor value
 * @param[in] sensorUnit The sensor unit information corresponding to the @ref
 *     PhidgetVoltageRatioInput_getSensorValue(). *   Helps keep track of the type of information
 *     being calculated from the voltage ratio input
 */
typedef void (CCONV *PhidgetVoltageRatioInput_OnSensorChangeCallback)(PhidgetVoltageRatioInputHandle ch,
  void *ctx, double sensorValue, Phidget_UnitInfo *sensorUnit);

/**
 * The most recent sensor value the channel has measured will be reported in this event, which
 * occurs when the `DataInterval` has elapsed.
 *
 * *   If a `SensorValueChangeTrigger` has been set to a non-zero value, the @ref
 *     PhidgetVoltageRatioInput_setOnSensorChangeHandler() event will not occur until the sensor
 *     value has changed by at least the `SensorValueChangeTrigger` value.
 * *   This event only fires when `SensorType` is not set to @ref SENSOR_TYPE_VOLTAGERATIO
 *
 * @param[in] ch The channel handle
 * @param[in] fptr The event handler callback function
 * @param[in] ctx User supplied context pointer
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetVoltageRatioInput_setOnSensorChangeHandler(PhidgetVoltageRatioInputHandle ch,
  PhidgetVoltageRatioInput_OnSensorChangeCallback fptr, void *ctx);

/**
 * @brief Callback function type for PhidgetVoltageRatioInput_setOnVoltageRatioChangeHandler().
 *
 * @param[in] ch The channel handle
 * @param[in] ctx Pointer to the user context
 * @param[in] voltageRatio The voltage ratio
 */
typedef void (CCONV *PhidgetVoltageRatioInput_OnVoltageRatioChangeCallback)(PhidgetVoltageRatioInputHandle ch,
  void *ctx, double voltageRatio);

/**
 * The most recent voltage ratio value the channel has measured will be reported in this event,
 * which occurs when the `DataInterval` has elapsed.
 *
 * *   If a `VoltageRatioChangeTrigger` has been set to a non-zero value, the @ref
 *     PhidgetVoltageRatioInput_setOnVoltageRatioChangeHandler() event will not occur until the
 *     voltage has changed by at least the `VoltageRatioChangeTrigger` value.
 * *   If `SensorType` is supported and set to anything other than @ref
 *     SENSOR_TYPE_VOLTAGERATIO, this event will not fire.
 *
 * @param[in] ch The channel handle
 * @param[in] fptr The event handler callback function
 * @param[in] ctx User supplied context pointer
 * @return EPHIDGET_OK if the call succeeds, or an error code (@ref PhidgetReturnCode) if a
 *     failure occurs.
 */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetVoltageRatioInput_setOnVoltageRatioChangeHandler(PhidgetVoltageRatioInputHandle ch,
  PhidgetVoltageRatioInput_OnVoltageRatioChangeCallback fptr, void *ctx);

/** @} */ /* PhidgetVoltageRatioInput */

/* Enumerate VINT devices attached to a VINT hub */
/** @private */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_getChildDevices(PhidgetHandle dev, PhidgetHandle *arr, size_t *arrCnt);
/** @private */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_releaseDevices(PhidgetHandle *arr, size_t arrCnt);

#if defined(__APPLE__)
/* macOS system sleep / wake handlers */
/** @private */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_setOnWillSleepHandler(void(CCONV *fptr)(void *ctx), void *ctx);
/** @private */
PHIDGET22_API PhidgetReturnCode CCONV Phidget_setOnWakeupHandler(void(CCONV *fptr)(void *ctx), void *ctx);
#endif

/* Used by the network server */
/** @private */
PHIDGET22_API int CCONV Phidget_validDictionaryKey(const char *);
/** @private */
typedef void(CCONV *PhidgetDictionary_OnChangeCallback)(int, const char *, void *, int, const char *, const char *);
/** @private */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetDictionary_setOnChangeCallbackHandler(PhidgetDictionary_OnChangeCallback, void *);

/* Network Logging */
/** @private */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLog_enableNetwork(const char *address, int port);
/** @private */
PHIDGET22_API PhidgetReturnCode CCONV PhidgetLog_disableNetwork(void);

/* Device and Channel info strings */
/** @private */
PHIDGET22_API const char *CCONV deviceInfo(PhidgetHandle dev, char *buf, uint32_t buflen);
/** @private */
PHIDGET22_API const char *CCONV channelInfo(PhidgetHandle ch, char *buf, uint32_t buflen);

/* Enum to/from string conversion */
/** @private */
PHIDGET22_API const char *CCONV Phidget_enumString(const char *, int);
/** @private */
PHIDGET22_API int CCONV Phidget_enumFromString(const char *);

__END_DECLS

#endif /* PHIDGET22_H */
