# Little-Diver **Repository Path**: FSW_ei/Little-Diver ## Basic Information - **Project Name**: Little-Diver - **Description**: Little Diver - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-04-07 - **Last Updated**: 2026-06-15 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 🤿 小小潜水员 (Little Diver) ## 演示视频: - 抖音 「芯火小铺」 - 微信公众号、微信视频号、B站、小红书,全平台同名 **「芯火XH」** ## 交流群: 公众号回复【群】 一个有趣的ESP32互动游戏项目,让潜水员在虚拟海底探险,收集宝藏,躲避水母!使用真实的水深传感器控制游戏角色的深度。 **适用人群**:Arduino/ESP32初学者、电子爱好者、创客教育 **难度**:初级 ⭐⭐ --- ## 📋 目录 - [项目介绍](#项目介绍) - [所需硬件](#所需硬件) - [软件安装](#软件安装) - [硬件连接](#硬件连接) - [配置与编译](#配置与编译) - [游戏玩法](#游戏玩法) - [按键/传感器说明](#按键传感器说明) - [项目文件结构](#项目文件结构) - [常见问题](#常见问题) - [高级调整](#高级调整) --- ## 项目介绍 ### 这是什么? 小小潜水员是一款交互式游戏,在两个OLED屏显示: - **左屏**(游戏屏):显示潜水员在水下世界的冒险场景 - **右屏**(信息屏):显示菜单、分数、游戏状态 ### 游戏特色 ✨ **完整游戏体验** - 用水深传感器实时控制潜水员的下潜/上浮 - 躲避危险的水母 - 收集海底宝藏获得分数 - 动态摄像机跟随角色移动 ✨ **实时传感** - 将物体浸入水中,游戏会感知并转换为角色深度 - 创意玩法:用手指、冰块或其他物体改变传感器灵敏度 ✨ **双屏显示** - 游戏屏和信息屏独立运行 - 支持当地高刷显示,录像效果更清晰 --- ## 所需硬件 ### 核心部分(必需) | 物品 | 数量 | 说明 | |------|------|------| | **ESP32-S3-DevKitC-1开发板** | 1 | 内存:8MB Flash + PSRAM | | **SSD1306 OLED屏幕 (128×64)** | 2 | I2C接口,地址0x3C | | **模拟水深传感器** | 1 | 电阻式湿度/水分传感器(如FS400A) | | **杜邦线** | 若干 | 用于连接各组件 | | **USB-C线** | 1 | 用于编程和供电 | ### 可选配件 | 物品 | 说明 | |------|------| | 蜂鸣器 | 接AO引脚,用于音效 | | 小水盆/罐子 | 放置传感器进行测试 | | 面包板 | 简化电路连接 | ### 估算成本 - ESP32-S3开发板:约 15 元 - 两块OLED屏:约 10 元 - 土壤湿度传感器:约 3 元 - 杜邦线+其他:约 5 元 - **总计**:约 30 元 --- ## 软件安装 ### 第1步:安装VS Code和PlatformIO 1. **下载VS Code** → https://code.visualstudio.com/ 2. **打开VS Code**,点击左侧扩展图标(六个小方格) 3. **搜索PlatformIO** → 找到"PlatformIO IDE"(官方出品)→ 点击安装 4. **等待安装完成**(可能需要2-5分钟,第一次会自动下载工具链) > **提示**:PlatformIO会自动识别ESP32开发板,无需手动配置Arduino IDE。 ### 第2步:克隆或下载项目 **方法A:使用Git(推荐)** ```bash git clone https://github.com/YourRepo/Little-Diver.git cd "Little Diver" ``` **方法B:直接下载** - 点击GitHub上的 `Code` → `Download ZIP` - 解压到任意目录 - 用VS Code打开该文件夹 ### 第3步:打开项目 1. **VS Code主菜单** → `File` → `Open Folder` 2. **选择项目所在的文件夹**(包含 `platformio.ini` 的那个) 3. **等待索引完成**(左下角PlatformIO Logo消失表示完成) --- ## 硬件连接 ### 接线图(ESP32-S3 40-pin版本) ``` ┌─────────────────────────────────────────────────────┐ │ ESP32-S3-DevKitC-1 (俯视图) │ │ 左侧 (USB往下) │ 右侧 │ │ GND 🟤 │ GND 🟤 │ │ 3V3 🔴 │ 3V3 🔴 ← 重要:两块屏都接3V3 │ │ ... │ ... │ │ IO1 (INFO_SDA) │ IO2 (INFO_SCL) │ │ IO6 (GAME_SDA) │ IO7 (GAME_SCL) │ │ IO9 (DO_PIN) │ IO10 (AO_PIN) │ │ 传感器信号→IO10 │ ... │ └─────────────────────────────────────────────────────┘ ``` ### 详细接线表 #### **OLED屏幕1 - 游戏屏(I2C地址:0x3C)** | 屏幕引脚 | 连接到ESP32 | 说明 | |---------|-----------|------| | GND | GND | 电源地 | | VCC | 3V3 | 电源+3.3V | | SCL | **IO7** | 时钟 | | SDA | **IO6** | 数据 | #### **OLED屏幕2 - 信息屏(I2C地址:0x3C)** | 屏幕引脚 | 连接到ESP32 | 说明 | |---------|-----------|------| | GND | GND | 电源地 | | VCC | 3V3 | 电源+3.3V | | SCL | **IO2** | 时钟 | | SDA | **IO1** | 数据 | #### **水深传感器** | 传感器引脚 | 连接到ESP32 | 说明 | |---------|-----------|------| | 信号(S) | **IO10** | 模拟输入 | | VCC | 3V3 | 电源+3.3V | | GND | GND | 电源地 | #### **可选:蜂鸣器** | 蜂鸣器 | 连接到ESP32 | 说明 | |------|-----------|------| | 正极 | **IO9** (DO_PIN) | 音量控制 | | 负极 | GND | 电源地 | ### 实物接线示意 ``` 三个I2C从设备(两块屏 + 传感器)都连接到同一组I2C总线: ESP32-S3 ┌───────┐ 3V3 ─┤3V3 │ GND ─┤GND │ [屏1] ─────────────┤IO6 │ VCC(3V3) │IO7 │───────── [屏2] SCL/SDA(屏1用区分) │ │ SCL/SDA不同 [屏2单独] ─┤IO1 │ │IO2 │───── [屏2] ADC ─┤IO10 │ (传感器信号) │IO9 │─── 蜂鸣器(可选) │IO10 │ └───────┘ ``` ### 接线建议 ✅ **推荐做法** - 用面包板组织连接,避免焊接错误 - 准备多根杜邦线(至少20根) - 使用不同颜色的杜邦线区分:红=3V3、黑=GND、其他=信号 ❌ **常见错误** - 把两块屏幕接到同一I2C地址而不改地址跳线 → 只会显示一个屏 - 忘记连接GND → 可能出现奇怪的问题 - 传感器接错ADC引脚 → 读数无效 --- ## 配置与编译 ### 第1步:连接开发板 1. **用USB-C线连接ESP32到电脑** - 应该会自动识别(Windows/Mac/Linux都有驱动) - VS Code左下角会出现 `PlatformIO` 图标 2. **检查串口连接** - VS Code底部 → 点击 `PlatformIO` 快速菜单 - 看是否显示 `Upload` 等选项(有的话表示连接成功) ### 第2步:初次编译 1. **打开项目根目录的 `platformio.ini` 文件** → 检查以下设置: ```ini [env:esp32s3-wroom-n8r2] platform = espressif32 board = esp32-s3-devkitc-1 ; ← 确认这行与你的开发板型号一致 framework = arduino board_build.flash_mode = qio ; ... 其他配置 ``` > **如果你用的不是 N8R2 版本**(比如 N16R8),改这行即可。其他行保持默认。 2. **点击编译按钮** - VS Code 底部有一排图标 → 找到 `✓` 符号(或左下角PlatformIO菜单 → Build) - 首次会自动下载依赖库(需要1-2分钟) 3. **等待编译完成** ``` 总成功案例: ======= [100%] Took 45.23s ======= Environment esp32s3-wroom-n8r2: [SUCCESS] ``` ### 第3步:上传代码到开发板 1. **准备好接线的硬件**(至少连接电源、GND、两块屏) 2. **点击上传按钮** - VS Code 底部 `→` 符号(或按 `Ctrl+Alt+U`) 3. **上传过程中** → 屏幕可能闪烁几次,这是正常的 4. **看到提示上传成功** → 开发板会重启,游戏开始运行 ``` ✓ Upload successful Total successful operations: 1 ``` --- ## 游戏玩法 ### 🎮 游戏流程 ``` 1. 启动后显示标题屏(有倒计时) ↓ 2. 进入游戏场景 ↓ 3. 控制潜水员躲避水母、收集宝藏 ↓ 4. 宝藏多或被水母碰到时游戏结束 ↓ 5. 显示分数、返回菜单 ``` ### 🕹️ 操作说明 | 操作 | 按键/传感器 | 效果 | |------|---------|------| | **下潜** | 把传感器浸入水中 | 潜水员向下移动 | | **上浮** | 拿出传感器(干燥) | 潜水员向上移动 | | **向右游** | 自动 | 潜水员持续向右 | | **收集宝藏** | 靠近宝藏 | 碰到即得分 | | **躲避水母** | 移动位置 | 接触水母游戏结束 | ### 🎯 游戏目标 - **收集尽可能多的宝藏** → 增加分数 - **躲避水母和障碍** → 不要碰撞 - **在海底探险** → 寻找更多宝藏 ### 📊 屏幕说明 **左屏(游戏屏)显示:** - 潜水员角色(中心) - 背景(海草、气泡) - 水母和宝藏 - 深度指示器(右下角HUD) **右屏(信息屏)显示:** - 菜单(开始/设置/排行榜) - 当前分数 - 游戏状态文字 - 倒计时 --- ## 按键/传感器说明 ### 水深传感器工作原理 传感器读取 **模拟电压** → 转换为 **0-4095 的ADC值** ``` 干燥状态(空气中) ↓ ADC 值 ≈ 4000 (设定 SENSOR_DRY = 4000) ↓ 对应游戏中的"海面"(深度=0) ↓ 潜水员在屏幕中间位置 浸入水中(湿润状态) ↓ ADC 值 ≈ 2000 (设定 SENSOR_WET = 2000) ↓ 对应游戏中的"海底"(深度=100) ↓ 潜水员在屏幕下方位置 ``` ### ⚙️ 传感器校准 如果传感器反应不灵敏,需要调整 `src/main.cpp` 中的两个参数: ```cpp #define SENSOR_DRY 4000 // 干燥时的 ADC 值(改这个让"上浮"更快) #define SENSOR_WET 2000 // 湿润时的 ADC 值(改这个让"下潜"更快) ``` **调整方法:** 1. 打开 `src/main.cpp` 2. 找到这两行(约在第25-26行) 3. **取中间值**更快地达到深度 - 若上浮慢 → 减小 `SENSOR_DRY` (如改为 3800) - 若下潜慢 → 增大 `SENSOR_WET` (如改为 2200) 4. 重新编译上传,测试效果 --- ## 项目文件结构 ``` Little Diver/ ├── platformio.ini # 项目配置文件(编译参数、库依赖) ├── README.md # 项目说明(你正在读这个!) │ ├── src/ # 源代码文件夹 │ └── main.cpp # 主程序(游戏逻辑、屏幕渲染等) │ ├── include/ # 头文件(通常为空) │ └── README │ ├── lib/ # 自定义库文件夹(项目通常不用) │ └── README │ ├── data/ # 文件系统数据(LittleFS) │ └── (可选的资源文件) │ ├── src-backup/ # 备份版本 │ ├── 小小潜水员单屏版.cpp # 之前的单屏版本(参考) │ └── 小小潜水员双屏版.cpp # 之前的双屏版本(参考) │ └── test/ # 测试文件夹(暂未使用) └── README ``` ### 主要文件说明 #### `platformio.ini` - 编译配置 告诉PlatformIO: - 用什么开发板(ESP32-S3) - 用什么编译器 - 需要什么库(Adafruit、U8g2等) - 用什么串口速率 **修改时机**: - 换不同ESP32型号 → 改 `board =` 这行 - 加新库 → 在 `lib_deps` 加一行 #### `src/main.cpp` - 主程序 包含所有游戏逻辑: - 初始化硬件(屏幕、传感器) - 主游戏循环 - 绘图函数 - 物理检测(碰撞) **最常改的参数**(都在文件顶部): ```cpp #define SENSOR_DRY 4000 // 传感器校准 #define SENSOR_WET 2000 #define WORLD_MAX_DEPTH 200 // 最大深度 #define DIVER_SPEED_X8 8 // 潜水员游速 #define TARGET_FPS_MS 28 // 帧率(越小越快) ``` --- ## 常见问题 ### ❌ 问题1:屏幕不显示内容(全黑或乱码) **可能原因          接线检查** | 原因 | 解决方法 | |------|--------| | I2C接线松动 | 重新拔插杜邦线,检查是否完全插入 | | 屏幕地址冲突 | 两块屏都是 0x3C,需改一块的地址跳线 | | 没装依赖库 | PlatformIO编译时会自动下载,检查输出日志 | | 屏幕坏了 | 换一块屏测试 | **快速诊断**: ```cpp // 在 main.cpp setup() 开始加这几行,编译上传,打开串口监视器 Serial.begin(115200); Serial.println("Testing I2C..."); // 会打印发现的设备地址 ``` --- ### ❌ 问题2:编译失败,提示"library not found" **现象**: ``` fatal error: Adafruit_SSD1306.h: No such file or directory ``` **解决**: 1. 检查 `platformio.ini` 中的 `lib_deps` 是否完整 2. 删除 `.platformio` 文件夹(PlatformIO缓存),让它重新下载 3. 执行命令:`platformio lib update` --- ### ❌ 问题3:上传失败,提示"COM口打不开"或"无法检测到开发板" **原因                 解决方案** | 原因 | 解决 | |------|-----| | USB线是充电线(不支持数据传输) | 换一条带数据传输功能的USB-C线 | | 驱动未安装 | Windows可能需要 CH340/CH341 驱动,去网上搜下载 | | 其他程序占用COM口 | 关闭Arduino IDE、其他串口工具,重启VS Code | | 开发板是损坏的 | 换一块开发板 | **快速检测**:设备管理器里看是否出现 `COM3` 或 `COM4` 之类的端口。 --- ### ❌ 问题4:传感器反应很慢或没反应 **调试步骤**: 1. **确认传感器接线** - 信号引脚 → IO10 - VCC → 3V3, GND → GND 2. **添加调试代码**(在 `main.cpp` 的 loop() 开始): ```cpp static int lastPrint = 0; if (millis() - lastPrint > 500) { int sensorValue = analogRead(10); Serial.println(sensorValue); // 打印ADC值 lastPrint = millis(); } ``` 3. **打开串口监视器**(波特率115200) - 看数值是否跟着变化 - 没变 → 接线有问题 - 反向变化 → 改 `SENSOR_DRY` 和 `SENSOR_WET` 的数值 --- ### ✅ 问题5:游戏卡顿/掉帧 **原因与优化**: | 现象 | 可能原因 | 优化方法 | |------|--------|--------| | 画面不流畅 | 帧率设置太低 | 改 `TARGET_FPS_MS = 20`(数字越小越快) | | 屏幕闪烁 | I2C速度不匹配 | 检查 `main.cpp` 中 I2C 初始化的波特率 | | 偶尔卡顿 | PSRAM初始化不稳定 | 更新 platformio.ini 的 PSRAM参数 | **推荐参数**: ```cpp #define TARGET_FPS_MS 28 // 约35 FPS #define OLED_CLOCKDIV_GAME 0xA0 // 提升游戏屏速率 #define INFO_REFRESH_PLAY_MS 28 // 信息屏同步 ``` --- ## 高级调整 ### 🎨 修改游戏难度 在 `src/main.cpp` 修改这些参数: ```cpp // 增加宝藏数量(但需改 MAX_TREASURES) #define MAX_TREASURES 6 // 改成 8 或 10 // 增加水母数量 #define MAX_JELLYFISH 5 // 改成 7 或 10 // 修改潜水员游速 #define DIVER_SPEED_X8 8 // 改成 12(更快)或 5(更慢) // 修改游戏区域大小 #define WORLD_MAX_DEPTH 200 // 改成 300 允许更深的潜水 ``` 修改后 → 保存 → 重新编译上传。 --- ### 🔊 调整音量/禁用蜂鸣器 没接蜂鸣器 → 注释掉音频代码: 在 setup() 中找到初始化蜂鸣器的代码,改成: ```cpp // pinMode(DO_PIN, OUTPUT); // 注释掉这行 // digitalWrite(DO_PIN, 0); // 注释掉这行 ``` --- ### 📊 添加调试信息 想看游戏内部变量(分数、深度、碰撞等),改 `main.cpp` 中的: ```cpp // #define DEBUG_MODE 0 改成下面这行 #define DEBUG_MODE 1 // 启用调试模式 ``` 重新编译后,串口会输出详细信息。 --- ### 🎮 添加本地排行榜(LittleFS) 项目已配置LittleFS(ESP32的文件系统),可以保存分数。 在 `data/` 文件夹创建 `ranking.txt`,格式: ``` Score:1000 Score:800 Score:650 ``` 游戏可以读这个文件显示排行。(具体实现代码暂未集成,可自行添加) --- ## 📞 获取帮助 ### 常问渠道 1. **项目GitHub Issues** → 提问题和Bug报告 2. **ESP32官方文档** → https://docs.espressif.com/ 3. **PlatformIO文档** → https://docs.platformio.org/ 4. **Adafruit库文档** → https://github.com/adafruit/Adafruit_SSD1306 ### 提问时请提供 - 开发板型号(如 ESP32-S3-DevKitC-1) - 屏幕型号(通常是 SSD1306) - 出现的错误信息(最好带截图) - 你做过的调试步骤 --- ## 📄 许可证 本项目代码默认遵循 **MIT许可证**(如有改变会另行说明)。 --- ## 🙏 致谢 感谢使用本项目!如果你的小小潜水员游戏成功运行了,欢迎: - 分享你的改进和想法 - 在 Issues 提交Bug - 给项目一个 Star ⭐ 祝你玩得开心!🌊🤿✨