基于单片机与WiFi通信的教室人数与照明上位机监控系统设计

1 基于单片机与WiFi通信的教室人数与照明上位机监控系统设计

点击链接下载prrotues仿真设计资料:https://download.csdn.net/download/m0_51061483/91964733

1.1 设计背景与应用意义

在高校与中小学的教学楼场景中,教室照明通常采用人工开关方式,存在"开灯忘关、白天强光仍开灯、无人教室灯常亮"等普遍问题,造成大量电能浪费。与此同时,教室人数统计往往依靠人工点名或门禁系统间接推断,实时性差,且无法与照明系统联动,难以实现精细化节能与管理。

随着物联网与无线通信技术的发展,将"人数检测 + 光照度检测 + 照明控制 + 上位机集中监控"融合为统一系统,能够显著提升教室照明管理的智能化水平,降低能源浪费,并为教学管理提供数据支撑。例如:

1)无人教室自动关灯,减少不必要耗电;

2)自然光充足时自动关闭或降低部分区域照明;

3)按教室、按区域统计用灯情况,提高后勤管理效率;

4)实时人数统计可为教学安排、教室使用率分析提供依据;

5)通过上位机集中管理多间教室,降低人工巡检成本。

因此,本课题提出"基于单片机与WiFi通信的教室人数与照明上位机监控系统设计",实现从下位机(单片机节点)到上位机(PC端监控软件)的完整闭环控制与数据可视化,具有实际工程价值与推广意义。


2 系统功能与总体方案

2.1 系统功能概述

系统按照"数据采集---智能控制---无线通信---上位机监控"的思路构建,主要功能包括:

  1. 光照度与人数检测

    1.1 设计光照度检测电路,实时采集教室环境亮度数据,作为自动开关灯依据。

    1.2 设计人数检测电路,实现教室人数实时统计,并为上位机提供数据。

  2. 上位机控制与监测

    2.1 上位机软件显示多个教室信息,包括教室编号、实时人数、分区灯具状态。

    2.2 支持对全部教室或某个教室的远程照明控制(开灯、关灯、分区控制)。

  3. 下位机(单片机)控制

    3.1 配备按键控制电路,支持人工手动控制照明状态。

    3.2 根据光照度自动控制不同区域灯具,实现节能管理。

    3.3 采集并上传人数、光照度到上位机,同时接收上位机控制指令并执行。

  4. 无线通信功能

    4.1 WiFi模块实现上位机与下位机的双向数据传输。

    4.2 上位机发送控制指令,下位机执行并反馈状态,提高可靠性与实时性。

  5. 节能与管理优势

    5.1 光照度与人数联动,实现"按需照明"。

    5.2 上位机集中管理多教室,提高效率,形成可分析的数据闭环。


2.2 系统总体结构与工作流程

系统由"下位机节点"和"上位机监控端"构成。每间教室配置一套下位机节点,节点包括:单片机、光照度传感器、人数检测模块、按键模块、照明驱动控制模块、WiFi模块、电源模块。上位机通过WiFi网络与各节点通信,可实现集中显示与控制。

系统工作流程可描述为:

1)下位机周期采集光照度值与人数数据;

2)下位机按控制策略判断是否需要开灯或关灯(可选择自动模式或手动模式);

3)下位机将教室编号、人数、光照度、灯具状态封装为数据帧发送给上位机;

4)上位机解析数据,实时刷新界面显示,并存储或记录关键数据;

5)当管理员在上位机发出控制指令(全开、全关、分区控制或单教室控制),指令经WiFi发送到指定教室下位机;

6)下位机执行指令并反馈执行结果,确保控制可靠。


3 硬件电路设计

3.1 硬件模块划分

系统硬件电路按照功能划分为以下模块:

  1. 单片机最小系统模块
  2. 光照度检测模块
  3. 人数检测模块
  4. 照明控制与驱动模块(分区控制)
  5. 按键输入模块(本地手动控制)
  6. WiFi通信模块
  7. 电源与稳压模块
  8. 状态指示与保护模块(可选)

硬件设计的目标是:可靠采集、稳定控制、通信实时、可扩展性强,并且适应教室电气环境下的干扰与负载特性。


3.2 单片机最小系统模块设计

3.2.1 单片机选型与理由

本系统可选用常见8位单片机(如STC89C52、STC12系列、STM8等)或32位单片机(如STM32F103、ESP32等)。由于系统需处理多传感器采集、分区照明控制、WiFi串口通信以及上位机协议解析,推荐选择具备较强资源和串口能力的单片机,例如:

1)STC12C5A系列:兼容51,速度快,资源更丰富;

2)STM32:外设多、功耗低、支持更复杂协议;

3)若WiFi模块使用ESP8266/ESP32,可选择ESP32直接作为主控,集成WiFi与GPIO。

在典型教学楼改造场景中,为便于开发与成本控制,可以采用"STC单片机 + ESP8266 WiFi模块"的组合,下位机单片机负责采集、控制与策略,WiFi模块负责联网与数据传输。

3.2.2 时钟与复位电路要点

单片机时钟通常采用外部晶振或内部RC振荡。

1)外部晶振具有稳定性高、定时准确的优势,适合定时采样与串口通信。

2)复位电路可采用RC上电复位,并预留按键复位用于维护。

3)在电磁环境较强的场景中,复位脚需加强抗干扰设计,例如增加上拉电阻、滤波电容,避免误复位。

3.2.3 I/O与外设接口规划

由于系统包含多路输入输出,应合理规划接口:

1)ADC接口:用于光照度模拟采样或数字传感器接口;

2)人数检测接口:红外对射、热释电、超声波、摄像头等不同方案接口不同;

3)照明控制接口:多路继电器或固态继电器驱动;

4)按键接口:至少包含"模式切换/手动开关/分区控制"等;

5)串口通信接口:与WiFi模块连接,推荐使用硬件UART。


3.3 光照度检测模块设计

3.3.1 光照度检测方案选择

光照度检测模块是自动照明控制的核心。常见方案如下:

1)光敏电阻(LDR)+ 分压电路:成本低,电路简单,但精度与线性较差,受温度影响较大。

2)光电二极管/光电三极管:响应快,但需要放大电路,设计复杂。

3)数字光照度传感器(如BH1750):输出为数字量(I2C接口),精度高,抗干扰强,易标定。

在教学楼节能应用中,推荐使用数字光照度传感器(如BH1750),其直接输出Lux值,便于设定阈值与分区控制逻辑;若采用成本优先方案,可选用光敏电阻+ADC采样。

3.3.2 光敏电阻分压采样电路(典型方案)

若采用光敏电阻:

1)将光敏电阻与固定电阻串联形成分压;

2)取中间节点作为模拟电压输入ADC;

3)亮度越高,光敏电阻阻值越小/越大(与型号相关),输出电压随光变化;

4)通过软件标定建立"电压---光照度"映射。

为了提升稳定性,可加入:

1)RC滤波:抑制瞬态光变化与噪声;

2)多次采样平均:减少波动;

3)阈值滞回:避免灯频繁切换。

3.3.3 数字光照度传感器模块(推荐方案)

若采用BH1750:

1)通过I2C接口输出光照度数值;

2)无需额外ADC;

3)可直接设置Lux阈值,如:低于200Lux自动开灯,高于400Lux关闭部分灯具;

4)便于实现多区域"阶梯式照明控制"。


3.4 人数检测模块设计

3.4.1 人数检测需求与难点

教室人数统计要尽可能满足:

1)统计准确,不受短时遮挡影响;

2)能够区分"进入"与"离开";

3)成本可控,易维护;

4)适用于教室门口或室内人流。

实际工程中,人数统计比光照度更复杂。常用方案包括:

1)门口双红外对射计数:两组红外对射按顺序触发判断进/出;

2)PIR热释电检测:只能判断有人活动,难以准确计数;

3)超声波/毫米波雷达:可检测运动目标,但算法复杂;

4)摄像头视觉识别:准确度高,但成本与隐私问题突出;

5)座位压力传感器:可直接统计座位占用,但布线复杂、成本高。

综合考虑成本与实现难度,本系统建议采用"双红外对射进出计数"作为人数统计方案。

3.4.2 双红外对射计数电路设计

双红外方案结构为:在门框两侧安装两组红外对射(通道A与通道B),两通道间距约10~20cm。

工作原理:

1)人员进入时,先遮挡A后遮挡B,形成序列A→B;

2)人员离开时,先遮挡B后遮挡A,形成序列B→A;

3)下位机根据序列判定方向,进入则人数+1,离开则人数-1;

4)加入去抖与超时机制,避免多人并行造成误判。

电路设计要点:

1)红外接收端输出通常为数字电平,可直接输入单片机IO;

2)输入端建议加上拉/下拉与滤波,防止长线干扰;

3)可加入施密特触发整形提升抗干扰能力;

4)若使用模块化红外对射传感器,可简化电路并提高可靠性。

3.4.3 人数边界处理与异常修正

人数统计需考虑:

1)人数不能为负数:若检测离开但人数为0,则保持0;

2)多人同时进出:通过延时窗口与状态机减少误判;

3)统计偏差修正:上位机可提供"人数清零/校准"指令,用于管理人员修正。


3.5 照明控制与驱动模块设计(分区控制)

3.5.1 分区照明控制理念

教室照明通常按空间划分为多个区域,例如:

1)靠窗区域:受自然光影响大,白天可少开或不开;

2)中间区域:需要适中照明;

3)黑板区域:通常需要单独照明,保证教学清晰。

因此系统设计为分区控制,例如3路照明输出:

1)Zone1:靠窗灯组

2)Zone2:中间灯组

3)Zone3:讲台/黑板灯组

通过光照度与人数策略实现动态控制:

1)自然光充足且有人:仅开Zone2/Zone3;

2)自然光不足且有人:全开或开更多区域;

3)无人:全关;

4)上位机强制控制:覆盖自动策略(或与自动策略共存)。

3.5.2 驱动方式选择

由于照明灯具属于交流高压负载(220VAC),单片机不能直接驱动,必须使用隔离与功率驱动。常用方案:

1)继电器驱动:结构简单,隔离强,适合开关控制,但有机械寿命与噪声;

2)固态继电器(SSR):寿命长、无噪声、适合频繁开关,但成本高且有漏电流;

3)可控硅调光:可实现调光,但电路复杂,需要过零检测与抗干扰。

本系统以"开关控制"为主,推荐继电器或SSR。教学楼改造通常采用继电器模块即可满足需求。

3.5.3 继电器驱动电路设计要点

继电器线圈通常需要较大电流,单片机IO无法直接驱动,应采用:

1)三极管/ MOSFET驱动放大;

2)线圈两端并联续流二极管,吸收反向电动势;

3)继电器触点与交流负载之间应满足电气安全间距;

4)建议采用光耦隔离驱动,提升抗干扰与安全性。


3.6 按键输入模块设计

3.6.1 按键功能规划

本地按键用于在网络异常或管理员现场管理时进行手动控制。可设置:

1)模式切换键:自动模式/手动模式

2)全开/全关键:一键控制所有区域

3)分区控制键:Zone1/Zone2/Zone3独立开关

4)人数清零键(可选):管理员校准人数

3.6.2 硬件去抖设计

按键会产生机械抖动,需去抖:

1)硬件去抖:RC滤波 + 施密特输入;

2)软件去抖:检测到按下后延时10~20ms再确认状态。

通常采用软件去抖即可满足需求,配合上拉电阻避免悬空。


3.7 WiFi通信模块设计

3.7.1 WiFi模块选型

常用WiFi模块:ESP8266、ESP32等。ESP8266成本低、应用广,支持AT指令模式,适合作为通信模块与单片机串口连接。

3.7.2 通信模式设计

WiFi通信可采用:

1)TCP客户端/服务器模式:可靠性高,适合实时控制;

2)UDP广播模式:延迟低、实现简单,但可靠性需协议补偿;

3)MQTT方式:适合多节点与云平台,但需要Broker。

对于教室集中管理系统,推荐采用TCP或MQTT:

1)TCP适合局域网内上位机集中管理;

2)MQTT适合扩展到楼宇平台或云端。

本设计以"局域网TCP通信"为例,便于上位机直接建立连接管理多个教室节点。

3.7.3 通信可靠性设计

1)采用心跳包机制:下位机定期发送在线状态;

2)指令需要ACK确认:上位机发送控制指令后等待下位机回执;

3)断线重连:WiFi模块掉线时自动重连;

4)数据帧带校验:简单校验和或CRC,提高抗干扰能力。


3.8 电源与稳压模块设计

3.8.1 供电需求分析

下位机包含:单片机、WiFi模块、传感器、继电器驱动等。

1)单片机一般5V供电;

2)ESP8266需要3.3V且对供电稳定性要求高(发射瞬间电流峰值可达300mA以上);

3)继电器线圈可能需要5V/12V,视型号而定;

因此电源设计通常需要多路稳压:5V与3.3V。

3.8.2 稳压与隔离建议

1)推荐使用开关电源模块将220VAC转换为12V/5V,再使用LDO或DC-DC生成3.3V;

2)3.3V必须具有足够电流裕量,并在WiFi模块附近布置大电容(如100uF)+ 0.1uF去耦;

3)继电器驱动电源与逻辑电源尽量隔离或分区布线,减少干扰;

4)必要时加入TVS、保险丝、防反接保护,增强安全性。


4 程序设计

4.1 软件总体架构设计

系统软件由下位机固件与上位机软件两部分组成。

  1. 下位机程序主要任务

    1.1 传感器数据采集(光照度、红外计数)

    1.2 人数统计状态机与异常处理

    1.3 自动照明控制策略执行(分区控制)

    1.4 按键扫描与手动控制

    1.5 WiFi通信协议处理:数据上报、指令接收、执行反馈

    1.6 系统定时任务调度与看门狗(可选)

  2. 上位机程序主要任务

    2.1 网络连接管理:多个教室节点连接、断线提示

    2.2 数据解析与界面刷新:教室编号、人数、光照度、灯状态

    2.3 控制指令生成:全局控制、单教室控制、分区控制

    2.4 数据存储与导出(可选):历史记录、统计分析

    2.5 权限管理(可选):管理员/普通用户分级控制


4.2 下位机程序设计

4.2.1 传感器采集模块设计

1)光照度采集

若使用BH1750:周期读取Lux;

若使用光敏电阻:ADC采样多次平均得到亮度值。

2)红外对射采集

通过外部中断或轮询方式采集A、B通道变化。为了提高计数准确性,推荐采用"外部中断+状态机",在边沿触发时快速响应。

4.2.2 人数统计状态机模块设计

人数计数必须能区分方向。状态机是关键:

1)初始状态IDLE:等待A或B被遮挡;

2)若检测A先遮挡,进入状态A1,等待B遮挡,确认进入;

3)若检测B先遮挡,进入状态B1,等待A遮挡,确认离开;

4)设置超时时间,若超时未完成序列则回到IDLE,避免误判;

5)处理多人紧跟或并排通过时的异常情况,尽量减少计数偏差。

4.2.3 照明控制策略模块设计

照明控制必须考虑人数与光照度:

1)若人数=0:全部灯关闭;

2)若人数>0且光照度低:开启更多区域;

3)若人数>0且光照度高:只开必要区域或关闭靠窗区域;

4)支持手动模式:按键或上位机指令可直接控制灯状态;

5)支持上位机强制模式:上位机下发的命令可覆盖自动策略。

控制策略可通过"优先级"实现:

上位机强制 > 本地手动 > 自动控制。

这样可保证管理端具备最高控制权,同时保障断网情况下的可用性。

4.2.4 按键扫描模块设计

按键模块常用"定时扫描 + 软件去抖":

1)每10ms扫描一次按键输入;

2)检测到按下后延时确认;

3)支持短按切换、长按执行特殊功能(如人数清零)。

4.2.5 WiFi通信协议模块设计

通信协议应具备:

1)数据格式统一,便于上位机解析;

2)包含教室编号、人数、光照度、灯状态、模式信息;

3)包含帧头帧尾与校验,提高可靠性;

4)控制命令包含目标教室、目标区域、控制类型。

建议数据帧格式(示例):

1)上报帧:
$ID,PEO,LUX,Z1,Z2,Z3,MODE*CS\r\n

2)控制帧:
#ID,CTRL,Z1,Z2,Z3,MODE*CS\r\n

其中:

  • ID为教室编号
  • PEO为人数
  • LUX为光照度
  • Z1/Z2/Z3为分区灯状态(0/1)
  • MODE为模式(AUTO/MANUAL/FORCE)
  • CS为校验和

4.3 上位机程序设计

4.3.1 上位机界面功能模块

上位机软件建议包括:

1)教室列表区域:显示各教室编号、在线状态、人数、光照度;

2)灯状态区域:显示各教室分区灯状态(图标或颜色指示);

3)控制区域:

3.1 全局控制:全部开灯、全部关灯

3.2 单教室控制:选择教室后分区开关

3.3 模式控制:自动/手动/强制

4)日志区域:显示通信日志、报警提示(如人数异常、通信掉线)。

4.3.2 上位机通信与解析模块

上位机需实现:

1)与多个教室节点建立连接(多线程或异步IO);

2)接收数据并解析成结构化信息;

3)刷新UI显示;

4)下发控制命令并等待ACK;

5)断线重连与异常提示。

4.3.3 上位机数据管理与分析(扩展)

上位机可将每间教室的人数、光照度、灯使用时长记录到本地数据库或文件中:

1)统计教室使用率:每天平均人数、占用时间;

2)统计节能效果:灯具开启时间与节省电量估算;

3)异常检测:某教室长期无人但灯常亮,提示维护。


5 关键程序代码设计(示例)

5.1 下位机核心代码(C语言示例)

以下代码以"51单片机 + ESP8266 AT指令 + 双红外对射计数 + 光敏电阻ADC采样 + 3路继电器分区控制"为例。实际工程中可根据芯片与硬件连接调整端口与协议。

c 复制代码
#include <REGX52.H>
#include <string.h>

// -------------------- 硬件定义(示例) --------------------
// 红外对射输入
sbit IR_A = P3^2;   // 通道A
sbit IR_B = P3^3;   // 通道B

// 继电器输出(分区)
sbit RELAY_Z1 = P2^0;
sbit RELAY_Z2 = P2^1;
sbit RELAY_Z3 = P2^2;

// 按键
sbit KEY_MODE = P1^0;     // 自动/手动
sbit KEY_ALL  = P1^1;     // 全开/全关

// 状态LED(可选)
sbit LED_RUN = P1^7;

// -------------------- 参数配置 --------------------
#define CLASSROOM_ID  101     // 教室编号
#define LUX_LOW       200     // 低光阈值(示例)
#define LUX_HIGH      400     // 高光阈值(示例)

#define PEO_MAX       80      // 最大人数上限(防异常)

// 模式定义
typedef enum {
    MODE_AUTO = 0,
    MODE_MANUAL = 1,
    MODE_FORCE = 2
} SysMode;

volatile SysMode gMode = MODE_AUTO;

// 灯状态
volatile unsigned char gZ1 = 0;
volatile unsigned char gZ2 = 0;
volatile unsigned char gZ3 = 0;

// 人数与光照度
volatile int gPeople = 0;
volatile unsigned int gLux = 0;

// -------------------- 红外计数状态机 --------------------
typedef enum {
    IR_IDLE = 0,
    IR_A_FIRST,
    IR_B_FIRST
} IrState;

volatile IrState gIrState = IR_IDLE;
volatile unsigned int gIrTimer = 0;  // 超时计数(ms)
#define IR_TIMEOUT  800              // 0.8秒超时窗口

// -------------------- 简易定时器(1ms) --------------------
volatile unsigned int gMs = 0;

void Timer0_Init(void)
{
    TMOD &= 0xF0;
    TMOD |= 0x01;
    TH0 = 0xFC;  // 11.0592MHz 约1ms
    TL0 = 0x66;
    ET0 = 1;
    EA  = 1;
    TR0 = 1;
}

void Timer0_ISR(void) interrupt 1
{
    TH0 = 0xFC;
    TL0 = 0x66;

    gMs++;

    // 红外状态机超时计数
    if(gIrState != IR_IDLE)
    {
        gIrTimer++;
        if(gIrTimer > IR_TIMEOUT)
        {
            gIrState = IR_IDLE;
            gIrTimer = 0;
        }
    }
}

// -------------------- 人数统计(轮询版) --------------------
void People_Count_Process(void)
{
    // 假设IR_A/IR_B为低电平表示遮挡(按实际模块修改)
    unsigned char a_block = (IR_A == 0);
    unsigned char b_block = (IR_B == 0);

    switch(gIrState)
    {
        case IR_IDLE:
            if(a_block && !b_block)
            {
                gIrState = IR_A_FIRST;
                gIrTimer = 0;
            }
            else if(b_block && !a_block)
            {
                gIrState = IR_B_FIRST;
                gIrTimer = 0;
            }
            break;

        case IR_A_FIRST:
            if(b_block)
            {
                // A->B:进入
                gPeople++;
                if(gPeople > PEO_MAX) gPeople = PEO_MAX;
                gIrState = IR_IDLE;
            }
            // 若A解除遮挡且B未遮挡,可能误触发,可等待超时回IDLE
            break;

        case IR_B_FIRST:
            if(a_block)
            {
                // B->A:离开
                if(gPeople > 0) gPeople--;
                gIrState = IR_IDLE;
            }
            break;
    }
}

// -------------------- 光照度采集(示例:用ADC读光敏电阻) --------------------
// 这里用占位函数,实际需根据ADC芯片实现
unsigned int Read_Lux(void)
{
    // 示例:返回一个模拟值(工程中替换为真实ADC/BH1750读取)
    // 可用多次平均滤波提高稳定性
    return gLux; 
}

// -------------------- 继电器输出更新 --------------------
void Relay_Update(void)
{
    RELAY_Z1 = gZ1 ? 1 : 0;
    RELAY_Z2 = gZ2 ? 1 : 0;
    RELAY_Z3 = gZ3 ? 1 : 0;
}

// -------------------- 自动照明控制策略 --------------------
void Auto_Light_Control(unsigned int lux, int people)
{
    if(people <= 0)
    {
        gZ1 = 0; gZ2 = 0; gZ3 = 0;
        return;
    }

    // 有人时根据光照度进行分区控制(示例策略)
    if(lux < LUX_LOW)
    {
        // 光线很暗:全开
        gZ1 = 1; gZ2 = 1; gZ3 = 1;
    }
    else if(lux < LUX_HIGH)
    {
        // 光线适中:开中间+黑板
        gZ1 = 0; gZ2 = 1; gZ3 = 1;
    }
    else
    {
        // 光线充足:只开黑板区(或全部关闭,视需求)
        gZ1 = 0; gZ2 = 0; gZ3 = 1;
    }
}

// -------------------- 按键扫描(简化示例) --------------------
unsigned char Key_Scan(sbit key)
{
    if(key == 0)
    {
        // 简单去抖
        unsigned int t = gMs;
        while(gMs - t < 20);
        if(key == 0)
        {
            while(key == 0); // 等待释放
            return 1;
        }
    }
    return 0;
}

void Key_Process(void)
{
    // 模式切换
    if(Key_Scan(KEY_MODE))
    {
        if(gMode == MODE_AUTO) gMode = MODE_MANUAL;
        else if(gMode == MODE_MANUAL) gMode = MODE_AUTO;
    }

    // 全开/全关(手动模式下有效)
    if(Key_Scan(KEY_ALL))
    {
        if(gMode == MODE_MANUAL)
        {
            if(gZ1 || gZ2 || gZ3)
            {
                gZ1 = 0; gZ2 = 0; gZ3 = 0;
            }
            else
            {
                gZ1 = 1; gZ2 = 1; gZ3 = 1;
            }
        }
    }
}

// -------------------- WiFi通信(示例:串口发送上报帧) --------------------
// 这里只给出帧拼接与发送占位,实际需加入UART发送函数和ESP8266连接逻辑
void UART_SendString(char *s)
{
    // TODO: 串口逐字发送
}

unsigned char Calc_CheckSum(char *s)
{
    unsigned char cs = 0;
    while(*s)
    {
        cs ^= (unsigned char)(*s);
        s++;
    }
    return cs;
}

void Report_To_PC(void)
{
    char buf[128];
    unsigned char cs;
    // 数据主体
    sprintf(buf, "$%d,%d,%u,%d,%d,%d,%d",
            CLASSROOM_ID, gPeople, gLux, gZ1, gZ2, gZ3, gMode);

    cs = Calc_CheckSum(buf);

    // 拼接校验与结束符
    sprintf(buf + strlen(buf), "*%02X\r\n", cs);

    UART_SendString(buf);
}

// -------------------- 上位机指令解析(示例) --------------------
// 指令格式:#ID,CTRL,Z1,Z2,Z3,MODE*CS
void Execute_Command(unsigned char z1, unsigned char z2, unsigned char z3, SysMode mode)
{
    gMode = mode;
    gZ1 = z1; gZ2 = z2; gZ3 = z3;
    Relay_Update();
}

// -------------------- 主程序 --------------------
void main(void)
{
    unsigned int lastReport = 0;

    Timer0_Init();
    LED_RUN = 1;

    // 初始化输出
    gZ1 = gZ2 = gZ3 = 0;
    Relay_Update();

    while(1)
    {
        // 人数统计
        People_Count_Process();

        // 按键处理
        Key_Process();

        // 光照度读取(工程中用真实函数替换)
        // 这里建议每200ms更新一次lux,避免频繁读取
        if(gMs % 200 == 0)
        {
            gLux = Read_Lux();
        }

        // 自动控制
        if(gMode == MODE_AUTO)
        {
            Auto_Light_Control(gLux, gPeople);
            Relay_Update();
        }

        // 上报数据(例如每1秒)
        if(gMs - lastReport >= 1000)
        {
            lastReport = gMs;
            Report_To_PC();
        }

        // TODO: 接收上位机指令并解析执行(需串口接收中断缓冲)
    }
}

5.2 上位机核心逻辑示例(Python伪代码思路)

上位机可采用多种语言实现,例如C#(WinForms/WPF)、Python(PyQt)、Java等。考虑开发效率与串口/网络支持,Python + PyQt是较常见方案;若追求工程稳定性和Windows部署便利,C#更适合。以下给出上位机核心逻辑思路(伪代码示例),重点体现"接收解析、界面更新、指令下发"。

python 复制代码
import socket
import threading

classroom_map = {}  # key: ID, value: {"people":..,"lux":..,"z1":..}

def parse_frame(frame: str):
    # 示例:$ID,PEO,LUX,Z1,Z2,Z3,MODE*CS
    body, cs = frame.split("*")
    if not check_cs(body, cs):
        return None
    parts = body[1:].split(",")
    return {
        "id": int(parts[0]),
        "people": int(parts[1]),
        "lux": int(parts[2]),
        "z1": int(parts[3]),
        "z2": int(parts[4]),
        "z3": int(parts[5]),
        "mode": int(parts[6])
    }

def recv_thread(conn):
    buffer = ""
    while True:
        data = conn.recv(1024).decode("utf-8", errors="ignore")
        if not data:
            break
        buffer += data
        while "\r\n" in buffer:
            line, buffer = buffer.split("\r\n", 1)
            if line.startswith("$"):
                info = parse_frame(line)
                if info:
                    classroom_map[info["id"]] = info
                    update_ui(info)   # 刷新界面显示

def send_control(conn, room_id, z1, z2, z3, mode):
    body = f"#{room_id},CTRL,{z1},{z2},{z3},{mode}"
    cs = calc_cs(body)
    frame = f"{body}*{cs:02X}\r\n"
    conn.send(frame.encode("utf-8"))

6 系统节能策略与管理优势分析

6.1 节能策略效果分析

本系统的节能来自两个维度:

1)人数维度:无人必关灯,避免空教室耗电;

2)光照度维度:自然光越强,开灯区域越少,避免"白天开灯"。

以一间教室为例,若传统模式每天因忘关灯造成额外亮灯2小时,按教室照明功率500W计算,则每天浪费电量约1kWh。若一栋楼有30间教室,每天浪费约30kWh,一个月则约900kWh,节能潜力巨大。系统可在不影响教学体验的前提下显著降低浪费。

6.2 管理效率提升

上位机集中管理具备明显优势:

1)无需人工逐间检查灯状态;

2)可以一键全关,适用于夜间闭楼管理;

3)可按教室分区控制,满足不同教学需求;

4)可记录历史数据,为后勤管理和教学资源优化提供依据。

6.3 系统可扩展性与兼容性

系统采用模块化设计,后期可扩展:

1)增加温湿度、CO₂监测,辅助通风管理;

2)接入校园平台,实现楼宇级物联网管理;

3)采用更精确的人数检测(毫米波/视觉)提升统计精度;

4)增加调光控制与能耗计量,实现更精细节能。


7 总结

本文设计了一套基于单片机与WiFi通信的教室人数与照明上位机监控系统。系统通过光照度检测与双红外对射人数统计实现教室状态感知,并结合分区照明控制实现"按需照明"的节能目标。下位机采用单片机负责采集与控制,通过WiFi模块与上位机进行双向通信;上位机可集中显示各教室人数、光照度、分区灯状态,并支持全局或单教室远程控制。系统结构清晰、易部署、成本可控,适用于教学楼照明节能改造与教室管理信息化应用,具有良好的推广价值与工程扩展空间。

相关推荐
ACP广源盛139246256732 小时前
GSV2501@ACP#2501产品规格参数详解及产品应用场景分享
单片机·嵌入式硬件·计算机外设·音视频
secondyoung10 小时前
TLE9180短路检测功能总结
经验分享·嵌入式硬件·mcu·汽车·流程图·infineon·tle9180
xyx-3v11 小时前
ESP32-C3开发板简单介绍
单片机·嵌入式硬件
VX:Fegn089512 小时前
计算机毕业设计|基于springboot + vue校园社团管理系统(源码+数据库+文档)
前端·数据库·vue.js·spring boot·后端·课程设计
刻BITTER12 小时前
在TRAE 上安装PlatformIO
c++·单片机·嵌入式硬件·arduino
m0_5557629013 小时前
I.MX8 Plus —— 系统总线与互连
嵌入式硬件
luoluoal13 小时前
基于python的小区监控图像拼接系统(源码+文档)
python·mysql·django·毕业设计·源码
+VX:Fegn089515 小时前
计算机毕业设计|基于springboot + vueOA工程项目管理系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·后端·课程设计
mastercoder--16 小时前
速通51单片机————按键控制LED流水灯与定时器闹钟
单片机·嵌入式硬件·51单片机