基于Deepin 23与树莓派的智能小车:从GPIO控制到Web遥控实践

基于Deepin 23与树莓派的智能小车:从GPIO控制到Web遥控实践 1. 项目概述与核心思路之前折腾树莓派装过各种系统从官方的Raspberry Pi OS到Ubuntu Server总觉得差点意思。直到把deepin 23装上去看到那个熟悉的、精致的桌面环境在小小的板子上跑起来感觉一下子就对了。但光有个漂亮的系统还不够树莓派的灵魂在于它的GPIO在于它能和真实世界“握手”。所以这次我们不玩虚的直接上硬菜用deepin 23 树莓派驱动一个实实在在的智能小车底盘让它听你的话前后左右跑起来。这个项目本质上是一个软硬件结合的嵌入式控制实践。核心思路非常清晰以树莓派作为“大脑”和“决策中心”运行我们基于Python编写的控制程序以TB6612FNG电机驱动模块作为“神经中枢”和“功率放大器”负责将树莓派GPIO输出的微弱控制信号转换成足以驱动直流电机的电流和电压最后通过两个直流减速电机组成的“双腿”带动小车底盘运动。而deepin 23在这里扮演的角色是一个稳定、友好且功能完整的开发与运行平台。它提供了我们熟悉的桌面环境用于代码编写和调试其底层的Debian系架构又保证了丰富的软件包支持和稳定的系统服务比如我们将要用到的pigpiod服务。整个项目的价值在于它打通了从高级操作系统deepin到低级硬件控制电机的完整链路。你不仅是在学习如何接线和写几行Python更是在理解一个典型的物联网或机器人项目中软件层、系统服务层、硬件抽象层和物理执行层是如何协同工作的。这对于想入门机器人、嵌入式开发或者单纯想给树莓派找个有趣“身体”的朋友来说是一个绝佳的起点。下面我们就从硬件清单开始一步步拆解直到让你的小车在桌面上跑出第一个轨迹。2. 硬件选型、清单与连接原理动手之前清点并理解每一件硬件是成功的第一步。这里的每一个组件都不是随意选择的背后都有其考量。2.1 核心控制器树莓派 4B选择树莓派4B作为主控几乎是当前平衡性能、功耗、社区支持和性价比的最优解。相比前代4B的CPU和GPU性能有显著提升这意味着运行deepin 23桌面环境会更加流畅。更重要的是它提供了标准的40针GPIO接口这是我们与外部硬件通信的物理桥梁。GPIO通用输入输出引脚可以编程控制为高电平3.3V或低电平0V或者读取外部电压状态我们正是通过它向TB6612模块发送控制信号。注意树莓派3B或更新型号理论上也可以但4B在处理桌面环境和未来可能更复杂的任务如图像识别时余量更足。务必确认你的树莓派型号因为GPIO引脚排列是统一的但不同型号的电源管理和性能会影响整体体验。2.2 执行机构智能小车底盘与电机这里选择的是常见的“智能小车底盘”通常包含一个双层亚克力或金属底盘、两个带减速箱的直流电机已集成车轮、一个万向轮或球轮以及一个安装电池盒的支架。直流减速电机这是小车的“肌肉”。为什么是“减速”电机因为普通直流电机转速太高、扭矩太小直接驱动车轮会导致小车速度过快、力量不足无法起步或爬坡。减速箱通过齿轮组将高速低扭矩转换为低速高扭矩让小车更有“劲”。电机参数通常这种套件里的电机工作电压在3-6V之间。使用两节5号电池串联约3V或一节18650锂电池约3.7V驱动是合适的。直接连接树莓派的5V或3.3V引脚是无法驱动电机的电流远远不够这就是我们需要驱动模块的核心原因。2.3 动力心脏电源系统这个项目需要两套独立的供电系统这是新手最容易忽略和出错的关键点。树莓派供电采用Type-C接口的5V锂电池。这是最稳定可靠的选择。树莓派4B对电源质量要求较高劣质电源或电量不足的电池会导致系统不稳定、重启或损坏。一块容量在10000mAh以上的5V PD快充移动电源是绝佳选择它既能提供持续稳定的5V电压又有足够的电量支持长时间运行。电机驱动供电使用**电池盒装入2节5号电池约3V**为电机驱动模块VM引脚供电。这里为什么不用树莓派的5V因为电机启动和堵转时会产生很大的瞬时电流可能高达1A以上如果和树莓派共用电源这个电流波动会严重影响树莓派的电压稳定性导致其重启或损坏。物理隔离这两路电源是保证系统稳定的铁律。2.4 核心桥梁TB6612FNG电机驱动模块这是本项目的“明星”组件比常用的L298N驱动先进一代。理解它的优势和工作原理至关重要。为什么是TB6612FNG而不是L298N效率TB6612采用MOSFET管导通内阻小发热量远低于L298N的双极型晶体管效率更高更省电。体积与集成度TB6612模块体积小巧集成了必要的保护电路而L298N通常需要额外加装散热片和续流二极管。控制方式两者都支持PWM调速和方向控制但TB6612的逻辑更清晰引脚功能更明确。模块引脚功能深度解析 我们对照提供的接线表深入理解每个引脚模块引脚连接至功能解析与注意事项PWMA/AIN1/AIN2树莓派 GPIO这一组引脚控制A电机假设为左电机。AIN1和AIN2是方向控制引脚通过它们的高低电平组合决定电机正转、反转或刹车。PWMA是调速引脚需要接收来自树莓派的PWM脉冲宽度调制信号通过改变脉冲的占空比来调节电机电压的平均值从而实现调速。PWMB/BIN1/BIN2树莓派 GPIO控制B电机假设为右电机原理同A组。STBY树莓派 3.3V待机控制引脚。此引脚为高电平时驱动芯片才正常工作为低电平时所有输出关闭电机处于自由停止状态。通常我们直接接高电平3.3V使其一直工作。你也可以将它连接到一个GPIO上通过程序控制小车的总启停。VM电机电源正极电池盒电机驱动电压输入。接你的电机电源2节5号电池正极。这个电压决定了电机的最高转速和扭矩必须与电机额定电压匹配。GND (Power)电机电源负极电池盒-电机电源地。必须与树莓派的GND相连形成共同的参考地否则控制信号无法被正确识别。VCC树莓派 5V逻辑电平供电。给TB6612内部的逻辑电路供电使其能正确理解树莓派3.3V的控制信号。必须接。GND (Logic)树莓派 GND逻辑地。与树莓派GND相连。AO1/AO2A电机线不分正负接A电机的两根线。交换这两根线电机的转向会相反。BO1/BO2B电机线不分正负接B电机的两根线。实操心得电源共地是关键。务必确保电机驱动模块的GND (Power)和树莓派的GND用杜邦线可靠地连接在一起。这是所有数字电路正常通信的基础如果“地”没接好会出现控制失灵、信号乱跳等各种诡异问题。3. deepin 23系统环境与软件配置硬件连接是骨架软件环境则是灵魂。在deepin 23上配置开发环境过程与在Ubuntu或Debian上非常相似得益于其优秀的兼容性。3.1 Python虚拟环境配置在系统Python环境下直接安装包可能会引起版本冲突。使用虚拟环境venv是为项目创建独立、纯净Python运行空间的最佳实践。# 1. 更新软件包列表确保安装源是最新的 sudo apt update # 2. 安装必要的Python3工具链 # python3-pip: Python包管理工具 # python3-venv: 创建虚拟环境的模块 # python-dev-is-python3: 确保python命令指向python3deepin 23可能已默认配置安装更保险 sudo apt install python3-pip python3-venv python-dev-is-python3 -y # 3. 为小车项目创建一个专属的虚拟环境命名为venv名字可自定 python3 -m venv venv # 4. 激活虚拟环境 # 激活后命令提示符前通常会出现(venv)字样意味着后续的pip安装和python运行都局限在此环境中 source venv/bin/activate # 5. 在虚拟环境中安装项目所需的Python库 # bottle: 一个轻量级的Web框架用于创建我们后续的控制网页界面。 # rpi.gpio: 树莓派GPIO库的Python接口用于控制引脚。 pip3 install bottle rpi.gpio注意事项每次打开新的终端窗口进行项目开发时都需要先切换到项目目录然后执行source venv/bin/activate来重新激活虚拟环境。否则会使用系统全局的Python环境。3.2 安装并启用pigpio守护进程这是比直接使用RPi.GPIO库更优的一种GPIO控制方式。为什么用pigpio而不是直接用RPi.GPIO远程控制能力pigpiod是一个守护进程服务它允许通过网络TCP/IP来控制GPIO。这意味着你的控制程序Python脚本甚至可以运行在另一台电脑上通过网络指令让树莓派控制小车。更精准的硬件PWM树莓派的硬件PWM引脚有限pigpio库可以利用DMA和PWM/PCM硬件在任意GPIO上生成更稳定、更精准的软件PWM信号这对于需要平滑调速的小车应用非常重要。减少权限麻烦通过pigpiod服务访问GPIO可以避免Python脚本直接使用sudo权限操作硬件可能带来的安全问题。# 1. 安装pigpio守护进程及其客户端库 sudo apt install pigpiod -y # 2. 设置pigpiod服务开机自启 sudo systemctl enable pigpiod # 3. 立即启动pigpiod服务 sudo systemctl start pigpiod # 4. (可选) 检查服务运行状态 sudo systemctl status pigpiod看到状态显示为active (running)说明服务已成功启动。这个服务会在后台一直运行等待我们的Python程序连接并发送控制指令。4. 硬件连接实战与电路详解纸上得来终觉浅现在让我们拿起杜邦线和面包板如果使用开始真正的硬件连接。请务必在断电状态下进行所有接线操作。4.1 接线步骤与核对清单请严格按照下表使用公对母杜邦线进行连接并完成一项勾选一项序号TB6612FNG 引脚连接至 树莓派 GPIO (BCM编号)物理引脚号线色建议完成打钩1VCC5V Power引脚 2 或 4红色☐2GND (Logic)GND引脚 6, 9, 14, 20, 25, 30, 34, 39 任一黑色☐3STBY3.3V Power引脚 1 或 17橙色/黄色☐4AIN1GPIO17引脚 11黄色☐5AIN2GPIO27引脚 13绿色☐6PWMAGPIO18引脚 12蓝色☐7BIN1GPIO22引脚 15紫色☐8BIN2GPIO23引脚 16灰色☐9PWMBGPIO19引脚 35白色☐10GND (Power)电池盒负极和树莓派GND电池盒“-”端接出线并同时连接到树莓派任一GND引脚如引脚39黑色☐11VM电池盒正极电池盒“”端红色☐12AO1 / AO2左电机线(两根不分顺序)-通常电机自带红黑线☐13BO1 / BO2右电机线(两根不分顺序)-通常电机自带红黑线☐接线核心要点与验证电源隔离再次强调给树莓派供电的Type-C锂电池和给电机驱动VM供电的5号电池盒是两套独立的电源。它们之间唯一的公共连接点就是“地”GND。共地上表中第2步和第10步最终都将TB6612的逻辑地、电机电源地与树莓派的地连接在了一起。这是必须的。引脚编号树莓派GPIO有“物理引脚编号”板上1-40的顺序和“BCM编号”GPIO17, GPIO18等编程时使用的编号。上表已同时列出接线时按物理引脚号插编程时使用BCM编号。务必对照树莓派GPIO引脚图仔细核对。STBY接高电平我们将STBY直接接3.3V意味着驱动模块一直处于工作状态。如果你想通过程序控制总开关可以将其连接到一个GPIO如GPIO24并在代码中初始化为高电平。4.2 上电前最终检查在接通任何电源前请花一分钟进行“三检”一检线路对照表格肉眼检查每根杜邦线是否插在了正确的引脚上连接是否牢固有无松动或插错排针。二检短路检查所有裸露的金属部分特别是电源正负极、相邻GPIO引脚有没有意外碰在一起的风险。可以使用万用表通断档检查5V和GND之间是否短路蜂鸣器响则危险。三检电源确认Type-C锂电池开关未打开5号电池盒未装入电池。确认无误后先只打开给树莓派供电的Type-C锂电池开关。观察树莓派指示灯正常启动进入deepin 23系统。此时电机驱动模块因VM未供电电机不应转动。5. 控制程序解析与Web界面部署硬件就绪系统环境配置完成接下来就是让小车“活”起来的代码部分。我们将使用原作者valieo的项目进行修改和深度解析。5.1 获取与理解源代码在终端中切换到你的项目目录例如~/Projects/然后克隆代码# 克隆项目仓库 git clone https://github.com/valieo/Raspberry-Car.git cd Raspberry-Car # 确保虚拟环境已激活 source ../venv/bin/activate # 如果venv在上级目录 # 或 source venv/bin/activate # 如果venv在当前目录让我们深入看一下核心控制文件Start.py的关键部分。理解代码逻辑比单纯运行更重要。#!/usr/bin/env python3 # -*- coding: utf-8 -*- import pigpio from bottle import route, run, template, request import sys # 初始化pigpio库连接到本地运行的pigpiod守护进程 pi pigpio.pi() # 定义GPIO引脚BCM编号与TB6612的对应关系 # 左电机 AIN1 17 # 方向引脚1 AIN2 27 # 方向引脚2 PWMA 18 # PWM调速引脚 # 右电机 BIN1 22 BIN2 23 PWMB 19 # 初始化所有控制引脚为输出模式 for pin in [AIN1, AIN2, PWMA, BIN1, BIN2, PWMB]: pi.set_mode(pin, pigpio.OUTPUT) pi.write(pin, 0) # 初始化为低电平 # 设置PWM频率单位Hz。这里设为1000即1kHz对于直流电机调速是常用频率。 PWM_FREQ 1000 # 核心电机控制函数 def set_motor_speed(motor, speed): 控制指定电机速度和方向。 :param motor: left 或 right :param speed: -255 到 255。正数正转负数反转绝对值大小代表速度。 if motor left: in1, in2, pwm AIN1, AIN2, PWMA elif motor right: in1, in2, pwm BIN1, BIN2, PWMB else: return # 限制速度范围 speed max(-255, min(255, speed)) if speed 0: # 正转 pi.write(in1, 1) # TB6612逻辑IN11, IN20 为正转 pi.write(in2, 0) pi.set_PWM_dutycycle(pwm, speed) # 设置PWM占空比 (0-255) elif speed 0: # 反转 pi.write(in1, 0) # TB6612逻辑IN10, IN21 为反转 pi.write(in2, 1) pi.set_PWM_dutycycle(pwm, -speed) # 取绝对值 else: # 停止 pi.write(in1, 0) pi.write(in2, 0) pi.set_PWM_dutycycle(pwm, 0) # 定义小车的动作函数 def forward(speed200): set_motor_speed(left, speed) set_motor_speed(right, speed) def backward(speed200): set_motor_speed(left, -speed) set_motor_speed(right, -speed) def turn_left(speed200): 原地左转左轮反转右轮正转 set_motor_speed(left, -speed) set_motor_speed(right, speed) def turn_right(speed200): 原地右转左轮正转右轮反转 set_motor_speed(left, speed) set_motor_speed(right, -speed) def stop(): set_motor_speed(left, 0) set_motor_speed(right, 0) # Web服务器路由创建简单的网页控制界面 route(/) def index(): # 返回一个简单的HTML页面包含控制按钮 return template( !DOCTYPE html html headtitle树莓派小车控制器/title meta nameviewport contentwidthdevice-width, initial-scale1.0 style body {text-align: center; font-family: sans-serif;} .control {margin: 20px;} button {font-size: 24px; padding: 20px 40px; margin: 10px;} /style /head body h1Deepin 23 树莓派小车控制台/h1 div classcontrol button onclickcontrol(forward)前进/buttonbr button onclickcontrol(backward)后退/buttonbr button onclickcontrol(left)左转/button button onclickcontrol(right)右转/buttonbr button onclickcontrol(stop) stylebackground-color:#ff4444;停止/button /div script function control(cmd) { fetch(/ cmd) // 向服务器发送对应指令 .then(response response.text()) .then(data console.log(Response:, data)); } /script /body /html ) # 将动作函数绑定到Web路由 route(/forward) def api_forward(): forward() return Moving Forward route(/backward) def api_backward(): backward() return Moving Backward route(/left) def api_left(): turn_left() return Turning Left route(/right) def api_right(): turn_right() return Turning Right route(/stop) def api_stop(): stop() return Stopped # 程序退出时的清理函数 def cleanup(): stop() # 停止所有电机 pi.stop() # 断开与pigpiod的连接 print(\nGPIO资源已释放程序退出。) if __name__ __main__: try: # 启动Bottle Web服务器监听所有网络接口的8088端口 run(host0.0.0.0, port8088, debugTrue) except KeyboardInterrupt: print(用户中断程序) except Exception as e: print(f运行错误: {e}) finally: cleanup() # 确保无论何种方式退出都执行清理5.2 代码关键点解析与自定义修改PWM占空比与速度pi.set_PWM_dutycycle(pwm, speed)中的speed参数范围是0-255。255对应100%占空比全速127大约对应50%占空比半速。你可以通过调整forward(),backward()等函数中的默认速度值如200来改变小车的默认运动速度。转向逻辑示例中的turn_left()和turn_right()是原地转向差速转向的一种极端情况。如果你想实现更平滑的弧线转向可以修改为让一侧电机减速而非反转。例如左转时右轮速度保持200左轮速度降为50小车就会向左画弧线。Web服务器安全run(host0.0.0.0, port8088)意味着服务器监听所有IP地址。在家庭网络内这没问题。如果你在公共网络这存在安全风险。可以改为host127.0.0.1只允许本机访问或者配合防火墙设置。5.3 运行控制程序由于pigpio库需要访问硬件资源通常需要root权限。我们可以用sudo来运行但要注意虚拟环境路径。# 确保在项目目录 Raspberry-Car 下 # 方法一直接使用sudo运行注意激活虚拟环境的路径 sudo /home/你的用户名/Projects/venv/bin/python3 Start.py # 或者如果你将venv创建在项目目录内 sudo ./venv/bin/python3 Start.py # 方法二切换到root用户并激活虚拟环境如原文所述 sudo su source /home/你的用户名/Projects/venv/bin/activate python3 Start.py运行成功后终端会显示类似Bottle v0.12.25 server starting up (using WSGIRefServer())... Listening on http://0.0.0.0:8088/的信息。6. 测试、操控与问题深度排查现在激动人心的时刻到了。请将小车放在一个空旷、平坦的地面上远离桌边。6.1 首次上电与功能测试连接电机电源将两节5号电池装入电池盒。此时TB6612模块的电源指示灯如果有应该亮起。访问控制页面在你的电脑或手机需要与树莓派在同一局域网的浏览器中输入http://[树莓派的IP地址]:8088。如何获取树莓派IP在deepin 23桌面可以打开终端输入ip a或hostname -I查看。通常是以192.168.x.x开头的地址。功能测试点击网页上的“前进”、“后退”、“左转”、“右转”、“停止”按钮。每点击一个按钮浏览器可能会显示一个简短的响应文本如“Moving Forward”同时观察小车的反应。预期行为点击“前进”两个电机同时正转小车直线前进。点击“后退”两个电机同时反转小车直线后退。点击“左转”左轮反转右轮正转小车应原地顺时针旋转从上往下看。点击“右转”右轮反转左轮正转小车应原地逆时针旋转。点击“停止”所有电机停转。6.2 常见问题与排查实录干货收藏在实际操作中你几乎一定会遇到一些问题。别担心以下是经过大量实践总结的排查清单问题现象可能原因排查步骤与解决方案网页无法打开1. 树莓派IP地址错误。2. 防火墙阻止了8088端口。3. Python程序未成功运行。1. 在树莓派终端用hostname -I确认IP。2. 在树莓派终端运行sudo ufw status查看防火墙状态。如果是active暂时禁用sudo ufw disable或放行端口sudo ufw allow 8088。3. 检查终端是否有错误信息确认pigpiod服务已启动sudo systemctl status pigpiod。点击按钮网页无反应小车不动1. 浏览器控制台有CORS错误。2.pigpiod服务未运行或连接失败。3. Python脚本中GPIO引脚编号错误。1. 按F12打开浏览器开发者工具看Console是否有报错。原代码可能需添加CORS支持但对于本地局域网简单控制现代浏览器通常允许。2. 在树莓派终端运行sudo systemctl restart pigpiod重启服务。3.重点核对代码中的AIN117等BCM编号是否与你的实际接线本章节4.1的表格完全一致。小车只有一个轮子转或转向相反1. 电机线接反。2. 左右电机控制引脚定义弄反。3. 代码中左右电机转向逻辑错误。1. 这是最常见的问题。将不转或转向不对的电机的两根线如AO1和AO2对调焊接或连接。2. 检查代码中set_motor_speed(‘left‘, ...)和set_motor_speed(‘right‘, ...)函数里对应的in1, in2, pwm引脚是否正确。3. 根据TB6612真值表确认speed0时(in11, in20)的转向是否是你定义的正转。如果不是交换in1和in2的赋值逻辑。电机抖动但不转或转速很慢1. 电机供电电压不足。2. PWM频率不合适。3. 电池电量耗尽。1. 用万用表测量电池盒空载电压两节新5号电池应高于2.8V。电压过低请更换电池。尝试用3节电池约4.5V或一节18650锂电池3.7V供电注意不要超过电机额定电压。2. 尝试修改代码中的PWM_FREQ常见值有500, 1000, 2000。频率太低电机会有噪音太高可能驱动不了。3. 直接更换新电池。树莓派控制时重启或断电1. 电机电源干扰树莓派电源。2. 树莓派电源Type-C锂电池功率不足。1.绝对确保电机电源电池盒和树莓派电源是独立的只共地。检查接线。2. 使用质量好、输出电流大于2.5A的5V电源给树莓派供电。移动电源的“小电流”模式可能导致树莓派在高负载时电压被拉低而重启。程序报错pigpio.errorpigpiod守护进程未启动或无法连接。1. 运行sudo systemctl start pigpiod。2. 检查是否有其他程序占用了GPIO资源。3. 尝试重启树莓派。独家避坑技巧在正式让小车跑起来之前做一个“静态测试”。注释掉Web服务器部分在if __name__ __main__:之前直接调用forward(100)两秒然后stop()。这样可以在不启动网页的情况下快速验证电机接线和基本控制逻辑是否正确避免同时调试硬件和软件带来的混乱。7. 项目优化与扩展思路让小车能动起来只是第一步。基于这个稳定的框架你可以进行无数有趣的扩展这才是树莓派和deepin生态的魅力所在。7.1 软件层面优化更优雅的控制界面用更现代的Web框架如Flask或JavaScript库如Node.js Socket.IO重构控制页面实现实时视频流、速度滑块控制、键盘控制WASD、甚至手机重力感应控制。加入速度渐变在set_motor_speed函数中不要直接从当前速度跳到目标速度而是加入一个循环让速度值逐步递增/递减这样小车启动和停止会更平滑减少机械冲击。实现自动避障购买一个HC-SR04超声波模块很便宜连接到树莓派GPIO。写一个后台线程持续测量前方距离。当距离小于设定阈值如20厘米时自动调用turn_left()或turn_right()函数实现最基础的自动避障。创建系统服务将Start.py脚本配置为deepin的系统服务实现开机自启。这样每次上电小车控制服务器就会自动运行无需手动登录启动。7.2 硬件层面扩展增加“眼睛”为树莓派配上官方摄像头或USB摄像头。利用deepin 23上丰富的软件生态安装OpenCV库。你可以尝试颜色跟踪让小车自动跟随一个特定颜色的球。人脸检测让小车朝着人脸的方向移动。二维码导航在地面放置二维码让小车巡线到不同二维码执行不同任务。增加“手臂”使用一个舵机Servo和简单的机械臂套件通过树莓派的GPIO需额外的舵机驱动板如PCA9685控制让小车能够抓取轻量物体。升级电源与驱动如果想驱动更重的底盘或更多电机可以考虑电源使用18650锂电池组7.4V或更高搭配DC-DC降压模块如LM2596为树莓派提供稳定的5V。驱动使用功率更大的电机驱动板如L298N的升级版、VNH5019等以支持更大电流的电机。7.3 融入deepin生态deepin 23不仅仅是一个“载体”其强大的桌面环境可以让你更方便地开发和管理这个项目。使用深度终端在deepin漂亮的终端里进行所有命令行操作多标签、分屏功能让调试更高效。利用深度商店安装VSCode、Thonny等IDE获得代码高亮、自动补全和调试功能大幅提升开发体验。远程桌面控制开启deepin的远程桌面功能VNC/RDP你可以在你的主力电脑上直接远程操作树莓派的桌面编写代码、测试运行无需外接显示器键鼠。这个项目就像一颗种子你亲手完成了从零到一的搭建。而它所能生长出的可能性只取决于你的想象力。无论是作为一个有趣的玩具一个学习嵌入式开发和机器人学的平台还是一个智能家居的移动节点这辆由deepin 23和树莓派驱动的小车都已经为你打开了那扇门。