znlgis 博客

GIS开发与技术分享

第24章:综合项目实践

本章通过几个综合项目,整合前面所学的传感器和执行器知识。


24.1 智能家居监控系统

24.1.1 系统功能

  • 温湿度监测
  • 光照检测
  • 烟雾报警
  • LCD 显示
  • LED 指示

24.1.2 硬件连接

DHT11      → GP19
光敏传感器  → GP26 (ADC0)
MQ-2       → GP27 (ADC1), GP22 (数字)
LCD1602    → I2C (GP20, GP21)
蜂鸣器     → GP15
LED        → GP0

24.1.3 完整代码

'''
智能家居监控系统
'''
from machine import Pin, ADC, I2C
import dht
import time

# 初始化传感器
dht_sensor = dht.DHT11(Pin(19))
light_sensor = ADC(26)
smoke_analog = ADC(27)
smoke_digital = Pin(22, Pin.IN)

# 初始化执行器
buzzer = Pin(15, Pin.OUT)
led = Pin(0, Pin.OUT)

# 初始化 LCD
i2c = I2C(0, sda=Pin(20), scl=Pin(21))
# lcd = LCD1602_I2C(i2c)  # 需要导入 LCD 驱动

class SmartHomeMonitor:
    def __init__(self):
        self.temp = 0
        self.humidity = 0
        self.light = 0
        self.smoke = 0
        self.smoke_alert = False
    
    def read_sensors(self):
        """读取所有传感器"""
        # DHT11
        try:
            dht_sensor.measure()
            self.temp = dht_sensor.temperature()
            self.humidity = dht_sensor.humidity()
        except:
            pass
        
        # 光照
        raw = light_sensor.read_u16()
        self.light = 100 - (raw / 65535 * 100)
        
        # 烟雾
        self.smoke = smoke_analog.read_u16()
        self.smoke_alert = smoke_digital.value() == 0
    
    def check_alerts(self):
        """检查报警条件"""
        alerts = []
        
        if self.temp > 35:
            alerts.append("高温警报!")
        if self.humidity > 80:
            alerts.append("湿度过高!")
        if self.smoke_alert:
            alerts.append("烟雾警报!")
        
        return alerts
    
    def update_display(self, alerts):
        """更新显示"""
        # LCD 显示
        # lcd.clear()
        # lcd.set_cursor(0, 0)
        # lcd.print(f"T:{self.temp}C H:{self.humidity}%")
        # lcd.set_cursor(0, 1)
        # if alerts:
        #     lcd.print(alerts[0][:16])
        # else:
        #     lcd.print(f"L:{self.light:.0f}% OK")
        
        # 串口输出
        print(f"温度: {self.temp}°C  湿度: {self.humidity}%  "
              f"光照: {self.light:.0f}%  烟雾: {self.smoke}")
        
        if alerts:
            print(f"⚠️ 警报: {', '.join(alerts)}")
    
    def handle_alerts(self, alerts):
        """处理报警"""
        if alerts:
            buzzer.value(1)
            led.value(1)
            time.sleep(0.2)
            buzzer.value(0)
            led.value(0)
            time.sleep(0.2)
        else:
            buzzer.value(0)
            led.value(0)
    
    def run(self):
        """主循环"""
        while True:
            self.read_sensors()
            alerts = self.check_alerts()
            self.update_display(alerts)
            self.handle_alerts(alerts)
            time.sleep(2)

# 运行
monitor = SmartHomeMonitor()
monitor.run()

24.2 智能小车

24.2.1 功能

  • 红外遥控
  • 避障行驶
  • 循线行驶
  • 超声波测距

24.2.2 硬件连接

左电机    → GP14, GP15
右电机    → GP16, GP17
左避障    → GP2
右避障    → GP3
循线传感器 → GP4, GP5
超声波    → GP6 (TRIG), GP7 (ECHO)
红外接收  → GP11

24.2.3 小车类

'''
智能小车控制类
'''
from machine import Pin, PWM
import time

class SmartCar:
    def __init__(self):
        # 电机
        self.motor_left_1 = PWM(Pin(14))
        self.motor_left_2 = PWM(Pin(15))
        self.motor_right_1 = PWM(Pin(16))
        self.motor_right_2 = PWM(Pin(17))
        
        for m in [self.motor_left_1, self.motor_left_2,
                  self.motor_right_1, self.motor_right_2]:
            m.freq(1000)
        
        # 传感器
        self.obs_left = Pin(2, Pin.IN)
        self.obs_right = Pin(3, Pin.IN)
        self.line_left = Pin(4, Pin.IN)
        self.line_right = Pin(5, Pin.IN)
        
        # 超声波
        self.trig = Pin(6, Pin.OUT)
        self.echo = Pin(7, Pin.IN)
    
    def set_motors(self, left, right):
        """设置电机速度 (-100 到 100)"""
        def set_motor(m1, m2, speed):
            if speed > 0:
                m1.duty_u16(int(speed / 100 * 65535))
                m2.duty_u16(0)
            elif speed < 0:
                m1.duty_u16(0)
                m2.duty_u16(int(-speed / 100 * 65535))
            else:
                m1.duty_u16(0)
                m2.duty_u16(0)
        
        set_motor(self.motor_left_1, self.motor_left_2, left)
        set_motor(self.motor_right_1, self.motor_right_2, right)
    
    def forward(self, speed=60):
        self.set_motors(speed, speed)
    
    def backward(self, speed=60):
        self.set_motors(-speed, -speed)
    
    def turn_left(self, speed=60):
        self.set_motors(-speed, speed)
    
    def turn_right(self, speed=60):
        self.set_motors(speed, -speed)
    
    def stop(self):
        self.set_motors(0, 0)
    
    def get_distance(self):
        """超声波测距"""
        self.trig.low()
        time.sleep_us(2)
        self.trig.high()
        time.sleep_us(10)
        self.trig.low()
        
        while self.echo.value() == 0:
            start = time.ticks_us()
        
        while self.echo.value() == 1:
            end = time.ticks_us()
        
        return time.ticks_diff(end, start) * 0.0343 / 2
    
    def avoid_obstacle(self):
        """避障模式"""
        left = self.obs_left.value() == 0
        right = self.obs_right.value() == 0
        
        if left and right:
            self.backward()
            time.sleep(0.5)
            self.turn_left()
            time.sleep(0.5)
        elif left:
            self.turn_right()
        elif right:
            self.turn_left()
        else:
            dist = self.get_distance()
            if dist < 20:
                self.turn_left()
            else:
                self.forward()
    
    def follow_line(self):
        """循线模式"""
        left = self.line_left.value() == 1   # 黑线
        right = self.line_right.value() == 1  # 黑线
        
        if left and right:
            self.forward(50)
        elif left:
            self.turn_left(40)
        elif right:
            self.turn_right(40)
        else:
            # 丢失线路,搜索
            self.turn_left(30)

# 使用
car = SmartCar()

# 避障模式
while True:
    car.avoid_obstacle()
    time.sleep(0.1)

24.3 气象站

24.3.1 功能

  • 温湿度采集
  • 气压测量(如有)
  • 数据记录
  • OLED 显示
  • 定时上报

24.3.2 代码框架

'''
微型气象站
'''
from machine import Pin, I2C, RTC
import dht
import time

class WeatherStation:
    def __init__(self):
        self.dht = dht.DHT11(Pin(19))
        self.rtc = RTC()
        # self.oled = SSD1306_I2C(128, 32, I2C(0))
        self.data_log = []
    
    def read_sensors(self):
        """读取传感器"""
        try:
            self.dht.measure()
            return {
                'temp': self.dht.temperature(),
                'humidity': self.dht.humidity(),
                'timestamp': self.rtc.datetime()
            }
        except:
            return None
    
    def log_data(self, data):
        """记录数据"""
        self.data_log.append(data)
        
        # 保存到文件
        with open('weather_log.csv', 'a') as f:
            t = data['timestamp']
            f.write(f"{t[0]}-{t[1]:02d}-{t[2]:02d} "
                   f"{t[4]:02d}:{t[5]:02d},"
                   f"{data['temp']},{data['humidity']}\n")
    
    def display(self, data):
        """显示数据"""
        print(f"温度: {data['temp']}°C  湿度: {data['humidity']}%")
        
        # OLED 显示
        # self.oled.fill(0)
        # self.oled.text(f"Temp: {data['temp']}C", 0, 0)
        # self.oled.text(f"Hum: {data['humidity']}%", 0, 12)
        # self.oled.show()
    
    def run(self, interval=60):
        """主循环"""
        while True:
            data = self.read_sensors()
            if data:
                self.display(data)
                self.log_data(data)
            time.sleep(interval)

# 运行
station = WeatherStation()
station.run(60)  # 每分钟采集一次

24.4 本章小结

本章展示了综合项目实践:

  1. 智能家居监控
    • 多传感器融合
    • 报警处理
    • 显示输出
  2. 智能小车
    • 电机控制
    • 避障循线
    • 模式切换
  3. 气象站
    • 数据采集
    • 文件存储
    • 定时任务

下一章将学习常见问题与故障排除。