电子工程师入门到实战

26 阅读14分钟

543e07397a564ca2b050fb5056bd00c7~tplv-obj.jpg # 电子工程师从入门到实战:理论与实践全攻略

一、电子工程基础与核心概念

1.1 基本电路理论与元器件

电子工程的核心建立在电路理论基础之上,包含:

  • 基本定律:欧姆定律、基尔霍夫定律、戴维南定理
  • 核心元器件:电阻、电容、电感、二极管、晶体管
  • 电路分析方法:节点电压法、网孔电流法
  • 信号类型:模拟信号与数字信号
# 电路计算辅助工具示例
class CircuitCalculator:
    """基础电路计算器"""
    
    @staticmethod
    def ohms_law(voltage=None, current=None, resistance=None):
        """欧姆定律计算"""
        if voltage is None:
            return current * resistance
        elif current is None:
            return voltage / resistance
        elif resistance is None:
            return voltage / current
        else:
            return "参数已完整,无需计算"
    
    @staticmethod
    def resistor_combine(resistors, connection='series'):
        """电阻组合计算"""
        if connection == 'series':
            return sum(resistors)  # 串联
        elif connection == 'parallel':
            # 并联公式:1/R_total = 1/R1 + 1/R2 + ...
            return 1 / sum(1/r for r in resistors)
    
    @staticmethod
    def rc_time_constant(R, C):
        """RC电路时间常数计算"""
        return R * C  # 单位:秒

# 使用示例
calc = CircuitCalculator()
print("串联电阻:", calc.resistor_combine([100, 200, 300], 'series'))
print("时间常数:", calc.rc_time_constant(1000, 10e-6))  # 1kΩ, 10μF

1.2 半导体器件原理

# 二极管特性计算
class DiodeCalculator:
    """二极管参数计算"""
    
    @staticmethod
    def forward_voltage(current, Is=1e-12, n=1, Vt=0.026):
        """
        计算二极管正向电压
        Is: 反向饱和电流
        n: 理想因子(通常1-2)
        Vt: 热电压(室温约26mV)
        """
        return n * Vt * math.log(current / Is + 1)
    
    @staticmethod
    def zener_voltage_regulator(Vin, R, Iz_min, Iz_max, Vz):
        """
        稳压二极管电路设计
        Vin: 输入电压
        R: 限流电阻
        Iz_min: 最小齐纳电流
        Iz_max: 最大齐纳电流
        Vz: 齐纳电压
        """
        I_load_max = (Vin - Vz) / R - Iz_min
        I_load_min = (Vin - Vz) / R - Iz_max
        return {
            'max_load_current': I_load_max,
            'min_load_current': I_load_min,
            'resistor_power': ((Vin - Vz) ** 2) / R
        }

二、模拟电路设计与实践

2.1 运算放大器电路

// 运算放大器常用电路实现
#include <math.h>

// 同相放大器
typedef struct {
    double R1;  // 输入电阻
    double Rf;  // 反馈电阻
} NonInvertingAmplifier;

double non_inverting_gain(NonInvertingAmplifier* amp) {
    return 1 + (amp->Rf / amp->R1);
}

double non_inverting_output(NonInvertingAmplifier* amp, double Vin) {
    return Vin * non_inverting_gain(amp);
}

// 反相放大器
typedef struct {
    double Rin;  // 输入电阻
    double Rf;   // 反馈电阻
} InvertingAmplifier;

double inverting_gain(InvertingAmplifier* amp) {
    return -(amp->Rf / amp->Rin);
}

double inverting_output(InvertingAmplifier* amp, double Vin) {
    return Vin * inverting_gain(amp);
}

// 低通滤波器设计
typedef struct {
    double R;    // 电阻值
    double C;    // 电容值
    double fc;   // 截止频率
} LowPassFilter;

void calculate_lowpass(LowPassFilter* filter) {
    // 计算截止频率:fc = 1/(2πRC)
    filter->fc = 1 / (2 * M_PI * filter->R * filter->C);
}

// 实际应用示例:温度传感器放大电路
void temperature_sensor_amplifier() {
    // 假设使用PT100温度传感器
    double R_pt100 = 100.0;  // 0°C时电阻值
    double alpha = 0.00385;  // 温度系数
    double temperature = 25.0;  // 当前温度
    
    // 计算当前电阻
    double R_current = R_pt100 * (1 + alpha * temperature);
    
    // 设计差动放大器读取温度信号
    InvertingAmplifier amp = {1000.0, 10000.0};  // 增益为-10
    
    // 假设电桥输出电压为0.1V
    double bridge_output = 0.1;
    double amplified_signal = inverting_output(&amp, bridge_output);
    
    printf("温度: %.1f°C, 放大信号: %.3fV\n", temperature, amplified_signal);
}

2.2 电源电路设计

// 开关电源控制器模块示例
module BuckConverter(
    input wire clk,          // 时钟信号
    input wire reset_n,      // 复位信号
    input wire [11:0] V_in,  // 输入电压(12位ADC值)
    input wire [11:0] V_ref, // 参考电压
    output reg pwm_out,      // PWM输出
    output reg [11:0] V_out  // 输出电压
);
    
    // PID控制器参数
    parameter KP = 8'd50;    // 比例系数
    parameter KI = 8'd5;     // 积分系数
    parameter KD = 8'd20;    // 微分系数
    
    reg [19:0] error_integral = 0;  // 误差积分
    reg [11:0] last_error = 0;      // 上次误差
    
    always @(posedge clk or negedge reset_n) begin
        if (!reset_n) begin
            pwm_out <= 0;
            V_out <= 0;
            error_integral <= 0;
            last_error <= 0;
        end else begin
            // 计算误差
            reg [11:0] error = V_ref - V_out;
            
            // PID计算
            error_integral <= error_integral + error;
            reg [11:0] error_derivative = error - last_error;
            
            reg [19:0] pid_output = 
                (KP * error) + 
                (KI * error_integral) + 
                (KD * error_derivative);
            
            // 生成PWM信号(占空比 = pid_output / 4096)
            static reg [11:0] pwm_counter = 0;
            pwm_counter <= pwm_counter + 1;
            
            if (pwm_counter < pid_output[19:8]) begin
                pwm_out <= 1;
            end else begin
                pwm_out <= 0;
            end
            
            // 更新输出电压(模拟)
            V_out <= V_in * pid_output[19:8] / 4096;
            
            last_error <= error;
        end
    end
endmodule

三、数字电路与嵌入式系统

3.1 FPGA/CPLD开发

// VHDL/Verilog 数字电路设计示例
module SevenSegmentDisplay(
    input wire clk,
    input wire rst_n,
    input wire [3:0] bcd_input,  // BCD码输入
    output reg [6:0] segment,    // 7段显示输出
    output reg [7:0] digit_sel   // 位选信号
);
    
    // BCD到7段译码器
    always @(*) begin
        case (bcd_input)
            4'h0: segment = 7'b0111111;  // 0
            4'h1: segment = 7'b0000110;  // 1
            4'h2: segment = 7'b1011011;  // 2
            4'h3: segment = 7'b1001111;  // 3
            4'h4: segment = 7'b1100110;  // 4
            4'h5: segment = 7'b1101101;  // 5
            4'h6: segment = 7'b1111101;  // 6
            4'h7: segment = 7'b0000111;  // 7
            4'h8: segment = 7'b1111111;  // 8
            4'h9: segment = 7'b1101111;  // 9
            default: segment = 7'b0000000; // 关显示
        endcase
    end
    
    // 动态扫描逻辑
    reg [1:0] scan_counter = 0;
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            digit_sel <= 8'b11111111;
            scan_counter <= 0;
        end else begin
            // 每1ms扫描一位
            if (scan_counter == 2'd3) begin
                scan_counter <= 0;
                digit_sel <= 8'b11111110;  // 选中第一位
            end else begin
                scan_counter <= scan_counter + 1;
                digit_sel <= {digit_sel[6:0], 1'b1}; // 右移
            end
        end
    end
    
endmodule

// UART通信模块
module UART_Transmitter(
    input wire clk,
    input wire rst_n,
    input wire [7:0] tx_data,
    input wire tx_start,
    output reg tx_pin,
    output reg tx_busy
);
    
    parameter BAUD_RATE = 9600;
    parameter CLK_FREQ = 50000000;  // 50MHz
    
    localparam BAUD_COUNT = CLK_FREQ / BAUD_RATE;
    
    reg [15:0] baud_counter = 0;
    reg [3:0] bit_counter = 0;
    reg [7:0] shift_reg = 0;
    
    typedef enum logic [2:0] {
        IDLE,
        START_BIT,
        DATA_BITS,
        STOP_BIT
    } state_t;
    
    state_t state = IDLE;
    
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            state <= IDLE;
            tx_pin <= 1'b1;
            tx_busy <= 1'b0;
            baud_counter <= 0;
        end else begin
            case (state)
                IDLE: begin
                    tx_pin <= 1'b1;
                    if (tx_start) begin
                        state <= START_BIT;
                        shift_reg <= tx_data;
                        tx_busy <= 1'b1;
                        baud_counter <= 0;
                    end
                end
                
                START_BIT: begin
                    tx_pin <= 1'b0;  // 起始位
                    if (baud_counter == BAUD_COUNT-1) begin
                        baud_counter <= 0;
                        state <= DATA_BITS;
                        bit_counter <= 0;
                    end else begin
                        baud_counter <= baud_counter + 1;
                    end
                end
                
                DATA_BITS: begin
                    tx_pin <= shift_reg[0];
                    if (baud_counter == BAUD_COUNT-1) begin
                        baud_counter <= 0;
                        shift_reg <= {1'b0, shift_reg[7:1]};
                        if (bit_counter == 7) begin
                            state <= STOP_BIT;
                        end else begin
                            bit_counter <= bit_counter + 1;
                        end
                    end else begin
                        baud_counter <= baud_counter + 1;
                    end
                end
                
                STOP_BIT: begin
                    tx_pin <= 1'b1;  // 停止位
                    if (baud_counter == BAUD_COUNT-1) begin
                        baud_counter <= 0;
                        state <= IDLE;
                        tx_busy <= 1'b0;
                    end else begin
                        baud_counter <= baud_counter + 1;
                    end
                end
            endcase
        end
    end
endmodule

3.2 嵌入式C编程

// STM32 HAL库示例 - 基于ARM Cortex-M
#include "stm32f4xx_hal.h"
#include <stdio.h>

// GPIO引脚定义
#define LED_PIN GPIO_PIN_13
#define LED_PORT GPIOC
#define BUTTON_PIN GPIO_PIN_0
#define BUTTON_PORT GPIOA

// UART句柄
UART_HandleTypeDef huart2;

// ADC句柄
ADC_HandleTypeDef hadc1;

// PWM初始化
void PWM_Init(TIM_HandleTypeDef* htim, uint32_t channel) {
    TIM_OC_InitTypeDef sConfigOC = {0};
    
    htim->Instance = TIM2;
    htim->Init.Prescaler = 0;
    htim->Init.CounterMode = TIM_COUNTERMODE_UP;
    htim->Init.Period = 1000;  // 1kHz PWM
    htim->Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
    HAL_TIM_PWM_Init(htim);
    
    sConfigOC.OCMode = TIM_OCMODE_PWM1;
    sConfigOC.Pulse = 500;  // 50%占空比
    sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
    sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
    
    HAL_TIM_PWM_ConfigChannel(htim, &sConfigOC, channel);
    HAL_TIM_PWM_Start(htim, channel);
}

// ADC读取温度传感器
float Read_Temperature(void) {
    uint32_t adc_value;
    float temperature;
    
    HAL_ADC_Start(&hadc1);
    HAL_ADC_PollForConversion(&hadc1, 100);
    
    if (HAL_IS_BIT_SET(HAL_ADC_GetState(&hadc1), HAL_ADC_STATE_REG_EOC)) {
        adc_value = HAL_ADC_GetValue(&hadc1);
        
        // 假设使用NTC热敏电阻
        // 温度计算(简化模型)
        float resistance = 10000.0 * (4095.0 / adc_value - 1.0);
        
        // Steinhart-Hart方程(简化版)
        float steinhart = log(resistance / 10000.0);
        steinhart /= 3950.0;  // B值
        steinhart += 1.0 / (25.0 + 273.15);
        temperature = 1.0 / steinhart - 273.15;
    }
    
    HAL_ADC_Stop(&hadc1);
    return temperature;
}

// 中断服务例程
void EXTI0_IRQHandler(void) {
    if (__HAL_GPIO_EXTI_GET_IT(BUTTON_PIN) != RESET) {
        __HAL_GPIO_EXTI_CLEAR_IT(BUTTON_PIN);
        
        // 按钮按下处理
        HAL_GPIO_TogglePin(LED_PORT, LED_PIN);
        
        // 发送调试信息
        char message[50];
        float temp = Read_Temperature();
        sprintf(message, "Button pressed! Temp: %.1fC\r\n", temp);
        HAL_UART_Transmit(&huart2, (uint8_t*)message, strlen(message), 100);
    }
}

// 主函数
int main(void) {
    HAL_Init();
    SystemClock_Config();
    
    // 初始化外设
    MX_GPIO_Init();
    MX_USART2_UART_Init();
    MX_ADC1_Init();
    MX_TIM2_Init();
    
    // 初始化PWM
    TIM_HandleTypeDef htim2;
    PWM_Init(&htim2, TIM_CHANNEL_1);
    
    // 主循环
    while (1) {
        // 读取ADC并调整PWM占空比
        static uint16_t pwm_value = 500;
        float voltage = Read_Temperature();
        
        // 简单的温度控制逻辑
        if (voltage > 30.0) {
            pwm_value = 700;  // 增加风扇速度
        } else if (voltage < 20.0) {
            pwm_value = 300;  // 降低风扇速度
        }
        
        // 更新PWM占空比
        __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, pwm_value);
        
        HAL_Delay(1000);  // 1秒延迟
    }
}

四、PCB设计与信号完整性

4.1 PCB设计要点

# PCB设计规则检查脚本示例
import math

class PCBDesignRules:
    """PCB设计规则检查器"""
    
    def __init__(self):
        self.rules = {
            'min_trace_width': 0.2,    # 最小线宽(mm)
            'min_trace_spacing': 0.2,   # 最小线间距(mm)
            'min_via_diameter': 0.3,    # 最小过孔直径(mm)
            'min_pad_size': 0.5,        # 最小焊盘尺寸(mm)
            'max_current_density': 20,  # 最大电流密度(A/mm²)
        }
    
    def check_trace_width_for_current(self, current, copper_thickness=0.035):
        """
        根据电流计算所需线宽
        current: 电流(A)
        copper_thickness: 铜厚(mm)
        """
        # IPC-2221标准: I = k * ΔT^0.44 * A^0.725
        # 简化计算: 线宽(mm) = 电流(A) / (电流密度 * 铜厚)
        required_width = current / (self.rules['max_current_density'] * copper_thickness)
        
        return max(required_width, self.rules['min_trace_width'])
    
    def calculate_impedance(self, trace_width, trace_height, dielectric_const=4.5):
        """
        计算微带线特性阻抗
        trace_width: 线宽(mm)
        trace_height: 到参考层距离(mm)
        dielectric_const: 介电常数
        """
        # 简化微带线阻抗公式
        if trace_width / trace_height <= 1:
            Z0 = (87 / math.sqrt(dielectric_const + 1.41)) * \
                 math.log(5.98 * trace_height / (0.8 * trace_width + trace_height))
        else:
            Z0 = (60 / math.sqrt(dielectric_const)) * \
                 math.log(4 * trace_height / (0.67 * math.pi * trace_width * (0.8 + trace_width / trace_height)))
        
        return Z0
    
    def check_signal_integrity(self, frequency, trace_length, rise_time=None):
        """
        检查信号完整性
        frequency: 信号频率(Hz)
        trace_length: 走线长度(mm)
        """
        results = {}
        
        # 计算电气长度
        c = 3e8  # 光速(m/s)
        vp = c / math.sqrt(4.5)  # 传播速度(假设FR4)
        electrical_length = (trace_length / 1000) / vp * frequency
        
        # 判断是否为传输线
        if rise_time:
            # 根据上升时间判断
            critical_length = (rise_time * vp) / 6
            is_transmission_line = (trace_length / 1000) > critical_length
        else:
            # 根据电气长度判断
            is_transmission_line = electrical_length > 0.1  # 1/10波长
        
        results['electrical_length'] = electrical_length
        results['is_transmission_line'] = is_transmission_line
        results['wavelength'] = vp / frequency
        
        return results
    
    def calculate_decoupling_capacitor(self, current_switch, voltage_ripple, frequency):
        """
        计算去耦电容容值
        current_switch: 开关电流(A)
        voltage_ripple: 允许的电压纹波(V)
        frequency: 开关频率(Hz)
        """
        # C = I * dt / dV
        dt = 1 / frequency / 10  # 假设响应时间为周期的1/10
        capacitance = current_switch * dt / voltage_ripple
        
        # 考虑ESR
        esr_max = voltage_ripple / current_switch
        
        return {
            'capacitance': capacitance,
            'esr_max': esr_max,
            'recommended_type': 'X5R/X7R陶瓷电容'
        }

# 使用示例
pcb_rules = PCBDesignRules()

# 计算电源走线宽度
current = 2.0  # 2A电流
width_needed = pcb_rules.check_trace_width_for_current(current)
print(f"2A电流需要的最小线宽: {width_needed:.2f}mm")

# 计算阻抗
impedance = pcb_rules.calculate_impedance(0.3, 0.2)
print(f"微带线特性阻抗: {impedance:.1f}Ω")

# 检查信号完整性
si_result = pcb_rules.check_signal_integrity(100e6, 50)  # 100MHz, 50mm
print(f"是否为传输线: {si_result['is_transmission_line']}")

五、项目实战:智能家居控制器

5.1 系统架构设计

// 完整项目:基于ESP32的智能家居控制器
#include <WiFi.h>
#include <WebServer.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>
#include <DHT.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>

// 引脚定义
#define DHT_PIN 4
#define RELAY1_PIN 23
#define RELAY2_PIN 22
#define RELAY3_PIN 21
#define RELAY4_PIN 19
#define LDR_PIN 34
#define PIR_PIN 18

// 网络配置
const char* ssid = "SmartHome";
const char* password = "your_password";
const char* mqtt_server = "mqtt.broker.com";

// 传感器对象
DHT dht(DHT_PIN, DHT22);
WiFiClient espClient;
PubSubClient client(espClient);
WebServer server(80);

// 全局变量
struct SensorData {
    float temperature;
    float humidity;
    int light_level;
    bool motion_detected;
    bool relay_states[4];
} sensor_data;

// MQTT回调函数
void mqtt_callback(char* topic, byte* payload, unsigned int length) {
    char message[length + 1];
    memcpy(message, payload, length);
    message[length] = '\0';
    
    StaticJsonDocument<256> doc;
    deserializeJson(doc, message);
    
    // 处理控制命令
    if (strcmp(topic, "smarthome/relay/control") == 0) {
        int relay_num = doc["relay"];
        bool state = doc["state"];
        
        if (relay_num >= 1 && relay_num <= 4) {
            digitalWrite(RELAY1_PIN + (relay_num - 1), state ? HIGH : LOW);
            sensor_data.relay_states[relay_num - 1] = state;
            
            // 发布状态更新
            char status_msg[50];
            sprintf(status_msg, "{"relay":%d,"state":%s}", 
                    relay_num, state ? "true" : "false");
            client.publish("smarthome/relay/status", status_msg);
        }
    }
}

// Web服务器处理函数
void handle_root() {
    String html = "<!DOCTYPE html><html><head>";
    html += "<meta name='viewport' content='width=device-width, initial-scale=1'>";
    html += "<style>";
    html += ".card {background: #f0f0f0; padding: 20px; margin: 10px; border-radius: 10px;}";
    html += ".relay {background: #4CAF50; color: white; padding: 10px 20px; border: none; border-radius: 5px;}";
    html += "</style></head><body>";
    html += "<h1>智能家居控制器</h1>";
    
    // 传感器数据显示
    html += "<div class='card'>";
    html += "<h2>传感器数据</h2>";
    html += "<p>温度: " + String(sensor_data.temperature) + "°C</p>";
    html += "<p>湿度: " + String(sensor_data.humidity) + "%</p>";
    html += "<p>光照: " + String(sensor_data.light_level) + "</p>";
    html += "<p>运动检测: " + String(sensor_data.motion_detected ? "是" : "否") + "</p>";
    html += "</div>";
    
    // 继电器控制
    html += "<div class='card'><h2>设备控制</h2>";
    for (int i = 1; i <= 4; i++) {
        html += "<p>继电器 " + String(i) + ": ";
        html += "<button class='relay' onclick="controlRelay(" + String(i) + ", true)">开启</button> ";
        html += "<button class='relay' onclick="controlRelay(" + String(i) + ", false)">关闭</button>";
        html += "</p>";
    }
    html += "</div>";
    
    // JavaScript控制函数
    html += "<script>";
    html += "function controlRelay(relay, state) {";
    html += "  fetch('/control', {";
    html += "    method: 'POST',";
    html += "    headers: {'Content-Type': 'application/json'},";
    html += "    body: JSON.stringify({relay: relay, state: state})";
    html += "  });";
    html += "}";
    html += "</script>";
    html += "</body></html>";
    
    server.send(200, "text/html", html);
}

void handle_control() {
    if (server.method() == HTTP_POST) {
        String body = server.arg("plain");
        StaticJsonDocument<200> doc;
        deserializeJson(doc, body);
        
        int relay_num = doc["relay"];
        bool state = doc["state"];
        
        if (relay_num >= 1 && relay_num <= 4) {
            int pin = RELAY1_PIN + (relay_num - 1);
            digitalWrite(pin, state ? HIGH : LOW);
            sensor_data.relay_states[relay_num - 1] = state;
            
            server.send(200, "application/json", "{"status":"success"}");
        }
    }
}

// 传感器读取任务
void read_sensors(void *parameter) {
    while (1) {
        // 读取DHT22温湿度
        sensor_data.temperature = dht.readTemperature();
        sensor_data.humidity = dht.readHumidity();
        
        // 读取光敏电阻
        sensor_data.light_level = analogRead(LDR_PIN);
        
        // 读取PIR传感器
        sensor_data.motion_detected = digitalRead(PIR_PIN);
        
        // 发布传感器数据到MQTT
        if (client.connected()) {
            char sensor_msg[100];
            sprintf(sensor_msg, 
                   "{"temp":%.1f,"hum":%.1f,"light":%d,"motion":%s}",
                   sensor_data.temperature,
                   sensor_data.humidity,
                   sensor_data.light_level,
                   sensor_data.motion_detected ? "true" : "false");
            client.publish("smarthome/sensors", sensor_msg);
        }
        
        vTaskDelay(5000 / portTICK_PERIOD_MS);  // 5秒间隔
    }
}

// 自动控制逻辑
void auto_control_logic() {
    // 基于光照的灯光控制
    if (sensor_data.light_level < 500 && !sensor_data.relay_states[0]) {
        // 光线暗且灯未开时,自动开灯
        digitalWrite(RELAY1_PIN, HIGH);
        sensor_data.relay_states[0] = true;
    } else if (sensor_data.light_level > 800 && sensor_data.relay_states[0]) {
        // 光线亮且灯开着时,自动关灯
        digitalWrite(RELAY1_PIN, LOW);
        sensor_data.relay_states[0] = false;
    }
    
    // 基于温度的通风控制
    if (sensor_data.temperature > 28.0 && !sensor_data.relay_states[1]) {
        // 温度高且风扇未开时,自动开风扇
        digitalWrite(RELAY2_PIN, HIGH);
        sensor_data.relay_states[1] = true;
    } else if (sensor_data.temperature < 24.0 && sensor_data.relay_states[1]) {
        digitalWrite(RELAY2_PIN, LOW);
        sensor_data.relay_states[1] = false;
    }
}

void setup() {
    Serial.begin(115200);
    
    // 初始化GPIO
    pinMode(RELAY1_PIN, OUTPUT);
    pinMode(RELAY2_PIN, OUTPUT);
    pinMode(RELAY3_PIN, OUTPUT);
    pinMode(RELAY4_PIN, OUTPUT);
    pinMode(LDR_PIN, INPUT);
    pinMode(PIR_PIN, INPUT);
    
    // 初始化传感器
    dht.begin();
    
    // 连接WiFi
    WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
    }
    Serial.println("\nWiFi connected");
    Serial.print("IP address: ");
    Serial.println(WiFi.localIP());
    
    // 设置MQTT
    client.setServer(mqtt_server, 1883);
    client.setCallback(mqtt_callback);
    
    // 设置Web服务器
    server.on("/", handle_root);
    server.on("/control", handle_control);
    server.begin();
    
    // 创建传感器读取任务
    xTaskCreate(
        read_sensors,    // 任务函数
        "ReadSensors",   // 任务名称
        4096,            // 堆栈大小
        NULL,            // 参数
        1,               // 优先级
        NULL             // 任务句柄
    );
}

void loop() {
    // 处理MQTT连接
    if (!client.connected()) {
        if (client.connect("ESP32Client")) {
            client.subscribe("smarthome/relay/control");
        }
    }
    client.loop();
    
    // 处理Web请求
    server.handleClient();
    
    // 执行自动控制逻辑
    auto_control_logic();
    
    delay(100);
}

5.2 测试与调试

# 自动化测试脚本
import serial
import time
import json
import pytest

class HardwareTester:
    """硬件测试框架"""
    
    def __init__(self, port='COM3', baudrate=115200):
        self.ser = serial.Serial(port, baudrate, timeout=1)
        time.sleep(2)  # 等待连接稳定
    
    def send_command(self, command):
        """发送命令到设备"""
        self.ser.write((command + '\n').encode())
        return self.read_response()
    
    def read_response(self, timeout=2):
        """读取设备响应"""
        start_time = time.time()
        response = ""
        
        while time.time() - start_time < timeout:
            if self.ser.in_waiting:
                response += self.ser.read(self.ser.in_waiting).decode()
                if '\n' in response:
                    break
        
        return response.strip()
    
    def test_relay_operation(self, relay_num):
        """测试继电器操作"""
        # 打开继电器
        self.send_command(f"RELAY{relay_num} ON")
        time.sleep(0.5)
        
        # 验证状态
        response = self.send_command(f"RELAY{relay_num} STATUS")
        assert "ON" in response
        
        # 关闭继电器
        self.send_command(f"RELAY{relay_num} OFF")
        time.sleep(0.5)
        
        response = self.send_command(f"RELAY{relay_num} STATUS")
        assert "OFF" in response
        
        return True
    
    def test_sensors(self):
        """测试所有传感器"""
        sensors = ['TEMP', 'HUMIDITY', 'LIGHT', 'MOTION']
        readings = {}
        
        for sensor in sensors:
            response = self.send_command(f"READ {sensor}")
            try:
                value = float(response.split(':')[1].strip())
                readings[sensor] = value
                
                # 验证读数在合理范围内
                if sensor == 'TEMP':
                    assert -20 <= value <= 50
                elif sensor == 'HUMIDITY':
                    assert 0 <= value <= 100
                elif sensor == 'LIGHT':
                    assert 0 <= value <= 4095
            except:
                pytest.fail(f"传感器 {sensor} 读取失败")
        
        return readings
    
    def test_wifi_connection(self):
        """测试WiFi连接"""
        response = self.send_command("WIFI STATUS")
        assert "CONNECTED" in response
        
        # 获取IP地址
        response = self.send_command("WIFI IP")
        assert len(response.split('.')) == 4  # 验证IP格式
        
        return True
    
    def run_full_test(self):
        """运行完整测试套件"""
        test_results = {
            'relay_tests': [],
            'sensor_tests': {},
            'wifi_test': False,
            'all_passed': True
        }
        
        try:
            # 测试继电器
            for i in range(1, 5):
                if self.test_relay_operation(i):
                    test_results['relay_tests'].append(f"RELAY{i}: PASS")
                else:
                    test_results['relay_tests'].append(f"RELAY{i}: FAIL")
                    test_results['all_passed'] = False
            
            # 测试传感器
            test_results['sensor_tests'] = self.test_sensors()
            
            # 测试WiFi
            test_results['wifi_test'] = self.test_wifi_connection()
            
        except Exception as e:
            test_results['all_passed'] = False
            test_results['error'] = str(e)
        
        return test_results

# 运行测试
if __name__ == "__main__":
    tester = HardwareTester()
    results = tester.run_full_test()
    
    print("\n=== 测试结果 ===")
    print(json.dumps(results, indent=2))
    
    if results['all_passed']:
        print("\n✅ 所有测试通过!")
    else:
        print("\n❌ 测试失败!")

注:本文以教育为目的,系统介绍了电子工程师从入门到实战的学习路径。包含电路理论、模拟电路、数字电路、嵌入式系统、PCB设计等多个方面,并提供了完整的智能家居控制器项目实例。建议学习者:

  1. 理论学习与实践结合:边学边做,动手验证
  2. 从简单到复杂:先从基本电路开始,逐步挑战复杂系统
  3. 安全第一:高压实验做好防护,遵循安全规范
  4. 善用工具:熟练使用万用表、示波器、逻辑分析仪等工具
  5. 持续学习:关注新技术发展,不断更新知识体系

实际项目中请根据具体需求调整设计,注意电气安全,遵守相关法规和标准。