Skip to content

This document provides example code and wiring instructions for each peripheral on the 9Mod MCPBoard. All examples are built on the emMCP framework. After registering a tool via emMCP_RegTool, the AI can directly control peripherals or read sensor data through voice commands.

TIP

For the complete project source code, refer to the example/9Mod_MCPBoard/ directory in the emMCP repository.


1. Onboard LED Control

Wiring

The onboard LED is connected to STM32 PC13. Drive high to turn on.

MCP Tool Registration

c
char* led_control_cb(mcp_server_tool_type_t type, void *param)
{
    char *param_str = (char *)param;
    cJSON *json = cJSON_Parse(param_str);
    cJSON *state = cJSON_GetObjectItem(json, "state");

    if (state && strcmp(state->valuestring, "on") == 0) {
        HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);
    } else {
        HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);
    }
    cJSON_Delete(json);
    return "{\"result\": \"ok\"}";
}

emMCP_param_t led_params[] = {
    {"state", "Switch state: on/off"}
};
emMCP_tool_t led_tool = {
    .name = "led_control",
    .description = "Control the onboard LED",
    .params = led_params,
    .param_count = 1,
    .callback = led_control_cb
};
emMCP_RegTool(&emMCP_dev, &led_tool);

Voice Commands

"Turn on the LED" "Turn off the LED"


2. Relay Control

Wiring

Relay TerminalDescription
NO (Normally Open)Open by default, closes when high
COM (Common)Connect to load line
GND / VCCOnboard, no external wiring needed

STM32 control pin: PB5 (active high).

MCP Tool Registration

c
// Same pattern as LED control
emMCP_param_t relay_params[] = {
    {"state", "Switch state: on/off"}
};
emMCP_tool_t relay_tool = {
    .name = "relay_control",
    .description = "Control the relay switch",
    .params = relay_params,
    .param_count = 1,
    .callback = relay_control_cb
};
emMCP_RegTool(&emMCP_dev, &relay_tool);

Voice Commands

"Turn on the relay" "Turn off the relay"


3. WS2812 LED Strip Control

Wiring

The WS2812 LED strip connects via the onboard 4-pin header:

WS2812 PinDescription
5VPower (onboard 5V output)
GNDGround
DINData input — PA11
DOUTData output (cascade to next LED)

Supports RGB color and brightness control.

MCP Tool Registration

c
emMCP_param_t led_strip_params[] = {
    {"red", "Red value 0-255"},
    {"green", "Green value 0-255"},
    {"blue", "Blue value 0-255"},
    {"brightness", "Brightness 0-255"}
};
emMCP_tool_t led_strip_tool = {
    .name = "led_control",
    .description = "Control WS2812 LED strip color and brightness",
    .params = led_strip_params,
    .param_count = 4,
    .callback = led_strip_cb
};
emMCP_RegTool(&emMCP_dev, &led_strip_tool);

Voice Commands

"Set the LED strip to red" "Set brightness to 50%" "Turn off the LED strip"


4. Radar Human Detection

Wiring

The Rd-03L_V2 mmWave radar module connects via a 4-pin header:

Radar ModuleSTM32 Pin
VCC3.3V
GNDGND
OUTPA8 (GPIO Input)

PA8 goes high when human presence is detected, low when empty.

MCP Tool Registration

c
char* radar_status_cb(mcp_server_tool_type_t type, void *param)
{
    uint8_t detected = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_8);
    char result[64];
    snprintf(result, sizeof(result),
        "{\"detected\": %s}",
        detected ? "true" : "false");
    static char ret_buf[64];
    strcpy(ret_buf, result);
    return ret_buf;
}

emMCP_param_t radar_params[] = {};
emMCP_tool_t radar_tool = {
    .name = "get_radar_status",
    .description = "Get radar human detection status",
    .params = radar_params,
    .param_count = 0,
    .callback = radar_status_cb
};
emMCP_RegTool(&emMCP_dev, &radar_tool);

Voice Commands

"Is anyone in the room?" "Check the radar status"


5. SHT30 Temperature & Humidity

Wiring

SHT30 shares the I²C bus (PB6(SCL) / PB7(SDA)) with the OLED and PD decoy, using separate device addresses:

DeviceI²C Address
SHT30 Temp/Humidity0x44
OLED SSD13060x3C
CH224K PD Decoy0x48

MCP Tool Registration

c
emMCP_param_t env_params[] = {};
emMCP_tool_t env_tool = {
    .name = "get_environment",
    .description = "Get ambient temperature and humidity",
    .params = env_params,
    .param_count = 0,
    .callback = get_environment_cb
};
emMCP_RegTool(&emMCP_dev, &env_tool);

Voice Commands

"What's the temperature and humidity?" "Check the current temperature"


6. IR Air Conditioner Control

Wiring

The HXD039B2 IR transmitter module connects via a 5-pin header:

IR ModuleSTM32 Pin
VCC5V
GNDGND
TXPB10 (USART3_TX)
RXPB11 (USART3_RX)

Baud rate 9600. Built-in IR code library for主流 brands (Gree, Midea).

MCP Tool Registration

c
emMCP_param_t ir_params[] = {
    {"brand", "AC brand: gree/midea"},
    {"action", "Action: on/off/temp_up/temp_down"},
    {"temperature", "Target temperature: 16-30"}
};
emMCP_tool_t ir_tool = {
    .name = "ir_control",
    .description = "IR air conditioner control",
    .params = ir_params,
    .param_count = 3,
    .callback = ir_control_cb
};
emMCP_RegTool(&emMCP_dev, &ir_tool);

Voice Commands

"Turn on the air conditioner" "Set the AC to 26 degrees" "Turn off the AC"


7. PD Decoy Power Control

Wiring

PD decoy uses a CH224K chip configured via I²C. Connect a PD charger to the Type-C port.

PD DecoySTM32 Pin
SCLPB6
SDAPB7
I²C Address0x48

MCP Tool Registration

c
emMCP_param_t pd_params[] = {
    {"voltage", "Target voltage: 5/9/12/15/20"}
};
emMCP_tool_t pd_tool = {
    .name = "pd_set_voltage",
    .description = "Set PD decoy output voltage",
    .params = pd_params,
    .param_count = 1,
    .callback = pd_voltage_cb
};
emMCP_RegTool(&emMCP_dev, &pd_tool);

Voice Commands

"Set PD output to 12V" "Boost PD to 20V"


8. OLED Display Control

Wiring

0.96" OLED (SSD1306, 128×64) connects via I²C:

OLEDSTM32 Pin
SCLPB6
SDAPB7
I²C Address0x3C

Onboard Chinese font chip (GT20L61S) supports Chinese characters, ASCII, and images.

MCP Tool Registration

c
emMCP_param_t oled_params[] = {
    {"text", "Text content to display"}
};
emMCP_tool_t oled_tool = {
    .name = "oled_display",
    .description = "Display text on the OLED screen",
    .params = oled_params,
    .param_count = 1,
    .callback = oled_display_cb
};
emMCP_RegTool(&emMCP_dev, &oled_tool);

Voice Commands

"Display 'Hello' on the OLED" "Show the current temperature on the screen"


9. Full Example: Register All Peripherals

c
void RegisterAllTools(void)
{
    emMCP_RegTool(&emMCP_dev, &led_tool);
    emMCP_RegTool(&emMCP_dev, &relay_tool);
    emMCP_RegTool(&emMCP_dev, &led_strip_tool);
    emMCP_RegTool(&emMCP_dev, &radar_tool);
    emMCP_RegTool(&emMCP_dev, &env_tool);
    emMCP_RegTool(&emMCP_dev, &ir_tool);
    emMCP_RegTool(&emMCP_dev, &pd_tool);
    emMCP_RegTool(&emMCP_dev, &oled_tool);
}

After registering all tools, call emMCP_RegistrationTools() once to sync all tool definitions to the AI platform.

Verification Method

  1. Compile check: Ensure the project compiles without errors
  2. Serial log: After flashing, connect the debug serial port (USART1, 115200). Say "Xiao An" (你好小安) to the module. You should see [DEBUG] emMCP_EventCallback: event:8 log output
  3. Tool sync: When tool_list transmission success appears in the serial log, it means the tools have been registered to the AI platform
  4. Functional test: Speak the corresponding voice commands from the examples to observe peripheral responses

Further Reading

Released under the MIT License.