719 lines
20 KiB
Markdown
719 lines
20 KiB
Markdown
# Avaota F1 开发日志 - Day 4:模拟麦克风配置
|
||
|
||
**版本**:v1.0
|
||
**日期**:2025-11-26
|
||
**主机环境**:Windows + Ubuntu 24.04 LTS
|
||
**目标平台**:Avaota F1 (全志 V821 / 32-bit RISC-V)
|
||
|
||
---
|
||
|
||
## 项目背景
|
||
|
||
根据 Day 3 的计划,原定配置 PDM 数字麦克风(DMIC)以实现音频采集功能。但在实际开发中发现,开发板使用的是**板载模拟麦克风**,通过芯片内部 Audio Codec 进行音频采集,而非独立的 PDM/DMIC 设备。
|
||
|
||
---
|
||
|
||
## 第一部分:硬件类型确认
|
||
|
||
### 1. 文档确认
|
||
|
||
查阅 [`MIC.md`](file:///d:/CodingProjects/Antigravity/AvaotaF1/MIC.md) 文档后确认:
|
||
|
||
**硬件配置**:
|
||
- **麦克风类型**:模拟麦克风(板载)
|
||
- **接口**:通过芯片内部 Audio Codec
|
||
- **ALSA 设备名称**:`hw:audiocodec` 或 `hw:0,0`
|
||
- **驱动**:`audiocodec` (已内置于内核)
|
||
|
||
**关键区别**:
|
||
|
||
| 项目 | 原计划 (PDM/DMIC) | 实际硬件 (模拟麦克风) |
|
||
|------|-------------------|----------------------|
|
||
| **接口** | PDM 数字信号 | 模拟信号 → ADC |
|
||
| **Device Tree** | 需配置 `&dmic` 节点 | 使用 `&codec` 节点 |
|
||
| **引脚配置** | 需 pinctrl 设置 | 无需额外引脚配置 |
|
||
| **ALSA 设备** | `hw:snddmic` | `hw:audiocodec` |
|
||
| **运行时配置** | 即插即用 | 需打开 MIC Switch |
|
||
|
||
**结论**:配置难度大幅降低,无需修改 Device Tree。
|
||
|
||
---
|
||
|
||
## 第二部分:Device Tree 验证
|
||
|
||
### 1. 检查现有配置
|
||
|
||
查看 [`board.dts`](file:///d:/CodingProjects/Antigravity/AvaotaF1/board.dts) 第 759-797 行:
|
||
|
||
```dts
|
||
&codec {
|
||
tx-hub-en;
|
||
rx-sync-en;
|
||
|
||
dac-vol = <63>; /* DAC 音量 */
|
||
dacl-vol = <160>; /* DAC L 音量 */
|
||
adc-vol = <160>; /* ✅ ADC 音量(麦克风采集)*/
|
||
lineout-gain = <31>; /* LINEOUT 增益 */
|
||
mic-gain = <31>; /* ✅ 麦克风增益(最大值)*/
|
||
adcdelaytime = <0>; /* ADC 延迟时间 */
|
||
|
||
pa-pin-max = <1>;
|
||
pa-pin-0 = <&pio PC 15 GPIO_ACTIVE_HIGH>;
|
||
pa-pin-level-0 = <1>;
|
||
pa-pin-msleep-0 = <0>;
|
||
|
||
status = "okay"; /* ✅ 已启用 */
|
||
};
|
||
|
||
&codec_plat {
|
||
status = "okay";
|
||
};
|
||
|
||
&codec_mach {
|
||
status = "okay";
|
||
soundcard-mach,cpu {
|
||
sound-dai = <&codec_plat>;
|
||
};
|
||
soundcard-mach,codec {
|
||
sound-dai = <&codec>;
|
||
};
|
||
};
|
||
```
|
||
|
||
**验证结果**:
|
||
- ✅ `&codec` 节点已启用(`status = "okay"`)
|
||
- ✅ `mic-gain` 已设置为 31(最大值)
|
||
- ✅ `adc-vol` 已配置为 160
|
||
- ✅ **无需修改 Device Tree**
|
||
|
||
---
|
||
|
||
## 第三部分:测试脚本开发
|
||
|
||
### 1. 创建自动化测试脚本
|
||
|
||
为了简化测试流程,创建了 [`test_mic.sh`](file:///d:/CodingProjects/Antigravity/AvaotaF1/src/test_mic.sh) 脚本:
|
||
|
||
**功能**:
|
||
1. 检查 ALSA 设备
|
||
2. 配置麦克风(打开 MIC Switch,设置 Gain)
|
||
3. 执行 5 秒录音测试
|
||
4. 播放录音验证
|
||
|
||
**关键命令**:
|
||
```bash
|
||
# 打开 MIC 开关(必须)
|
||
amixer -Dhw:audiocodec cset name="MIC Switch" 1
|
||
|
||
# 设置 MIC 增益
|
||
amixer -Dhw:audiocodec cset name="MIC Gain" 15
|
||
|
||
# 录音测试
|
||
arecord -D hw:audiocodec -f S16_LE -t wav -r 16000 -c 1 -d 5 /tmp/test_mic.wav
|
||
|
||
# 播放验证(使用 I2S 扬声器)
|
||
aplay -D hw:1,0 /tmp/test_mic.wav
|
||
```
|
||
|
||
---
|
||
|
||
## 第四部分:开发板测试
|
||
|
||
### 1. ALSA 设备验证
|
||
|
||
在开发板上检查音频设备:
|
||
|
||
```bash
|
||
root@(none):/# cat /proc/asound/cards
|
||
0 [audiocodec ]: audiocodec - audiocodec
|
||
audiocodec
|
||
1 [sndi2s0 ]: sndi2s0 - sndi2s0
|
||
sndi2s0
|
||
```
|
||
|
||
✅ **结果**:audiocodec (card 0) 和 sndi2s0 (card 1) 都已正常识别。
|
||
|
||
```bash
|
||
root@(none):/# arecord -l
|
||
**** List of CAPTURE Hardware Devices ****
|
||
card 0: audiocodec [audiocodec], device 0: ...
|
||
```
|
||
|
||
✅ **结果**:audiocodec 录音设备已注册。
|
||
|
||
---
|
||
|
||
### 2. 麦克风配置测试
|
||
|
||
执行配置命令:
|
||
|
||
```bash
|
||
# 打开 MIC 开关
|
||
root@(none):/# amixer -Dhw:audiocodec cset name="MIC Switch" 1
|
||
numid=16,iface=MIXER,name='MIC Switch'
|
||
; type=BOOLEAN,access=rw------,values=1
|
||
: values=on
|
||
|
||
# 设置初始增益为 15
|
||
root@(none):/# amixer -Dhw:audiocodec cset name="MIC Gain" 15
|
||
numid=15,iface=MIXER,name='MIC Gain'
|
||
; type=INTEGER,access=rw---R--,values=1,min=0,max=31,step=0
|
||
: values=15
|
||
```
|
||
|
||
✅ **结果**:MIC Switch 已打开,增益设置成功。
|
||
|
||
---
|
||
|
||
### 3. 录音测试(第一次)
|
||
|
||
```bash
|
||
root@(none):/# arecord -D hw:audiocodec -f S16_LE -t wav -r 16000 -c 1 -d 5 /tmp/test.wav
|
||
Recording WAVE 'stdin' : Signed 16 bit Little Endian, Rate 16000 Hz, Mono
|
||
|
||
root@(none):/# ls -lh /tmp/test.wav
|
||
-rw-r--r-- 1 root root 160.0K Nov 26 15:32 test.wav
|
||
|
||
root@(none):/# aplay -D hw:1,0 /tmp/test.wav
|
||
Playing WAVE '/tmp/test.wav' : Signed 16 bit Little Endian, Rate 16000 Hz, Mono
|
||
```
|
||
|
||
✅ **结果**:
|
||
- 录音成功,文件大小正常(160KB ≈ 5 秒 @ 16kHz)
|
||
- 播放时**有声音,听得清**
|
||
- **但声音很小**
|
||
|
||
---
|
||
|
||
### 4. 增益调优
|
||
|
||
**问题**:MIC Gain 15 时音量较小
|
||
**方案**:逐步增加增益值
|
||
|
||
#### 测试 1:MIC Gain = 25
|
||
|
||
```bash
|
||
root@(none):/# amixer -Dhw:audiocodec cset name="MIC Gain" 25
|
||
root@(none):/# arecord -D hw:audiocodec -f S16_LE -t wav -r 16000 -c 1 -d 5 /tmp/test2.wav
|
||
root@(none):/# aplay -D hw:1,0 /tmp/test2.wav
|
||
```
|
||
|
||
✅ **结果**:音量适中,清晰度良好
|
||
|
||
#### 测试 2:MIC Gain = 31 (最大值)
|
||
|
||
```bash
|
||
root@(none):/# amixer -Dhw:audiocodec cset name="MIC Gain" 31
|
||
root@(none):/# arecord -D hw:audiocodec -f S16_LE -t wav -r 16000 -c 1 -d 5 /tmp/test3.wav
|
||
root@(none):/# aplay -D hw:1,0 /tmp/test3.wav
|
||
```
|
||
|
||
✅ **结果**:音量最大,但有轻微底噪
|
||
|
||
**最佳配置**:**MIC Gain = 25**
|
||
- 音量适中
|
||
- 音质清晰
|
||
- 无明显杂音
|
||
|
||
---
|
||
|
||
## 第五部分:AudioCapture 集成
|
||
|
||
### 1. 验证设备名称
|
||
|
||
检查 [`test_audio.cpp`](file:///d:/CodingProjects/Antigravity/AvaotaF1/src/test_audio.cpp) 第 23 行:
|
||
|
||
```cpp
|
||
const char* DEVICE_NAME = "hw:0,0"; // audiocodec 是 card 0
|
||
```
|
||
|
||
✅ **兼容性**:
|
||
- `hw:0,0` 正确指向 audiocodec
|
||
- 也可以使用 `hw:audiocodec`(更明确)
|
||
|
||
---
|
||
|
||
### 2. 集成方案
|
||
|
||
在主程序 [`main.cpp`](file:///d:/CodingProjects/Antigravity/AvaotaF1/src/main.cpp) 的 `audio_capture_thread()` 中:
|
||
|
||
```cpp
|
||
void audio_capture_thread() {
|
||
LOG_INFO("Starting audio capture thread...");
|
||
|
||
// 1. 配置麦克风(打开 MIC 开关和增益)
|
||
system("amixer -Dhw:audiocodec cset name='MIC Switch' 1");
|
||
system("amixer -Dhw:audiocodec cset name='MIC Gain' 25");
|
||
|
||
// 2. 初始化音频采集
|
||
AudioCapture mic("hw:audiocodec", 16000, 1);
|
||
if (!mic.init()) {
|
||
LOG_ERROR("Failed to initialize microphone");
|
||
return;
|
||
}
|
||
|
||
// 3. 连接 WebSocket 服务器
|
||
WSClient ws_aud(SERVER_HOST, SERVER_PORT, "/ws_audio");
|
||
if (!ws_aud.connect()) {
|
||
LOG_ERROR("Failed to connect to audio WebSocket");
|
||
return;
|
||
}
|
||
|
||
// 4. 音频采集循环
|
||
int16_t buffer[320]; // 20ms @ 16kHz
|
||
while (g_running) {
|
||
snd_pcm_sframes_t frames = mic.read(buffer, 320);
|
||
if (frames > 0) {
|
||
// 发送音频数据到服务器
|
||
ws_aud.send_binary((uint8_t*)buffer, frames * 2);
|
||
}
|
||
}
|
||
|
||
LOG_INFO("Audio capture thread stopped");
|
||
}
|
||
```
|
||
|
||
**关键点**:
|
||
- 使用 `system()` 调用 `amixer` 配置(简单直接)
|
||
- 或者可以使用 ALSA Mixer API(更优雅)
|
||
|
||
---
|
||
|
||
## 第六部分:技术总结
|
||
|
||
### 1. 关键发现
|
||
|
||
**硬件差异**:
|
||
- 原计划:PDM 数字麦克风(DMIC)
|
||
- 实际硬件:模拟麦克风(Audio Codec ADC)
|
||
|
||
**配置方式**:
|
||
- Device Tree:✅ 已完整配置,无需修改
|
||
- 运行时:需通过 `amixer` 打开 MIC Switch
|
||
|
||
### 2. 配置要点
|
||
|
||
| 配置项 | 说明 | 推荐值 |
|
||
|--------|------|--------|
|
||
| **MIC Switch** | 麦克风开关 (必须打开) | `1` (on) |
|
||
| **MIC Gain** | 麦克风增益 (0-31) | `25` |
|
||
| **ADC Volume** | ADC 音量 (0-255) | `160` (默认) |
|
||
|
||
### 3. 音频参数
|
||
|
||
- **采样率**:16000 Hz (16kHz)
|
||
- **位深度**:16-bit signed PCM (S16_LE)
|
||
- **声道数**:1 (Mono)
|
||
- **ALSA 设备**:`hw:audiocodec` 或 `hw:0,0`
|
||
|
||
---
|
||
|
||
## 第七部分:问题与解决
|
||
|
||
### 问题 1:音量太小
|
||
|
||
**现象**:MIC Gain 15 时录音音量偏小
|
||
**原因**:初始增益设置过低
|
||
**解决**:增加 MIC Gain 到 25
|
||
|
||
### 问题 2:增益过高有杂音
|
||
|
||
**现象**:MIC Gain 31 时有轻微底噪
|
||
**原因**:增益过高放大了底噪
|
||
**解决**:降低到 25,平衡音量和音质
|
||
|
||
---
|
||
|
||
## 🏆 Day 4 成果
|
||
|
||
### 核心成就
|
||
|
||
1. ✅ **确认硬件类型**:模拟麦克风(非 PDM/DMIC)
|
||
2. ✅ **验证 Device Tree**:audiocodec 已完整配置
|
||
3. ✅ **创建测试脚本**:[`test_mic.sh`](file:///d:/CodingProjects/Antigravity/AvaotaF1/src/test_mic.sh)
|
||
4. ✅ **完成硬件测试**:录音功能正常
|
||
5. ✅ **调优增益参数**:MIC Gain = 25 (最佳)
|
||
6. ✅ **集成方案设计**:AudioCapture 集成代码
|
||
|
||
### 技术文档
|
||
|
||
- [MIC.md](file:///d:/CodingProjects/Antigravity/NaviGlass/NaviGlassClient/MIC.md) - 官方麦克风使用文档
|
||
- [board.dts](file:///d:/CodingProjects/Antigravity/NaviGlass/NaviGlassClient/board.dts) - Device Tree 配置
|
||
- [test_mic.sh](file:///d:/CodingProjects/Antigravity/NaviGlass/NaviGlassClient/src/test_mic.sh) - 自动化测试脚本
|
||
- [Microphone_Configuration_Complete.md](file:///d:/CodingProjects/Antigravity/NaviGlass/Docs/Microphone_Configuration_Complete.md) - 完整配置报告
|
||
|
||
### 测试结果
|
||
|
||
| 测试项 | 状态 | 备注 |
|
||
|--------|------|------|
|
||
| ALSA 设备识别 | ✅ 通过 | audiocodec (card 0) |
|
||
| MIC Switch 配置 | ✅ 通过 | amixer 控制正常 |
|
||
| 录音功能 | ✅ 通过 | 5 秒录音成功 |
|
||
| 音质测试 | ✅ 通过 | 清晰、无明显杂音 |
|
||
| 增益调优 | ✅ 完成 | MIC Gain = 25 最佳 |
|
||
|
||
### 配置完成度
|
||
|
||
**音频系统**:
|
||
- ✅ 音频播放(I2S + MAX98357A)- Day 3 完成
|
||
- ✅ 音频采集(模拟麦克风 + audiocodec)- Day 4 完成
|
||
- ⏳ 端到端集成(WebSocket + HTTP)- 待完成
|
||
|
||
**整体进度**:约 **60%** (+10%)
|
||
|
||
---
|
||
|
||
## 下一步计划
|
||
|
||
### 短期目标(Day 5)
|
||
|
||
1. **音频系统集成**
|
||
- 集成 MIC 配置到主程序
|
||
- WebSocket 音频上传测试
|
||
- HTTP TTS 下载播放测试
|
||
- 完整语音对话闭环验证
|
||
|
||
2. **或进入摄像头开发**(取决于优先级)
|
||
- GC2083 摄像头配置
|
||
- MPP 库集成
|
||
- JPEG 硬件编码
|
||
|
||
### 中期目标(Day 6-7)
|
||
|
||
3. **摄像头系统**
|
||
- ISP 参数加载
|
||
- 视频流采集
|
||
- WebSocket 图像上传
|
||
|
||
4. **IMU 系统**
|
||
- MPU6050 I2C 配置
|
||
- 数据读取和校准
|
||
- UDP 上报
|
||
|
||
5. **系统完整集成**
|
||
- 多线程协同
|
||
- 性能优化
|
||
- 稳定性测试
|
||
|
||
---
|
||
|
||
## 经验总结
|
||
|
||
### 收获
|
||
|
||
1. **硬件确认的重要性**
|
||
- 开发前必须确认实际硬件类型
|
||
- 文档(MIC.md)比猜测更可靠
|
||
|
||
2. **Device Tree 的灵活性**
|
||
- 如果驱动已配置,无需重复造轮子
|
||
- 运行时配置(amixer)比编译时更灵活
|
||
|
||
3. **逐步调优的必要性**
|
||
- 增益参数需要实测调优
|
||
- 音量和音质需要平衡
|
||
|
||
### 启示
|
||
|
||
- **模拟麦克风 vs PDM**:模拟方案配置更简单,但抗干扰能力较弱
|
||
- **运行时配置**:MIC Switch 默认关闭,需要程序主动打开
|
||
- **增益设置**:过高会放大噪声,过低影响音量,需要找到平衡点
|
||
|
||
|
||
---
|
||
|
||
## 第八部分:IMU 传感器配置
|
||
|
||
### 1. 硬件选型
|
||
|
||
**传感器型号**:ICM-42688-P
|
||
- 6 轴 IMU(3 轴加速度计 + 3 轴陀螺仪)
|
||
- 支持 I2C 和 SPI 双接口
|
||
- 高精度、低功耗
|
||
- TDK InvenSense 出品
|
||
|
||
### 2. 接口选择:I2C vs SPI
|
||
|
||
#### I2C 尝试(失败)
|
||
|
||
**初始方案**:
|
||
- 使用 GPIO 模拟 I2C(PD3/PD2)
|
||
- 原因:硬件 I2C 引脚配置复杂
|
||
|
||
**遇到的问题**:
|
||
1. Device Tree 配置困难
|
||
- PD1/PD2 支持 TWI0,但 PD1 被其他功能占用
|
||
- PL2/PL3 不支持 TWI0 功能
|
||
2. 设备响应地址但拒绝寄存器访问
|
||
- `Write addr (0xD0): ACK` - 地址响应正常
|
||
- `Write reg (0x75): NACK` - 寄存器访问失败
|
||
3. 可能原因:
|
||
- 需要特殊的初始化序列
|
||
- 寄存器 Bank 切换问题
|
||
- I2C 时序要求严格
|
||
|
||
#### SPI 方案(成功)✅
|
||
|
||
**优势**:
|
||
- 协议简单,无 ACK/NACK 握手
|
||
- 时序可靠,主设备完全控制
|
||
- 高速传输(可达 MHz 级)
|
||
- ICM-42688 官方推荐接口
|
||
|
||
**实现方式**:GPIO 模拟 SPI
|
||
|
||
### 3. 硬件连接(SPI 模式)
|
||
|
||
```
|
||
ICM-42688 模块 → Avaota F1
|
||
-------------- ---------
|
||
VCC → 3.3V
|
||
GND → GND
|
||
SCL/SCLK → PD3 (GPIO 99)
|
||
SDA/MOSI → PD2 (GPIO 98)
|
||
AD0/MISO → PD4 (GPIO 100)
|
||
CS → PD5 (GPIO 101)
|
||
INT1/INT2 → 悬空(未使用)
|
||
```
|
||
|
||
### 4. 软件实现
|
||
|
||
**驱动文件**:[`icm42688_spi.cpp`](file:///d:/CodingProjects/Antigravity/AvaotaF1/src/imu/icm42688_spi.cpp)
|
||
|
||
**关键特性**:
|
||
- GPIO 模拟 SPI(Mode 0: CPOL=0, CPHA=0)
|
||
- 速度约 500kHz(可调)
|
||
- 完整的寄存器读写功能
|
||
- 6 轴数据读取(加速度、陀螺仪、温度)
|
||
|
||
**SPI 时序实现**:
|
||
```cpp
|
||
static uint8_t spi_transfer_byte(uint8_t tx_byte) {
|
||
uint8_t rx_byte = 0;
|
||
for (int i = 7; i >= 0; i--) {
|
||
// 设置 MOSI
|
||
if (tx_byte & (1 << i)) mosi_high();
|
||
else mosi_low();
|
||
|
||
sclk_high(); // 上升沿:从设备采样
|
||
if (miso_read()) rx_byte |= (1 << i);
|
||
sclk_low(); // 下降沿:从设备准备下一位
|
||
}
|
||
return rx_byte;
|
||
}
|
||
```
|
||
|
||
**读取寄存器**:
|
||
```cpp
|
||
uint8_t ICM42688::read_register(uint8_t reg) {
|
||
cs_select();
|
||
spi_transfer_byte(reg | 0x80); // 读操作:地址最高位为 1
|
||
uint8_t value = spi_transfer_byte(0x00); // Dummy 字节
|
||
cs_deselect();
|
||
return value;
|
||
}
|
||
```
|
||
|
||
### 5. 测试结果
|
||
|
||
**成功识别**:
|
||
```
|
||
[INFO] ICM42688 detected, WHO_AM_I = 0x47
|
||
[INFO] ICM42688 initialized successfully
|
||
```
|
||
|
||
**数据采集**(静止状态):
|
||
```
|
||
[Sample 1]
|
||
Accel: X= -2.52 Y= -9.40 Z= 1.37 m/s²
|
||
Gyro: X= -0.06 Y= 0.00 Z= -0.18 °/s
|
||
Temp: 19.33 °C
|
||
```
|
||
|
||
**数据分析**:
|
||
- ✅ **加速度计**:总加速度 ≈ 9.8 m/s²(重力加速度)
|
||
- ✅ **陀螺仪**:接近 0°/s(静止状态)
|
||
- ✅ **温度**:19.3°C(室温)
|
||
- ✅ **数据稳定**:10 次采样波动极小
|
||
|
||
### 6. 配置参数
|
||
|
||
| 参数 | 配置值 | 说明 |
|
||
|------|--------|------|
|
||
| 加速度计量程 | ±16g | `AFS_16G` |
|
||
| 陀螺仪量程 | ±2000°/s | `GFS_2000DPS` |
|
||
| 输出数据率 | 1kHz | `ODR_1KHZ` |
|
||
| SPI 时钟 | ~500kHz | GPIO 模拟 |
|
||
|
||
### 7. 技术要点
|
||
|
||
**为什么加速度计静止也有数值?**
|
||
|
||
传感器测量的是**加速度**,包括:
|
||
- 运动加速度(移动时产生)
|
||
- 重力加速度(始终存在,约 9.8 m/s²)
|
||
|
||
静止状态下:
|
||
- 运动加速度 = 0
|
||
- 重力加速度 ≠ 0(分解在 X/Y/Z 三轴)
|
||
- 总加速度 = √(X² + Y² + Z²) ≈ 9.8 m/s²
|
||
|
||
**陀螺仪数据理解**:
|
||
- ✅ 静止时:0°/s±噪声
|
||
- ✅ 旋转时:几十到几百°/s
|
||
|
||
### 8. 集成方案
|
||
|
||
**在主程序中**:
|
||
```cpp
|
||
void imu_thread() {
|
||
LOG_INFO("Starting IMU thread...");
|
||
|
||
ICM42688 imu("/dev/spidev0.0", 0); // SPI 模式
|
||
if (!imu.init()) {
|
||
LOG_ERROR("Failed to initialize IMU");
|
||
return;
|
||
}
|
||
|
||
// UDP 发送器
|
||
UDPSender udp(SERVER_HOST, UDP_PORT);
|
||
|
||
while (g_running) {
|
||
if (imu.read_sensor()) {
|
||
// 构造 IMU 数据包
|
||
ImuData data = {
|
||
.ax = imu.get_accel_x(),
|
||
.ay = imu.get_accel_y(),
|
||
.az = imu.get_accel_z(),
|
||
.gx = imu.get_gyro_x(),
|
||
.gy = imu.get_gyro_y(),
|
||
.gz = imu.get_gyro_z(),
|
||
.temp = imu.get_temperature()
|
||
};
|
||
|
||
// UDP 发送
|
||
udp.send((uint8_t*)&data, sizeof(data));
|
||
}
|
||
usleep(10000); // 100Hz
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 🏆 Day 4 成果(更新)
|
||
|
||
### 核心成就
|
||
|
||
1. ✅ **确认硬件类型**:模拟麦克风(非 PDM/DMIC)
|
||
2. ✅ **验证 Device Tree**:audiocodec 已完整配置
|
||
3. ✅ **创建测试脚本**:[`test_mic.sh`](file:///d:/CodingProjects/Antigravity/AvaotaF1/src/test_mic.sh)
|
||
4. ✅ **完成硬件测试**:录音功能正常
|
||
5. ✅ **调优增益参数**:MIC Gain = 25 (最佳)
|
||
6. ✅ **集成方案设计**:AudioCapture 集成代码
|
||
7. ✅ **IMU 配置完成**:ICM-42688 SPI 模式成功
|
||
8. ✅ **6 轴数据采集**:加速度、陀螺仪、温度
|
||
|
||
### 技术文档
|
||
|
||
- [MIC.md](file:///d:/CodingProjects/Antigravity/AvaotaF1/MIC.md) - 官方麦克风使用文档
|
||
- [board.dts](file:///d:/CodingProjects/Antigravity/AvaotaF1/board.dts) - Device Tree 配置
|
||
- [test_mic.sh](file:///d:/CodingProjects/Antigravity/AvaotaF1/src/test_mic.sh) - 麦克风测试脚本
|
||
- [icm42688_spi.cpp](file:///d:/CodingProjects/Antigravity/AvaotaF1/src/imu/icm42688_spi.cpp) - IMU SPI 驱动
|
||
- [test_imu.cpp](file:///d:/CodingProjects/Antigravity/AvaotaF1/src/test_imu.cpp) - IMU 测试程序
|
||
|
||
### 测试结果
|
||
|
||
| 测试项 | 状态 | 备注 |
|
||
|--------|------|------|
|
||
| ALSA 设备识别 | ✅ 通过 | audiocodec (card 0) |
|
||
| MIC Switch 配置 | ✅ 通过 | amixer 控制正常 |
|
||
| 录音功能 | ✅ 通过 | 5 秒录音成功 |
|
||
| 音质测试 | ✅ 通过 | 清晰、无明显杂音 |
|
||
| 增益调优 | ✅ 完成 | MIC Gain = 25 最佳 |
|
||
| **IMU 识别** | ✅ 通过 | WHO_AM_I = 0x47 |
|
||
| **IMU 数据读取** | ✅ 通过 | 6 轴数据正常 |
|
||
| **SPI 通信** | ✅ 通过 | GPIO 模拟稳定 |
|
||
|
||
### 配置完成度
|
||
|
||
**传感器系统**:
|
||
- ✅ 音频播放(I2S + MAX98357A)- Day 3 完成
|
||
- ✅ 音频采集(模拟麦克风 + audiocodec)- Day 4 完成
|
||
- ✅ IMU 传感器(ICM-42688 SPI)- Day 4 完成
|
||
- ⏳ 摄像头(GC2083 MIPI)- 待完成
|
||
- ⏳ 端到端集成(WebSocket + HTTP + UDP)- 待完成
|
||
|
||
**整体进度**:约 **70%** (+10%)
|
||
|
||
---
|
||
|
||
## 下一步计划
|
||
|
||
### 短期目标(Day 5)
|
||
|
||
1. **音频系统集成**
|
||
- 集成 MIC 配置到主程序
|
||
- WebSocket 音频上传测试
|
||
- HTTP TTS 下载播放测试
|
||
- 完整语音对话闭环验证
|
||
|
||
2. **IMU 系统集成**
|
||
- 集成到主程序多线程
|
||
- UDP 数据上报
|
||
- 姿态解算(可选)
|
||
|
||
### 中期目标(Day 6-7)
|
||
|
||
3. **摄像头系统**
|
||
- GC2083 配置
|
||
- MPP 库集成
|
||
- JPEG 硬件编码
|
||
- WebSocket 图像上传
|
||
|
||
4. **系统完整集成**
|
||
- 多线程协同
|
||
- 性能优化
|
||
- 稳定性测试
|
||
|
||
---
|
||
|
||
## 经验总结
|
||
|
||
### 收获
|
||
|
||
1. **硬件确认的重要性**
|
||
- 开发前必须确认实际硬件类型
|
||
- 文档(MIC.md)比猜测更可靠
|
||
|
||
2. **Device Tree 的灵活性**
|
||
- 如果驱动已配置,无需重复造轮子
|
||
- 运行时配置(amixer)比编译时更灵活
|
||
|
||
3. **逐步调优的必要性**
|
||
- 增益参数需要实测调优
|
||
- 音量和音质需要平衡
|
||
|
||
4. **接口选型的技巧**
|
||
- I2C:简单但对时序要求高,易受干扰
|
||
- SPI:引脚多但可靠性高,速度快
|
||
- 遇到 I2C 问题时,尝试 SPI 是明智选择
|
||
|
||
5. **GPIO 模拟的实用性**
|
||
- 绕过复杂的 Device Tree 配置
|
||
- 完全用户空间实现,调试方便
|
||
- 性能对 IMU 等低速设备完全够用
|
||
|
||
### 启示
|
||
|
||
- **模拟麦克风 vs PDM**:模拟方案配置更简单,但抗干扰能力较弱
|
||
- **运行时配置**:MIC Switch 默认关闭,需要程序主动打开
|
||
- **增益设置**:过高会放大噪声,过低影响音量,需要找到平衡点
|
||
- **SPI vs I2C**:高性能场景优先选择 SPI
|
||
- **传感器数据理解**:加速度计测量重力+运动,静止时仍有读数
|
||
|
||
---
|
||
|
||
**模拟麦克风 + IMU 传感器配置完成!** 🎉
|
||
|