上传文件至 /

This commit is contained in:
Frank14f 2026-06-11 19:49:42 +08:00
parent 6dc255fc2d
commit 4d14308da2
2 changed files with 276 additions and 8 deletions

View File

@ -306,7 +306,8 @@ pinball_exp_rp5/
├── drv_encodermotor.py # 编码器电机驱动模块 — 控制圆柱旋转I2C 通信)
├── drv_stepmotor.py # 步进电机驱动模块 — 控制圆柱平移I2C + PWM
├── test.ipynb # 教学演示 NotebookJupyter 笔记本)
├── test.ipynb # 教学演示 NotebookJupyter 笔记本,可在 VS Code 中直接打开)
├── demo.py # 精简版演示脚本(一个文件涵盖所有模块,适合快速上手)
└── signal_features.json # 实验信号参数(已脱敏处理)
```
@ -314,26 +315,49 @@ pinball_exp_rp5/
## 8. 如何运行
本项目提供了两种运行方式:
### 方式一:运行 `demo.py`(最简方式)
```bash
# 1. 激活虚拟环境(如果之前创建了虚拟环境)
source venv/bin/activate
# 2. 启动 Jupyter Notebook
# 2. 直接运行 demo.py
python3 demo.py
```
`demo.py` 是一个精简的演示脚本,把所有功能写在一个文件里,运行后会自动在终端打印每一步的说明。适合第一次接触本项目时快速了解全貌。
### 方式二:在 VS Code / Jupyter Notebook 中打开 `test.ipynb`
`test.ipynb` 是 Jupyter Notebook 格式的文件,把文字说明和代码分块组织在一起,更适合逐步学习。
**在 VS Code 中打开:**
如果你使用 VS Code推荐直接双击 `test.ipynb` 文件即可在 VS Code 中打开。VS Code 内置了对 `.ipynb` 文件的支持,无需额外安装 Jupyter 服务器。打开后:
- 每个代码块Cell左侧有一个 ▶ 播放按钮,点击即可运行
- 也可以按 `Shift + Enter` 运行当前 Cell 并跳转到下一个
- 运行结果会直接显示在 Cell 下方
**在浏览器中使用 Jupyter Notebook**
```bash
# 1. 激活虚拟环境(如果之前创建了虚拟环境)
source venv/bin/activate
# 2. 启动 Jupyter Notebook 服务器
jupyter notebook
# 3. 终端会显示一个链接(类似 http://127.0.0.1:8888/
# 用浏览器打开这个链接
# 4. 在浏览器中点击 test.ipynb 文件
# 5. 在 Notebook 中按顺序从上到下运行每个 Cell代码单元格
# - 点击一个 Cell 选中它
# - 按 Shift + Enter 运行当前 Cell 并自动跳转到下一个
# - 也可以点工具栏上的 "Run" 按钮
```
> **什么是 Jupyter Notebook**
> Jupyter Notebook 是一种交互式的编程环境,把代码、运行结果、文字说明放在一个文件(`.ipynb`)中。每个代码块叫做一个"Cell",可以单独运行,非常适合教学和实验。
> Jupyter Notebook 是一种交互式的编程环境,把代码、运行结果、文字说明放在一个文件(`.ipynb`)中。每个代码块叫做一个"Cell"可以单独运行非常适合教学和实验。VS Code 也支持直接打开 `.ipynb` 文件。
---

244
demo.py Normal file
View File

@ -0,0 +1,244 @@
"""
============================================================================
圆柱水槽控制系统 精简演示脚本
============================================================================
本脚本演示三个驱动模块的基本用法适合第一次接触本项目时快速了解全貌
运行方式
python3 demo.py
注意事项
所有涉及真实硬件的操作都会打印 [需要硬件] 标记
如果你没有连接实际硬件可以阅读代码和打印输出来了解流程
============================================================================
"""
# ============================================================
# 第一步:导入依赖
# ============================================================
# 导入时间模块,用于延时和计时
import time
# 导入数学模块,用于数学计算(如正弦函数)
import math
# 导入三个驱动模块(请确保这些 .py 文件与本脚本在同一目录下)
# 编码器电机驱动 — 控制圆柱旋转
from drv_encodermotor import EncoderMotorDriver, SPEED_MODE
# 步进电机驱动 — 控制圆柱平移
from drv_stepmotor import StepMotorDriver
# ADC 驱动 — 采集应变片电压信号
from drv_adc import ADS124S08
# ============================================================
# 第二步EncoderMotor编码器电机演示 — 控制圆柱旋转
# ============================================================
def demo_encodermotor():
"""
演示编码器电机的速度控制流程
通过 I2C 总线与 M5Stack 4EncoderMotor 模块通信
"""
print("=" * 60)
print("【EncoderMotor】编码器电机演示 — 控制圆柱旋转")
print("=" * 60)
# 使用 with 语句创建驱动实例,退出后自动释放 I2C 资源
# bus=1 表示使用树莓派的 I2C 总线 1/dev/i2c-1
with EncoderMotorDriver(bus=1) as driver:
# 1. 设置通道 0 为速度模式SPEED_MODE
# 速度模式下,电机会自动维持设定的目标转速
print(" [需要硬件] 设置通道 0 为速度模式...")
driver.set_mode(0, SPEED_MODE)
# 2. 配置速度 PID 参数
# kp比例、ki积分、kd微分配合使速度控制更精确
print(" [需要硬件] 配置 PID 参数 (kp=1, ki=100, kd=1)...")
driver.set_speed_pid(0, kp=1, ki=100, kd=1)
# 3. 启用软启停功能,让电机加减速更平滑
print(" [需要硬件] 启用软启停...")
driver.set_soft_start_and_stop(0, True)
# 4. 设置目标线速度(单位:米/秒)
# 正数 = 正转,负数 = 反转
print(" [需要硬件] 设定目标速度0.02 m/s")
driver.set_linear_speed_m_s(0, 0.02)
# 等待 1 秒让电机跑起来
time.sleep(1)
# 5. 读取编码器数值(电机转过的脉冲数)
print(" [需要硬件] 读取编码器数值...")
encoder_val = driver.get_encoder_value(0)
print(f" 编码器数值:{encoder_val}")
# 6. 读取电机总电流
print(" [需要硬件] 读取电机电流...")
current = driver.get_motor_current()
print(f" 总电流:{current:.4f} A")
# 7. 速度归零,停止电机
print(" [需要硬件] 停止电机...")
driver.set_linear_speed_m_s(0, 0.0)
time.sleep(1)
# 退出 with 语句块I2C 连接自动关闭
print(" [完成] EncoderMotor 演示结束,资源已释放\n")
# ============================================================
# 第三步StepMotor步进电机演示 — 控制圆柱平移
# ============================================================
def demo_stepmotor():
"""
演示步进电机的控制流程
通过 I2C + 硬件 PWM M5Stack StepMotor Driver 模块通信
三个步进电机共享同一路 PWM 脉冲但方向可独立控制
"""
print("=" * 60)
print("【StepMotor】步进电机演示 — 控制圆柱平移")
print("=" * 60)
# 创建驱动实例(这里演示用 try/finally 手动释放资源)
drv = StepMotorDriver()
try:
# 1. 使能电机 — 让电机驱动芯片开始接收脉冲
print(" [需要硬件] 使能电机...")
drv.enable_motor()
# 2. 复位所有 3 个电机通道(恢复到初始状态)
print(" [需要硬件] 复位所有电机通道...")
for i in range(3):
drv.reset_motor(i, True)
# 3. 设置运动方向True=正向False=反向)
print(" [需要硬件] 设置方向为正向...")
drv.set_dir(True)
# 4. S 曲线加速启动(速度 0.02 m/s用 0.1 秒加速到目标)
# 加速曲线用了余弦函数,非常平滑
drv.ramp_time = 0.1 # 为了演示,把加减速时间设短
print(" [需要硬件] S 曲线加速启动 (0.02 m/s)...")
drv.start(0.02)
time.sleep(1)
# 5. 在运行中切换速度0.04 m/s
print(" [需要硬件] 切换速度 (0.04 m/s)...")
drv.change_speed(0.04)
time.sleep(1)
# 6. S 曲线减速停止
print(" [需要硬件] S 曲线减速停止...")
drv.stop()
print(" [完成] StepMotor 演示结束\n")
finally:
# 释放资源(停止电机、关闭 I2C 和 PWM
drv.close()
# ============================================================
# 第四步ADC模数转换器演示 — 采集电压信号
# ============================================================
def demo_adc():
"""
演示 ADC 的数据采集流程
通过 SPI 总线与 ADS124S08 芯片通信读取应变片电压信号
"""
print("=" * 60)
print("【ADC】模数转换器演示 — 采集电压信号")
print("=" * 60)
# 创建 ADC 实例(构造函数会自动完成上电和初始化)
adc = ADS124S08()
try:
# 1. 配置 PGA可编程增益放大器
# pga_en=1 启用放大gain=5 对应 ×32 倍
print(" [需要硬件] 配置 PGA (×32 倍)...")
adc.set_pga(pga_en=1, gain=5)
# 2. 配置数据速率和转换模式
# dr=8 对应 200 SPS每秒 200 次采样)
# mode=1 单次转换模式(每次触发转换一次)
print(" [需要硬件] 配置数据速率 (200 SPS, 单次模式)...")
adc.set_datarate(dr=8, mode=1)
# 3. 读取三个通道0, 1, 2的数据
# 返回 24 位有符号整数的列表
print(" [需要硬件] 读取通道 0/1/2...")
channels = [0, 1, 2]
raw_values = adc.request_channels(channels=channels)
print(f" 原始采样值:{raw_values}")
# 4. 将 ADC 原始值转换为电压
print(" 转换为电压值:")
for ch, raw in zip(channels, raw_values):
voltage = adc.convert_to_voltage(raw)
print(f" 通道 {ch}{voltage:.6f} V")
print(" [完成] ADC 演示结束\n")
finally:
# 关闭 SPI 总线,释放 GPIO 引脚
adc.close()
# ============================================================
# 第五步:信号生成演示(纯数学计算,无需硬件)
# ============================================================
def demo_signal_generation():
"""
演示如何根据频率分量合成周期运动信号
这是控制循环中的核心算法不需要硬件即可运行
"""
print("=" * 60)
print("【信号合成】周期运动信号生成演示(纯软件,无需硬件)")
print("=" * 60)
# 定义一组简化的信号特征(包含均值 + 两个正弦波分量)
signal_feature = {
"mean": 0.0, # 均值(直流分量)
"components": [ # 正弦波分量列表
(0.27, 0.005, -1.5), # (频率Hz, 幅值, 相位rad)
(0.81, 0.001, 2.8), # (频率Hz, 幅值, 相位rad)
]
}
# 在 3 秒内每隔 0.5 秒生成一个信号值
print(" 时间(s) | 信号值(m/s) ")
print(" -------|-------------")
t = 0.0
while t <= 3.0:
# 合成信号:均值 + 各正弦分量之和
value = signal_feature["mean"]
for freq, amp, phase in signal_feature["components"]:
value += amp * math.cos(2 * math.pi * freq * t + phase)
print(f" {t:5.1f} | {value:+.6f}")
t += 0.5
print(" [完成] 信号合成演示结束\n")
# ============================================================
# 主程序入口
# ============================================================
if __name__ == "__main__":
print()
print("⏺ 圆柱水槽控制系统 — 精简演示")
print("⏺ 本脚本将逐个演示三个驱动模块和信号生成功能")
print()
# 逐个执行演示(按顺序注释掉可以单独运行某个演示)
demo_encodermotor()
demo_stepmotor()
demo_adc()
demo_signal_generation()
print("=" * 60)
print("所有演示已完成。")
print("提示:运行 test.ipynb 可以获得更详细的分步讲解。")
print("=" * 60)
print()