# NS4168 I2S 功放组件 / NS4168 I2S Amplifier Component
**EN** — ESP-IDF component for the NS4168 (2.5W mono Class-D, I2S input) audio amplifier. Audio data is pushed into a FreeRTOS ring buffer and streamed to I2S by a background task; the amplifier is enabled only while audio is playing and released before power-off.
**中文** — 面向 ESP-IDF 的 NS4168(2.5W 单声道 D 类、I2S 数字输入)功放组件。音频数据写入环形缓冲,由后台任务搬运到 I2S;有数据才使能功放,播完自动关断,关机前可释放引脚。
---
## Features / 功能特性
**EN**
- Non-blocking write API backed by a FreeRTOS ring buffer
- Background task owns the I2S channel and the amplifier CTRL pin
- CTRL is asserted only during playback, so the amplifier stays in shutdown (≈1µA) when idle
- Runtime sample rate change via `NS4168SetI2sSampleRate()`
- Full shutdown path: `NS4168TaskClose()` + `NS4168PinRelease()` put the I2S pins into high-impedance before power-off
- Thread-safe: multiple tasks may call the write API concurrently
**中文**
- 写接口非阻塞,内部使用 FreeRTOS 环形缓冲
- 后台任务独占 I2S 通道与功放 CTRL 引脚
- 只在播放期间拉高 CTRL,空闲时功放处于关断状态(约 1µA)
- 支持运行时修改采样率
- 提供完整的关闭流程:`NS4168TaskClose()` + `NS4168PinRelease()`,关机前把 I2S 引脚置高阻
- 写接口线程安全,可多任务调用
---
## Requirements / 运行环境
**EN**
- ESP-IDF >= 5.0 (developed and verified on v5.5.4)
- Targets: ESP32 / ESP32-S2 / ESP32-S3 / ESP32-C3 / ESP32-C6 (any chip with a standard I2S peripheral)
- Depends on: `esp_driver_gpio`, `esp_driver_i2s`, `esp_ringbuf`
**中文**
- ESP-IDF >= 5.0(已在 v5.5.4 上编译验证)
- 支持目标:ESP32 / ESP32-S2 / ESP32-S3 / ESP32-C3 / ESP32-C6 等带标准 I2S 外设的芯片
- 依赖组件:`esp_driver_gpio`、`esp_driver_i2s`、`esp_ringbuf`
---
## Directory / 目录结构
```text
esp_ns4168/
├── CMakeLists.txt # 组件注册
├── idf_component.yml # 组件清单(版本 / 开源协议 / 依赖 / 适用芯片)
├── NS4168.c # 实现
├── include/NS4168.h # 对外接口
├── examples/ns4168_tone/ # 例程工程(正弦波播放)
├── CHANGELOG.md # 版本更新记录
├── LICENSE # MIT 开源协议
└── README.md
```
---
## Install / 安装
**EN** — From the ESP Component Registry (recommended):
```bash
idf.py add-dependency "junhui93/esp_ns4168^1.1.0"
```
Or declare it manually in `main/idf_component.yml`:
```yaml
dependencies:
junhui93/esp_ns4168: "^1.1.0"
```
**中文** — 推荐用组件管理器从组件仓库安装,`idf.py add-dependency` 会自动写入 `main/idf_component.yml`;也可以手动添加上面的依赖。直接使用本仓库时,把本目录整体放到工程的 `components/` 下,或在工程 `CMakeLists.txt` 里用 `EXTRA_COMPONENT_DIRS` 指向本目录即可。
**EN** — Registry page: <https://components.espressif.com/components/junhui93/esp_ns4168>
**中文** — 组件仓库页面:<https://components.espressif.com/components/junhui93/esp_ns4168>
---
## Wiring / 接线
模块引脚名为 NS4168 eSOP-8 的丝印名称,部分模块会写成 `DIN / SCK / WS / EN`,功能一一对应。
| NS4168 引脚 | 引脚号 | 说明 | ESP32-S3 示例引脚 |
| --- | --- | --- | --- |
| VDD | 6 | 电源输入,3.0V ~ 5.5V | 3V3 |
| GND | 7 | 电源地 | GND |
| SDATA | 4 | I2S 串行数据输入 | GPIO4 |
| BCLK | 3 | I2S 位时钟 | GPIO5 |
| LRCLK | 2 | I2S 左右声道帧时钟 | GPIO6 |
| CTRL | 1 | 使能 / 声道选择:高电平使能,低电平关断 | GPIO7 |
| VoP | 8 | 功放输出正端 | 喇叭正端 |
| VoN | 5 | 功放输出负端 | 喇叭负端 |
**EN** — VoP/VoN form a BTL differential output: connect the speaker across VoP and VoN, never to GND.
**中文** — VoP/VoN 是 BTL 差分输出,喇叭两端分别接 VoP 与 VoN,任一端都不能接地。
---
## API
| 函数 | 说明 |
| --- | --- |
| `void NS4168TaskStart(gpio_num_t SDATA, gpio_num_t BCLK, gpio_num_t LRCLK, gpio_num_t CTRL)` | 初始化 GPIO 与 I2S 通道并创建播放任务;重复调用会被忽略 |
| `void NS4168i2sWrite(void *pvItem, size_t xItemSize)` | 写入 PCM 数据(16bit 单声道);缓冲满时最多阻塞 3 秒,超时丢弃并打印 `音频数据丢失` |
| `void NS4168SetI2sSampleRate(int sample_rate)` | 运行时修改采样率(NS4168 支持 8kHz ~ 96kHz),与播放任务互斥 |
| `void NS4168TaskClose(void)` | 停止任务,等待其退出后释放环形缓冲与 I2S 通道 |
| `void NS4168PinRelease(void)` | 关机前调用:拉低 CTRL 并把 SDATA / BCLK / LRCLK 置为高阻 |
**播放行为 / Playback behaviour**
| 阶段 | 内部动作 |
| --- | --- |
| 缓冲数据超过 3/4(约 3.8KB) | 拉高 CTRL、使能 I2S 通道并开始播放 |
| 缓冲数据排空 | 关断 CTRL、disable I2S 通道 |
| 关闭任务 | 先停止任务再释放资源,不会与重启流程冲突 |
**数据格式 / Data format**
- 采样率:默认 16000Hz,可在 `NS4168SetI2sSampleRate()` 中修改
- 位宽 / 声道:16bit 单声道,Philips 标准 I2S 格式(BCLK 延迟一个时钟)
- 缓冲深度:5120 字节(16kHz 16bit 约 160ms)
---
## Usage / 使用
```c
#include "NS4168.h"
#define NS4168_SDATA GPIO_NUM_4
#define NS4168_BCLK GPIO_NUM_5
#define NS4168_LRCLK GPIO_NUM_6
#define NS4168_CTRL GPIO_NUM_7
void app_main(void){
//1. 启动功放任务
NS4168TaskStart(NS4168_SDATA,NS4168_BCLK,NS4168_LRCLK,NS4168_CTRL);
//2. 送音频数据(16bit 单声道 PCM), 可循环调用
int16_t pcm[160];
while(1){
NS4168i2sWrite(pcm,sizeof(pcm));
vTaskDelay(pdMS_TO_TICKS(10));
}
}
```
**EN** — Recommended shutdown order: stop feeding audio → `NS4168TaskClose()` → `NS4168PinRelease()`.
**中文** — 建议的关机顺序:先停止喂音频 → `NS4168TaskClose()` → `NS4168PinRelease()`。
```c
//停止播放并释放资源
NS4168TaskClose();
NS4168PinRelease();
```
---
## Example / 例程
`examples/ns4168_tone` 每 10ms 生成一包 1kHz 正弦波送入功放,并每 3 秒在 1kHz / 2kHz / 4kHz 之间切换。引脚宏在 `main.c` 顶部,按实际接线修改。
```bash
cd examples/ns4168_tone
idf.py set-target esp32s3 # 其他芯片改成对应型号
idf.py -p COMx flash monitor
```
预期串口输出(关键信息):
```text
I (xxx) ns4168_tone: NS4168 例程启动, 采样率 16000 Hz
W (xxx) NS4168Task: 喇叭输出开始
I (xxx) ns4168_tone: 切换音频 2000 Hz
W (xxx) NS4168Task: 喇叭输出结束
```
**EN** — Example build: `idf.py set-target esp32s3 && idf.py build`.
**中文** — 只编译不烧录:`idf.py set-target esp32s3` 后执行 `idf.py build`。
---
## Notes / 注意事项
- 供电范围 3.0V ~ 5.5V;CTRL 为高电平时使能功放(并选择右声道),低电平关断,关断电流约 1µA。
- CTRL 除了使能,还具备「一线脉冲设置内部输入高通滤波器转折点」的功能,因此不要在使能状态下频繁翻转该引脚;本组件只在播放开始 / 结束时各翻转一次。
- 采样率支持 8kHz ~ 96kHz,切换采样率后送入的数据格式需同步改变,否则音调会不对。
- 组件使用 MONO slot 模式发送,输入数据为单声道 PCM。
- `NS4168TaskClose()` 会等待播放任务退出(最长 5 秒),若此时仍有任务阻塞在写接口上,等待时间还会增加最多 3 秒,建议先停止喂数据再关闭。
- 需要更小延迟时可减小触发阈值(`NS4168.c` 中 `i2sRawDataRingbufLen/4`)与单包长度,代价是更容易断流。
---
## Links / 相关链接
| 内容 | 地址 |
| --- | --- |
| 源码仓库 | <https://gitcode.com/CJhui/esp_ns4168> |
| 组件仓库页面 | <https://components.espressif.com/components/junhui93/esp_ns4168> |
| 更新记录 | [CHANGELOG.md](CHANGELOG.md) |
---
## License / 许可证
**EN** — Released under the MIT License, see [LICENSE](LICENSE). Anyone may use, modify and redistribute this component, including for commercial purposes, as long as the copyright notice and permission notice are retained.
**中文** — 本项目采用 MIT 开源协议,详见 [LICENSE](LICENSE)。任何人可自由使用、修改和再发布(含商用),只需保留版权声明与许可声明。
idf.py add-dependency "junhui93/esp_ns4168^1.1.0"