GPIO を使用して Xiao ESP32S3 から reSpeaker Flex を制御する
目的
このガイドでは、I2C インターフェースを使用して XVF3800 ボイスプロセッサ上の GPIO ピンを読み取り・制御する方法 を説明します。ここでは次のことを学びます:
- GPI および GPO ピンの状態を読み取る
- GPIO のマッピングとその用途を理解する
| reSpeaker Flex XVF3800 Linear with XIAO ESP32S3 | reSpeaker Flex XVF3800 Circular with XIAO ESP32S3 | |
|---|---|---|
![]() | ![]() | |
GPIO の概要
| ピン名 | 方向 | 機能 |
|---|---|---|
| X1D09 | 入力 (RO) | ブートボタン状態 / GPI0 |
| X1D13 | 入力 (RO) | フローティング / GPI1 |
| X1D34 | 入力 (RO) | フローティング / GPI2 |
| X0D11 | 出力 (RW) | フローティング / GPO、SPI MOSI と共有 |
| X0D30 | 出力 (RW) | SD/FAULT 制御 |
| X0D31 | 出力 (RW) | PA / アンプ制御 |
| X0D32 | 出力 (RW) | XMOS GPIO 1 |
| X0D33 | 出力 (RW) | XMOS GPIO 2 |
| X0D39 | 出力 (RW) | フローティング / GPO、SPI MISO と共有 |
GPO ピン状態の読み取り
目的: 出力可能な GPIO(GPO) の論理レベルをすべて確認します。 コードのポイント:
- 次の設定で読み取り要求を送信します:
- リソース ID: 20 (GPO)
- コマンド ID: 0 (GPO_READ_VALUES)
- 5 つの GPO ピン状態を次の順序で読み取ります: X0D11 → X0D30 → X0D31 → X0D33 → X0D39
- 応答を検証するためのステータスバイトを含みます
#include <Wire.h>
#define XMOS_ADDR 0x2C // I2C 7-bit address
#define GPO_SERVICER_RESID 20
#define GPO_SERVICER_RESID_GPO_READ_VALUES 0
#define GPO_GPO_READ_NUM_BYTES 5
void setup() {
Serial.begin(115200);
while (!Serial);
Wire.begin();
delay(1000);
Serial.println("XVF3800 GPO Read Test Starting...");
}
void loop() {
uint8_t gpo_values[GPO_GPO_READ_NUM_BYTES] = {0};
uint8_t status = 0xFF;
bool success = read_gpo_values(gpo_values, &status);
if (success) {
Serial.print("I2C Communication SUCCESS. Status byte: 0x");
Serial.print(status, HEX);
Serial.print(" | GPO Output Values: ");
for (uint8_t i = 0; i < GPO_GPO_READ_NUM_BYTES; i++) {
Serial.print("0x");
Serial.print(gpo_values[i], HEX);
Serial.print(" ");
}
Serial.println();
} else {
Serial.println("Failed to read GPO values.");
}
delay(1000);
}
bool read_gpo_values(uint8_t *buffer, uint8_t *status) {
const uint8_t resid = GPO_SERVICER_RESID;
const uint8_t cmd = GPO_SERVICER_RESID_GPO_READ_VALUES | 0x80;
const uint8_t read_len = GPO_GPO_READ_NUM_BYTES;
// Step 1: Write command
Wire.beginTransmission(XMOS_ADDR);
Wire.write(resid);
Wire.write(cmd);
Wire.write(read_len + 1);
uint8_t result = Wire.endTransmission();
if (result != 0) {
Serial.print("I2C Write Error: ");
Serial.println(result);
return false;
}
// Step 2: Read response (status + payload)
Wire.requestFrom(XMOS_ADDR, (uint8_t)(read_len + 1));
if (Wire.available() < read_len + 1) {
Serial.println("I2C Read Error: Not enough data received.");
return false;
}
*status = Wire.read();
for (uint8_t i = 0; i < read_len; i++) {
buffer[i] = Wire.read();
}
return true;
}
GPI ピン状態の読み取り
目的: 入力可能な GPIO(例:ミュートボタンの状態)を確認します。 コードのポイント:
- 次の宛先にコマンドを送信します:
- リソース ID: 36 (IO_CONFIG)
- コマンド ID: 6 (GPI_VALUE_ALL)
- X1D09、X1D13、X1D34 の状態を表す 3 つの GPI を受信します
#include <Wire.h>
#define XMOS_ADDR 0x2C // I2C 7-bit address of XVF3800
// Resource and command IDs for GPI
#define IO_CONFIG_SERVICER_RESID 36
#define IO_CONFIG_SERVICER_RESID_GPI_READ_VALUES 0
#define GPI_READ_NUM_BYTES 3 // From header: IO_CONFIG_SERVICER_RESID_GPI_READ_VALUES_NUM_VALUES
void setup() {
Serial.begin(115200);
while (!Serial);
Wire.begin();
delay(1000);
Serial.println("XVF3800 GPI Read Test Starting...");
}
void loop() {
uint8_t gpi_values[GPI_READ_NUM_BYTES] = {0};
uint8_t status = 0xFF;
bool success = read_gpi_values(gpi_values, &status);
if (success) {
Serial.print("I2C Communication SUCCESS. Status byte: 0x");
Serial.print(status, HEX);
Serial.print(" | GPI Input Values: ");
for (uint8_t i = 0; i < GPI_READ_NUM_BYTES; i++) {
Serial.print("0x");
Serial.print(gpi_values[i], HEX);
Serial.print(" ");
}
Serial.println();
} else {
Serial.println("Failed to read GPI values.");
}
delay(1000);
}
bool read_gpi_values(uint8_t *buffer, uint8_t *status) {
const uint8_t resid = IO_CONFIG_SERVICER_RESID;
const uint8_t cmd = IO_CONFIG_SERVICER_RESID_GPI_READ_VALUES | 0x80; // Read command
const uint8_t read_len = GPI_READ_NUM_BYTES;
// Step 1: Send the command
Wire.beginTransmission(XMOS_ADDR);
Wire.write(resid);
Wire.write(cmd);
Wire.write(read_len + 1); // +1 for status byte
uint8_t result = Wire.endTransmission();
if (result != 0) {
Serial.print("I2C Write Error: ");
Serial.println(result);
return false;
}
// Step 2: Read response (status + payload)
Wire.requestFrom(XMOS_ADDR, (uint8_t)(read_len + 1));
if (Wire.available() < read_len + 1) {
Serial.println("I2C Read Error: Not enough data received.");
return false;
}
*status = Wire.read(); // first byte is status
for (uint8_t i = 0; i < read_len; i++) {
buffer[i] = Wire.read();
}
return true;
}
ブートボタンを押すと、状態が変化します。

技術サポート & 製品ディスカッション
弊社製品をお選びいただきありがとうございます。私たちは、製品をできるだけスムーズにご利用いただけるよう、さまざまなサポートを提供しています。お好みやニーズに合わせて選べる複数のコミュニケーションチャネルをご用意しています。

