实验04:颜色传感器巡线
这个实验做完你会得到什么
先做一个颜色识别器(把不同颜色的乐高件放到传感器下,手机报出颜色名); 再进阶到巡线小车 —— 车沿着黑色胶带自己走。
| 项目 | 说明 |
|---|---|
| 难度 | ★★★☆☆ |
| 用时 | 约 50 分钟 |
| 前置 | 实验02:差速小车遥控 |
一、器材与接线
| 器材 | 数量 | 接到 |
|---|---|---|
| EV3 主机 + 两个大型马达 | 1 | 马达接 B、C |
| EV3 颜色传感器 | 1 | 传感器接 S3 |
| 黑色电工胶带 | 1 卷 | 在白色地面贴一条闭合线路 |
传感器装在车头下方、朝向地面,离地约 5~10 毫米。太高读数弱,太低会蹭到地面。
二、三种工作模式
颜色传感器有三种模式,必须先设对模式再读数:
| 模式 | 设置方法 | 读什么 | 用在哪 |
|---|---|---|---|
| 颜色模式 | SetColorMode() |
颜色编号 / 颜色名 | 识别色块 |
| 反射光模式 | SetReflectedMode() |
0~100 的反光百分比(读不到返回 -1) | 巡线 |
| 环境光模式 | SetAmbientMode() |
0~100 的环境亮度 | 检测明暗 |
巡线要用反射光模式,不是颜色模式。颜色模式只能给出有限的几种颜色, 在黑白交界处会跳来跳去;反射光给的是连续值(白色 ~70、黑色 ~10), 能判断”压线多少”,控制才平滑。
三、界面组件
| 组件 | 命名 | 关键属性 |
|---|---|---|
| 按钮 | 按钮_识别颜色 |
文本「读一次颜色」 |
| 标签 | 标签_颜色 |
字号 28,文本「–」 |
| 标签 | 标签_反光 |
文本「反光值:–」 |
| 按钮 | 按钮_标定白 / 按钮_标定黑 |
文本「记录白」「记录黑」 |
| 按钮 | 按钮_巡线 |
文本「开始巡线」 |
| 计时器 | 计时器1 |
计时器启用取消勾选、间隔 100 |
| EV3颜色传感器 | EV3颜色传感器1 |
BluetoothClient = 蓝牙客户端1、SensorPort = 3 |
| EV3马达 | EV3马达1 |
BluetoothClient = 蓝牙客户端1、MotorPorts = BC |
四、分步搭代码块
第 1 步:颜色识别
when 按钮_识别颜色.Click() {
EV3颜色传感器1.SetColorMode()
标签_颜色.Text = EV3颜色传感器1.GetColorName()
}
中途验证:把红/蓝/绿色的乐高件放到传感器下方,点按钮,显示对应颜色名。
GetColorName()返回颜色名字符串,GetColorCode()返回数字编号。 要做逻辑判断用编号更方便(不用比字符串)。识别距离很关键:传感器要贴近物体(1 厘米内),远了全都读成
none。
第 2 步:切到反射光模式,标定黑白
global 白值 = 70
global 黑值 = 10
global 反光 = 0
when 按钮_读反光.Click() {
EV3颜色传感器1.SetReflectedMode()
global 反光 = EV3颜色传感器1.GetLightLevel()
标签_反光.Text = join("反光值:", 反光)
}
when 按钮_标定白.Click() {
global 白值 = 反光
标签_状态.Text = join("白值 = ", 白值)
}
when 按钮_标定黑.Click() {
global 黑值 = 反光
标签_状态.Text = join("黑值 = ", 黑值)
}
中途验证:传感器放白色地面上读一次点「记录白」,放黑胶带上读一次点「记录黑」。 两个值应该差 30 以上,差太小说明传感器离地太高或环境光太强。
一定要标定。教程里写的 70 和 10 只是典型值 —— 换个地面、换个灯光、 甚至白天晚上,读数都不一样。巡线失败十有八九是没标定。
第 3 步:单边巡线
最经典的巡线算法:盯着黑线的一条边走,压得多就往外拐,压得少就往里拐。
global 白值 = 70
global 黑值 = 10
when 按钮_巡线.Click() {
EV3颜色传感器1.SetReflectedMode()
计时器1.TimerEnabled = true
标签_状态.Text = "巡线中…"
}
when 计时器1.Timer() {
var 当前 = EV3颜色传感器1.GetLightLevel()
var 中线 = (白值 + 黑值) / 2
var 偏差 = 当前 - 中线
var 转向 = max(-80, min(80, 偏差 * 2))
标签_反光.Text = join("反光 ", 当前, " 转向 ", round(转向))
EV3马达1.RotateSyncIndefinitely(35, round(转向))
}
when 按钮_停.Click() {
计时器1.TimerEnabled = false
EV3马达1.Stop(true)
标签_状态.Text = "已停止"
}
中途验证:把车放在黑线边缘(传感器一半压着线),点「开始巡线」,车沿着线的边缘走。
原理:中线是黑白的中间值。压到白多(当前 > 中线)就朝一边拐, 压到黑多就朝另一边拐 —— 这就是最简单的比例控制(P 控制)。
* 2是比例系数,决定反应强度:太小转不过弯冲出线,太大来回蛇形摆动。 从 2 开始试,蛇行就调小、过不了弯就调大。走反了怎么办:
偏差 * 2改成偏差 * -2即可 —— 这取决于传感器压在线的 左边还是右边。
第 4 步:丢线保护(可选)
global 白值 = 70
when 计时器1.Timer() {
var 当前 = EV3颜色传感器1.GetLightLevel()
if 当前 > 白值 - 5 {
EV3马达1.RotateSyncIndefinitely(30, 60)
标签_状态.Text = "丢线,正在找回"
}
}
完全读到白色说明车跑出线了。让它朝一个固定方向转圈找线, 通常几秒内就能重新压上。
五、排错表
| 现象 | 原因与处理 |
|---|---|
颜色一直读成 none |
传感器离物体太远,凑近到 1 厘米内 |
| 反光值黑白差别很小 | 传感器离地太高(应 5~10 毫米);或环境光太强,关掉直射灯 |
| 车压着线不动 | 功率太低(<25 带不动);或计时器没启用 |
| 车蛇形剧烈摆动 | 比例系数太大,从 * 2 降到 * 1 |
| 车过不了弯直接冲出去 | 比例系数太小;或前进功率太高,降到 30 |
| 车朝反方向拐 | 比例系数取负,或把传感器移到线的另一侧 |
| 巡一会儿就丢线 | 没标定,或弯道太急。加第 4 步的丢线保护 |
| 换个房间就不灵 | 光照变了,重新标定 |
| 读到 -1 | 组件文档:读不到时返回 -1。传感器线松了或端口不对,别把 -1 当成有效亮度参与计算 |
六、下一步
- 实验05:陀螺仪精确转向 —— 转准 90 度
- EV3 超声波避障 —— 巡线 + 避障合起来就是完整的竞赛车
扫码添加客服咨询