课程设计:智能小区安保管理系统

  • 0x00:设计要求
  • 0x01:硬件设计 & 实物展示
    • 设计框图 & 实物展示:
      • 设计框图:
      • 实物展示:
    • 主节点PCB设计:
      • 电源管理 & 对应外设:
  • 0x02:软件设计
    • 主节点:
      • 门禁模式:
      • OpenArt交互 & 人脸识别:
    • QT上位机设计:
  • 0x03:系统通讯
    • 主 & 从节点通信:
    • 主节点 & PC上位机:

0x00:设计要求

设计任务和要求:
安防系统主要由门禁管理系统、巡更系统等组成。
门禁管理系统:用卡片、按键、电子门锁等装置控制出入口门的开关。
巡更系统:在保安人员巡逻路线上设置发信器,以确认保安人员的巡视记录、时间等。

门禁系统功能如下:

  • 进出通道的权限的管理:对通道进出权限的管理主要有进出通道的权限、进出通道的方式、进出通道的时段。
  • 实时监控功能:系统管理人员可以通过微机实时查看每个门区人员的进出情况;也可以在紧急状态打开或关闭所有的门。
  • 出入记录查询功能:系统可储存所有的进出记录、状态记录,可按不同的查询条件查询,配备相应考勤软件可实现考勤、门禁一卡通。
  • 异常报警功能:在异常情况下可以实现微机报警或报警器报警,如:非法入侵、门超时未关等。

巡更系统功能如下:

  • 保安值班人员巡更时.必须确认设定的巡视路线在规定时间区段内顺序到达每一巡更点,以巡更钥匙去触碰巡更点。
  • 巡更资料也可以贮存在电脑内,供随时查询,并作考勤记录。

0x01:硬件设计 & 实物展示

设计框图 & 实物展示:

设计框图:

实物展示:


主节点PCB设计:

电源管理 & 对应外设:

3.3V 5.0V
核心板 OpenArt
NRF24L01 门禁RFID
OLED ESP8266
蜂鸣器 RG90舵机

具体原理图与PCB与之前的智能家居课设当中的设计基本一致,只是多引出了几个IO,读者可去智能家居智能家居这篇博客中进行下载(下载链接在文末百度网盘~)

0x02:软件设计

主节点:

门禁模式:

门禁卡识别其实非常简单,本次课设我使用的门禁卡识别模块是通过串口与单片机进行通讯的(波特率必须为9600)当时刚使用这个模块的时候,被店家给的教程给坑到了,其实注册卡根本不需要从串口助手发送指令注册,模块上有个按键,只要通过按键就可以进行注册卡、删除卡的操作。
识别卡号是否与已注册卡的卡号一致,如果一致,则开门(其实只需要使用strcmp(const char str1[], const char str2[]),的函数即可进行判断)
如下为整套系统切换模式 + 状态判断部分代码:

void ACCESS_HUB(void){UI();
//    OLED_P6x8Int(1, 2, INFRARD1_READ, 1);//    OLED_P6x8Str(3, 2, USART3_RX_BUF);ux = camera_times();if(Current_mode.Identify_mode == CAMERA){if(ux > 0) {printf("u%d   ", ux); Current_mode.Accmode = OPEN; ux = 0;}
//    else if(camera_times() > 0 && camera_times() <= 5){printf("b%d\r\n", camera_times()-3); Beep_Bling();}}else if(Current_mode.Identify_mode == IC){if(USART3_RX_STA & 0x8000){if(!strcmp(USART3_RX_BUF, ZYQ)) {printf("ZYQ   "); Current_mode.Accmode = OPEN;}else if(!strcmp(USART3_RX_BUF, CXY)) {printf("CXY   "); Current_mode.Accmode = OPEN;}else if(!strcmp(USART3_RX_BUF, Security_1)) {printf("ZKA   "); Current_mode.Accmode = OPEN;}else if(!strcmp(USART3_RX_BUF, Security_2)) {printf("HCC  "); Current_mode.Accmode = OPEN;}}memset(USART3_RX_BUF, 0, USART3_REC_LEN); USART3_RX_STA = 0;}NRF_rec(rec_buff, rec_buff1, 5);if(!memcmp(rec_buff, "b1", 2) || !memcmp(rec_buff1, "b1", 2)) {printf("b1   "); memset(rec_buff, 0, 6); memset(rec_buff1, 0, 6);}else if(!memcmp(rec_buff, "b2", 2)|| !memcmp(rec_buff1, "b2", 2)) {printf("b2   "); memset(rec_buff, 0, 6); memset(rec_buff1, 0, 6);}if(Current_mode.Accmode == OPEN) {TIM_SetCompare2(TIM4, 350);Beep_Bling_once();delay_ms(5000);Current_mode.Accmode = CLOSE;}else if(Current_mode.Accmode == CLOSE) TIM_SetCompare2(TIM4, 1200);else if(Current_mode.Accmode == ALARM) Beep_Bling();
}

此部分相对较为简单,但是调试过程比较艰辛,配置及模块都出现过小问题,不过目前已经解决~

OpenArt交互 & 人脸识别:

OpenArt部分使用了星瞳官网给的比较简单的人脸辨别算法,通过计算当前帧图片的blobs与图像库中图片的blobs做差,相差较小的图像即为得出的结果,但是这样不过是否有人,都会有结果输出,不是我们识别人脸的初衷,所以我们需要在计算出差值后,在当前背景下估算出差值范围!!!这点很重要!!!
如下为实现代码:

  • 采集图像部分:
import sensor, image, pybsensor.reset() # Initialize the camera sensor.
sensor.set_pixformat(sensor.GRAYSCALE) # or sensor.GRAYSCALE
sensor.set_framesize(sensor.QQVGA) # or sensor.QQVGA (or others)
sensor.set_windowing((92,112))
sensor.skip_frames(10) # Let new settings take affect.
sensor.skip_frames(time = 2000)num = 1 #设置被拍摄者序号,第一个人的图片保存到s1文件夹,第二个人的图片保存到s2文件夹,以此类推。每次更换拍摄者时,修改num值。n = 20 #设置每个人拍摄图片数量。#连续拍摄n张照片,每间隔3s拍摄一次。
while(n):#红灯亮#pyb.LED(RED_LED_PIN).on()sensor.skip_frames(time = 1000) # Give the user time to get ready.等待3s,准备一下表情。#保存截取到的图片到SD卡print(n)sensor.snapshot().save("singtown/s%s/%s.pgm" % (num, n) ) # or "example.bmp" (or others)n -= 1#pyb.LED(BLUE_LED_PIN).off()print("Done! Reset the camera to see the saved image.")
  • 识别交互部分:
import sensor, time, image, pyb
from machine import UART
import IPS114 as ips114sensor.reset() # Initialize the camera sensor.
sensor.set_pixformat(sensor.GRAYSCALE) # or sensor.GRAYSCALE
sensor.set_framesize(sensor.QQVGA) # or sensor.QQVGA (or others)
sensor.set_windowing((92,112))
sensor.skip_frames(10) # Let new settings take affect.
sensor.skip_frames(time = 2000) #等待5sclock = time.clock()
uart = UART(2, baudrate = 115200)
ips114.ips_init()#SUB = "s1"
NUM_SUBJECTS = 3 #图像库中不同人数,一共3人
NUM_SUBJECTS_IMGS = 10 #每人有20张样本图片# 拍摄当前人脸。
area_ROI = (10, 5, 80, 90)while(True):#uart_flag = uart.any()uart_flag = 1if(uart_flag>0):img = sensor.snapshot()   # 获得图片img.draw_rectangle(area_ROI,color = (0, 255, 0))   #绘制出ROI区域#ips114.ips_display(img,img.width(),img.height())   # 显示图像d0 = img.find_lbp(area_ROI)#d0为当前人脸的lbp特征img = Nonepmin = 999999num=0def min(pmin, a, s):global numif a<pmin:pmin=anum=sreturn pminfor s in range(1, NUM_SUBJECTS+1):dist = 0for i in range(2, NUM_SUBJECTS_IMGS+1):img = image.Image("singtown/s%d/%d.pgm"%(s, i))d1 = img.find_lbp(area_ROI)#d1为第s文件夹中的第i张图片的lbp特征dist += image.match_descriptor(d0, d1)#计算d0 d1即样本图像与被检测人脸的特征差异度。#print("Average dist for subject %d: %d"%(s, dist/NUM_SUBJECTS_IMGS))pmin = min(pmin, dist/NUM_SUBJECTS_IMGS, s)#特征差异度越小,被检测人脸与此样本更相似更匹配。#print(pmin)if pmin < 5000:print(num) # num为当前最匹配的人的编号。if num == 1 and pmin < 4800:uart.write("u1")elif num == 2 and pmin < 4700:uart.write("u2")elif num == 3:uart.write("u3")

QT上位机设计:

  • UI

    由于之前没有做过上位机开发,所以借这次课设的时间浅浅了解了一下上位机的设计(QT C++开发)并且麻烦实验室学长帮忙一起调试了一晚上~
    学长的上位机教学博客大家可以参考学长这个系列的博客进行QT上位机的开发学习!
    以下是我实现的一些槽函数:
#include "mainwindow.h"
#include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{ui->setupUi(this);m_Server=new QTcpServer(this);m_Socket=NULL;//m_Socket=new QTcpSocket(this);m_sLocalIP="192.168.43.3";m_sRemoteIP="192.168.0.111";m_sPort=2333;isListening=false;isConnect=false;ui->lineEdit_listenIP->setText(m_sLocalIP);ui->lineEdit_listenPort->setText(QString("%1").arg(m_sPort));heartbeatTimer=new QTimer(this);heartbeatTimer->setInterval(4000);connect(heartbeatTimer,SIGNAL(timeout()),this,SLOT(heartbeatTimeout()));heartbeatMsg=new char('t');listen();
}MainWindow::~MainWindow()
{delete ui;
}bool MainWindow::listen()
{if(m_Server==NULL||isListening)return false;if(!m_Server->listen(QHostAddress(m_sLocalIP),m_sPort)){ui->pushButton_listen->setText("监听");log("开启监听失败:"+m_Server->errorString());return false;}ui->pushButton_listen->setText("停止监听");isListening=true;connect(m_Server, SIGNAL(newConnection()), this, SLOT(handleNewConnection()));log(QString("开始监听 %1 %2").arg(m_Server->serverAddress().toString()).arg(m_Server->serverPort()));return true;
}void MainWindow::handleNewConnection()
{if(heartbeatTimer->isActive())heartbeatTimer->stop();m_bufferReceive.clear();qDebug()<<m_Socket;if(m_Socket!=NULL){log(QString("连接前state %1").arg(m_Socket->state()));if(m_Socket->state()==QAbstractSocket::SocketState::ConnectedState){m_Socket->abort();}m_Socket->deleteLater();delete m_Socket;m_Socket=NULL;}qDebug()<<m_Socket;m_Socket = m_Server->nextPendingConnection();connect(m_Socket, SIGNAL(readyRead()), this, SLOT(handleSocketReadyRead()));connect(m_Socket, SIGNAL(error(QAbstractSocket::SocketError)),this, SLOT(handleSocketError(QAbstractSocket::SocketError)));connect(m_Socket,SIGNAL(disconnected()),this,SLOT(handlSocketDisconnect()));log(QString("新连接 %1 %2").arg(m_Socket->peerAddress().toString()).arg(m_Socket->peerPort()));log(QString("连接后state %1").arg(m_Socket->state()));isConnect=true;heartbeatTimer->start();ui->textBrowser_heartbeat->clear();
}void MainWindow::handleSocketError(QAbstractSocket::SocketError)
{log(QString("Socket错误 %1").arg(m_Socket->errorString()));log(QString("错误处state %1").arg(m_Socket->state()));
}
void MainWindow::handleSocketReadyRead()
{QTime time = QTime::currentTime();
//    ui->textBrowser_log->append(name + time.toString());ui->textBrowser_recive->append(m_Socket->readAll() + time.toString());
}void MainWindow::User_discreminate(void){//    UserNode *temp = head->next;QString name;QString str1 = m_Socket->readAll();if(str1 == "u1") name = "ZYQ";else if(str1 == "u2") name = "CXY";else if(str1 == "u3") name = "ZKA";else if(str1 == "u4") name = "HCC";else name = str1;QTime time = QTime::currentTime();ui->textBrowser_log->append(name + time.toString());
}void MainWindow::on_pushButton_listen_clicked()
{m_sLocalIP=ui->lineEdit_listenIP->text();m_sPort=ui->lineEdit_listenPort->text().toShort();if(isListening){if(m_Socket!=NULL){if(m_Socket->state()==QAbstractSocket::SocketState::ConnectedState){m_Socket->disconnectFromHost();}}m_Server->close();ui->pushButton_listen->setText("监听");disconnect(m_Server, SIGNAL(newConnection()), this, SLOT(handleNewConnection()));log("停止监听");isListening=false;}else{listen();}
}void MainWindow::log(QString text)
{ui->textBrowser_log->append(text);
}void MainWindow::log_u(UserNode *user){ui->textBrowser_log->append(user->name+user->time.toString());
}void MainWindow::handlSocketDisconnect()
{log(QString("Socket disconnect %1").arg(m_Socket->state()));disconnect(m_Socket, SIGNAL(readyRead()), this, SLOT(handleSocketReadyRead()));disconnect(m_Socket, SIGNAL(error(QAbstractSocket::SocketError)),this, SLOT(handleSocketError(QAbstractSocket::SocketError)));disconnect(m_Socket,SIGNAL(disconnected()),this,SLOT(handlSocketDisconnect()));isConnect=false;if(heartbeatTimer->isActive())heartbeatTimer->stop();
}void MainWindow::heartbeatTimeout()
{if(m_Socket!=NULL&&m_Socket->state()==QAbstractSocket::SocketState::ConnectedState){//char *data="t";
//        m_Socket->write(heartbeatMsg);
//        if(m_Socket->waitForBytesWritten()){//            ui->textBrowser_heartbeat->append(QTime::currentTime().toString("HH:mm:ss zzz")
//                                           +":"+heartbeatMsg);
//        }
//        else
//            ui->textBrowser_heartbeat->append(QTime::currentTime().toString("HH:mm:ss zzz")
//                                           +":写心跳失败");}
}void MainWindow::on_pushButton_send_clicked()
{QString sSend = ui->lineEdit_send->text();if(isConnect){m_Socket->write(sSend.toLatin1());if(m_Socket->waitForBytesWritten())log("写数据成功");elselog("写数据失败");}elselog("未连接");
//    log("信息即将导出:");
//    temp = head->next;
//    for(int i = 0; i < list_len; i++){//        log_u(temp);
//        temp = temp->next;
//    }
//    log("所有信息已导出");
}

0x03:系统通讯

主 & 从节点通信:

主从节点之间使用了NRF24L01模块实现通信,两个从节点使用了两个不同的地址,在主节点接收过程中只需要读取不同的缓冲区内容即可对收到的内容进行判断!!!,较为简单,就不多赘述这部分了。

主节点 & PC上位机:

主节点与PC上位机之间是通过ESP8266进行通信的(其中ESP8266配置成了透传模式)PC作为服务器,通过监听套接字的IP地址端口,就可以建立连接、数据传输,代码部分可以看如上代码。

本篇博客写的较为匆忙,主要是备考考研时间不是很充裕,之后有机会会详细展开作每部分模块的教程,敬请期待,如代码中有什么问题,大家可以在评论区进行指正,如果有想要工程文件的小伙伴可以私聊我,看到之后会及时回复的!!

基于STM32的智能小区安保管理系统设计相关推荐

  1. 基于STM32的农业灾害监测系统设计

    毕业论文(设计) 基于STM32的农业灾害监测系统设计 院:XX 学院(三号黑体字,下同) 业:XXXX 班 级:XXXX 班 名:X X X 号:2006XXXXXXX 指导教师:X X X 20X ...

  2. asp毕业设计——基于asp+sqlserver的住户管理系统设计与实现(毕业论文+程序源码)——住户管理系统

    基于asp+sqlserver的住户管理系统设计与实现(毕业论文+程序源码) 大家好,今天给大家介绍基于asp+sqlserver的住户管理系统设计与实现,文章末尾附有本毕业设计的论文和源码下载地址哦 ...

  3. 基于数字电路交通灯信号灯控制系统设计-基于单片机病房温度监测与呼叫系统设计-基于STM32的无线蓝牙心电监护仪系统设计-基于STM32的智能蓝牙温控风扇控制设计-基于STM32的智能温室控制系统设计

    1617基于数字电路交通灯信号灯控制系统设计(仿真电路,论文报告)  摘  要:交通灯控制系统在城市交通控制中发挥着重要的作用,本次课程设计就是以城市交通灯控制系统为背景的,主要通过运用学过的数字电路 ...

  4. 基于STM32的智能温室控制系统仿真电路设计(温控补光)-基于STM32的智能蓝牙温控风扇控制系统设计-基于STM32的无线蓝牙心电监护仪系统设计【毕设课设分享】

    1609 基于STM32的智能蓝牙温控风扇控制系统设计-毕设课设 1.LCD1602液晶显示当前温度,温度上下限值,风扇等级,自动手动模式: 2.设置有4个按键,按键1可以设置自动和手动2种模式切换: ...

  5. asp毕业设计——基于asp+access的订单管理系统设计与实现(毕业论文+程序源码)——订单管理系统

    基于asp+access的订单管理系统设计与实现(毕业论文+程序源码) 大家好,今天给大家介绍基于asp+access的订单管理系统设计与实现,文章末尾附有本毕业设计的论文和源码下载地址哦. 文章目录 ...

  6. asp毕业设计——基于asp+sqlserver的选题管理系统设计与实现(毕业论文+程序源码)——选题管理系统

    基于asp+sqlserver的选题管理系统设计与实现(毕业论文+程序源码) 大家好,今天给大家介绍基于asp+sqlserver的选题管理系统设计与实现,文章末尾附有本毕业设计的论文和源码下载地址哦 ...

  7. asp毕业设计——基于asp+access的档案管理系统设计与实现(毕业论文+程序源码)——档案管理系统

    基于asp+access的档案管理系统设计与实现(毕业论文+程序源码) 大家好,今天给大家介绍基于asp+access的档案管理系统设计与实现,文章末尾附有本毕业设计的论文和源码下载地址哦. 文章目录 ...

  8. asp毕业设计——基于asp+sqlserver的学籍管理系统设计与实现(毕业论文+程序源码)——学籍管理系统

    基于asp+sqlserver的学籍管理系统设计与实现(毕业论文+程序源码) 大家好,今天给大家介绍基于asp+sqlserver的学籍管理系统设计与实现,文章末尾附有本毕业设计的论文和源码下载地址哦 ...

  9. 基于SSM架构的新闻管理系统设计与实现论文

    标题基于SSM架构的新闻管理系统设计与实现 摘 要 当代社会发展迅速,电脑和网络已经是人们日常生活中必不可或缺的收取信息的工具,起到了至关重要的作用,而随着网络与计算机的发展,网站行业也迅速发展起来, ...

  10. asp毕业设计——基于asp+access的学生管理系统设计与实现(毕业论文+程序源码)——学生管理系统

    基于asp+access的学生管理系统设计与实现(毕业论文+程序源码) 大家好,今天给大家介绍基于asp+access的学生管理系统设计与实现,文章末尾附有本毕业设计的论文和源码下载地址哦.需要下载开 ...

最新文章

  1. php for循环可以变量关联数组,数组字符串变量之间的转换,数组元素的回调,for循环遍历关联数组...
  2. tcp序列号为什么是随机的_每个开发人员都应该掌握的TCP知识
  3. array DEMO
  4. 转移 MariaDB
  5. 使用nginx cache缓存网站数据实践
  6. 令xtu3service开机时立即启动_Mac开机时可以使用的快捷键 苹果电脑快捷键使用介绍...
  7. html(+css)/02/html标记语义应用,html列表与图片的应用
  8. python处理子进程_Python多处理+子进程问题
  9. 自动化测试是测试人员的遮羞布?
  10. microsoft store 安装包_Stata 15软件安装包免费下载附安装教程
  11. winpe加载raid_winpe集成raid驱动~
  12. HP 打印机系列打印出来有折痕,断断续续,解决方法如下:
  13. Micrium uC-Probe 使用
  14. 快速使用easy rule
  15. 互联网营销新模式,泰山众筹sun4.0模式了解一下
  16. 职场减压移魂大法几则 (转东转西)
  17. 关于找工作---职业规划[转]
  18. 玩转Python脚本开发-01
  19. 修改ELF可执行文件entry入口感染一个程序
  20. 如何提高微信小程序的访问量?

热门文章

  1. 批处理常用DOS命令简述
  2. onenote2019导入_将OneNote 2010笔记本导入Evernote
  3. php 显示探针_X 探针(刘海探针)-免费开源 PHP 探针
  4. 32 位和 64 位版本的 Office 2010 之间的兼容性
  5. erp软件涉及哪些计算机技术?,ERP软件应该学习哪些内容?
  6. 网游开发引擎应用分析
  7. 硬笔行书字帖3500常用字_2018年【成年人实用硬笔行书】一对一直播培训简介
  8. mysql备份管家婆_管家婆怎么恢复数据,备份数据
  9. [译文]使用VBA-SDL-H寻找图片
  10. cso是什么职位(企业cso是什么职位)