【代码开源】基于STM32的智能路灯控制系统设计

项目说明

本项目以 STM32 为核心控制器,构建智能路灯控制系统。系统利用 BH1750 采集环境光照强度,结合人体红外传感器(如 HC-SR501)判断人员活动情况,从而实现"按需照明"。

控制策略为:当环境光照强度低于设定阈值且检测到有人活动时,开启路灯;当光照强度高于阈值或长时间无人时,自动关闭路灯。

在通信方面,引入 ESP-01S 模块,通过 MQTT 协议将设备运行状态(包括光照值、人员检测状态及路灯开关状态)实时上报至服务器,实现远程监控与数据采集。

项目开源链接见文章结尾。

项目硬件连接

系统以 STM32 为核心控制单元,各外设模块连接关系如下:

  • 人体红外传感器 (HC-SR501)

    信号输出端连接至 STM32 的 PA0 引脚 ,用于检测人体活动并产生中断或状态输入信号。工作跳帽接到 L上,不重复触发。

  • 光照传感器 (BH1750)

    SCL → PB6

    SDA → PB7

    ADDR 引脚接地,器件地址配置为低地址模式。

  • Wi-Fi 通信模块 (ESP-01S)

    连接至 STM32 的 USART3 串口 ,用于 MQTT 数据通信;

    同时使用 USART1 作为调试串口,便于系统调试与日志输出。

  • LED 指示灯(模拟路灯)

    连接至 STM32 的 PC13 引脚,用于模拟路灯的开关状态输出。

ESP01S固件状态

ESP01S 需要使用带 MQTT 固件的版本。在安信可的官网可以找到,使用1471号固件,他也有对应的说明文档。如果嫌麻烦,可以直接看我文件中提供的文档和说明。

ESP01S官网:docs.ai-thinker.com/esp8266/

软件设计

软件设计的整体流程是:

1、初始化各个设备。

2、外部中断触发检测人体红外状态。每次状态保存一段时间。

3、每隔1S检测一次光照强度。并且使用MQTT上报数据。

c 复制代码
void main_control_init(void)
{
	int ret = 0;
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);

	// 常用外设初始化
	bsp_usart1_init(115200);
	bsp_usart3_init(115200);
	delay_init();
    
    led_init();
	hc_sr50x_init();
	soft_i2c_init(SOFT_I2C1);
			
	bh1750_init(BH1750_ADDR_L,BH1750_CONT_H_RES);
	bh1750_set_mtreg(BH1750_ADDR_L,69);
	
    printf("SmartLed V1.2  Build Time: %s %s\r\n", __DATE__, __TIME__);

    esp_init();
	 
	ret = esp_at_cmd(&esp01s_device, "AT+RST", "OK", 2000);
    printf("AT+RESET resp: %s\n", esp01s_device.resp_buf);
	if(ret != 0) while(1); 
	delay_ms(500);
	
    ret = esp_at_cmd(&esp01s_device, "AT", "OK", 2000);
    printf("AT resp: %s\n", esp01s_device.resp_buf); 
	if(ret != 0) while(1);
	
    ret = esp_at_cmd(&esp01s_device, "AT+CWMODE=1", "OK", 2000);
    printf("AT+CWMODE resp: %s\n", esp01s_device.resp_buf); 
	if(ret != 0) while(1);
	
    ret = esp_at_cmd(&esp01s_device, "AT+CWJAP=\"CMCC-XJmL\",\"sR62HiPv\"", "OK", 5000);
    printf("AT+CWJAP resp: %s\n", esp01s_device.resp_buf); 
	if(ret != 0) while(1);
	
    ret = esp_at_cmd(&esp01s_device, "AT+MQTTUSERCFG=0,1,\"lqh\",\"lqh\",\"123\",0,0,\"\"", "OK", 2000);
    printf("AT+MQTTUSERCFG resp: %s\n", esp01s_device.resp_buf); 
	if(ret != 0) while(1);
	
    ret = esp_at_cmd(&esp01s_device, "AT+MQTTCONN=0,\"broker.emqx.io\",1883,0", "OK", 5000);
    printf("AT+MQTTCONN resp: %s\n", esp01s_device.resp_buf); 
	if(ret != 0) while(1);
	
    ret = esp_at_cmd(&esp01s_device, "AT+MQTTSUB=0,\"/lqh/mqtttest/led\",0", "OK", 2000);  
    printf("AT+MQTTSUB resp: %s\n", esp01s_device.resp_buf); 
	if(ret != 0) while(1);
}

void main_control_loop(void)
{ 
    uint16_t count = 0;
    float lux; 
	uint8_t hc_sr50x_delay_state = 0;
    uint32_t hc_sr50x_state_delay_count = 0;
    char mqtt_put_message[256]={0};
    uint8_t led_state = 0;
    while (1)
    { 
        count++;
        // 如果有人 hc_sr50_state 这个状态在中断中置 1
        if(hc_sr50_state == 1)
        {
			// 有人就处于状态延迟状态
            hc_sr50x_delay_state       = 1;
            hc_sr50x_state_delay_count = 0;
            hc_sr50_state = 0; 
            printf("Someone has entered the area\r\n");
        }
		// 如果处于状态延迟状态
        if(hc_sr50x_delay_state == 1)
        {
            hc_sr50x_state_delay_count++;
            if(hc_sr50x_state_delay_count > 200) // 将每次的有人进入状态至少保持 2S
            {
				// 2S后清空这个 状态延迟状态
                hc_sr50x_state_delay_count = 0;
                hc_sr50x_delay_state = 0;
            }
        } 
 
		if(count % 100 == 0) // 1S 读取一次光照强度
		{
			if (bh1750_read_lux(BH1750_ADDR_L, BH1750_CONT_H_RES, &lux) == 0)
			{
				printf("continuous Light = %.2f lux hc_sr50x_delay_state:%d\r\n", lux, hc_sr50x_delay_state);
			}
			// 光照小于一定值,且有人处于状态延迟状态时,打开灯
			if(lux < 500 && hc_sr50x_delay_state == 1){
				led_on();
                led_state = 1;
			}else{
				// 其他情况关灯
				led_off();
                led_state = 0;
			} 
			// 上报状态信息
            sprintf(mqtt_put_message,"AT+MQTTPUB=0,\"/lqh/mqtttest/led_state\",\"%d\",0,0",led_state);
            esp_at_cmd(&esp01s_device, mqtt_put_message , "OK", 2000);  
            printf("AT+MQTTSUB resp: %s\n", esp01s_device.resp_buf);
            sprintf(mqtt_put_message,"AT+MQTTPUB=0,\"/lqh/mqtttest/lux\",\"%.2f\",0,0",lux);
            esp_at_cmd(&esp01s_device, mqtt_put_message , "OK", 2000);  
            printf("AT+MQTTSUB resp: %s\n", esp01s_device.resp_buf);
            sprintf(mqtt_put_message,"AT+MQTTPUB=0,\"/lqh/mqtttest/hc_sr50x_delay_state\",\"%d\",0,0",hc_sr50x_delay_state);
            esp_at_cmd(&esp01s_device, mqtt_put_message , "OK", 2000);  
            printf("AT+MQTTSUB resp: %s\n", esp01s_device.resp_buf);
		} 

        // 读取 ESP 接收
        int ret = esp_read_line(&esp01s_device);
        if(ret == 0)
        {
            printf("Received line: %s", esp01s_device.resp_buf);
            esp_dispatch_line(&esp01s_device, (char *)esp01s_device.resp_buf); 
        } else {
            // 没有完整行数据,继续等待
        } 

        delay_ms(10);
    }
}

void USART3_IRQHandler(void)
{
	if (USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)
	{
		uint8_t data = USART_ReceiveData(USART3); 
        ringbuffer_putchar(&esp01s_device.rx_rb, data);
		USART_ClearITPendingBit(USART3, USART_IT_RXNE);
	}
}

代码中使用需要修改的部分,一个是连接初始化,一个是MQTT部分。

首先连接WIFI需要是自己的WIFI。

c 复制代码
ret = esp_at_cmd(&esp01s_device, "AT+CWJAP=\"CMCC-XJmL\",\"sR62HiPv\"", "OK", 1000);
printf("AT+CWJAP resp: %s\n", esp01s_device.resp_buf);

还有就是MQTT的连接订阅主题,尽量使用自己的,如果你使用我代码中的,如果你是用的自己服务器还好,但是如果使用的是我这个公用的,那大家可能会冲突。

项目开源链接

本项目资料包单片机软件总工程开源,设计文档,使用文档部分开源。开源部分有讲解视频方便大家跑起来理解。可先查看代码下在自己环境中是否能够正常使用,再决定后续操作。

软件开源链接:https://gitee.com/snqx-lqh/ProjectOpenSourceReleasePage

在发布页中,找到开源项目集,对应项目获取方式。

相关推荐
巴巴媛66610 小时前
STM32学习笔记【38.DHT11实验】
笔记·stm32·学习
深圳市泰凌微电子10 小时前
HK航顺 HK32F407RGT7替STM32F405RGT6 微控制器32位MCU
stm32·单片机·嵌入式硬件
lzqrzpt11 小时前
LED驱动电源行业品牌格局与技术差异深度总结
python·单片机·嵌入式硬件
SteveSenna12 小时前
直流减速电机 + STM32 控制接线方案
单片机·嵌入式硬件
ClouGence12 小时前
CloudDM 数据库管理平台,全新 UI,更清晰、更高效!
数据库·开源
云栖梦泽13 小时前
Camera驱动开发与应用开发中的零拷贝与DMA
linux·驱动开发·嵌入式硬件
小心亦新15 小时前
STM32学习16--定时器输出比较2直流电机
stm32·嵌入式硬件·学习
humbinal15 小时前
同时支持 gui & cli 的 parquet 文件查看工具,高性能小清新!
hive·python·rust·spark·开源·github·parquet
危桥带雨16 小时前
Freertos——任务通知
stm32·单片机·嵌入式硬件·freertos
十月的皮皮17 小时前
stm20260719-STM32F103RCT6_HAL库_三人抢答器
c语言·stm32·单片机·嵌入式硬件·stm32cubemx·hal库