znlgis 博客

GIS开发与技术分享

第7章:红外与光电传感器

本章介绍避障传感器、循线传感器、光折断传感器等红外/光电类传感器的工作原理与应用。


7.1 红外避障传感器

7.1.1 工作原理

红外避障传感器由红外发射管和红外接收管组成:

   红外发射管        障碍物        红外接收管
      ↓               ↓               ↓
     TX ────→ 红外光 ←───反射───→ RX
              ←───────────────→
                  探测范围

工作流程

  1. NE555 时基电路驱动发射管发送 38kHz 红外信号
  2. 红外光照射到障碍物反射回来
  3. 接收管检测反射信号强度
  4. LM393 比较器判断是否超过阈值

7.1.2 输出逻辑

状态 信号值 LED
检测到障碍物 低电平 (0)
无障碍物 高电平 (1)

7.1.3 灵敏度调节

模块上有两个电位器:

  • 发射功率调节:调节红外发射强度
  • 接收频率调节:调节接收灵敏度

调节方法

  1. 顺时针调节发射功率电位器到底,再回调少许
  2. 调节使 P LED 处于亮与不亮的临界点
  3. 调节接收频率电位器,使 S LED 在临界点

7.1.4 检测代码

'''
实验:红外避障检测
接线:S 端连接 GP16
'''
from machine import Pin
import time

obstacle = Pin(16, Pin.IN)

while True:
    if obstacle.value() == 0:
        print("检测到障碍物!")
    else:
        print("无障碍物")
    time.sleep(0.1)

7.1.5 避障小车逻辑

'''
实验:双传感器避障逻辑
'''
from machine import Pin
import time

left_sensor = Pin(16, Pin.IN)
right_sensor = Pin(17, Pin.IN)

def get_obstacle_state():
    """获取障碍物状态"""
    left = left_sensor.value() == 0
    right = right_sensor.value() == 0
    return left, right

def decide_action(left, right):
    """决策动作"""
    if not left and not right:
        return "前进"
    elif left and not right:
        return "右转"
    elif not left and right:
        return "左转"
    else:
        return "后退"

while True:
    left, right = get_obstacle_state()
    action = decide_action(left, right)
    print(f"左:{left} 右:{right}{action}")
    time.sleep(0.2)

7.2 循线传感器

7.2.1 工作原理

循线传感器基于 TCRT5000 反射式红外传感器:

        红外 LED (发射)
            ↓
    ═══════════════════  黑线(吸收)
    ───────────────────  白底(反射)
            ↑
        光敏三极管 (接收)

颜色检测原理

  • 黑色:吸收红外光 → 反射少 → 信号弱 → 输出高电平
  • 白色:反射红外光 → 反射强 → 信号强 → 输出低电平

7.2.2 输出逻辑

检测表面 信号值
白色/浅色 低电平 (0)
黑色/深色 高电平 (1)

7.2.3 灵敏度调节

调节电位器改变检测灵敏度(高度范围 0-3cm):

  • 顺时针旋转:提高灵敏度
  • 逆时针旋转:降低灵敏度

最佳状态:LED 处于亮与不亮临界点

7.2.4 循线检测代码

'''
实验:循线传感器检测
接线:S 端连接 GP3
'''
from machine import Pin
import time

tracker = Pin(3, Pin.IN, Pin.PULL_UP)

while True:
    if tracker.value() == 0:
        print("检测到白色/浅色")
    else:
        print("检测到黑色/深色")
    time.sleep(0.1)

7.2.5 循线小车逻辑

'''
实验:三路循线传感器
'''
from machine import Pin
import time

left = Pin(2, Pin.IN)
center = Pin(3, Pin.IN)
right = Pin(4, Pin.IN)

def get_line_state():
    """获取循线状态 (1=黑线, 0=白底)"""
    return (left.value(), center.value(), right.value())

def decide_action(state):
    """根据状态决定动作"""
    l, c, r = state
    
    if c == 1 and l == 0 and r == 0:
        return "直行"
    elif l == 1 and c == 1:
        return "左转"
    elif r == 1 and c == 1:
        return "右转"
    elif l == 1 and c == 0 and r == 0:
        return "急左转"
    elif l == 0 and c == 0 and r == 1:
        return "急右转"
    elif l == 1 and c == 1 and r == 1:
        return "停止(十字路口)"
    else:
        return "寻找黑线"

while True:
    state = get_line_state()
    action = decide_action(state)
    print(f"状态:{state}{action}")
    time.sleep(0.1)

7.3 光折断传感器

7.3.1 工作原理

光折断传感器(槽型光电开关)由 ITR-9608 组成:

    ┌─────┐   ┌─────┐
    │ LED │   │ PT  │
    │发射 │   │接收 │
    └──┬──┘   └──┬──┘
       │   槽   │
       │   ↓    │
    ═══│═══════│═══  ← 遮挡物穿过
       │       │

工作流程

  1. 红外 LED 持续发光
  2. 光敏三极管持续接收
  3. 物体遮挡时,信号中断
  4. 可用于计数、测速

7.3.2 输出逻辑

状态 信号值 LED
无遮挡 低电平 (0)
有遮挡 高电平 (1)

7.3.3 计数应用

'''
实验:光折断计数器
接线:S 端连接 GP3
'''
from machine import Pin
import time

sensor = Pin(3, Pin.IN, Pin.PULL_UP)

count = 0
last_state = 0

while True:
    current_state = sensor.value()
    
    # 检测上升沿(从无遮挡到遮挡)
    if current_state == 1 and last_state == 0:
        count += 1
        print(f"计数: {count}")
    
    last_state = current_state
    time.sleep(0.01)  # 10ms 采样间隔

7.3.4 转速测量

'''
实验:转速测量(RPM)
假设编码盘有 N 个槽
'''
from machine import Pin
import time

sensor = Pin(3, Pin.IN, Pin.PULL_UP)

SLOTS = 20  # 编码盘槽数
pulse_count = 0
last_state = 0

def measure_rpm(duration_ms=1000):
    """测量 RPM"""
    global pulse_count, last_state
    
    pulse_count = 0
    start = time.ticks_ms()
    
    while time.ticks_diff(time.ticks_ms(), start) < duration_ms:
        current = sensor.value()
        if current == 1 and last_state == 0:
            pulse_count += 1
        last_state = current
        time.sleep_us(100)
    
    # 计算 RPM
    revolutions = pulse_count / SLOTS
    rpm = revolutions * (60000 / duration_ms)
    return rpm

while True:
    rpm = measure_rpm(1000)
    print(f"转速: {rpm:.1f} RPM")

7.4 倾斜传感器

7.4.1 工作原理

倾斜传感器内部有一颗金属滚珠:

    正常姿态         倾斜姿态
    ┌──────┐        ┌──────┐
    │      │        │    ○ │
    │  ○   │   →    │      │
    │ ═══  │        │ ═══  │
    └──────┘        └──────┘
    滚珠接触触点      滚珠离开
    → 导通           → 断开

7.4.2 检测代码

'''
实验:倾斜检测
接线:S 端连接 GP17
'''
from machine import Pin
import time

tilt = Pin(17, Pin.IN)

while True:
    if tilt.value() == 0:
        print("传感器倾斜(触点导通)")
    else:
        print("传感器正常(触点断开)")
    time.sleep(0.1)

7.4.3 倾斜报警器

'''
实验:倾斜报警器
'''
from machine import Pin
import time

tilt = Pin(17, Pin.IN)
buzzer = Pin(20, Pin.OUT)

TILT_THRESHOLD = 3  # 连续检测次数

def is_tilted(samples=5, delay_ms=50):
    """多次采样判断倾斜状态"""
    tilt_count = sum(
        1 for _ in range(samples) 
        if tilt.value() == 0 or time.sleep_ms(delay_ms)
    )
    return tilt_count >= TILT_THRESHOLD

while True:
    if is_tilted():
        buzzer.value(1)
        print("警报!检测到倾斜!")
    else:
        buzzer.value(0)
    time.sleep(0.1)

7.5 碰撞传感器

7.5.1 工作原理

碰撞传感器使用微动开关检测物理接触:

         弹片
          ↓
    ═══════════
    │ 微动开关 │
    ═══════════
          │
        触点
  • 弹片按下 → 触点导通 → 低电平
  • 弹片松开 → 触点断开 → 高电平(上拉)

7.5.2 检测代码

'''
实验:碰撞检测
接线:S 端连接 GP17
'''
from machine import Pin
import time

collision = Pin(17, Pin.IN)

while True:
    if collision.value() == 0:
        print("检测到碰撞!")
    else:
        print("正常")
    time.sleep(0.1)

7.5.3 碰撞保护

'''
实验:碰撞保护系统
'''
from machine import Pin
import time

front_collision = Pin(17, Pin.IN)
motor_enable = Pin(0, Pin.OUT)

motor_enable.value(1)  # 启动电机

while True:
    if front_collision.value() == 0:
        # 碰撞!立即停止
        motor_enable.value(0)
        print("碰撞!电机停止!")
        
        # 等待碰撞解除
        while front_collision.value() == 0:
            time.sleep(0.1)
        
        print("碰撞解除,3秒后恢复")
        time.sleep(3)
        motor_enable.value(1)
    
    time.sleep(0.05)

7.6 传感器信号编码总结

7.6.1 数字信号编码

传感器 检测到目标 未检测到 编码逻辑
避障传感器 0 (低) 1 (高) 低有效
循线传感器 1 (黑) 0 (白) 高=黑
光折断传感器 1 (遮挡) 0 (通) 高=遮挡
倾斜传感器 0 (倾斜) 1 (正常) 低有效
碰撞传感器 0 (碰撞) 1 (正常) 低有效

7.6.2 统一接口封装

class DigitalSensor:
    """数字传感器通用类"""
    
    def __init__(self, pin_num, active_low=True, pull_up=True):
        """
        pin_num: GPIO 引脚号
        active_low: True 表示低电平有效
        pull_up: 是否启用内部上拉
        """
        pull = Pin.PULL_UP if pull_up else None
        self.pin = Pin(pin_num, Pin.IN, pull)
        self.active_low = active_low
    
    def is_active(self):
        """检测是否触发"""
        value = self.pin.value()
        return value == 0 if self.active_low else value == 1
    
    def value(self):
        """原始值"""
        return self.pin.value()

# 使用示例
obstacle = DigitalSensor(16, active_low=True)
tracker = DigitalSensor(3, active_low=False)

if obstacle.is_active():
    print("检测到障碍物")

7.7 本章小结

本章介绍了红外与光电类传感器:

  1. 避障传感器:红外反射检测,低电平表示有障碍物
  2. 循线传感器:黑色吸收、白色反射原理
  3. 光折断传感器:槽型设计,适合计数测速
  4. 倾斜传感器:滚珠开关原理
  5. 碰撞传感器:微动开关机械检测

下一章将学习磁场检测传感器。