基于STM32+手机APP设计的智能停车场系统
演示视频
基于STM32+手机APP设计的智能停车场系统
元器件:DHT11、MQ2、STM32F103C8T6、SG90舵机、RC522频射模块、HC-SR04超声波模块、OLED、wifi模块、LED灯、蜂鸣器
功能简介
1、进出停车场时需要刷卡,进行一个记时、计费的功能。
2、停车位配有超声波检测,主要识别车位是否被占用。
3、车位区域配有OLED显示屏,用户可以通过显示屏看到空闲车位。
4、车位配有车位灯。当用户找不到车位可以通过手机点亮车位灯
5、停车场配有温湿度检测和烟雾检测模块。当环境发生异常状态。会触动紧急报警。
6、停车场信息会通过Wi-Fi发送数据上传至阿里云。用户可以通过手机了解到停车场空闲车位和停车时间、费用。
摘要
本文详细介绍了一种基于 STM32 的智能停车场管理系统的设计与实现。该系统结合了多种传感器和通信技术,实现了停车场的智能化管理,包括车辆进出计时计费、车位占用检测、空闲车位显示、车位灯控制、环境监测以及数据上传等功能。本文对系统的硬件设计和软件设计进行了深入探讨,阐述了各模块的工作原理和实现细节。
关键词:STM32;智能停车场;传感器;通信技术
一、引言
随着城市化进程的加速,汽车数量不断增加,停车场的管理变得越来越重要。传统的停车场管理方式存在效率低下、人工成本高、信息不透明等问题。为了解决这些问题,智能停车场管理系统应运而生。本文设计的智能停车场管理系统采用了 STM32 微控制器作为核心,结合了多种传感器和通信技术,实现了停车场的智能化管理,提高了停车场的运营效率和用户体验。
二、系统总体设计
(一)系统功能需求
- 进出停车场时需要刷卡,进行计时、计费的功能。
- 停车位配有超声波检测,识别车位是否被占用。
- 车位区域配有 OLED 显示屏,用户可以通过显示屏看到空闲车位。
- 车位配有车位灯。当用户找不到车位可以通过手机点亮车位灯。
- 停车场配有温湿度检测和烟雾检测模块。当环境发生异常状态,会触动紧急报警。
- 停车场信息会通过 Wi-Fi 发送数据上传至阿里云。用户可以通过手机了解到停车场空闲车位和停车时间、费用。
(二)系统总体架构
系统主要由 STM32 最小系统、DHT11 模块、MQ - 2 模块、SG90 舵机、OLED 显示模块、HC - SR04 超声波模块、RC522 频射模块、Wi - Fi 模块、LED 灯、蜂鸣器等组成。STM32 最小系统作为核心控制器,负责协调各模块的工作,实现数据的采集、处理和传输。DHT11 模块用于检测停车场的温湿度,MQ - 2 模块用于检测烟雾浓度,SG90 舵机用于控制停车场的门,OLED 显示模块用于显示停车场的信息,HC - SR04 超声波模块用于检测车位是否被占用,RC522 频射模块用于刷卡识别车辆,Wi - Fi 模块用于将停车场的数据上传至阿里云,LED 灯用于指示车位的状态,蜂鸣器用于报警。
三、硬件设计
(一)STM32 最小系统
STM32 最小系统包括 STM32F103C8T6 芯片、时钟电路、复位电路、电源电路等。STM32F103C8T6 芯片是一款基于 ARM Cortex - M3 内核的微控制器,具有高性能、低功耗、丰富的外设接口等特点。时钟电路为芯片提供时钟信号,复位电路用于系统的复位,电源电路为系统提供稳定的电源。
(二)传感器模块
- DHT11 模块
- DHT11 是一款数字式温湿度传感器,它包括一个电容式感湿元件和一个 NTC 测温元件,并与一个高性能 8 位单片机相连接。
- 该模块通过 PA4 引脚与 STM32 连接,实现温湿度的检测。STM32 通过单总线协议与 DHT11 进行通信,发送起始信号后,DHT11 会返回温湿度数据。
- MQ - 2 模块
- MQ - 2 是一款半导体烟雾传感器,能够检测空气中的烟雾浓度。
- 它通过 PB0 引脚与 STM32 连接,将检测到的烟雾浓度模拟信号传输给 STM32 的 ADC(模数转换器),STM32 对模拟信号进行采样和转换,得到数字形式的烟雾浓度数据。
- HC - SR04 超声波模块
- HC - SR04 超声波模块用于检测车位是否被占用,它通过发射超声波并接收反射回来的超声波来测量距离。
- 该模块通过 PA6 和 PA7 引脚与 STM32 连接,PA6 作为 Trig 引脚,用于发送触发信号,PA7 作为 Echo 引脚,用于接收反射回来的超声波信号。STM32 通过精确计时超声波的发射和接收时间差,根据声速计算出车位与障碍物之间的距离。
(三)执行器模块
- SG90 舵机
- SG90 舵机用于控制停车场的门,通过 PA1 引脚与 STM32 连接。
- STM32 通过发送 PWM(脉冲宽度调制)信号控制舵机的角度,实现门的开关操作。PWM 信号的占空比决定了舵机的转角位置。
- OLED 显示模块
- OLED 显示模块用于显示停车场的信息,如空闲车位、温湿度、烟雾浓度等。
- 它通过 PB8 和 PB9 引脚与 STM32 连接,分别作为 SCL(串行时钟线)和 SDA(串行数据线)信号的输入输出引脚。STM32 通过 IIC(集成电路总线)协议与 OLED 显示模块进行通信,发送指令和数据,控制 OLED 显示相应的信息。
- LED 灯和蜂鸣器
- LED 灯用于指示车位的状态,通过 PB5 和 PB6 引脚与 STM32 连接。STM32 可以通过控制这两个引脚的电平高低来点亮或熄灭 LED 灯。
- 蜂鸣器用于报警,当烟雾浓度过高时,STM32 通过 PB7 引脚控制蜂鸣器发出警报声。
(四)射频模块
RC522 频射模块用于刷卡识别车辆,通过 PA3、PA2、PA1、PWM、VCC 和 GND 引脚与 STM32 连接。
当车辆进入停车场时,用户需要刷卡,RC522 频射模块读取卡片信息,并将信息通过 SPI(串行外设接口)或 IIC 等通信方式传输给 STM32 进行处理。
(五)Wi - Fi 模块
Wi - Fi 模块用于将停车场的数据上传至阿里云,通过 PA9 和 PA10 引脚与 STM32 连接。
STM32 通过串口与 Wi - Fi 模块进行通信,将停车场的信息(如空闲车位数量、停车时间、费用等)打包成特定的数据格式,发送给 Wi - Fi 模块,Wi - Fi 模块再将数据上传至阿里云服务器,用户可以通过手机 APP 或网页等方式访问阿里云服务器,获取停车场的实时信息。
四、软件设计
(一)操作系统选择
本系统采用了 UCOSIII 操作系统,它是一种实时操作系统,具有多任务管理、任务调度、中断管理等功能。UCOSIII 可以提高系统的实时性和可靠性,保证系统的稳定运行。
(二)任务划分
根据系统的功能需求,将系统划分为以下几个任务:
- 开始任务(start_task):创建完任务二和任务三就删除自己。
- 任务一(task1_task):亮灯,并打印出信息。
- 任务二(task2_task):打印任务二执行信息。
- 任务三(task3_task):收集超声波信息。
(三)任务实现
- 开始任务(start_task)
-
任务优先级为 3,堆栈大小为 128。
-
主要功能包括系统初始化、创建其他任务以及删除自身。
-
具体步骤如下:
- 进行系统初始化,包括时钟初始化、中断分组配置、串口初始化等。
- 初始化各个外设模块,如舵机、LED、蜂鸣器、ADC、DHT11、OLED、RC522、定时器等。
- 进入临界区,创建任务一、任务二和任务三。
- 退出临界区,删除开始任务自身。
在代码中,相关部分如下:
-
// 开始任务函数
void start_task(void *p_arg)
{
OS_ERR err;
CPU_SR_ALLOC();
p_arg = p_arg;
CPU_Init();
#if OS_CFG_STAT_TASK_EN > 0u
OSStatTaskCPUUsageInit(&err); // 统计任务
#endif
#ifdef CPU_CFG_INT_DIS_MEAS_EN // 如果使能了测量中断关闭时间
CPU_IntDisMeasMaxCurReset();
#endif
#if OS_CFG_SCHED_ROUND_ROBIN_EN // 当使用时间片轮转的时候
// 使能时间片轮转调度功能,时间片长度为1个系统时钟节拍,既1 * 5 = 5ms
OSSchedRoundRobinCfg(DEF_ENABLED, 1, &err);
#endif
OS_CRITICAL_ENTER(); // 进入临界区
// 创建TASK1任务
OSTaskCreate((OS_TCB *) &Task1_TaskTCB,
(CPU_CHAR *) "Task1 task",
(OS_TASK_PTR) task1_task,
(void *) 0,
(OS_PRIO) TASK1_TASK_PRIO,
(CPU_STK *) &TASK1_TASK_STK[0],
(CPU_STK_SIZE) TASK1_STK_SIZE / 10,
(CPU_STK_SIZE) TASK1_STK_SIZE,
(OS_MSG_QTY) 0,
(OS_TICK) 0,
(void *) 0,
(OS_OPT) OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR,
(OS_ERR *) &err);
// 创建TASK2任务
OSTaskCreate((OS_TCB *) &Task2_TaskTCB,
(CPU_CHAR *) "task2 task",
(OS_TASK_PTR) task2_task,
(void *) 0,
(OS_PRIO) TASK2_TASK_PRIO,
(CPU_STK *) &TASK2_TASK_STK[0],
(CPU_STK_SIZE) TASK2_STK_SIZE / 10,
(CPU_STK_SIZE) TASK2_STK_SIZE,
(OS_MSG_QTY) 0,
(OS_TICK) 0,
(void *) 0,
(OS_OPT) OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR,
(OS_ERR *) &err);
// 创建TASK3任务
OSTaskCreate((OS_TCB *) &Task3_TaskTCB,
(CPU_CHAR *) "task3 task",
(OS_TASK_PTR) task3_task,
(void *) 0,
(OS_PRIO) TASK3_TASK_PRIO,
(CPU_STK *) &TASK3_TASK_STK[0],
(CPU_STK_SIZE) TASK3_STK_SIZE / 10,
(CPU_STK_SIZE) TASK3_STK_SIZE,
(OS_MSG_QTY) 0,
(OS_TICK) 0,
(void *) 0,
(OS_OPT) OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR,
(OS_ERR *) &err);
OS_CRITICAL_EXIT(); // 退出临界区
OSTaskDel((OS_TCB *) 0, &err); // 删除start_task任务自身
}
- 任务一(task1_task)
-
任务优先级为 4,堆栈大小为 128。
-
主要功能包括控制车门开关、检测环境数据、处理车位占用信息以及显示停车场数据。
-
具体步骤如下:
- 进入临界区和退出临界区,目前临界区未进行具体操作。
- 根据车辆进出标志(car.in_out)控制车门开关。当车辆需要开关门时,根据报警标志(sys_flag.alarm)和车窗状态标志(sys_flag.window_flag)判断是否执行开门或关门操作,并更新相关标志和计时。
- 读取 MQ2 传感器的数据获取烟雾浓度(sys_dat.air),并通过 DHT11 读取温湿度数据(sys_dat.temp 和 sys_dat.humi)。
- 根据超声波检测结果更新车位占用标志(car._1_falg 和 car._2_falg)。
- 当车辆进出标志为 0 时,调用 OLED_Display 函数显示停车场数据。
- 根据烟雾浓度判断是否触发报警,控制蜂鸣器状态和危险信号标志位。
- 延时 1 秒。
在代码中,相关部分如下:
-
// task1任务函数
void task1_task(void *p_arg)
{
OS_ERR err;
CPU_SR_ALLOC();
p_arg = p_arg;
OS_CRITICAL_ENTER();
OS_CRITICAL_EXIT();
while (1)
{
if (car.in_out == 1) // 开关门
{
if (sys_flag.alarm == 0 && sys_flag.window_flag == 0) // 在关门状态下才能开门
{
SG90_angle(180); // 开门
sys_flag.window_flag = 1;
}
if (++car.window_time >= 3) // 开门间隔
{
if (sys_flag.alarm == 0 && sys_flag.window_flag == 1) // 在开门状态下才能关门
{
OLED_Clear(); // 清屏
SG90_angle(0); // 关门
sys_flag.window_flag = 0;
car.window_time = 0;
}
car.in_out = 0;
}
}
sys_dat.air = get_adc_value(ADC_Channel_8) / 40.96; // PB0 MQ2
DHT11_Read_Data(&sys_dat.temp, &sys_dat.humi); // PA4 温湿度检测
if (car.in_out == 0)
{
OLED_Display();
}
if (car.SR04_1 < 5)
{
car._1_falg = 1;
}
else
{
car._1_falg = 0;
}
if (car.SR04_2 < 5)
{
car._2_falg = 1;
}
else
{
car._2_falg = 0;
}
if (sys_dat.air > air_threshold) // 烟雾过高报警
{
BEEP_ON; // 危险报警
sys_flag.beep_flag = 1; // 蜂鸣器状态
sys_flag.alarm = 1; // 危险信号标志位
}
else
{
BEEP_OFF; // 消除危险报警
sys_flag.beep_flag = 0; // 蜂鸣器状态
sys_flag.alarm = 0; // 危险信号标志位
}
OSTimeDlyHMSM(0, 0, 2, 0, OS_OPT_TIME_HMSM_STRICT, &err); // 延时1s
}
}
- 任务二(task2_task)
-
任务优先级为 5,堆栈大小为 512。
-
主要功能是处理刷卡信息,包括读取卡片 ID、记录车辆信息、计算费用和余额、更新车辆状态等。
-
具体步骤如下:
- 进入临界区和退出临界区,目前临界区未进行具体操作。
- 通过 RC522 射频模块进行刷卡操作,获取卡片信息。
- 判断刷卡是否成功,如果成功,则读取卡片 ID 并进行相关处理。
- 遍历记录的卡片信息数组,判断当前卡片是否已存在。如果已存在,根据车辆驶出或进入的标志进行相应的处理,包括计算费用、更新余额、上传数据等。如果是新卡,则将其信息记录到数组中,并设置相应的车辆状态和余额。
- 控制 OLED 显示相关信息,如卡号、车辆驶入或驶出状态、时间、费用、余额等。
- 遍历车辆信息数组,根据车辆状态更新时间信息。
- 发布 MQTT 消息,上传停车场数据。
- 延时 1 秒。
在代码中,相关部分如下:
-
// task2任务函数
void task2_task(void *p_arg)
{
OS_ERR err;
CPU_SR_ALLOC();
p_arg = p_arg;
int i;
u8 temp_buff[20] = {0}, temp = 0;
OS_CRITICAL_ENTER(); // 进入临界区
OS_CRITICAL_EXIT(); // 退出临界区域
while (1)
{
status = PcdRequest(REQ_ALL, TagType);
if (!status)
{
status = PcdAnticoll(SelectedSnr);
if (!status)
{
status = PcdSelect(SelectedSnr);
if (!status)
{
snr = 1; // 扇区号1
status = PcdAuthState(KEYA, (snr * 4 + 3), DefaultKey, SelectedSnr); // 校验1扇区密码,密码位于每一扇区第3块
{
if (!status)
{
status = PcdRead((snr * 4 + 0), buf); // 读卡,读取1扇区0块数据到buf[0] - buf[16]
if (!status)
{
OLED_Clear(); // 清屏
sprintf((char *)ID_Card, ":%d%d%d%d", SelectedSnr[0], SelectedSnr[1], SelectedSnr[2], SelectedSnr[3]);
OLED_ASCII_GB2312_Show(0, 2, "卡号"); // 显示
4. 任务三(task3_task) - 任务优先级为 6,堆栈大小为 128。 - 主要功能是收集超声波信息,获取车位与障碍物之间的距离。 - 具体步骤如下: - 进入临界区和退出临界区,目前临界区未进行具体操作。 - 通过 SR04_1_DataMean 和 SR04_2_DataMean 函数获取两个超声波模块检测到的距离数据,并将其存储在 car.SR04_1 和 car.SR04_2 中。 - 延时 1 秒。 在代码中,相关部分如下: ```c // task3任务函数 void task3_task(void *p_arg) { OS_ERR err; CPU_SR_ALLOC(); p_arg = p_arg; OS_CRITICAL_ENTER(); // 进入临界区 OS_CRITICAL_EXIT(); // 退出临界区域 while (1) { car.SR04_1 = SR04_1_DataMean(); // 超声波的数据采集(平均值) car.SR04_2 = SR04_2_DataMean(); OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_HMSM_STRICT, &err); // 延时1s } }
(四)显示函数
-
OLED_Display
函数用于显示停车场的数据,包括车位状态、车位灯状态、车门状态、烟雾浓度、温度和湿度等信息。 -
在函数中,通过
OLED_ASCII_GB2312_Show
和OLED_ASCII_ShowString
函数在 OLED 显示屏上显示相应的文字和数据。在代码中,相关部分如下:
// 显示停车场数据
void OLED_Display(void)
{
// OLED_ASCII_GB2312_Show(0, 0, "停车场系统"); // 显示英文,汉字字符串
OLED_ASCII_GB2312_Show(0, 0, "位"); // 显示英文,汉字字符串
sprintf(temp_buff[0], "1:%d", car._1_falg);
OLED_ASCII_ShowString(16, 0, temp_buff[0]);
OLED_ASCII_GB2312_Show(60, 0, "位"); // 显示英文,汉字字符串
sprintf(temp_buff[1], "2:%d", car._2_falg);
OLED_ASCII_ShowString(76, 0, temp_buff[1]);
OLED_ASCII_GB2312_Show(0, 2, "灯"); // 显示英文,汉字字符串
sprintf(temp_buff[2], "1:%d", sys_flag.led1_flag);
OLED_ASCII_ShowString(16, 2, temp_buff[2]);
OLED_ASCII_GB2312_Show(60, 2, "灯"); // 显示英文,汉字字符串
sprintf(temp_buff[3], "2:%d", sys_flag.led2_flag);
OLED_ASCII_ShowString(76, 2, temp_buff[3]);
OLED_ASCII_GB2312_Show(0, 4, "门"); // 显示英文,汉字字符串
sprintf(temp_buff[4], ":%d", sys_flag.window_flag);
OLED_ASCII_ShowString(16, 4, temp_buff[4]);
OLED_ASCII_GB2312_Show(60, 4, "烟"); // 显示英文,汉字字符串
sprintf(temp_buff[5], ":%d", (int)sys_dat.air);
OLED_ASCII_ShowString(76, 4, temp_buff[5]);
OLED_ASCII_GB2312_Show(0, 6, "温"); // 显示英文,汉字字符串
sprintf(temp_buff[6], ":%d", (int)sys_dat.temp);
OLED_ASCII_ShowString(16, 6, temp_buff[6]);
OLED_ASCII_GB2312_Show(60, 6, "湿"); // 显示英文,汉字字符串
sprintf(temp_buff[7], ":%d", (int)sys_dat.humi);
OLED_ASCII_ShowString(76, 6, temp_buff[7]);
}
五、软件设计中的关键技术
(一)临界区保护
在 UCOS III 中,使用 OS_CRITICAL_ENTER
和 OS_CRITICAL_EXIT
宏来保护临界区。当一个任务或中断进入临界区时,它必须调用 OS_CRITICAL_ENTER
宏以获得临界区的保护,禁用中断,确保执行临界区的代码不会被中断或抢占,从而保证了临界区的原子性。当代码执行完毕时,任务或中断必须调用 OS_CRITICAL_EXIT
宏来恢复中断。
(二)任务优先级调度
UCOS III 使用抢占式调度,任务的执行顺序基于优先级。具有更高优先级的任务比低优先级的任务更可能得到调度。当有一个高优先级的任务就绪时,当前正在执行的任务将被中断并且高优先级任务将被执行。任务切换通常发生在任务主动调用相关函数退让 CPU 或中断服务程序执行时。
(三)传感器数据处理
对于 DHT11 传感器,通过特定的通信协议获取温湿度数据,并进行相应的处理和转换。对于 MQ - 2 传感器,将模拟信号通过 ADC 转换为数字信号,以获取烟雾浓度数据。对于 HC - SR04 超声波模块,通过精确计时超声波的发射和接收时间差,根据声速计算出距离。
(四)射频模块通信
RC522 频射模块通过特定的通信接口(如 SPI 或 IIC)与 STM32 进行通信,STM32 发送指令控制 RC522 进行刷卡操作,RC522 将读取到的卡片信息返回给 STM32 进行处理。
(五)数据显示与上传
OLED 显示模块通过特定的显示指令和数据格式进行控制,以显示停车场的各种信息。Wi - Fi 模块通过串口与 STM32 进行通信,STM32 将停车场的数据打包成特定的格式发送给 Wi - Fi 模块,Wi - Fi 模块再将数据上传至阿里云服务器。
六、系统测试与结果分析
(一)测试环境搭建
搭建实际的停车场测试环境,安装好各个硬件模块,连接好电路,确保系统正常运行。设置相关的测试设备,如模拟车辆进出的卡片、障碍物等。
(二)功能测试
- 车辆进出测试
- 测试刷卡功能,验证车辆能否正常进出停车场,计时计费是否准确。
- 检查车门开关控制是否正常,车窗状态标志是否正确更新。
- 车位检测测试
- 放置障碍物在车位上,测试超声波模块能否准确检测车位是否被占用。
- 验证 OLED 显示屏上的车位状态信息是否与实际情况相符。
- 环境监测测试
- 模拟不同的温湿度和烟雾浓度环境,测试 DHT11 和 MQ - 2 模块的检测准确性。
- 检查报警功能是否在烟雾浓度过高时正常触发。
- 数据上传测试
- 查看阿里云平台上是否能正常接收停车场的数据,包括空闲车位、停车时间、费用等信息。
- 验证手机 APP 能否实时显示停车场的相关信息。
(三)结果分析
通过对系统进行全面测试,各项功能均能正常实现。车辆进出计时计费准确,车位检测灵敏可靠,环境监测数据准确,报警功能正常,数据上传稳定。OLED 显示屏能够清晰显示停车场的各种信息,用户可以通过手机方便地了解停车场的情况。
七、结论
本文设计的基于 STM32 的智能停车场管理系统,通过合理的硬件设计和软件编程,实现了预期的功能。该系统具有较高的稳定性和可靠性,能够提高停车场的管理效率和用户体验。在实际应用中,还可以根据具体需求进行进一步的优化和扩展,如增加车位引导功能、实现远程控制等。未来,随着物联网技术的不断发展,智能停车场管理系统将具有更广阔的应用前景。