描述
<h1>1、项目功能介绍</h1>
<p>家里小朋友喜欢听故事,有自己喜欢的人物和故事偏好,结合AI个性化定制专属的故事。</p>
<p>比如小朋友按一个键或者摇一摇,然后,故事机就会利用AI大模型,真的把这个独一无二的故事“编”出来,然后用听起来很自然的声音讲给他听。</p>
<p><img src="https://image.lceda.cn/oshwhub/pullImage/a21cfea51c514ea6870be880b7dcc6d2.png" alt="概念设计图.png"></p>
<h1>2、项目属性</h1>
<p>原创,未参与过其他比赛</p>
<h1>3、开源协议</h1>
<p>GPL3.0开源协议</p>
<h1>4、硬件部分</h1>
<p>其实类似的方案很多,我只需要一个简版,但是我手上只有普通的驻极体麦克风,就需要ADC芯片,加上麦克风也需要功放,就在某宝买了几个ES8311。</p>
<p>东西倒不贵,到了以后我就后悔了,太小了,之前看介绍没有实感,到货以后字都看不清楚,我感觉我没法焊接,又重新买了电子放大镜和加热台。</p>
<p><img src="https://image.lceda.cn/oshwhub/pullImage/4fdfeda6afc347198262c0c1fe19759d.png" alt="dMZkcOxsPmpa0Rofsw7SmINqY718gTpdsRkBRSXm.png"></p>
<p>(用下立创商城的图,只有3mm大)</p>
<p>为了保险起见,先只焊接ES8311,没想到整体出乎意料的顺利,第一次焊接ES8311就成功了。
然后用电烙铁焊接的剩余元器件的时候不小心把电容焊接错了,麦克风正负极意外连上了,上电以后直接发烫,还好主控没坏。
第二块板子整体加热台焊接顺利焊好了,麦克风是之前哪次从立创商城凑单屯的货,只有线没有头,我又重新买了XH2.54的端子用镊子压了一个,接上去麦克风不响。重新买了压线钳之后终于听到声音了。</p>
<p>感觉如果不追求最终实物的大小,其实用模块可能更快一些。</p>
<p>最开始屏幕和按键都在正面,发现娃老是乱按,就把按钮拆下来反过来焊接,正面只留屏幕。再后来晚上睡前听故事,又发现娃老是要注意屏幕,屏幕还闪烁,把屏幕也下了。语音唤醒对于发音要求还蛮高的,小孩子的声音始终没法语音唤醒,最后直接搞成最简形态,背面的按钮按一下开始放故事,按一下切换和暂停。</p>
<p>为了检测晃动,还加上了六轴运动处理传感器(MPU-6500)和SD卡座,想着后面可以做儿歌播放,现在智能音响虽然可以播放音乐,但是每次都先插播广告,让人难受。MPU-6500也很小,焊接失败过一次,这块暂时预留硬件能力,还没有写软件部分。</p>
<p>外壳是第一次尝试立创的3打印,外壳大小没问题,就是这个螺丝孔确实没有明白怎么玩,没有螺纹不知道怎么装,最后热熔胶沾上的。</p>
<p><img src="https://image.lceda.cn/oshwhub/pullImage/899f87c68a5647f888352516b218fbf5.jpg" alt="1.jpg"></p>
<p><img src="https://image.lceda.cn/oshwhub/pullImage/d0dcb87c81384d9d931039b957fc6c4c.jpg" alt="2.jpg"></p>
<h1>5、软件部分</h1>
<p>软件部分使用ESP IDF 和 C++开发。</p>
<p>AI部分主要考虑速度和成本,综合一圈下来,某度的ERNIE-Speed模型免费且速度快,适合生成故事。TTS先尝试用了ESP-SR自带的,声音稍微有点声音,最后换成百度的短文本生成,可选音色很多,效果不错,合成一次几厘钱。</p>
<p>折腾硬件焊接用了太多时间,目前软件实现比较简单,按键后播放预设的主题和故事,硬件预留了麦克风和三个按键后面有时间再添加其他功能。</p>
<p>当前项目结构和说明</p>
<ol>
<li>
<p><strong><code>main/main.cc</code></strong>:</p>
<ul>
<li>程序的入口点,包含 <code>app_main</code> 函数。它初始化了 <code>App</code> 类的单例实例,并调用其 <code>Start()</code> 和 <code>MainLoop()</code> 方法。这是整个应用程序启动的地方。</li>
</ul>
</li>
<li>
<p><strong><code>main/app.h</code> / <code>main/app.cc</code></strong>:</p>
<ul>
<li><strong>核心应用逻辑 (<code>App</code> 类)</strong>:
<ul>
<li><code>App</code> 是一个单例类,管理整个应用程序的生命周期。</li>
<li><code>Start()</code> 方法是初始化和执行流程的核心:
<ul>
<li>初始化 NVS (非易失性存储)。</li>
<li>启动 WiFi 连接。</li>
<li>初始化 I2C 总线。</li>
<li>初始化 <code>AudioService</code>。</li>
<li>初始化 <code>AI</code> 模块。</li>
<li>初始化 <code>TTS</code> 模块。</li>
<li>调用 <code>AI</code> 模块生成一个关于“小熊布鲁喜欢刷牙”的故事。</li>
<li>调用 <code>TTS</code> 模块将生成的故事文本转换为 PCM 音频数据。</li>
<li>调用 <code>AudioService</code> 播放生成的音频。</li>
</ul></li>
<li><code>MainLoop()</code> 方法进入一个无限循环,等待并处理事件(目前只处理错误事件)。</li>
</ul></li>
</ul>
</li>
<li>
<p><strong><code>main/board/board.h</code> / <code>main/board/board.cc</code></strong>:</p>
<ul>
<li><strong>硬件抽象和初始化 (<code>Board</code> 类)</strong>:
<ul>
<li><code>Board</code> 也是一个单例类,负责与底层硬件(特别是网络和 I2C)交互。</li>
<li><code>initNvs()</code>: 初始化 NVS 闪存。</li>
<li><code>startWifi()</code>: 配置并启动 WiFi 连接,使用 <code>config.h</code> 中定义的 SSID 和密码。</li>
<li><code>initI2C()</code>: 配置并初始化 I2C 主总线,用于与音频编解码器通信。</li>
<li><code>GetI2CBusHandle()</code>: 提供对已初始化的 I2C 总线句柄的访问,供其他模块(如 <code>AudioService</code>)使用。</li>
</ul></li>
</ul>
</li>
<li>
<p><strong><code>main/ai/ai.h</code> / <code>main/ai/ai.cc</code></strong>:</p>
<ul>
<li><strong>AI 故事生成 (<code>AI</code> 类)</strong>:
<ul>
<li>封装了与 OpenAI 兼容的 API(如文心一言)的交互。</li>
<li><code>ai_init()</code>: 使用 <code>config.h</code> 中的 API 密钥和基础 URL 初始化 OpenAI 客户端库,设置模型和参数。</li>
<li><code>ai_get_story_content()</code>: 向 AI API 发送一个带有特定提示(要求创作儿童故事)的请求,获取生成的文本故事内容。</li>
</ul></li>
</ul>
</li>
<li>
<p><strong><code>main/tts/tts.h</code> / <code>main/tts/tts.cc</code></strong>:</p>
<ul>
<li><strong>文本转语音 (<code>TTS</code> 类)</strong>:
<ul>
<li>使用百度 AI 平台的 TTS 服务。</li>
<li><code>tts_init()</code>: 通过百度 API 获取访问令牌 (<code>access_token</code>),这是调用 TTS 服务所必需的。</li>
<li><code>tts_generate()</code>: 使用获取到的令牌和故事文本,向百度 TTS API 发送请求,将文本转换为 PCM 格式的音频数据,并存储在 <code>pcm_audio_buffer</code> 成员变量中。</li>
</ul></li>
</ul>
</li>
<li>
<p><strong><code>main/audio/audio.h</code> / <code>main/audio/audio.cc</code></strong>:</p>
<ul>
<li><strong>音频播放 (<code>AudioService</code> 类)</strong>:
<ul>
<li>负责配置和控制音频硬件(I2S 接口和 ES8311 编解码器)。</li>
<li><code>Initialize()</code>: 初始化 I2S 通道和 ES8311 音频编解码器,设置采样率、位宽等参数,打开音频设备。</li>
<li><code>Play()</code>: 接收 PCM 音频数据(来自 <code>TTS</code> 模块),并通过配置好的编解码器和 I2S 接口播放出来。</li>
</ul></li>
</ul>
</li>
<li>
<p><strong><code>main/config.h</code></strong>:</p>
<ul>
<li><strong>配置文件</strong>: 包含所有需要配置的敏感信息和设置,如 WiFi 凭据、OpenAI API 密钥和端点、百度 AI API 密钥和 TTS 相关参数。这是项目中需要根据实际环境进行修改的关键文件。</li>
</ul>
</li>
</ol>
<h1>6、BOM清单</h1>
<table>
<tr>
<th style="text-align: left;">类别</th>
<th style="text-align: left;">名称</th>
<th style="text-align: left;">封装</th>
<th style="text-align: left;">数量</th>
</tr>
<tr>
<td style="text-align: left;"><strong>芯片</strong></td>
<td style="text-align: left;">LCKFB-ESP32S3R8N8</td>
<td style="text-align: left;">DIP-40_L20.32-W51.66-P2.54-LS15.24</td>
<td style="text-align: left;">1</td>
</tr>
<tr>
<td style="text-align: left;"></td>
<td style="text-align: left;">ES8311</td>
<td style="text-align: left;">WQFN-20_L3.0-W3.0-P0.40-BL-EP1.7</td>
<td style="text-align: left;">1</td>
</tr>
<tr>
<td style="text-align: left;"></td>
<td style="text-align: left;">NS4150B</td>
<td style="text-align: left;">MSOP-8_L3.0-W3.0-P0.65-LS5.0-BL</td>
<td style="text-align: left;">1</td>
</tr>
<tr>
<td style="text-align: left;"></td>
<td style="text-align: left;">MPU-6500</td>
<td style="text-align: left;">QFN-24_L3.0-W3.0-P0.40-BL-EP</td>
<td style="text-align: left;">1</td>
</tr>
<tr>
<td style="text-align: left;"><strong>电阻</strong></td>
<td style="text-align: left;">5.1kΩ</td>
<td style="text-align: left;">R1206</td>
<td style="text-align: left;">2</td>
</tr>
<tr>
<td style="text-align: left;"></td>
<td style="text-align: left;">10kΩ</td>
<td style="text-align: left;">R1206</td>
<td style="text-align: left;">1</td>
</tr>
<tr>
<td style="text-align: left;"></td>
<td style="text-align: left;">2.2kΩ</td>
<td style="text-align: left;">R1206</td>
<td style="text-align: left;">2</td>
</tr>
<tr>
<td style="text-align: left;"></td>
<td style="text-align: left;">220Ω</td>
<td style="text-align: left;">R1206</td>
<td style="text-align: left;">2</td>
</tr>
<tr>
<td style="text-align: left;"></td>
<td style="text-align: left;">4.7kΩ</td>
<td style="text-align: left;">R1206</td>
<td style="text-align: left;">3</td>
</tr>
<tr>
<td style="text-align: left;"></td>
<td style="text-align: left;">0Ω</td>
<td style="text-align: left;">R1206</td>
<td style="text-align: left;">2</td>
</tr>
<tr>
<td style="text-align: left;"><strong>电容</strong></td>
<td style="text-align: left;">1uF</td>
<td style="text-align: left;">C1206</td>
<td style="text-align: left;">11</td>
</tr>
<tr>
<td style="text-align: left;"></td>
<td style="text-align: left;">100nF</td>
<td style="text-align: left;">C1206</td>
<td style="text-align: left;">6</td>
</tr>
<tr>
<td style="text-align: left;"></td>
<td style="text-align: left;">22uF</td>
<td style="text-align: left;">CAP-TH_BD6.3-P2.50-D0.6-FD-1</td>
<td style="text-align: left;">1</td>
</tr>
<tr>
<td style="text-align: left;"><strong>连接器</strong></td>
<td style="text-align: left;">TYPE-C 6P(073)</td>
<td style="text-align: left;">TYPE-C-SMD_TYPE-C-6P-073</td>
<td style="text-align: left;">1</td>
</tr>
<tr>
<td style="text-align: left;"></td>
<td style="text-align: left;">2.54-1*8P母环保</td>
<td style="text-align: left;">HDR-TH_8P-P2.54-V-F-1</td>
<td style="text-align: left;">1</td>
</tr>
<tr>
<td style="text-align: left;"></td>
<td style="text-align: left;">ZX-XH2.54-2PZZ</td>
<td style="text-align: left;">CONN-TH_2P-P2.50_HX25003-2A</td>
<td style="text-align: left;">1</td>
</tr>
<tr>
<td style="text-align: left;"><strong>开关/按键</strong></td>
<td style="text-align: left;">SK-12E12-G5</td>
<td style="text-align: left;">SW-TH_SK-12E12-G5</td>
<td style="text-align: left;">1</td>
</tr>
<tr>
<td style="text-align: left;"></td>
<td style="text-align: left;">ZX-QC66-8.5CJ</td>
<td style="text-align: left;">SW-TH_4P-L6.0-W6.0-P4.50-LS6.3</td>
<td style="text-align: left;">3</td>
</tr>
<tr>
<td style="text-align: left;"><strong>卡座</strong></td>
<td style="text-align: left;">TF PUSH</td>
<td style="text-align: left;">TF-SMD_TF-PUSH</td>
<td style="text-align: left;">1</td>
</tr>
<tr>
<td style="text-align: left;"><strong>发光二极管</strong></td>
<td style="text-align: left;">XL-3216UGC-FB</td>
<td style="text-align: left;">LED1206-FD_GREEN-EH</td>
<td style="text-align: left;">1</td>
</tr>
<tr>
<td style="text-align: left;"><strong>麦克风</strong></td>
<td style="text-align: left;">GMI9745P-56DB</td>
<td style="text-align: left;">MIC-TH_BD9.7-P2.54-D0.8-L-FD</td>
<td style="text-align: left;">1</td>
</tr>
<tr>
<td style="text-align: left;"><strong>结构件</strong></td>
<td style="text-align: left;">M3螺丝</td>
<td style="text-align: left;">M3螺丝</td>
<td style="text-align: left;">4</td>
</tr>
</table>
<h1>7、大赛LOGO验证</h1>
<p><img src="https://image.lceda.cn/oshwhub/pullImage/57158054f4ff42c29c7ee21602d550dc.png" alt="正面.png"></p>
评论(0)