External IO Control API¶
Functions in xm_api_external_io.h for controlling the Extension Port. You can read external sensor values or control digital devices in a style similar to Arduino. The default configuration is 8 DIO + 4 ADC channels; if needed, DIO pins can be dynamically switched to ADC mode to expand up to 12 analog input channels.
Board pin locations and labels may vary by board revision. Refer to the Hardware Pinmap — Rev 1.1 / Rev 2.0 for physical details. This page focuses on how to use the functions.
Pin Overview¶
| API Name | Type | Notes |
|---|---|---|
XM_EXT_DIO_1 ~ XM_EXT_DIO_8 |
Digital I/O | All 8 pins can be dynamically switched to ADC |
XM_EXT_ADC_1 ~ XM_EXT_ADC_4 |
Analog input (fixed) | 0–3.3 V, 10 kHz sampling |
XM_EXT_ADC_5 ~ XM_EXT_ADC_12 |
Analog input (dynamic) | Available after calling XM_SwitchDioToAdc() |
For PCB labels, header locations, and pin assignments, see the hardware pinmap documentation.
Note on External IMU Usage¶
When you enable an external IMU (XSENS MTi-630) by calling XM_AttachXsensMTi630(), some ADC pins on Rev 1.1 are reassigned for UART communication. (Rev 2.0 uses a dedicated USART2 port, so no ADC pins are occupied.) Which pins are affected depends on the board revision — see the "Note on External IMU Usage" section in the relevant pinmap documentation.
Data Structures¶
Pin Identifiers¶
XmDioPin_t¶
typedef enum {
XM_EXT_DIO_1 = 0,
XM_EXT_DIO_2,
XM_EXT_DIO_3,
XM_EXT_DIO_4,
XM_EXT_DIO_5,
XM_EXT_DIO_6,
XM_EXT_DIO_7,
XM_EXT_DIO_8,
XM_EXT_DIO_COUNT
} XmDioPin_t;
XmAdcPin_t¶
typedef enum {
XM_EXT_ADC_1 = 0,
XM_EXT_ADC_2,
XM_EXT_ADC_3,
XM_EXT_ADC_4,
/* Available after dynamic DIO → ADC switch (requires XM_SwitchDioToAdc call) */
XM_EXT_ADC_5, // DIO 1 → ADC
XM_EXT_ADC_6, // DIO 2 → ADC
XM_EXT_ADC_7, // DIO 3 → ADC
XM_EXT_ADC_8, // DIO 4 → ADC
XM_EXT_ADC_9, // DIO 5 → ADC
XM_EXT_ADC_10, // DIO 6 → ADC
XM_EXT_ADC_11, // DIO 7 → ADC
XM_EXT_ADC_12, // DIO 8 → ADC
XM_EXT_ADC_COUNT
} XmAdcPin_t;
Configuration Types¶
XmPinMode_t¶
Determines the operating mode of a pin. Used with the XM_SetPinMode function.
typedef enum {
XM_EXT_DIO_MODE_INPUT, /**< Digital input (floating) */
XM_EXT_DIO_MODE_INPUT_PULLUP, /**< Digital input (internal pull-up resistor) */
XM_EXT_DIO_MODE_INPUT_PULLDOWN, /**< Digital input (internal pull-down resistor) */
XM_EXT_DIO_MODE_OUTPUT /**< Digital output */
} XmPinMode_t;
| Mode | Description |
|---|---|
XM_EXT_DIO_MODE_INPUT |
Digital input (default). Leaves the pin in a floating state. |
XM_EXT_DIO_MODE_INPUT_PULLUP |
Pull-up input. Connects the pin to 3.3 V through an internal resistor. Useful when connecting switches. |
XM_EXT_DIO_MODE_INPUT_PULLDOWN |
Pull-down input. Connects the pin to 0 V through an internal resistor. |
XM_EXT_DIO_MODE_OUTPUT |
Digital output. Drives 0 V or 3.3 V. (5 V output is possible with hardware modification.) |
XmLogicLevel_t¶
Represents the level of a digital signal.
3. Function Reference¶
3.1. Configuration Function¶
XM_SetPinMode¶
Sets the operating mode (input / output / analog) of a pin. Must be called before using the pin.
- Syntax
- Parameters
pin: Pin to configure (XM_EXT_DIO_1\~8)mode: Operating mode (XM_EXT_DIO_MODE_INPUT,XM_EXT_DIO_MODE_INPUT_PULLUP,XM_EXT_DIO_MODE_INPUT_PULLDOWN,XM_EXT_DIO_MODE_OUTPUT)
- Note: This is a non-real-time function. It calls
HAL_GPIO_Initinternally, so do not call it inside the 1 ms real-time control loop (1 kHz). Configure pins once inControl_Setup(). - Example
3.2. Digital I/O Functions¶
XM_DigitalWrite¶
Drives a digital pin high or low. Only effective when the pin is in XM_EXT_DIO_MODE_OUTPUT mode.
- Syntax
- Parameters
pin: Target pinlevel:XM_HIGH(3.3 V) orXM_LOW(0 V)
- Example
XM_DigitalRead¶
Reads the current voltage state of a digital pin.
- Syntax
- Returns:
XM_HIGH(input is near 3.3 V) orXM_LOW(input is near 0 V) - Example
3.3. Analog I/O Functions¶
XM_AnalogRead¶
Reads the pin voltage as a 16-bit integer.
- Syntax
- Returns: 0 \~ 65535 (maps to 0 V \~ 3.3 V; 16-bit by default)
- Note: Even if the hardware ADC resolution is 12-bit, the API always returns a 16-bit normalized value. Use
XM_SetAnalogReadResolution()to change the output resolution.
XM_AnalogReadMillivolts¶
Reads the pin voltage in millivolts (mV).
- Syntax
- Returns: 0 ~ 3300 (mV)
XM_SetAnalogReadResolution¶
Sets the output resolution of XM_AnalogRead.
- Syntax
- Parameters
bits: Desired resolution in bits (8, 10, 12, or 16)
- Example
XM_GetAnalogResolution¶
Returns the hardware-native resolution of the specified ADC pin.
- Syntax
- Parameters:
pin— ADC pin to query - Returns: Native resolution of that ADC channel (in bits)
- Example
XM_GetAnalogReadResolution¶
Returns the current output resolution of XM_AnalogRead. Reflects the value set by XM_SetAnalogReadResolution().
- Syntax
- Returns: Current output resolution in bits (default: 16)
3.4. DIO ↔ ADC Dynamic Switch Functions (new in v2.0.0)¶
Switch DIO pins to ADC mode at runtime, enabling up to 12 analog input channels (8 DIO + 4 fixed ADC).
XM_SwitchDioToAdc¶
Switches a specific DIO pin to ADC mode.
- Syntax
- Parameters
pin: DIO pin to switch to ADC
- Returns:
true(switch successful),false(pin not supported) - Example
XM_SwitchAllDioToAdc¶
Switches all DIO pins to ADC mode at once.
- Syntax
- Returns:
true(switch successful)
XM_IsDioSwitchedToAdc¶
Checks whether a specific DIO pin is currently in ADC mode.
- Syntax
- Returns:
true(ADC mode),false(DIO mode)
XM_DIO_TO_ADC_PIN (macro)¶
Converts a DIO pin identifier to the corresponding ADC pin identifier. Use this with XM_AnalogRead() after calling XM_SwitchDioToAdc().
- Syntax
3.5. External IMU Control¶
XM_AttachXsensMTi630 / XM_ConfigureXsensMTi630¶
Attaches an external IMU (XSENS MTi-630) to the External UART (USART2). After attaching, access IMU data through XM.status.ext_imu.*.
- Syntax
- Note:
XM_AttachXsensMTi630()is safe to call even when no sensor is connected — it activates automatically once the cable is plugged in. On Rev 1.1, attaching the IMU reassignsXM_EXT_ADC_1andXM_EXT_ADC_3to UART, making them unavailable for ADC use. (Rev 2.0 uses a dedicated USART2 port, so no ADC pins are affected.)
3.6. Extension Port Power (3.3V / 5V) (Rev 2.0)¶
Switches the sensor supply voltage of the extension port between 3.3V and 5V (board signal EXT_PWR_SEL_5V, PE3). To use an external sensor that runs on 5V (e.g. some EMG modules), switch to 5V in Control_Setup(). The default is 3.3V.
⚠️ This voltage powers the sensor. The ADC signal input range is always 0~3.3V, independent of the supply. If the output (signal) of a 5V-powered sensor exceeds 3.3V it can damage the ADC pin — keep the signal line within 0~3.3V and add a voltage divider if needed.
XM_SetExtPowerVoltage¶
- Syntax
- Parameters
voltage:XM_EXT_PWR_3V3(3.3V, default) orXM_EXT_PWR_5V(5V)
- Example
- Note: Extension-port voltage switching is confirmed on Rev 2.0.
Related Examples¶
| Example | Difficulty | External I/O Usage |
|---|---|---|
| 04_Ext_IO_Basic | Beginner | DIO input and output |
| 05_Ext_IO_analog | Beginner | Reading fixed ADC voltage |
| 05a_Ext_IO_DIO_to_ADC | Beginner | Single DIO → ADC switch |
| 05b_Ext_IO_FSR_8ch | Intermediate | Batch switch all 8 channels + resolution |
| 05c_Ext_IO_Mixed_ADC | Intermediate | Mixed fixed and dynamic ADC |
| 05d_Ext_IO_DIO_ADC_Hybrid | Advanced | Mixed GPIO and ADC mode |
| 06_Ext_IO_Safety_Switch | Intermediate | Safety switch interlock |
⚠️ Common Mistakes¶
| Symptom | Cause | Fix |
|---|---|---|
XM_EXT_ADC_1 or _3 always returns 0 mV |
XM_AttachXsensMTi630() is active and has claimed the pin for UART (Rev 1.1) |
On Rev 1.1: use XM_EXT_ADC_2 / XM_EXT_ADC_4 (PA0_C / PA1_C). On Rev 2.0: unaffected (dedicated USART2 port) |
GPIO not restored after SwitchDioToAdc |
ADC mode switch is permanent until reboot (by design) | Reset the board or power-cycle |
DigitalWrite(ADC-switched DIO, ...) has no effect |
Guard mechanism — intentional behavior | ADC pins must only be used through the ADC API |
| Raw value exceeds 255 with 8-bit resolution | SetAnalogReadResolution not called, or mV API used (resolution does not apply to mV reads) |
Call SetAnalogReadResolution(8) in setup |
| mV always reads 0 or 3300 with FSR voltage divider | Missing 10 kΩ pull-down resistor, or FSR short circuit | Wire as: FSR (3.3 V) — DIO pin — 10 kΩ — GND |
XM_DIO_TO_ADC_PIN does not compile |
Pin outside DIO 1–8 range used (e.g., DIO_9) | Macro is only valid for DIO_1 through DIO_8 |
| High ADC noise | Long wires or ground potential difference | Use short jumper wires, share a common GND, and add an external RC filter if needed |