用Python控制硬件:Raspberry Pi项目初体验

目录

  • [用Python控制硬件:Raspberry Pi项目初体验](#用Python控制硬件:Raspberry Pi项目初体验)
    • [1. Raspberry Pi与Python硬件编程概述](#1. Raspberry Pi与Python硬件编程概述)
      • [1.1 Raspberry Pi简介](#1.1 Raspberry Pi简介)
      • [1.2 Python在硬件控制中的优势](#1.2 Python在硬件控制中的优势)
    • [2. 环境搭建与基础配置](#2. 环境搭建与基础配置)
      • [2.1 系统安装与初始设置](#2.1 系统安装与初始设置)
      • [2.2 GPIO引脚布局与电气特性](#2.2 GPIO引脚布局与电气特性)
    • [3. 基础硬件控制项目](#3. 基础硬件控制项目)
      • [3.1 LED控制与PWM调光](#3.1 LED控制与PWM调光)
      • [3.2 按钮输入与中断处理](#3.2 按钮输入与中断处理)
    • [4. 传感器数据采集项目](#4. 传感器数据采集项目)
      • [4.1 温湿度传感器 (DHT11/DHT22)](#4.1 温湿度传感器 (DHT11/DHT22))
      • [4.2 光敏电阻与运动传感器](#4.2 光敏电阻与运动传感器)
    • [5. 完整项目:智能家居控制系统](#5. 完整项目:智能家居控制系统)
      • [5.1 系统架构与集成](#5.1 系统架构与集成)
    • [6. 完整代码结构与部署](#6. 完整代码结构与部署)
      • [6.1 项目配置文件](#6.1 项目配置文件)
      • [6.2 系统服务与自启动](#6.2 系统服务与自启动)
      • [6.3 Web控制界面](#6.3 Web控制界面)
    • [7. 总结与进阶学习](#7. 总结与进阶学习)
      • [7.1 Raspberry Pi Python硬件编程要点](#7.1 Raspberry Pi Python硬件编程要点)
      • [7.2 电气安全与最佳实践](#7.2 电气安全与最佳实践)
      • [7.3 进阶学习路径](#7.3 进阶学习路径)
      • [7.4 故障排除指南](#7.4 故障排除指南)
      • [7.5 项目扩展思路](#7.5 项目扩展思路)
      • [7.6 社区资源推荐](#7.6 社区资源推荐)
      • [7.7 持续学习建议](#7.7 持续学习建议)

『宝藏代码胶囊开张啦!』------ 我的 CodeCapsule 来咯!✨

写代码不再头疼!我的新站点 CodeCapsule 主打一个 "白菜价"+"量身定制 "!无论是卡脖子的毕设/课设/文献复现 ,需要灵光一现的算法改进 ,还是想给项目加个"外挂",这里都有便宜又好用的代码方案等你发现!低成本,高适配,助你轻松通关!速来围观 👉 CodeCapsule官网

用Python控制硬件:Raspberry Pi项目初体验

1. Raspberry Pi与Python硬件编程概述

1.1 Raspberry Pi简介

Raspberry Pi(树莓派)是一款信用卡大小的单板计算机,由英国树莓派基金会开发,旨在促进基础计算机科学教育。自2012年问世以来,它已成为创客、教育工作者和物联网开发者的首选平台。

树莓派的核心优势

  • 低成本:价格亲民,适合大规模部署
  • 开源生态:基于Linux系统,软件资源丰富
  • GPIO接口:40针通用输入输出引脚,可直接连接传感器和执行器
  • 社区支持:全球活跃的开发者社区
  • Python友好:原生支持Python,硬件控制库完善

1.2 Python在硬件控制中的优势

Python凭借其简洁的语法和丰富的库生态系统,成为树莓派硬件控制的首选语言:

python 复制代码
# 传统C语言硬件控制 vs Python硬件控制
"""
C语言示例(复杂):
#include <wiringPi.h>
#include <stdio.h>

int main() {
    wiringPiSetup();
    pinMode(0, OUTPUT);
    
    while(1) {
        digitalWrite(0, HIGH);
        delay(500);
        digitalWrite(0, LOW);
        delay(500);
    }
    return 0;
}

Python示例(简洁):
import RPi.GPIO as GPIO
import time

GPIO.setmode(GPIO.BCM)
GPIO.setup(18, GPIO.OUT)

while True:
    GPIO.output(18, GPIO.HIGH)
    time.sleep(0.5)
    GPIO.output(18, GPIO.LOW)
    time.sleep(0.5)
"""

Python硬件编程的优势公式:
开发效率 = 功能实现 代码复杂度 × 库生态丰富度 \text{开发效率} = \frac{\text{功能实现}}{\text{代码复杂度}} \times \text{库生态丰富度} 开发效率=代码复杂度功能实现×库生态丰富度

2. 环境搭建与基础配置

2.1 系统安装与初始设置

python 复制代码
# scripts/setup_raspberry_pi.py
"""
树莓派环境设置脚本
"""
import subprocess
import sys
import os
from pathlib import Path

def run_command(cmd, check=True, capture_output=False):
    """运行shell命令并返回结果"""
    print(f"执行命令: {cmd}")
    result = subprocess.run(cmd, shell=True, capture_output=capture_output, text=True)
    if check and result.returncode != 0:
        print(f"错误: {result.stderr}")
        return False
    return True

def check_system_requirements():
    """检查系统要求"""
    try:
        # 检查是否在树莓派上运行
        with open('/proc/device-tree/model', 'r') as f:
            model = f.read()
            if 'Raspberry Pi' not in model:
                print("⚠️  警告: 可能未在树莓派上运行")
            else:
                print(f"✅ 检测到: {model.strip()}")
        
        # 检查Python版本
        version = sys.version_info
        print(f"Python版本: {version.major}.{version.minor}.{version.micro}")
        
        if version.major < 3 or (version.major == 3 and version.minor < 7):
            print("❌ 需要Python 3.7或更高版本")
            return False
        
        return True
        
    except Exception as e:
        print(f"❌ 系统检查失败: {e}")
        return False

def install_required_packages():
    """安装必要的软件包"""
    packages = [
        "python3-pip",
        "python3-venv",
        "git",
        "build-essential",
        "python3-dev",
        "i2c-tools",
        "spi-tools"
    ]
    
    print("更新软件包列表...")
    if not run_command("sudo apt update"):
        return False
    
    for package in packages:
        print(f"安装 {package}...")
        if not run_command(f"sudo apt install -y {package}"):
            print(f"❌ 安装 {package} 失败")
            return False
    
    return True

def install_python_libraries():
    """安装Python库"""
    libraries = [
        "RPi.GPIO==0.7.1",
        "gpiozero==1.6.2",
        "picamera==1.13",
        "adafruit-blinka==8.23.0",
        "adafruit-circuitpython-bme280==2.5.10",
        "adafruit-circuitpython-dht==3.7.4",
        "smbus2==0.4.3",
        "spidev==3.6",
        "pillow==10.0.1",
        "numpy==1.24.3",
        "opencv-python==4.8.1.78",
        "pyserial==3.5"
    ]
    
    for lib in libraries:
        print(f"安装 {lib}...")
        if not run_command(f"pip3 install {lib}"):
            print(f"❌ 安装 {lib} 失败")
            return False
    
    return True

def enable_interfaces():
    """启用硬件接口"""
    interfaces = [
        ("Interface Options", "I2C", "yes"),
        ("Interface Options", "SPI", "yes"), 
        ("Interface Options", "Serial Port", "no"),  # 禁用登录shell,启用串口
        ("Interface Options", "Serial Console", "no"),
        ("Interface Options", "Camera", "yes"),
        ("Interface Options", "SSH", "yes"),
        ("Interface Options", "VNC", "yes")
    ]
    
    print("启用硬件接口...")
    for category, interface, enabled in interfaces:
        cmd = f"sudo raspi-config nonint {interface.lower().replace(' ', '_')} {'1' if enabled == 'yes' else '0'}"
        if not run_command(cmd):
            print(f"❌ 启用 {interface} 失败")
    
    return True

def setup_project_structure():
    """设置项目目录结构"""
    directories = [
        "projects/led_control",
        "projects/sensor_monitoring", 
        "projects/camera_projects",
        "projects/iot_applications",
        "libraries",
        "docs",
        "config"
    ]
    
    for directory in directories:
        Path(directory).mkdir(parents=True, exist_ok=True)
        print(f"创建目录: {directory}")
    
    # 创建基础配置文件
    config_files = {
        "config/gpio_setup.py": """
# GPIO引脚配置
LED_PINS = {
    'red': 17,
    'green': 27, 
    'blue': 22
}

BUTTON_PINS = {
    'btn1': 2,
    'btn2': 3
}

SENSOR_PINS = {
    'dht11': 4,
    'motion': 18
}
""",
        "config/i2c_devices.py": """
# I2C设备地址配置
I2C_DEVICES = {
    'bme280': 0x76,
    'ssd1306': 0x3C,
    'pcf8574': 0x20
}
"""
    }
    
    for file_path, content in config_files.items():
        with open(file_path, 'w') as f:
            f.write(content)
        print(f"创建文件: {file_path}")
    
    return True

def test_gpio_access():
    """测试GPIO访问权限"""
    try:
        import RPi.GPIO as GPIO
        GPIO.setmode(GPIO.BCM)
        GPIO.setup(18, GPIO.OUT)
        GPIO.output(18, GPIO.HIGH)
        GPIO.cleanup()
        print("✅ GPIO访问测试成功")
        return True
    except Exception as e:
        print(f"❌ GPIO访问测试失败: {e}")
        return False

def main():
    """主安装流程"""
    print("🎮 Raspberry Pi Python环境设置")
    print("=" * 50)
    
    if not check_system_requirements():
        return
    
    if not install_required_packages():
        print("❌ 软件包安装失败")
        return
    
    if not install_python_libraries():
        print("❌ Python库安装失败") 
        return
    
    if not enable_interfaces():
        print("❌ 硬件接口启用失败")
        return
    
    if not setup_project_structure():
        print("❌ 项目结构设置失败")
        return
    
    if not test_gpio_access():
        print("❌ GPIO测试失败")
        return
    
    print("\n" + "=" * 50)
    print("🎉 环境设置完成!")
    print("接下来可以开始Raspberry Pi项目开发了!")

if __name__ == "__main__":
    main()

2.2 GPIO引脚布局与电气特性

树莓派的40针GPIO接口提供了多种通信协议和电源引脚:

python 复制代码
# libraries/gpio_map.py
"""
GPIO引脚映射和电气特性
"""
import RPi.GPIO as GPIO
from typing import Dict, List, Tuple

class GPIOMapper:
    """GPIO引脚映射器"""
    
    # BCM编号引脚映射
    BCM_MAPPING = {
        # 电源引脚
        2: {"type": "5V", "description": "5V电源"},
        4: {"type": "5V", "description": "5V电源"},
        17: {"type": "3.3V", "description": "3.3V电源"},
        34: {"type": "3.3V", "description": "3.3V电源"},
        
        # 接地引脚
        6: {"type": "GND", "description": "接地"},
        9: {"type": "GND", "description": "接地"},
        14: {"type": "GND", "description": "接地"},
        20: {"type": "GND", "description": "接地"},
        25: {"type": "GND", "description": "接地"},
        30: {"type": "GND", "description": "接地"},
        34: {"type": "GND", "description": "接地"},
        39: {"type": "GND", "description": "接地"},
        
        # GPIO引脚
        3: {"type": "GPIO", "description": "GPIO 2 (SDA1)", "pwm": False, "pull": True},
        5: {"type": "GPIO", "description": "GPIO 3 (SCL1)", "pwm": False, "pull": True},
        7: {"type": "GPIO", "description": "GPIO 4 (GPCLK0)", "pwm": False, "pull": True},
        8: {"type": "GPIO", "description": "GPIO 14 (TXD0)", "pwm": False, "pull": False},
        10: {"type": "GPIO", "description": "GPIO 15 (RXD0)", "pwm": False, "pull": False},
        11: {"type": "GPIO", "description": "GPIO 17", "pwm": False, "pull": True},
        12: {"type": "GPIO", "description": "GPIO 18 (PWM0)", "pwm": True, "pull": True},
        13: {"type": "GPIO", "description": "GPIO 27", "pwm": False, "pull": True},
        15: {"type": "GPIO", "description": "GPIO 22", "pwm": False, "pull": True},
        16: {"type": "GPIO", "description": "GPIO 23", "pwm": False, "pull": True},
        18: {"type": "GPIO", "description": "GPIO 24", "pwm": False, "pull": True},
        19: {"type": "GPIO", "description": "GPIO 10 (MOSI)", "pwm": False, "pull": True},
        21: {"type": "GPIO", "description": "GPIO 9 (MISO)", "pwm": False, "pull": True},
        22: {"type": "GPIO", "description": "GPIO 25", "pwm": False, "pull": True},
        23: {"type": "GPIO", "description": "GPIO 11 (SCLK)", "pwm": False, "pull": True},
        24: {"type": "GPIO", "description": "GPIO 8 (CE0)", "pwm": False, "pull": True},
        26: {"type": "GPIO", "description": "GPIO 7 (CE1)", "pwm": False, "pull": True},
        27: {"type": "GPIO", "description": "GPIO 0 (ID_SD)", "pwm": False, "pull": True},
        28: {"type": "GPIO", "description": "GPIO 1 (ID_SC)", "pwm": False, "pull": True},
        29: {"type": "GPIO", "description": "GPIO 5", "pwm": False, "pull": True},
        31: {"type": "GPIO", "description": "GPIO 6", "pwm": False, "pull": True},
        32: {"type": "GPIO", "description": "GPIO 12 (PWM0)", "pwm": True, "pull": True},
        33: {"type": "GPIO", "description": "GPIO 13 (PWM1)", "pwm": True, "pull": True},
        35: {"type": "GPIO", "description": "GPIO 19 (PCM_FS)", "pwm": True, "pull": True},
        36: {"type": "GPIO", "description": "GPIO 16", "pwm": False, "pull": True},
        37: {"type": "GPIO", "description": "GPIO 26", "pwm": False, "pull": True},
        38: {"type": "GPIO", "description": "GPIO 20 (PCM_DIN)", "pwm": False, "pull": True},
        40: {"type": "GPIO", "description": "GPIO 21 (PCM_DOUT)", "pwm": False, "pull": True},
    }
    
    # 特殊功能引脚
    SPECIAL_PINS = {
        "I2C": {
            "SDA": [3],  # BCM 2
            "SCL": [5]   # BCM 3
        },
        "SPI": {
            "MOSI": [19],  # BCM 10
            "MISO": [21],  # BCM 9  
            "SCLK": [23],  # BCM 11
            "CE0": [24],   # BCM 8
            "CE1": [26]    # BCM 7
        },
        "UART": {
            "TXD": [8],    # BCM 14
            "RXD": [10]    # BCM 15
        },
        "PWM": {
            "PWM0": [12, 32],  # BCM 18, 12
            "PWM1": [33, 35]   # BCM 13, 19
        }
    }
    
    @classmethod
    def get_pin_info(cls, pin: int) -> Dict:
        """获取引脚信息"""
        return cls.BCM_MAPPING.get(pin, {"type": "UNKNOWN", "description": "未知引脚"})
    
    @classmethod
    def list_all_pins(cls):
        """列出所有引脚信息"""
        print("Raspberry Pi GPIO引脚映射 (BCM编号):")
        print("=" * 60)
        
        for pin_num in sorted(cls.BCM_MAPPING.keys()):
            info = cls.BCM_MAPPING[pin_num]
            pin_type = info["type"]
            description = info["description"]
            
            if pin_type == "GPIO":
                pwm_info = " (PWM)" if info.get("pwm", False) else ""
                pull_info = " (上拉)" if info.get("pull", False) else ""
                print(f"GPIO {pin_num:2d}: {description}{pwm_info}{pull_info}")
            else:
                print(f"{pin_type:5} {pin_num:2d}: {description}")
    
    @classmethod
    def validate_pin_usage(cls, pin: int, purpose: str) -> bool:
        """验证引脚用途是否合适"""
        info = cls.get_pin_info(pin)
        
        if info["type"] != "GPIO":
            print(f"❌ 引脚 {pin} 不是GPIO引脚")
            return False
        
        if purpose == "PWM" and not info.get("pwm", False):
            print(f"❌ 引脚 {pin} 不支持PWM")
            return False
        
        if purpose == "INPUT" and not info.get("pull", False):
            print(f"⚠️  引脚 {pin} 没有内部上拉电阻")
        
        return True
    
    @classmethod
    def calculate_current_requirements(cls, components: List[Dict]) -> Tuple[float, float]:
        """
        计算电流需求
        
        Args:
            components: 组件列表,每个组件包含 'current_ma' 和 'voltage' 字段
            
        Returns:
            (总电流mA, 总功率W)
        """
        total_current_3v3 = 0.0
        total_current_5v = 0.0
        
        for comp in components:
            if comp['voltage'] == 3.3:
                total_current_3v3 += comp['current_ma']
            elif comp['voltage'] == 5:
                total_current_5v += comp['current_ma']
        
        total_power = (total_current_3v3 * 3.3 + total_current_5v * 5.0) / 1000  # 转换为瓦特
        
        print(f"电源需求分析:")
        print(f"  3.3V总线: {total_current_3v3:.1f} mA")
        print(f"  5V总线: {total_current_5v:.1f} mA") 
        print(f"  总功率: {total_power:.2f} W")
        
        # 树莓派4B的电源限制
        if total_current_3v3 > 500:
            print("⚠️  警告: 3.3V总线电流接近极限 (500mA)")
        if total_current_5v > 2500:
            print("⚠️  警告: 5V总线电流接近极限 (2.5A)")
        
        return total_current_3v3 + total_current_5v, total_power

def demonstrate_gpio_mapping():
    """演示GPIO映射功能"""
    mapper = GPIOMapper()
    
    # 显示所有引脚
    mapper.list_all_pins()
    
    print("\n特殊功能引脚:")
    for interface, pins in mapper.SPECIAL_PINS.items():
        print(f"{interface}:")
        for name, pin_list in pins.items():
            print(f"  {name}: {pin_list}")
    
    # 验证一些引脚用途
    test_cases = [
        (18, "PWM"),      # 有效的PWM引脚
        (17, "OUTPUT"),   # 普通输出引脚
        (3, "I2C"),       # I2C引脚
        (2, "OUTPUT")     # 电源引脚(应该失败)
    ]
    
    print("\n引脚验证测试:")
    for pin, purpose in test_cases:
        result = mapper.validate_pin_usage(pin, purpose)
        print(f"引脚 {pin} 用于 {purpose}: {'✅ 通过' if result else '❌ 失败'}")
    
    # 电流需求计算示例
    components = [
        {"name": "LED", "voltage": 3.3, "current_ma": 20},
        {"name": "传感器", "voltage": 3.3, "current_ma": 5},
        {"name": "舵机", "voltage": 5, "current_ma": 500}
    ]
    
    print("\n电源需求计算:")
    total_current, total_power = mapper.calculate_current_requirements(components)
    print(f"总需求: {total_current:.1f} mA, {total_power:.2f} W")

if __name__ == "__main__":
    demonstrate_gpio_mapping()

3. 基础硬件控制项目

3.1 LED控制与PWM调光

python 复制代码
# projects/led_control/led_manager.py
"""
LED控制管理器 - 基础GPIO控制
"""
import RPi.GPIO as GPIO
import time
import threading
from typing import Dict, List, Optional
from enum import Enum

class LEDState(Enum):
    """LED状态枚举"""
    OFF = 0
    ON = 1
    BLINKING = 2
    BREATHING = 3

class LEDController:
    """LED控制器"""
    
    def __init__(self, pin: int, frequency: int = 1000):
        """
        初始化LED控制器
        
        Args:
            pin: GPIO引脚 (BCM编号)
            frequency: PWM频率 (Hz)
        """
        self.pin = pin
        self.frequency = frequency
        self.state = LEDState.OFF
        self.brightness = 0  # 0-100
        self.blink_thread = None
        self.breath_thread = None
        self.running = False
        
        # GPIO设置
        GPIO.setmode(GPIO.BCM)
        GPIO.setup(self.pin, GPIO.OUT)
        
        # PWM初始化
        self.pwm = GPIO.PWM(self.pin, self.frequency)
        self.pwm.start(0)  # 初始亮度为0
        
        print(f"✅ LED控制器初始化完成 - 引脚: {self.pin}")
    
    def set_brightness(self, brightness: int):
        """
        设置LED亮度
        
        Args:
            brightness: 亮度值 (0-100)
        """
        self.brightness = max(0, min(100, brightness))
        duty_cycle = self.brightness
        
        if self.state not in [LEDState.BLINKING, LEDState.BREATHING]:
            self.pwm.ChangeDutyCycle(duty_cycle)
            self.state = LEDState.ON if duty_cycle > 0 else LEDState.OFF
        
        print(f"💡 LED亮度设置为: {self.brightness}%")
    
    def on(self):
        """打开LED (100%亮度)"""
        self.set_brightness(100)
        self.state = LEDState.ON
    
    def off(self):
        """关闭LED"""
        self.set_brightness(0)
        self.state = LEDState.OFF
    
    def toggle(self):
        """切换LED状态"""
        if self.state == LEDState.OFF:
            self.on()
        else:
            self.off()
    
    def blink(self, interval: float = 0.5, duration: Optional[float] = None):
        """
        LED闪烁
        
        Args:
            interval: 闪烁间隔 (秒)
            duration: 持续时间 (秒),None表示无限
        """
        self._stop_threads()
        self.state = LEDState.BLINKING
        self.running = True
        
        def blink_task():
            start_time = time.time()
            while self.running:
                self.pwm.ChangeDutyCycle(100)  # 亮
                time.sleep(interval)
                self.pwm.ChangeDutyCycle(0)    # 灭
                time.sleep(interval)
                
                # 检查持续时间
                if duration and (time.time() - start_time) >= duration:
                    break
            
            self.off()
            self.state = LEDState.OFF
        
        self.blink_thread = threading.Thread(target=blink_task)
        self.blink_thread.daemon = True
        self.blink_thread.start()
        
        print(f"✨ LED开始闪烁 - 间隔: {interval}s")
    
    def breath(self, cycle_time: float = 2.0, duration: Optional[float] = None):
        """
        LED呼吸效果
        
        Args:
            cycle_time: 完整呼吸周期时间 (秒)
            duration: 持续时间 (秒)
        """
        self._stop_threads()
        self.state = LEDState.BREATHING
        self.running = True
        
        def breath_task():
            start_time = time.time()
            steps = 50  # 每个周期的步数
            
            while self.running:
                # 渐亮
                for i in range(steps):
                    if not self.running:
                        break
                    brightness = int((i / steps) ** 2 * 100)  # 非线性变化,更自然
                    self.pwm.ChangeDutyCycle(brightness)
                    time.sleep(cycle_time / (2 * steps))
                
                # 渐暗
                for i in range(steps, 0, -1):
                    if not self.running:
                        break
                    brightness = int((i / steps) ** 2 * 100)
                    self.pwm.ChangeDutyCycle(brightness)
                    time.sleep(cycle_time / (2 * steps))
                
                # 检查持续时间
                if duration and (time.time() - start_time) >= duration:
                    break
            
            self.off()
            self.state = LEDState.OFF
        
        self.breath_thread = threading.Thread(target=breath_task)
        self.breath_thread.daemon = True
        self.breath_thread.start()
        
        print(f"🌬️  LED开始呼吸效果 - 周期: {cycle_time}s")
    
    def _stop_threads(self):
        """停止所有线程"""
        self.running = False
        if self.blink_thread and self.blink_thread.is_alive():
            self.blink_thread.join(timeout=1.0)
        if self.breath_thread and self.breath_thread.is_alive():
            self.breath_thread.join(timeout=1.0)
    
    def get_status(self) -> Dict:
        """获取LED状态"""
        return {
            "pin": self.pin,
            "state": self.state.name,
            "brightness": self.brightness,
            "frequency": self.frequency
        }
    
    def cleanup(self):
        """清理资源"""
        self._stop_threads()
        self.pwm.stop()
        print(f"🧹 LED控制器清理完成 - 引脚: {self.pin}")

class RGBLEDController:
    """RGB LED控制器"""
    
    def __init__(self, red_pin: int, green_pin: int, blue_pin: int):
        """
        初始化RGB LED控制器
        
        Args:
            red_pin: 红色引脚
            green_pin: 绿色引脚
            blue_pin: 蓝色引脚
        """
        self.leds = {
            'red': LEDController(red_pin),
            'green': LEDController(green_pin),
            'blue': LEDController(blue_pin)
        }
        
        self.current_color = (0, 0, 0)
        print("🌈 RGB LED控制器初始化完成")
    
    def set_color(self, red: int, green: int, blue: int):
        """
        设置RGB颜色
        
        Args:
            red: 红色亮度 (0-100)
            green: 绿色亮度 (0-100)
            blue: 蓝色亮度 (0-100)
        """
        self.leds['red'].set_brightness(red)
        self.leds['green'].set_brightness(green)
        self.leds['blue'].set_brightness(blue)
        
        self.current_color = (red, green, blue)
        print(f"🎨 RGB颜色设置为: R{red} G{green} B{blue}")
    
    def set_color_hex(self, hex_color: str):
        """
        使用十六进制颜色代码设置颜色
        
        Args:
            hex_color: 十六进制颜色代码 (如 "#FF5733")
        """
        hex_color = hex_color.lstrip('#')
        if len(hex_color) != 6:
            raise ValueError("颜色代码必须是6位十六进制数")
        
        red = int(hex_color[0:2], 16) * 100 // 255
        green = int(hex_color[2:4], 16) * 100 // 255
        blue = int(hex_color[4:6], 16) * 100 // 255
        
        self.set_color(red, green, blue)
    
    def color_cycle(self, colors: List[tuple], interval: float = 1.0):
        """
        RGB颜色循环
        
        Args:
            colors: 颜色列表,每个颜色为 (r, g, b) 元组
            interval: 颜色切换间隔 (秒)
        """
        def cycle_task():
            while getattr(threading.current_thread(), "do_run", True):
                for color in colors:
                    if not getattr(threading.current_thread(), "do_run", True):
                        return
                    self.set_color(*color)
                    time.sleep(interval)
        
        thread = threading.Thread(target=cycle_task)
        thread.do_run = True
        thread.daemon = True
        thread.start()
        
        return thread  # 返回线程以便控制
    
    def rainbow_effect(self, duration: float = 10.0):
        """
        彩虹效果
        
        Args:
            duration: 效果持续时间 (秒)
        """
        def rainbow_task():
            start_time = time.time()
            steps = 360  # 色相步数
            
            while (time.time() - start_time) < duration:
                elapsed = time.time() - start_time
                progress = (elapsed / duration) % 1.0
                
                # HSV到RGB转换
                hue = progress * 360
                r, g, b = self.hsv_to_rgb(hue, 1.0, 1.0)
                
                self.set_color(int(r * 100), int(g * 100), int(b * 100))
                time.sleep(0.05)
        
        thread = threading.Thread(target=rainbow_task)
        thread.daemon = True
        thread.start()
        
        return thread
    
    @staticmethod
    def hsv_to_rgb(h: float, s: float, v: float) -> tuple:
        """HSV到RGB颜色转换"""
        h = h % 360
        c = v * s
        x = c * (1 - abs((h / 60) % 2 - 1))
        m = v - c
        
        if 0 <= h < 60:
            r, g, b = c, x, 0
        elif 60 <= h < 120:
            r, g, b = x, c, 0
        elif 120 <= h < 180:
            r, g, b = 0, c, x
        elif 180 <= h < 240:
            r, g, b = 0, x, c
        elif 240 <= h < 300:
            r, g, b = x, 0, c
        else:
            r, g, b = c, 0, x
        
        return (r + m, g + m, b + m)
    
    def get_status(self) -> Dict:
        """获取RGB LED状态"""
        return {
            "pins": {color: led.pin for color, led in self.leds.items()},
            "current_color": self.current_color,
            "states": {color: led.get_status() for color, led in self.leds.items()}
        }
    
    def cleanup(self):
        """清理资源"""
        for led in self.leds.values():
            led.cleanup()
        print("🧹 RGB LED控制器清理完成")

def demonstrate_led_control():
    """演示LED控制功能"""
    try:
        # 单色LED演示
        print("单色LED演示:")
        led = LEDController(18)  # 使用GPIO18
        
        led.on()
        time.sleep(1)
        
        led.set_brightness(50)
        time.sleep(1)
        
        led.blink(0.3, 2)  # 闪烁2秒
        time.sleep(2.5)
        
        led.breath(3, 5)   # 呼吸效果5秒
        time.sleep(6)
        
        led.off()
        
        # RGB LED演示
        print("\nRGB LED演示:")
        rgb_led = RGBLEDController(17, 27, 22)  # R:17, G:27, B:22
        
        # 基本颜色
        colors = [
            (100, 0, 0),    # 红
            (0, 100, 0),    # 绿  
            (0, 0, 100),    # 蓝
            (100, 100, 0),  # 黄
            (100, 0, 100),  # 紫
            (0, 100, 100)   # 青
        ]
        
        for color in colors:
            rgb_led.set_color(*color)
            time.sleep(1)
        
        # 十六进制颜色
        rgb_led.set_color_hex("#FF5733")  # 橙色
        time.sleep(1)
        
        # 彩虹效果
        print("开始彩虹效果...")
        rainbow_thread = rgb_led.rainbow_effect(5)
        rainbow_thread.join()
        
        rgb_led.set_color(0, 0, 0)  # 关闭
        
        print("✅ LED控制演示完成")
        
    except KeyboardInterrupt:
        print("\n🛑 演示被用户中断")
    except Exception as e:
        print(f"❌ 演示错误: {e}")
    finally:
        # 清理GPIO
        GPIO.cleanup()
        print("🧹 GPIO资源已清理")

if __name__ == "__main__":
    demonstrate_led_control()

3.2 按钮输入与中断处理

python 复制代码
# projects/led_control/button_manager.py
"""
按钮输入管理器 - GPIO输入和中断处理
"""
import RPi.GPIO as GPIO
import time
import threading
from typing import Dict, List, Callable, Optional
from enum import Enum

class ButtonEvent(Enum):
    """按钮事件类型"""
    PRESS = 1
    RELEASE = 2
    CLICK = 3
    LONG_PRESS = 4
    DOUBLE_CLICK = 5

class ButtonController:
    """按钮控制器"""
    
    def __init__(self, pin: int, pull_up: bool = True, 
                 bounce_time: int = 300, long_press_duration: float = 2.0):
        """
        初始化按钮控制器
        
        Args:
            pin: GPIO引脚 (BCM编号)
            pull_up: 是否使用上拉电阻
            bounce_time: 防抖时间 (毫秒)
            long_press_duration: 长按判定时间 (秒)
        """
        self.pin = pin
        self.pull_up = pull_up
        self.bounce_time = bounce_time
        self.long_press_duration = long_press_duration
        
        # 状态变量
        self.last_state = GPIO.HIGH if pull_up else GPIO.LOW
        self.press_start_time = 0
        self.click_count = 0
        self.last_click_time = 0
        
        # 事件回调函数
        self.event_handlers = {event: [] for event in ButtonEvent}
        
        # GPIO设置
        GPIO.setmode(GPIO.BCM)
        pull_resistor = GPIO.PUD_UP if pull_up else GPIO.PUD_DOWN
        GPIO.setup(self.pin, GPIO.IN, pull_up_down=pull_resistor)
        
        # 添加边缘检测
        edge = GPIO.FALLING if pull_up else GPIO.RISING
        GPIO.add_event_detect(self.pin, edge, callback=self._edge_callback, 
                             bouncetime=self.bounce_time)
        
        # 状态监测线程
        self.monitoring = False
        self.monitor_thread = None
        
        print(f"✅ 按钮控制器初始化完成 - 引脚: {pin} (上拉: {pull_up})")
    
    def add_event_handler(self, event: ButtonEvent, handler: Callable):
        """
        添加事件处理器
        
        Args:
            event: 按钮事件类型
            handler: 处理函数
        """
        self.event_handlers[event].append(handler)
    
    def remove_event_handler(self, event: ButtonEvent, handler: Callable):
        """移除事件处理器"""
        if handler in self.event_handlers[event]:
            self.event_handlers[event].remove(handler)
    
    def _edge_callback(self, channel):
        """边缘检测回调函数"""
        if channel != self.pin:
            return
        
        current_state = GPIO.input(self.pin)
        
        # 检测按钮按下(上拉模式下低电平表示按下)
        if self.pull_up and current_state == GPIO.LOW and self.last_state == GPIO.HIGH:
            self._handle_press()
        # 检测按钮释放
        elif self.pull_up and current_state == GPIO.HIGH and self.last_state == GPIO.LOW:
            self._handle_release()
        
        self.last_state = current_state
    
    def _handle_press(self):
        """处理按钮按下事件"""
        self.press_start_time = time.time()
        self._trigger_event(ButtonEvent.PRESS)
        
        print(f"🔘 按钮按下 - 引脚: {self.pin}")
    
    def _handle_release(self):
        """处理按钮释放事件"""
        press_duration = time.time() - self.press_start_time
        
        self._trigger_event(ButtonEvent.RELEASE)
        
        # 判断点击类型
        current_time = time.time()
        
        if press_duration >= self.long_press_duration:
            # 长按
            self._trigger_event(ButtonEvent.LONG_PRESS)
            self.click_count = 0
            print(f"⏱️  长按检测 - 持续时间: {press_duration:.2f}s")
        else:
            # 短按,检查是否双击
            if current_time - self.last_click_time < 0.5:  # 双击时间窗口
                self.click_count += 1
                if self.click_count >= 2:
                    self._trigger_event(ButtonEvent.DOUBLE_CLICK)
                    self.click_count = 0
                    print("👆 双击检测")
            else:
                self.click_count = 1
                self._trigger_event(ButtonEvent.CLICK)
                print("👉 单击检测")
        
        self.last_click_time = current_time
    
    def _trigger_event(self, event: ButtonEvent):
        """触发事件"""
        for handler in self.event_handlers[event]:
            try:
                handler(self.pin)
            except Exception as e:
                print(f"❌ 事件处理器错误: {e}")
    
    def start_monitoring(self):
        """开始状态监测"""
        if self.monitoring:
            return
        
        self.monitoring = True
        
        def monitor_task():
            while self.monitoring:
                current_state = GPIO.input(self.pin)
                time.sleep(0.1)  # 降低CPU使用率
        
        self.monitor_thread = threading.Thread(target=monitor_task)
        self.monitor_thread.daemon = True
        self.monitor_thread.start()
        
        print(f"📊 开始按钮状态监测 - 引脚: {self.pin}")
    
    def stop_monitoring(self):
        """停止状态监测"""
        self.monitoring = False
        if self.monitor_thread:
            self.monitor_thread.join(timeout=1.0)
        print(f"🛑 停止按钮状态监测 - 引脚: {self.pin}")
    
    def is_pressed(self) -> bool:
        """检查按钮是否被按下"""
        current_state = GPIO.input(self.pin)
        return current_state == (GPIO.LOW if self.pull_up else GPIO.HIGH)
    
    def wait_for_press(self, timeout: Optional[float] = None) -> bool:
        """
        等待按钮按下
        
        Args:
            timeout: 超时时间 (秒)
            
        Returns:
            是否成功检测到按下
        """
        start_time = time.time()
        
        while True:
            if self.is_pressed():
                return True
            
            if timeout and (time.time() - start_time) >= timeout:
                return False
            
            time.sleep(0.01)  # 小延迟避免过高CPU使用
    
    def get_status(self) -> Dict:
        """获取按钮状态"""
        return {
            "pin": self.pin,
            "pulled_up": self.pull_up,
            "is_pressed": self.is_pressed(),
            "bounce_time": self.bounce_time,
            "event_handlers": {event.name: len(handlers) 
                             for event, handlers in self.event_handlers.items()}
        }
    
    def cleanup(self):
        """清理资源"""
        self.stop_monitoring()
        GPIO.remove_event_detect(self.pin)
        print(f"🧹 按钮控制器清理完成 - 引脚: {self.pin}")

class ButtonManager:
    """多按钮管理器"""
    
    def __init__(self):
        self.buttons = {}
        self.sequences = {}  # 按钮序列检测
        print("🎮 按钮管理器初始化完成")
    
    def add_button(self, name: str, pin: int, **kwargs):
        """
        添加按钮
        
        Args:
            name: 按钮名称
            pin: GPIO引脚
            **kwargs: 其他ButtonController参数
        """
        if name in self.buttons:
            print(f"⚠️  按钮 '{name}' 已存在,正在替换")
            self.buttons[name].cleanup()
        
        self.buttons[name] = ButtonController(pin, **kwargs)
        print(f"✅ 添加按钮: {name} (引脚: {pin})")
    
    def remove_button(self, name: str):
        """移除按钮"""
        if name in self.buttons:
            self.buttons[name].cleanup()
            del self.buttons[name]
            print(f"🗑️  移除按钮: {name}")
    
    def add_button_sequence(self, sequence_name: str, button_sequence: List[str], 
                          timeout: float = 3.0, handler: Optional[Callable] = None):
        """
        添加按钮序列检测
        
        Args:
            sequence_name: 序列名称
            button_sequence: 按钮名称序列
            timeout: 序列超时时间
            handler: 序列完成时的处理函数
        """
        self.sequences[sequence_name] = {
            'sequence': button_sequence,
            'timeout': timeout,
            'handler': handler,
            'current_index': 0,
            'last_press_time': 0
        }
        
        # 为序列中的按钮添加点击处理器
        for button_name in button_sequence:
            if button_name in self.buttons:
                self.buttons[button_name].add_event_handler(
                    ButtonEvent.CLICK, 
                    lambda pin, btn=button_name, seq=sequence_name: 
                    self._handle_sequence_press(btn, seq)
                )
        
        print(f"🔢 添加按钮序列: {sequence_name} -> {button_sequence}")
    
    def _handle_sequence_press(self, button_name: str, sequence_name: str):
        """处理序列按钮按下"""
        if sequence_name not in self.sequences:
            return
        
        seq_info = self.sequences[sequence_name]
        current_time = time.time()
        
        # 检查超时
        if (seq_info['last_press_time'] > 0 and 
            current_time - seq_info['last_press_time'] > seq_info['timeout']):
            seq_info['current_index'] = 0  # 超时重置
        
        # 检查序列匹配
        expected_button = seq_info['sequence'][seq_info['current_index']]
        if button_name == expected_button:
            seq_info['current_index'] += 1
            seq_info['last_press_time'] = current_time
            
            print(f"🎯 序列 '{sequence_name}' 进度: {seq_info['current_index']}/{len(seq_info['sequence'])}")
            
            # 序列完成
            if seq_info['current_index'] >= len(seq_info['sequence']):
                seq_info['current_index'] = 0
                if seq_info['handler']:
                    try:
                        seq_info['handler'](sequence_name)
                    except Exception as e:
                        print(f"❌ 序列处理器错误: {e}")
                print(f"🎉 按钮序列 '{sequence_name}' 完成!")
        else:
            # 序列错误,重置
            seq_info['current_index'] = 0
            print(f"🔄 序列 '{sequence_name}' 重置")
    
    def get_button(self, name: str) -> Optional[ButtonController]:
        """获取按钮控制器"""
        return self.buttons.get(name)
    
    def get_all_status(self) -> Dict:
        """获取所有按钮状态"""
        return {
            name: button.get_status() 
            for name, button in self.buttons.items()
        }
    
    def cleanup(self):
        """清理所有资源"""
        for button in self.buttons.values():
            button.cleanup()
        self.buttons.clear()
        self.sequences.clear()
        print("🧹 按钮管理器清理完成")

def demonstrate_button_control():
    """演示按钮控制功能"""
    try:
        from led_control.led_manager import LEDController, RGBLEDController
        
        # 初始化LED
        led = LEDController(18)
        rgb_led = RGBLEDController(17, 27, 22)
        
        # 初始化按钮管理器
        button_mgr = ButtonManager()
        
        # 添加按钮
        button_mgr.add_button("red_button", 2, pull_up=True)      # GPIO2
        button_mgr.add_button("green_button", 3, pull_up=True)    # GPIO3
        button_mgr.add_button("blue_button", 4, pull_up=True)     # GPIO4
        
        # 单色LED控制
        def handle_red_click(pin):
            led.toggle()
            print(f"🔴 红色按钮点击 - LED状态: {'开' if led.state.name == 'ON' else '关'}")
        
        def handle_green_click(pin):
            if led.state.name == 'ON':
                led.blink(0.2, 3)
            print("🟢 绿色按钮点击 - LED开始闪烁")
        
        def handle_blue_click(pin):
            if led.state.name == 'ON':
                led.breath(2, 5)
            print("🔵 蓝色按钮点击 - LED开始呼吸")
        
        # 绑定事件处理器
        button_mgr.get_button("red_button").add_event_handler(ButtonEvent.CLICK, handle_red_click)
        button_mgr.get_button("green_button").add_event_handler(ButtonEvent.CLICK, handle_green_click)
        button_mgr.get_button("blue_button").add_event_handler(ButtonEvent.CLICK, handle_blue_click)
        
        # RGB LED控制
        def handle_red_long_press(pin):
            rgb_led.set_color(100, 0, 0)
            print("🔴 红色按钮长按 - RGB设为红色")
        
        def handle_green_long_press(pin):
            rgb_led.set_color(0, 100, 0)
            print("🟢 绿色按钮长按 - RGB设为绿色")
        
        def handle_blue_long_press(pin):
            rgb_led.set_color(0, 0, 100)
            print("🔵 蓝色按钮长按 - RGB设为蓝色")
        
        button_mgr.get_button("red_button").add_event_handler(ButtonEvent.LONG_PRESS, handle_red_long_press)
        button_mgr.get_button("green_button").add_event_handler(ButtonEvent.LONG_PRESS, handle_green_long_press)
        button_mgr.get_button("blue_button").add_event_handler(ButtonEvent.LONG_PRESS, handle_blue_long_press)
        
        # 按钮序列示例
        def handle_konami_code(sequence_name):
            rgb_led.rainbow_effect(5)
            print("🎮 科乐美代码激活! 彩虹效果启动")
        
        # 上上下下左右左右BA (使用现有按钮模拟)
        button_mgr.add_button_sequence(
            "konami_code",
            ["red_button", "red_button", "green_button", "green_button", 
             "blue_button", "blue_button", "red_button", "green_button"],
            timeout=5.0,
            handler=handle_konami_code
        )
        
        # 开始监测
        for button in button_mgr.buttons.values():
            button.start_monitoring()
        
        print("\n🎯 按钮控制演示开始")
        print("单击红色按钮: 切换LED开关")
        print("单击绿色按钮: LED闪烁")  
        print("单击蓝色按钮: LED呼吸")
        print("长按红色按钮: RGB设为红色")
        print("长按绿色按钮: RGB设为绿色")
        print("长按蓝色按钮: RGB设为蓝色")
        print("序列: 红红绿绿蓝蓝红绿 -> 彩虹效果")
        print("按Ctrl+C退出演示")
        
        # 主循环
        try:
            while True:
                # 显示当前状态
                status = button_mgr.get_all_status()
                pressed_buttons = [name for name, info in status.items() if info['is_pressed']]
                
                if pressed_buttons:
                    print(f"当前按下的按钮: {pressed_buttons}")
                
                time.sleep(0.1)
                
        except KeyboardInterrupt:
            print("\n🛑 演示被用户中断")
            
    except Exception as e:
        print(f"❌ 演示错误: {e}")
    finally:
        # 清理资源
        if 'button_mgr' in locals():
            button_mgr.cleanup()
        if 'led' in locals():
            led.cleanup()
        if 'rgb_led' in locals():
            rgb_led.cleanup()
        GPIO.cleanup()
        print("🧹 所有资源已清理")

if __name__ == "__main__":
    demonstrate_button_control()

4. 传感器数据采集项目

4.1 温湿度传感器 (DHT11/DHT22)

python 复制代码
# projects/sensor_monitoring/dht_sensor.py
"""
DHT11/DHT22温湿度传感器读取
"""
import time
import threading
from typing import Dict, Optional, Callable
import RPi.GPIO as GPIO

class DHTSensor:
    """DHT系列温湿度传感器"""
    
    def __init__(self, pin: int, sensor_type: str = "DHT11"):
        """
        初始化DHT传感器
        
        Args:
            pin: 数据引脚 (BCM编号)
            sensor_type: 传感器类型 ("DHT11" 或 "DHT22")
        """
        self.pin = pin
        self.sensor_type = sensor_type.upper()
        
        if self.sensor_type not in ["DHT11", "DHT22"]:
            raise ValueError("传感器类型必须是 'DHT11' 或 'DHT22'")
        
        # 传感器特性
        self.sensor_specs = {
            "DHT11": {
                "temperature_range": (0, 50),
                "humidity_range": (20, 90),
                "accuracy": {"temp": "±2°C", "humi": "±5%"},
                "reading_interval": 1  # 最小读取间隔(秒)
            },
            "DHT22": {
                "temperature_range": (-40, 80),
                "humidity_range": (0, 100),
                "accuracy": {"temp": "±0.5°C", "humi": "±2%"},
                "reading_interval": 2
            }
        }
        
        # 状态变量
        self.last_reading = None
        self.last_read_time = 0
        self.reading_interval = self.sensor_specs[self.sensor_type]["reading_interval"]
        self.monitoring = False
        self.monitor_thread = None
        self.callbacks = []
        
        # GPIO设置
        GPIO.setmode(GPIO.BCM)
        
        print(f"✅ {self.sensor_type}传感器初始化完成 - 引脚: {pin}")
    
    def _read_sensor(self) -> Optional[Dict]:
        """
        读取传感器数据
        
        Returns:
            包含温度和湿度的字典,读取失败返回None
        """
        # 检查读取间隔
        current_time = time.time()
        if current_time - self.last_read_time < self.reading_interval:
            time.sleep(0.1)
            return self.last_reading
        
        # 发送开始信号
        GPIO.setup(self.pin, GPIO.OUT)
        GPIO.output(self.pin, GPIO.LOW)
        time.sleep(0.018)  # 18ms低电平
        
        # 准备读取数据
        GPIO.setup(self.pin, GPIO.IN, pull_up_down=GPIO.PUD_UP)
        
        # 等待传感器响应
        if not self._wait_for_state(GPIO.LOW, 100):  # 等待80μs低电平
            print("❌ 传感器响应超时")
            return None
        
        if not self._wait_for_state(GPIO.HIGH, 100):  # 等待80μs高电平
            print("❌ 传感器准备超时")
            return None
        
        # 读取40位数据
        data = []
        for i in range(40):
            # 每个位以50μs低电平开始
            if not self._wait_for_state(GPIO.LOW, 60):
                print(f"❌ 数据位 {i} 开始超时")
                return None
            
            # 高电平持续时间决定位值
            high_duration = self._measure_pulse(GPIO.HIGH, 100)
            if high_duration is None:
                print(f"❌ 数据位 {i} 读取超时")
                return None
            
            data.append(1 if high_duration > 40 else 0)
        
        # 解析数据
        humidity = self._parse_data(data[0:8])
        humidity_decimal = self._parse_data(data[8:16])
        temperature = self._parse_data(data[16:24])
        temperature_decimal = self._parse_data(data[24:32])
        checksum = self._parse_data(data[32:40])
        
        # 验证校验和
        calculated_checksum = humidity + humidity_decimal + temperature + temperature_decimal
        if checksum != calculated_checksum & 0xFF:
            print("❌ 校验和错误")
            return None
        
        # 计算最终值
        if self.sensor_type == "DHT11":
            final_humidity = humidity
            final_temperature = temperature
        else:  # DHT22
            final_humidity = (humidity * 256 + humidity_decimal) / 10.0
            # 处理负数温度
            if temperature & 0x80:
                temperature = -((temperature & 0x7F) * 256 + temperature_decimal) / 10.0
            else:
                final_temperature = (temperature * 256 + temperature_decimal) / 10.0
        
        # 数据验证
        specs = self.sensor_specs[self.sensor_type]
        if not (specs["temperature_range"][0] <= final_temperature <= specs["temperature_range"][1]):
            print(f"❌ 温度值超出范围: {final_temperature}")
            return None
        
        if not (specs["humidity_range"][0] <= final_humidity <= specs["humidity_range"][1]):
            print(f"❌ 湿度值超出范围: {final_humidity}")
            return None
        
        reading = {
            "temperature": final_temperature,
            "humidity": final_humidity,
            "timestamp": time.time(),
            "sensor_type": self.sensor_type
        }
        
        self.last_reading = reading
        self.last_read_time = current_time
        
        return reading
    
    def _wait_for_state(self, state: int, timeout_ms: int) -> bool:
        """等待引脚达到指定状态"""
        start_time = time.time()
        while GPIO.input(self.pin) != state:
            if (time.time() - start_time) * 1000 > timeout_ms:
                return False
        return True
    
    def _measure_pulse(self, state: int, timeout_ms: int) -> Optional[float]:
        """测量脉冲持续时间(微秒)"""
        if not self._wait_for_state(state, timeout_ms):
            return None
        
        start_time = time.time()
        while GPIO.input(self.pin) == state:
            if (time.time() - start_time) * 1000 > timeout_ms:
                return None
        
        return (time.time() - start_time) * 1000000  # 转换为微秒
    
    def _parse_data(self, bits: list) -> int:
        """解析8位数据"""
        value = 0
        for bit in bits:
            value = (value << 1) | bit
        return value
    
    def read(self, max_retries: int = 3) -> Optional[Dict]:
        """
        读取传感器数据(带重试)
        
        Args:
            max_retries: 最大重试次数
            
        Returns:
            传感器数据字典
        """
        for attempt in range(max_retries):
            try:
                reading = self._read_sensor()
                if reading:
                    return reading
                time.sleep(0.1)
            except Exception as e:
                print(f"❌ 读取尝试 {attempt + 1} 失败: {e}")
        
        print(f"❌ 传感器读取失败,已重试 {max_retries} 次")
        return None
    
    def add_callback(self, callback: Callable):
        """添加数据回调函数"""
        self.callbacks.append(callback)
    
    def start_monitoring(self, interval: float = 5.0):
        """
        开始持续监测
        
        Args:
            interval: 读取间隔(秒)
        """
        if self.monitoring:
            return
        
        self.monitoring = True
        
        def monitor_task():
            while self.monitoring:
                reading = self.read()
                if reading and self.callbacks:
                    for callback in self.callbacks:
                        try:
                            callback(reading)
                        except Exception as e:
                            print(f"❌ 回调函数错误: {e}")
                
                time.sleep(interval)
        
        self.monitor_thread = threading.Thread(target=monitor_task)
        self.monitor_thread.daemon = True
        self.monitor_thread.start()
        
        print(f"📊 开始传感器监测 - 间隔: {interval}s")
    
    def stop_monitoring(self):
        """停止监测"""
        self.monitoring = False
        if self.monitor_thread:
            self.monitor_thread.join(timeout=1.0)
        print("🛑 停止传感器监测")
    
    def get_sensor_info(self) -> Dict:
        """获取传感器信息"""
        specs = self.sensor_specs[self.sensor_type]
        return {
            "sensor_type": self.sensor_type,
            "gpio_pin": self.pin,
            "temperature_range": specs["temperature_range"],
            "humidity_range": specs["humidity_range"],
            "accuracy": specs["accuracy"],
            "min_reading_interval": specs["reading_interval"]
        }
    
    def cleanup(self):
        """清理资源"""
        self.stop_monitoring()
        print(f"🧹 {self.sensor_type}传感器清理完成")

class EnvironmentMonitor:
    """环境监测系统"""
    
    def __init__(self):
        self.sensors = {}
        self.data_log = []
        self.max_log_size = 1000
        
        print("🌡️  环境监测系统初始化完成")
    
    def add_sensor(self, name: str, pin: int, sensor_type: str = "DHT11"):
        """添加传感器"""
        if name in self.sensors:
            print(f"⚠️  传感器 '{name}' 已存在,正在替换")
            self.sensors[name].cleanup()
        
        self.sensors[name] = DHTSensor(pin, sensor_type)
        
        # 添加数据回调
        def sensor_callback(data):
            self._handle_sensor_data(name, data)
        
        self.sensors[name].add_callback(sensor_callback)
        print(f"✅ 添加传感器: {name} ({sensor_type} - 引脚: {pin})")
    
    def _handle_sensor_data(self, sensor_name: str, data: Dict):
        """处理传感器数据"""
        log_entry = {
            "sensor": sensor_name,
            "timestamp": data["timestamp"],
            "temperature": data["temperature"],
            "humidity": data["humidity"]
        }
        
        self.data_log.append(log_entry)
        
        # 限制日志大小
        if len(self.data_log) > self.max_log_size:
            self.data_log.pop(0)
        
        # 打印数据
        print(f"📈 {sensor_name}: {data['temperature']:.1f}°C, {data['humidity']:.1f}%")
    
    def start_monitoring(self, interval: float = 5.0):
        """开始监测所有传感器"""
        for name, sensor in self.sensors.items():
            sensor.start_monitoring(interval)
        print(f"🚀 开始环境监测 - 间隔: {interval}s")
    
    def stop_monitoring(self):
        """停止监测所有传感器"""
        for sensor in self.sensors.values():
            sensor.stop_monitoring()
        print("🛑 停止环境监测")
    
    def get_current_readings(self) -> Dict:
        """获取当前所有传感器读数"""
        readings = {}
        for name, sensor in self.sensors.items():
            readings[name] = sensor.read()
        return readings
    
    def get_statistics(self, sensor_name: str, data_points: int = 100) -> Dict:
        """获取传感器统计信息"""
        sensor_data = [entry for entry in self.data_log if entry["sensor"] == sensor_name]
        sensor_data = sensor_data[-data_points:]  # 最近的数据点
        
        if not sensor_data:
            return {}
        
        temperatures = [d["temperature"] for d in sensor_data]
        humidities = [d["humidity"] for d in sensor_data]
        
        return {
            "sensor": sensor_name,
            "data_points": len(sensor_data),
            "temperature": {
                "current": temperatures[-1],
                "average": sum(temperatures) / len(temperatures),
                "min": min(temperatures),
                "max": max(temperatures),
                "trend": self._calculate_trend(temperatures)
            },
            "humidity": {
                "current": humidities[-1],
                "average": sum(humidities) / len(humidities),
                "min": min(humidities),
                "max": max(humidities),
                "trend": self._calculate_trend(humidities)
            }
        }
    
    def _calculate_trend(self, data: list) -> str:
        """计算数据趋势"""
        if len(data) < 2:
            return "stable"
        
        # 使用线性回归计算趋势
        x = list(range(len(data)))
        y = data
        
        n = len(x)
        sum_x = sum(x)
        sum_y = sum(y)
        sum_xy = sum(x[i] * y[i] for i in range(n))
        sum_x2 = sum(xi * xi for xi in x)
        
        slope = (n * sum_xy - sum_x * sum_y) / (n * sum_x2 - sum_x * sum_x)
        
        if slope > 0.1:
            return "rising"
        elif slope < -0.1:
            return "falling"
        else:
            return "stable"
    
    def generate_report(self) -> Dict:
        """生成监测报告"""
        report = {
            "timestamp": time.time(),
            "sensors": {},
            "summary": {
                "total_sensors": len(self.sensors),
                "total_data_points": len(self.data_log),
                "monitoring_duration": self.data_log[-1]["timestamp"] - self.data_log[0]["timestamp"] if self.data_log else 0
            }
        }
        
        for sensor_name in self.sensors:
            stats = self.get_statistics(sensor_name)
            if stats:
                report["sensors"][sensor_name] = stats
        
        return report
    
    def cleanup(self):
        """清理所有资源"""
        self.stop_monitoring()
        for sensor in self.sensors.values():
            sensor.cleanup()
        self.sensors.clear()
        print("🧹 环境监测系统清理完成")

def demonstrate_dht_sensor():
    """演示DHT传感器功能"""
    try:
        # 创建环境监测系统
        monitor = EnvironmentMonitor()
        
        # 添加传感器(假设DHT11连接在GPIO4,DHT22连接在GPIO17)
        monitor.add_sensor("living_room", 4, "DHT11")
        monitor.add_sensor("outside", 17, "DHT22")
        
        # 显示传感器信息
        print("\n传感器信息:")
        for name, sensor in monitor.sensors.items():
            info = sensor.get_sensor_info()
            print(f"{name}: {info['sensor_type']} - 温度范围: {info['temperature_range']}, 精度: {info['accuracy']}")
        
        # 单次读取测试
        print("\n单次读取测试:")
        readings = monitor.get_current_readings()
        for name, reading in readings.items():
            if reading:
                print(f"{name}: {reading['temperature']:.1f}°C, {reading['humidity']:.1f}%")
            else:
                print(f"{name}: 读取失败")
        
        # 开始持续监测
        print("\n开始持续监测...")
        monitor.start_monitoring(interval=3.0)
        
        # 监测10秒后生成报告
        time.sleep(10)
        
        print("\n生成监测报告:")
        report = monitor.generate_report()
        print(f"监测时长: {report['summary']['monitoring_duration']:.1f}秒")
        print(f"数据点数: {report['summary']['total_data_points']}")
        
        for sensor_name, stats in report['sensors'].items():
            print(f"\n{sensor_name}统计:")
            print(f"  温度: {stats['temperature']['current']:.1f}°C "
                  f"(平均: {stats['temperature']['average']:.1f}°C, "
                  f"趋势: {stats['temperature']['trend']})")
            print(f"  湿度: {stats['humidity']['current']:.1f}% "
                  f"(平均: {stats['humidity']['average']:.1f}%, "
                  f"趋势: {stats['humidity']['trend']})")
        
        # 继续监测一段时间
        print("\n继续监测5秒...")
        time.sleep(5)
        
    except KeyboardInterrupt:
        print("\n🛑 演示被用户中断")
    except Exception as e:
        print(f"❌ 演示错误: {e}")
    finally:
        # 清理资源
        if 'monitor' in locals():
            monitor.cleanup()
        GPIO.cleanup()
        print("🧹 所有资源已清理")

if __name__ == "__main__":
    demonstrate_dht_sensor()

4.2 光敏电阻与运动传感器

python 复制代码
# projects/sensor_monitoring/light_motion_sensors.py
"""
光敏电阻和运动传感器监测
"""
import RPi.GPIO as GPIO
import time
import threading
import math
from typing import Dict, List, Callable, Optional
from enum import Enum

class SensorType(Enum):
    """传感器类型枚举"""
    LIGHT = 1
    MOTION = 2

class AnalogSensor:
    """模拟传感器基类(使用RC电路测量)"""
    
    def __init__(self, pin: int, sensor_type: SensorType, 
                 charge_time: float = 0.01, max_measure_time: float = 0.1):
        """
        初始化模拟传感器
        
        Args:
            pin: GPIO引脚
            sensor_type: 传感器类型
            charge_time: 充电时间(秒)
            max_measure_time: 最大测量时间(秒)
        """
        self.pin = pin
        self.sensor_type = sensor_type
        self.charge_time = charge_time
        self.max_measure_time = max_measure_time
        
        # 状态变量
        self.last_value = 0
        self.calibration = {"min": 0, "max": 1}
        self.callbacks = []
        
        # GPIO设置
        GPIO.setmode(GPIO.BCM)
        
        print(f"✅ {sensor_type.name}传感器初始化完成 - 引脚: {pin}")
    
    def _measure_rc_time(self) -> float:
        """
        测量RC电路放电时间
        
        Returns:
            放电时间(秒)
        """
        # 充电阶段
        GPIO.setup(self.pin, GPIO.OUT)
        GPIO.output(self.pin, GPIO.HIGH)
        time.sleep(self.charge_time)
        
        # 放电阶段
        GPIO.setup(self.pin, GPIO.IN)
        start_time = time.time()
        
        # 等待引脚变为低电平
        while GPIO.input(self.pin) == GPIO.HIGH:
            if time.time() - start_time > self.max_measure_time:
                return self.max_measure_time
        
        return time.time() - start_time
    
    def read_raw(self) -> float:
        """读取原始测量值"""
        return self._measure_rc_time()
    
    def read_normalized(self) -> float:
        """读取归一化值 (0-1)"""
        raw_value = self.read_raw()
        normalized = (raw_value - self.calibration["min"]) / (self.calibration["max"] - self.calibration["min"])
        return max(0.0, min(1.0, normalized))
    
    def calibrate(self, min_time: float = None, max_time: float = None):
        """
        校准传感器
        
        Args:
            min_time: 最小测量时间(暗环境)
            max_time: 最大测量时间(亮环境)
        """
        if min_time is None or max_time is None:
            print("开始自动校准...")
            print("请将传感器置于最暗环境,5秒后开始测量...")
            time.sleep(5)
            min_time = self.read_raw()
            print(f"最小值测量: {min_time:.4f}s")
            
            print("请将传感器置于最亮环境,5秒后开始测量...")
            time.sleep(5)
            max_time = self.read_raw()
            print(f"最大值测量: {max_time:.4f}s")
        
        self.calibration = {"min": min_time, "max": max_time}
        print(f"✅ 传感器校准完成: {min_time:.4f}s - {max_time:.4f}s")
    
    def add_callback(self, callback: Callable):
        """添加数据回调"""
        self.callbacks.append(callback)
    
    def cleanup(self):
        """清理资源"""
        print(f"🧹 {self.sensor_type.name}传感器清理完成")

class LightSensor(AnalogSensor):
    """光敏电阻传感器"""
    
    def __init__(self, pin: int):
        super().__init__(pin, SensorType.LIGHT)
    
    def read_lux(self) -> float:
        """
        读取光照强度(估算值)
        
        Returns:
            估算的光照强度(lux)
        """
        # 这是一个近似转换,实际值需要根据具体传感器校准
        normalized = self.read_normalized()
        
        # 使用对数关系近似光照强度(光敏电阻特性)
        if normalized < 0.01:
            return 0
        else:
            # 近似公式: lux ≈ 10^(4 * normalized - 2)
            return 10 ** (4 * normalized - 2)
    
    def get_light_level(self) -> str:
        """获取光照等级描述"""
        lux = self.read_lux()
        
        if lux < 10:
            return "黑暗"
        elif lux < 50:
            return "昏暗"
        elif lux < 200:
            return "一般"
        elif lux < 1000:
            return "明亮"
        else:
            return "非常明亮"

class MotionSensor:
    """PIR运动传感器"""
    
    def __init__(self, pin: int, warmup_time: int = 30):
        """
        初始化运动传感器
        
        Args:
            pin: 数字输出引脚
            warmup_time: 启动预热时间(秒)
        """
        self.pin = pin
        self.warmup_time = warmup_time
        self.last_motion_time = 0
        self.motion_detected = False
        self.callbacks = []
        self.monitoring = False
        self.monitor_thread = None
        
        # GPIO设置
        GPIO.setmode(GPIO.BCM)
        GPIO.setup(self.pin, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
        
        # 添加边缘检测
        GPIO.add_event_detect(self.pin, GPIO.RISING, callback=self._motion_callback)
        
        print(f"✅ PIR运动传感器初始化完成 - 引脚: {pin}")
        print(f"⏳ 传感器预热中... ({warmup_time}秒)")
        time.sleep(warmup_time)
        print("🔍 运动传感器就绪")
    
    def _motion_callback(self, channel):
        """运动检测回调"""
        if channel == self.pin:
            self.motion_detected = True
            self.last_motion_time = time.time()
            
            # 触发回调
            for callback in self.callbacks:
                try:
                    callback(self.last_motion_time)
                except Exception as e:
                    print(f"❌ 运动回调错误: {e}")
            
            print("🚶 检测到运动!")
    
    def add_callback(self, callback: Callable):
        """添加运动检测回调"""
        self.callbacks.append(callback)
    
    def start_monitoring(self):
        """开始监测"""
        if self.monitoring:
            return
        
        self.monitoring = True
        
        def monitor_task():
            while self.monitoring:
                # 检查运动状态超时(通常PIR传感器会在运动停止后自动复位)
                current_state = GPIO.input(self.pin)
                if not current_state and self.motion_detected:
                    self.motion_detected = False
                    print("💤 运动停止")
                
                time.sleep(0.1)
        
        self.monitor_thread = threading.Thread(target=monitor_task)
        self.monitor_thread.daemon = True
        self.monitor_thread.start()
        
        print("📊 开始运动监测")
    
    def stop_monitoring(self):
        """停止监测"""
        self.monitoring = False
        if self.monitor_thread:
            self.monitor_thread.join(timeout=1.0)
        print("🛑 停止运动监测")
    
    def get_status(self) -> Dict:
        """获取传感器状态"""
        current_state = GPIO.input(self.pin)
        time_since_motion = time.time() - self.last_motion_time if self.last_motion_time > 0 else float('inf')
        
        return {
            "pin": self.pin,
            "current_state": "运动" if current_state else "静止",
            "motion_detected": self.motion_detected,
            "last_motion_time": self.last_motion_time,
            "time_since_motion": time_since_motion,
            "warmup_complete": time.time() > self.warmup_time
        }
    
    def cleanup(self):
        """清理资源"""
        self.stop_monitoring()
        GPIO.remove_event_detect(self.pin)
        print("🧹 运动传感器清理完成")

class SmartLightController:
    """智能灯光控制器"""
    
    def __init__(self, light_sensor_pin: int, motion_sensor_pin: int, led_pins: List[int]):
        """
        初始化智能灯光控制器
        
        Args:
            light_sensor_pin: 光敏传感器引脚
            motion_sensor_pin: 运动传感器引脚
            led_pins: LED控制引脚列表
        """
        from led_control.led_manager import LEDController
        
        # 初始化传感器
        self.light_sensor = LightSensor(light_sensor_pin)
        self.motion_sensor = MotionSensor(motion_sensor_pin)
        
        # 初始化LED控制器
        self.leds = [LEDController(pin) for pin in led_pins]
        
        # 控制参数
        self.auto_mode = True
        self.light_threshold = 0.3  # 光照阈值 (0-1)
        self.motion_timeout = 60    # 运动超时时间(秒)
        self.last_activity = 0
        
        # 状态变量
        self.lights_on = False
        
        print("💡 智能灯光控制器初始化完成")
    
    def calibrate_sensors(self):
        """校准传感器"""
        print("开始传感器校准...")
        self.light_sensor.calibrate()
        print("✅ 传感器校准完成")
    
    def enable_auto_mode(self):
        """启用自动模式"""
        self.auto_mode = True
        
        # 设置传感器回调
        self.light_sensor.add_callback(self._light_sensor_callback)
        self.motion_sensor.add_callback(self._motion_sensor_callback)
        
        # 开始监测
        self.motion_sensor.start_monitoring()
        
        print("🤖 启用自动灯光模式")
    
    def disable_auto_mode(self):
        """禁用自动模式"""
        self.auto_mode = False
        self.motion_sensor.stop_monitoring()
        print("👤 禁用自动灯光模式")
    
    def _light_sensor_callback(self, data):
        """光敏传感器回调"""
        if not self.auto_mode:
            return
        
        light_level = self.light_sensor.read_normalized()
        
        # 根据环境光照调整LED亮度
        if self.lights_on:
            target_brightness = int((1 - light_level) * 100)
            for led in self.leds:
                led.set_brightness(target_brightness)
    
    def _motion_sensor_callback(self, timestamp):
        """运动传感器回调"""
        if not self.auto_mode:
            return
        
        self.last_activity = timestamp
        
        # 检查环境光照
        light_level = self.light_sensor.read_normalized()
        
        if light_level < self.light_threshold:
            # 环境较暗且检测到运动,打开灯光
            if not self.lights_on:
                self._turn_on_lights()
                self.lights_on = True
        else:
            # 环境明亮,保持灯光关闭
            if self.lights_on:
                self._turn_off_lights()
                self.lights_on = False
    
    def _check_motion_timeout(self):
        """检查运动超时"""
        if not self.auto_mode or not self.lights_on:
            return
        
        time_since_activity = time.time() - self.last_activity
        if time_since_activity > self.motion_timeout:
            self._turn_off_lights()
            self.lights_on = False
            print("💤 运动超时,关闭灯光")
    
    def _turn_on_lights(self):
        """打开灯光"""
        light_level = self.light_sensor.read_normalized()
        brightness = int((1 - light_level) * 100)
        
        for led in self.leds:
            led.set_brightness(brightness)
        
        print(f"💡 打开灯光 - 亮度: {brightness}%")
    
    def _turn_off_lights(self):
        """关闭灯光"""
        for led in self.leds:
            led.off()
        
        print("🌙 关闭灯光")
    
    def set_light_threshold(self, threshold: float):
        """设置光照阈值"""
        self.light_threshold = max(0.0, min(1.0, threshold))
        print(f"📏 光照阈值设置为: {self.light_threshold:.2f}")
    
    def set_motion_timeout(self, timeout: int):
        """设置运动超时时间"""
        self.motion_timeout = timeout
        print(f"⏰ 运动超时设置为: {timeout}秒")
    
    def manual_control(self, state: bool):
        """手动控制灯光"""
        self.disable_auto_mode()
        
        if state:
            self._turn_on_lights()
            self.lights_on = True
        else:
            self._turn_off_lights()
            self.lights_on = False
    
    def get_status(self) -> Dict:
        """获取控制器状态"""
        light_level = self.light_sensor.read_normalized()
        motion_status = self.motion_sensor.get_status()
        
        return {
            "auto_mode": self.auto_mode,
            "lights_on": self.lights_on,
            "light_level": light_level,
            "light_threshold": self.light_threshold,
            "motion_detected": motion_status["motion_detected"],
            "time_since_motion": motion_status["time_since_motion"],
            "motion_timeout": self.motion_timeout
        }
    
    def start(self):
        """启动控制器"""
        self.enable_auto_mode()
        
        # 启动超时检查线程
        def timeout_checker():
            while True:
                self._check_motion_timeout()
                time.sleep(5)  # 每5秒检查一次
        
        thread = threading.Thread(target=timeout_checker)
        thread.daemon = True
        thread.start()
        
        print("🚀 智能灯光控制器启动")
    
    def cleanup(self):
        """清理资源"""
        self.disable_auto_mode()
        self._turn_off_lights()
        
        self.light_sensor.cleanup()
        self.motion_sensor.cleanup()
        
        for led in self.leds:
            led.cleanup()
        
        print("🧹 智能灯光控制器清理完成")

def demonstrate_smart_light():
    """演示智能灯光控制系统"""
    try:
        # 创建智能灯光控制器
        # 假设: 光敏传感器-GPIO5, 运动传感器-GPIO6, LED-GPIO18
        controller = SmartLightController(
            light_sensor_pin=5,
            motion_sensor_pin=6, 
            led_pins=[18]
        )
        
        # 校准传感器(在实际使用中需要根据环境校准)
        print("跳过自动校准(演示模式)...")
        # controller.calibrate_sensors()
        
        # 设置参数
        controller.set_light_threshold(0.4)  # 40%光照阈值
        controller.set_motion_timeout(30)    # 30秒超时
        
        # 启动控制器
        controller.start()
        
        print("\n🎯 智能灯光演示开始")
        print("自动模式已启用 - 系统将根据环境和运动自动控制灯光")
        print("按Ctrl+C退出演示")
        
        # 显示状态信息
        try:
            while True:
                status = controller.get_status()
                
                print(f"\r环境光照: {status['light_level']:.2f} | "
                      f"灯光: {'开' if status['lights_on'] else '关'} | "
                      f"运动: {'是' if status['motion_detected'] else '否'} | "
                      f"超时: {status['time_since_motion']:.0f}s", end="")
                
                time.sleep(1)
                
        except KeyboardInterrupt:
            print("\n🛑 演示被用户中断")
            
    except Exception as e:
        print(f"❌ 演示错误: {e}")
    finally:
        # 清理资源
        if 'controller' in locals():
            controller.cleanup()
        GPIO.cleanup()
        print("🧹 所有资源已清理")

if __name__ == "__main__":
    demonstrate_smart_light()

5. 完整项目:智能家居控制系统

5.1 系统架构与集成

python 复制代码
# projects/iot_applications/smart_home.py
"""
智能家居控制系统 - 完整项目
"""
import RPi.GPIO as GPIO
import time
import threading
import json
import logging
from typing import Dict, List, Optional
from datetime import datetime, timedelta
from pathlib import Path

# 导入自定义模块
from sensor_monitoring.dht_sensor import EnvironmentMonitor
from sensor_monitoring.light_motion_sensors import SmartLightController
from led_control.led_manager import RGBLEDController
from led_control.button_manager import ButtonManager

class SmartHomeSystem:
    """智能家居主控制系统"""
    
    def __init__(self, config_file: str = "config/smart_home.json"):
        """
        初始化智能家居系统
        
        Args:
            config_file: 配置文件路径
        """
        self.config_file = Path(config_file)
        self.config = self._load_config()
        
        # 系统状态
        self.running = False
        self.components = {}
        self.automations = {}
        
        # 数据记录
        self.data_log = []
        self.max_log_size = self.config.get("max_log_size", 10000)
        
        # 设置日志
        self._setup_logging()
        
        # 初始化组件
        self._initialize_components()
        
        print("🏠 智能家居系统初始化完成")
    
    def _load_config(self) -> Dict:
        """加载配置文件"""
        default_config = {
            "gpio_pins": {
                "living_room_led": 18,
                "bedroom_led": 23,
                "rgb_led_red": 17,
                "rgb_led_green": 27,
                "rgb_led_blue": 22,
                "light_sensor": 5,
                "motion_sensor": 6,
                "dht_sensor": 4,
                "button_1": 2,
                "button_2": 3
            },
            "settings": {
                "auto_light_threshold": 0.3,
                "motion_timeout": 60,
                "temperature_alert": 30,
                "humidity_alert": 80,
                "check_interval": 5
            },
            "max_log_size": 10000,
            "log_file": "logs/smart_home.log"
        }
        
        if self.config_file.exists():
            try:
                with open(self.config_file, 'r') as f:
                    user_config = json.load(f)
                    # 合并配置
                    default_config.update(user_config)
                    print("✅ 配置文件加载成功")
            except Exception as e:
                print(f"❌ 配置文件加载失败: {e}, 使用默认配置")
        else:
            print("⚠️  配置文件不存在,使用默认配置")
            # 创建默认配置文件
            self.config_file.parent.mkdir(parents=True, exist_ok=True)
            with open(self.config_file, 'w') as f:
                json.dump(default_config, f, indent=2)
            print("📁 已创建默认配置文件")
        
        return default_config
    
    def _setup_logging(self):
        """设置日志系统"""
        log_file = Path(self.config["settings"].get("log_file", "logs/smart_home.log"))
        log_file.parent.mkdir(parents=True, exist_ok=True)
        
        logging.basicConfig(
            level=logging.INFO,
            format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
            handlers=[
                logging.FileHandler(log_file),
                logging.StreamHandler()
            ]
        )
        
        self.logger = logging.getLogger("SmartHome")
        self.logger.info("智能家居系统启动")
    
    def _initialize_components(self):
        """初始化所有组件"""
        pins = self.config["gpio_pins"]
        
        try:
            # 环境监测
            self.components["environment"] = EnvironmentMonitor()
            self.components["environment"].add_sensor("living_room", pins["dht_sensor"], "DHT11")
            
            # 智能灯光
            self.components["lights"] = SmartLightController(
                light_sensor_pin=pins["light_sensor"],
                motion_sensor_pin=pins["motion_sensor"],
                led_pins=[pins["living_room_led"], pins["bedroom_led"]]
            )
            
            # RGB情景灯
            self.components["mood_light"] = RGBLEDController(
                pins["rgb_led_red"],
                pins["rgb_led_green"], 
                pins["rgb_led_blue"]
            )
            
            # 按钮控制
            self.components["buttons"] = ButtonManager()
            self.components["buttons"].add_button("mode_button", pins["button_1"])
            self.components["buttons"].add_button("scene_button", pins["button_2"])
            
            self.logger.info("所有硬件组件初始化完成")
            
        except Exception as e:
            self.logger.error(f"组件初始化失败: {e}")
            raise
    
    def _setup_automations(self):
        """设置自动化规则"""
        settings = self.config["settings"]
        
        # 环境监测自动化
        def environment_alert(data):
            if data["temperature"] > settings["temperature_alert"]:
                self._trigger_alert("高温警报", f"温度过高: {data['temperature']}°C")
            
            if data["humidity"] > settings["humidity_alert"]:
                self._trigger_alert("高湿警报", f"湿度过高: {data['humidity']}%")
        
        self.automations["environment_alert"] = environment_alert
        
        # 按钮控制自动化
        def toggle_auto_mode(pin):
            lights = self.components["lights"]
            if lights.auto_mode:
                lights.disable_auto_mode()
                self.components["mood_light"].set_color(100, 50, 0)  # 橙色表示手动模式
                self.logger.info("切换到手动模式")
            else:
                lights.enable_auto_mode()
                self.components["mood_light"].set_color(0, 100, 0)  # 绿色表示自动模式
                self.logger.info("切换到自动模式")
        
        def cycle_scenes(pin):
            scenes = [
                (100, 100, 100),  # 白光
                (100, 50, 0),     # 暖黄
                (50, 0, 100),     # 紫调
                (0, 100, 100),    # 青蓝
                (100, 0, 50)      # 粉红
            ]
            
            current_color = self.components["mood_light"].current_color
            try:
                current_index = scenes.index(current_color)
                next_index = (current_index + 1) % len(scenes)
            except ValueError:
                next_index = 0
            
            new_color = scenes[next_index]
            self.components["mood_light"].set_color(*new_color)
            self.logger.info(f"切换到情景模式 {next_index + 1}")
        
        # 绑定按钮事件
        self.components["buttons"].get_button("mode_button").add_event_handler(
            lambda pin: toggle_auto_mode(pin)
        )
        
        self.components["buttons"].get_button("scene_button").add_event_handler(
            lambda pin: cycle_scenes(pin)
        )
        
        # 注册环境监测回调
        self.components["environment"].sensors["living_room"].add_callback(
            environment_alert
        )
        
        self.logger.info("自动化规则设置完成")
    
    def _trigger_alert(self, alert_type: str, message: str):
        """触发警报"""
        self.logger.warning(f"警报: {alert_type} - {message}")
        
        # 视觉警报:RGB灯闪烁红色
        def alert_blink():
            mood_light = self.components["mood_light"]
            original_color = mood_light.current_color
            
            for _ in range(6):
                mood_light.set_color(100, 0, 0)  # 红色
                time.sleep(0.5)
                mood_light.set_color(0, 0, 0)    # 关闭
                time.sleep(0.5)
            
            mood_light.set_color(*original_color)  # 恢复原颜色
        
        threading.Thread(target=alert_blink, daemon=True).start()
    
    def _log_system_data(self):
        """记录系统数据"""
        log_entry = {
            "timestamp": datetime.now().isoformat(),
            "environment": self.components["environment"].get_current_readings(),
            "lights": self.components["lights"].get_status(),
            "system": {
                "running_time": time.time() - self.start_time,
                "active_automations": len(self.automations)
            }
        }
        
        self.data_log.append(log_entry)
        
        # 限制日志大小
        if len(self.data_log) > self.max_log_size:
            self.data_log.pop(0)
    
    def _save_data_log(self):
        """保存数据日志到文件"""
        data_file = Path("data/system_log.json")
        data_file.parent.mkdir(parents=True, exist_ok=True)
        
        try:
            with open(data_file, 'w') as f:
                json.dump(self.data_log, f, indent=2, default=str)
        except Exception as e:
            self.logger.error(f"数据保存失败: {e}")
    
    def get_system_status(self) -> Dict:
        """获取系统状态"""
        status = {
            "timestamp": datetime.now().isoformat(),
            "running": self.running,
            "components": {},
            "statistics": {
                "total_data_points": len(self.data_log),
                "running_time": time.time() - self.start_time if hasattr(self, 'start_time') else 0
            }
        }
        
        # 收集各组件状态
        for name, component in self.components.items():
            if hasattr(component, 'get_status'):
                status["components"][name] = component.get_status()
            elif hasattr(component, 'get_current_readings'):
                status["components"][name] = component.get_current_readings()
        
        return status
    
    def start(self):
        """启动智能家居系统"""
        if self.running:
            self.logger.warning("系统已经在运行中")
            return
        
        self.running = True
        self.start_time = time.time()
        
        # 设置自动化
        self._setup_automations()
        
        # 启动各组件
        self.components["environment"].start_monitoring(
            self.config["settings"]["check_interval"]
        )
        self.components["lights"].start()
        self.components["buttons"].get_button("mode_button").start_monitoring()
        self.components["buttons"].get_button("scene_button").start_monitoring()
        
        # 设置初始情景
        self.components["mood_light"].set_color(0, 100, 0)  # 绿色 - 自动模式
        
        # 启动数据记录线程
        def data_logging_task():
            while self.running:
                self._log_system_data()
                time.sleep(self.config["settings"]["check_interval"])
        
        self.logging_thread = threading.Thread(target=data_logging_task)
        self.logging_thread.daemon = True
        self.logging_thread.start()
        
        # 启动自动保存线程
        def auto_save_task():
            while self.running:
                time.sleep(300)  # 每5分钟保存一次
                self._save_data_log()
        
        self.save_thread = threading.Thread(target=auto_save_task)
        self.save_thread.daemon = True
        self.save_thread.start()
        
        self.logger.info("智能家居系统启动完成")
        print("🚀 智能家居系统正在运行...")
        print("按Ctrl+C停止系统")
    
    def stop(self):
        """停止智能家居系统"""
        if not self.running:
            return
        
        self.running = False
        self.logger.info("正在停止智能家居系统...")
        
        # 停止各组件
        for name, component in self.components.items():
            if hasattr(component, 'cleanup'):
                try:
                    component.cleanup()
                    self.logger.info(f"组件 {name} 已停止")
                except Exception as e:
                    self.logger.error(f"停止组件 {name} 时出错: {e}")
        
        # 保存最终数据
        self._save_data_log()
        
        # 等待线程结束
        if hasattr(self, 'logging_thread'):
            self.logging_thread.join(timeout=5.0)
        if hasattr(self, 'save_thread'):
            self.save_thread.join(timeout=5.0)
        
        GPIO.cleanup()
        self.logger.info("智能家居系统已停止")
        print("🛑 智能家居系统已停止")
    
    def run_interactive(self):
        """运行交互式控制界面"""
        self.start()
        
        try:
            while self.running:
                print("\n" + "="*50)
                print("🏠 智能家居控制系统")
                print("="*50)
                
                status = self.get_system_status()
                
                # 显示环境信息
                env_data = status["components"]["environment"]["living_room"]
                if env_data:
                    print(f"🌡️  温度: {env_data['temperature']:.1f}°C")
                    print(f"💧 湿度: {env_data['humidity']:.1f}%")
                
                # 显示灯光状态
                light_status = status["components"]["lights"]
                print(f"💡 灯光: {'开' if light_status['lights_on'] else '关'}")
                print(f"🤖 模式: {'自动' if light_status['auto_mode'] else '手动'}")
                print(f"📏 光照: {light_status['light_level']:.2f}")
                print(f"🚶 运动: {'检测到' if light_status['motion_detected'] else '无'}")
                
                print("\n选项:")
                print("1. 切换自动/手动模式")
                print("2. 切换情景灯光")
                print("3. 打开所有灯光")
                print("4. 关闭所有灯光") 
                print("5. 系统状态报告")
                print("6. 退出系统")
                
                choice = input("\n请选择操作 (1-6): ").strip()
                
                if choice == "1":
                    # 模拟模式按钮按下
                    self.components["buttons"].get_button("mode_button")._handle_click()
                elif choice == "2":
                    # 模拟情景按钮按下
                    self.components["buttons"].get_button("scene_button")._handle_click()
                elif choice == "3":
                    self.components["lights"].manual_control(True)
                elif choice == "4":
                    self.components["lights"].manual_control(False)
                elif choice == "5":
                    self.generate_report()
                elif choice == "6":
                    break
                else:
                    print("❌ 无效选择")
                
                time.sleep(1)
                
        except KeyboardInterrupt:
            print("\n🛑 用户请求退出")
        finally:
            self.stop()
    
    def generate_report(self):
        """生成系统报告"""
        print("\n" + "="*50)
        print("📊 智能家居系统报告")
        print("="*50)
        
        status = self.get_system_status()
        
        print(f"系统运行时间: {status['statistics']['running_time']:.1f} 秒")
        print(f"数据记录数: {status['statistics']['total_data_points']}")
        
        # 环境统计
        if self.data_log:
            env_data = [entry["environment"]["living_room"] for entry in self.data_log if entry["environment"]["living_room"]]
            if env_data:
                temps = [d["temperature"] for d in env_data]
                humids = [d["humidity"] for d in env_data]
                
                print(f"\n环境统计 (最近{len(env_data)}次记录):")
                print(f"  温度: {sum(temps)/len(temps):.1f}°C (范围: {min(temps):.1f}-{max(temps):.1f}°C)")
                print(f"  湿度: {sum(humids)/len(humids):.1f}% (范围: {min(humids):.1f}-{max(humids):.1f}%)")
        
        # 组件状态
        print(f"\n组件状态:")
        for name, comp_status in status["components"].items():
            if name == "lights":
                print(f"  💡 灯光: {'运行中' if comp_status['auto_mode'] else '手动模式'}")
            elif name == "environment":
                print(f"  🌡️  环境监测: 运行中")
            elif name == "mood_light":
                print(f"  🎨 情景灯: 运行中")
            elif name == "buttons":
                print(f"  🔘 按钮控制: 运行中")
        
        input("\n按回车键继续...")

def main():
    """主函数"""
    print("🏠 Raspberry Pi 智能家居系统")
    print("="*50)
    
    try:
        # 创建智能家居系统
        smart_home = SmartHomeSystem()
        
        # 运行交互式界面
        smart_home.run_interactive()
        
    except Exception as e:
        print(f"❌ 系统错误: {e}")
        logging.error(f"系统错误: {e}", exc_info=True)
    finally:
        # 确保资源被清理
        GPIO.cleanup()
        print("🧹 所有资源已清理")

if __name__ == "__main__":
    main()

6. 完整代码结构与部署

6.1 项目配置文件

python 复制代码
# config/smart_home.json
{
  "gpio_pins": {
    "living_room_led": 18,
    "bedroom_led": 23,
    "rgb_led_red": 17,
    "rgb_led_green": 27,
    "rgb_led_blue": 22,
    "light_sensor": 5,
    "motion_sensor": 6,
    "dht_sensor": 4,
    "button_1": 2,
    "button_2": 3,
    "buzzer": 24
  },
  "settings": {
    "auto_light_threshold": 0.3,
    "motion_timeout": 60,
    "temperature_alert": 30,
    "humidity_alert": 80,
    "check_interval": 5,
    "data_save_interval": 300
  },
  "system": {
    "max_log_size": 10000,
    "log_file": "logs/smart_home.log",
    "data_file": "data/system_data.json"
  },
  "automations": {
    "enable_environment_alerts": true,
    "enable_auto_lighting": true,
    "enable_motion_detection": true
  }
}

6.2 系统服务与自启动

python 复制代码
# scripts/install_service.py
"""
智能家居系统服务安装脚本
"""
import os
import sys
import subprocess
from pathlib import Path

def check_root_privileges():
    """检查root权限"""
    if os.geteuid() != 0:
        print("❌ 需要root权限运行此脚本")
        print("请使用: sudo python install_service.py")
        sys.exit(1)

def create_systemd_service():
    """创建systemd服务文件"""
    service_content = """[Unit]
Description=Smart Home System
After=network.target

[Service]
Type=simple
User=pi
WorkingDirectory=/home/pi/smart_home
ExecStart=/usr/bin/python3 /home/pi/smart_home/main.py
Restart=always
RestartSec=10
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target
"""

    service_path = "/etc/systemd/system/smart-home.service"
    
    try:
        with open(service_path, 'w') as f:
            f.write(service_content)
        print(f"✅ 创建服务文件: {service_path}")
        return True
    except Exception as e:
        print(f"❌ 创建服务文件失败: {e}")
        return False

def enable_service():
    """启用系统服务"""
    commands = [
        "sudo systemctl daemon-reload",
        "sudo systemctl enable smart-home.service",
        "sudo systemctl start smart-home.service"
    ]
    
    for cmd in commands:
        try:
            subprocess.run(cmd, shell=True, check=True)
            print(f"✅ 执行: {cmd}")
        except subprocess.CalledProcessError as e:
            print(f"❌ 执行失败: {cmd} - {e}")
            return False
    
    return True

def setup_crontab():
    """设置定时任务"""
    # 添加每日数据备份任务
    crontab_line = "0 2 * * * /usr/bin/python3 /home/pi/smart_home/scripts/backup_data.py"
    
    try:
        # 获取当前crontab
        result = subprocess.run(["crontab", "-l"], capture_output=True, text=True)
        current_crontab = result.stdout
        
        # 检查是否已存在
        if "backup_data.py" not in current_crontab:
            new_crontab = current_crontab + f"\n{crontab_line}\n"
            subprocess.run(["crontab", "-"], input=new_crontab, text=True, check=True)
            print("✅ 添加定时备份任务")
        else:
            print("✅ 定时备份任务已存在")
        
        return True
    except Exception as e:
        print(f"❌ 设置定时任务失败: {e}")
        return False

def create_backup_script():
    """创建数据备份脚本"""
    backup_script = """#!/usr/bin/env python3
\"\"\"
智能家居数据备份脚本
\"\"\"
import json
import shutil
from datetime import datetime
from pathlib import Path

def backup_data():
    \"\"\"备份系统数据\"\"\"
    data_dir = Path("data")
    backup_dir = Path("backups")
    backup_dir.mkdir(exist_ok=True)
    
    timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
    backup_file = backup_dir / f"smart_home_backup_{timestamp}.json"
    
    try:
        # 备份数据文件
        if (data_dir / "system_data.json").exists():
            shutil.copy2(data_dir / "system_data.json", backup_file)
            print(f"✅ 数据备份完成: {backup_file}")
        
        # 清理旧备份(保留最近7天)
        for old_file in backup_dir.glob("smart_home_backup_*.json"):
            file_time = datetime.fromtimestamp(old_file.stat().st_mtime)
            if (datetime.now() - file_time).days > 7:
                old_file.unlink()
                print(f"🗑️  删除旧备份: {old_file}")
    
    except Exception as e:
        print(f"❌ 备份失败: {e}")

if __name__ == "__main__":
    backup_data()
"""

    script_path = Path("scripts/backup_data.py")
    script_path.parent.mkdir(exist_ok=True)
    
    with open(script_path, 'w') as f:
        f.write(backup_script)
    
    # 设置执行权限
    script_path.chmod(0o755)
    print(f"✅ 创建备份脚本: {script_path}")

def main():
    """主安装流程"""
    print("🔧 智能家居系统服务安装")
    print("=" * 50)
    
    # 检查权限
    check_root_privileges()
    
    # 创建备份脚本
    create_backup_script()
    
    # 创建systemd服务
    if not create_systemd_service():
        sys.exit(1)
    
    # 启用服务
    if not enable_service():
        sys.exit(1)
    
    # 设置定时任务
    if not setup_crontab():
        print("⚠️  定时任务设置失败,但服务安装完成")
    
    print("\n" + "=" * 50)
    print("🎉 智能家居系统服务安装完成!")
    print("\n服务管理命令:")
    print("  sudo systemctl start smart-home.service    # 启动服务")
    print("  sudo systemctl stop smart-home.service     # 停止服务") 
    print("  sudo systemctl restart smart-home.service  # 重启服务")
    print("  sudo systemctl status smart-home.service   # 查看状态")
    print("  journalctl -u smart-home.service -f        # 查看日志")

if __name__ == "__main__":
    main()

6.3 Web控制界面

python 复制代码
# projects/iot_applications/web_interface.py
"""
智能家居Web控制界面
"""
from flask import Flask, render_template, jsonify, request
import threading
import time
from pathlib import Path

# 假设这是我们的智能家居系统
from smart_home import SmartHomeSystem

app = Flask(__name__)
smart_home = None

def initialize_smart_home():
    """初始化智能家居系统"""
    global smart_home
    try:
        smart_home = SmartHomeSystem()
        smart_home.start()
        return True
    except Exception as e:
        print(f"❌ 智能家居系统初始化失败: {e}")
        return False

@app.route('/')
def index():
    """主页"""
    return render_template('index.html')

@app.route('/api/status')
def get_status():
    """获取系统状态API"""
    if not smart_home or not smart_home.running:
        return jsonify({"error": "系统未运行"}), 503
    
    try:
        status = smart_home.get_system_status()
        return jsonify(status)
    except Exception as e:
        return jsonify({"error": str(e)}), 500

@app.route('/api/lights', methods=['POST'])
def control_lights():
    """控制灯光API"""
    if not smart_home:
        return jsonify({"error": "系统未初始化"}), 503
    
    data = request.get_json()
    action = data.get('action')
    
    try:
        if action == 'auto':
            smart_home.components["lights"].enable_auto_mode()
        elif action == 'manual_on':
            smart_home.components["lights"].manual_control(True)
        elif action == 'manual_off':
            smart_home.components["lights"].manual_control(False)
        else:
            return jsonify({"error": "无效操作"}), 400
        
        return jsonify({"success": True})
    except Exception as e:
        return jsonify({"error": str(e)}), 500

@app.route('/api/moodlight', methods=['POST'])
def control_moodlight():
    """控制情景灯API"""
    if not smart_home:
        return jsonify({"error": "系统未初始化"}), 503
    
    data = request.get_json()
    color = data.get('color')  # hex颜色代码
    
    try:
        if color:
            smart_home.components["mood_light"].set_color_hex(color)
            return jsonify({"success": True})
        else:
            return jsonify({"error": "需要颜色参数"}), 400
    except Exception as e:
        return jsonify({"error": str(e)}), 500

@app.route('/api/scenes', methods=['POST'])
def activate_scene():
    """激活情景模式API"""
    if not smart_home:
        return jsonify({"error": "系统未初始化"}), 503
    
    data = request.get_json()
    scene = data.get('scene')
    
    scenes = {
        'reading': (100, 100, 100),  # 白光
        'relax': (100, 50, 0),       # 暖黄
        'party': (50, 0, 100),       # 紫调
        'night': (0, 0, 20)          # 夜灯
    }
    
    try:
        if scene in scenes:
            smart_home.components["mood_light"].set_color(*scenes[scene])
            return jsonify({"success": True})
        else:
            return jsonify({"error": "无效情景"}), 400
    except Exception as e:
        return jsonify({"error": str(e)}), 500

@app.route('/api/report')
def get_report():
    """获取系统报告API"""
    if not smart_home:
        return jsonify({"error": "系统未初始化"}), 503
    
    try:
        smart_home.generate_report()
        return jsonify({"success": True})
    except Exception as e:
        return jsonify({"error": str(e)}), 500

def run_web_server():
    """运行Web服务器"""
    print("🌐 启动Web控制界面...")
    app.run(host='0.0.0.0', port=5000, debug=False)

def main():
    """主函数"""
    print("🏠 智能家居Web控制系统")
    print("=" * 50)
    
    # 初始化智能家居系统
    if not initialize_smart_home():
        return
    
    # 启动Web服务器
    try:
        run_web_server()
    except KeyboardInterrupt:
        print("\n🛑 停止Web服务器")
    except Exception as e:
        print(f"❌ Web服务器错误: {e}")
    finally:
        # 清理资源
        if smart_home:
            smart_home.stop()

if __name__ == "__main__":
    main()

7. 总结与进阶学习

7.1 Raspberry Pi Python硬件编程要点

通过本文的完整学习,您已经掌握了树莓派Python硬件开发的核心技能:

  1. GPIO基础:数字输入输出、PWM控制、中断处理
  2. 传感器集成:模拟/数字传感器、环境监测、运动检测
  3. 执行器控制:LED控制、电机驱动、显示设备
  4. 系统集成:多线程编程、事件驱动架构、数据持久化
  5. 项目部署:系统服务、Web界面、生产环境配置

7.2 电气安全与最佳实践

重要安全公式

  • 电流限制 : I m a x = P s u p p l y V × 0.8 I_{max} = \frac{P_{supply}}{V} \times 0.8 Imax=VPsupply×0.8(80%安全余量)
  • 电压分压 : V o u t = V i n × R 2 R 1 + R 2 V_{out} = V_{in} \times \frac{R_2}{R_1 + R_2} Vout=Vin×R1+R2R2
  • 功率计算 : P = V × I P = V \times I P=V×I

安全实践

  • 使用逻辑电平转换器处理5V设备
  • 为电机等感性负载添加续流二极管
  • 使用保险丝和限流电阻保护GPIO引脚
  • 遵循正确的接地和屏蔽原则

7.3 进阶学习路径

基础GPIO控制 传感器集成 通信协议 物联网平台 电机控制 机器人技术 自主系统 计算机视觉 机器学习 AI边缘计算 云服务集成 大数据分析 预测性维护

7.4 故障排除指南

常见问题及解决方案

  1. GPIO无响应

    • 检查引脚编号模式(BCM vs BOARD)
    • 验证引脚是否被其他进程占用
    • 检查物理连接和电源
  2. 传感器读数不稳定

    • 添加软件去抖动
    • 使用硬件滤波电路
    • 检查电源噪声
  3. 系统性能问题

    • 优化线程管理和资源清理
    • 使用硬件PWM代替软件PWM
    • 实现数据缓存和批量处理

7.5 项目扩展思路

  1. 环境监测站:集成更多传感器(空气质量、噪音、辐射)
  2. 安防系统:添加摄像头、门磁传感器、报警器
  3. 农业自动化:土壤湿度、自动灌溉、生长监控
  4. 能源管理:电能监测、太阳能优化、智能开关
  5. 健康监测:心率、血氧、体温监测系统

7.6 社区资源推荐

7.7 持续学习建议

  1. 掌握电子基础:电路理论、数字逻辑、信号处理
  2. 学习通信协议:I2C、SPI、UART、MQTT
  3. 探索嵌入式Linux:设备树、内核模块、系统优化
  4. 实践项目管理:版本控制、文档编写、团队协作

通过持续学习和实践,您将能够开发出更加复杂和实用的物联网项目。记住,硬件编程是一个结合软件开发和电子工程的综合性领域,享受创造的过程!


重要安全提示

  • 本文提供的代码和电路仅供参考
  • 实际操作前请确保理解电路原理和安全规范
  • 高电压项目请在专业人士指导下进行
  • 始终遵循电气安全标准和当地法规
相关推荐
cherry--3 小时前
集合(开发重点)
java·开发语言
半桶水专家3 小时前
父子组件通信详解
开发语言·前端·javascript
寻星探路3 小时前
测试开发话题10---自动化测试常用函数(2)
java·前端·python
鸢尾掠地平3 小时前
Python中常用内置函数上【含代码理解】
开发语言·python
萧鼎3 小时前
Python 图像处理利器:Pillow 深度详解与实战应用
图像处理·python·pillow
高洁013 小时前
大模型-详解 Vision Transformer (ViT)
人工智能·python·深度学习·算法·transformer
api_180079054603 小时前
请求、认证与响应数据解析:1688 商品 API 接口深度探秘
java·大数据·开发语言·mysql·数据挖掘
唐古乌梁海3 小时前
【Java】JVM 内存区域划分
java·开发语言·jvm
低调小一4 小时前
Android Gradle 的 compileOptions 与 Kotlin jvmTarget 全面理解(含案例)
android·开发语言·kotlin