一. 产品定位
本产品为全自动地锁,通过车牌识别模块采集识别车牌号并判断是否为可解锁车辆,并由地锁控制模块做出相应动作。
特点
全自动,识别率高,成本低,能耗小。
优势
车位主人无需顾虑车位被占,使车主停车步骤大幅减少,确定车主车辆的车牌号为唯一确定车主身份的方式,避免其他车主占位。
二.产品介绍
产品功能
在车主停车时通过摄像头拍摄的车辆的车牌号的照片,并判断它是否有权限在此车位停车,如果有权限,则自动打开地锁允许车辆停车。
软件系统设计
硬件系统设计
部分代码
#Arduino部分
#include<LiquidCrystal.h>
#include <SPI.h>
#include <MFRC522.h>
#define SS_PIN 53
#define RST_PIN 5
MFRC522 rfid(SS_PIN, RST_PIN); //实例化类
// 初始化数组用于存储读取到的NUID
byte nuidPICC[4];
byte id[4] = {198, 147, 88, 249};
LiquidCrystal lcd(30, 31, 35, 34, 33, 32);
int buttom = 10;
int isl = 0;
int servopin = 9; //设置舵机驱动脚到数字口9
int myangle;//定义角度变量
int pulsewidth;//定义脉宽变量
int inputPin = 6; // 定义超声波信号接收接口
int outputPin = 7; // 定义超声波信号发出接口
void servopulse(int servopin, int myangle) /*定义一个脉冲函数,用来模拟方式产生PWM值*/
{
pulsewidth = (myangle * 11) + 500; //将角度转化为500-2480 的脉宽值
digitalWrite(servopin, HIGH); //将舵机接口电平置高
delayMicroseconds(pulsewidth);//延时脉宽值的微秒数
digitalWrite(servopin, LOW); //将舵机接口电平置低
delay(20 - pulsewidth / 1000); //延时周期内剩余时间
}
void duoji(char val)
{
if (val > '0' && val <= '9') //判断收到数据值是否符合范围
{
val = val - '0'; //将ASCII码转换成数值,例'9'-'0'=0x39-0x30=9
val = val * (180 / 9); //将数字转化为角度,例9*(180/9)=180
for (int i = 0; i <= 50; i++) //产生PWM个数,等效延时以保证能转到响应角度
{
servopulse(servopin, val); //模拟产生PWM
}
}
}
void lock()
{
duoji('1');
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Locked!!");
delay(2000);
isl = 1;
}
void unlock()
{
duoji('5');
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("unlock");
delay(10000);
isl = 0;
}
float getdis()
{
digitalWrite(outputPin, LOW); // 使发出发出超声波信号接口低电平2μs
delayMicroseconds(2);
digitalWrite(outputPin, HIGH); // 使发出发出超声波信号接口高电平10μs,这里是至少10μs
delayMicroseconds(10);
digitalWrite(outputPin, LOW); // 保持发出超声波信号接口低电平
float distance = float(pulseIn(inputPin, HIGH)); //存储回波等待时间,
distance = (distance * 17 ) / 1000;
return distance;
}
int rf()
{ // 找卡
if (!rfid.PICC_IsNewCardPresent())
return 0; // 验证NUID是否可读
if (!rfid.PICC_ReadCardSerial())
return 0;
MFRC522::PICC_Type piccType = rfid.PICC_GetType(rfid.uid.sak);
// 检查是否MIFARE卡类型
if (piccType != MFRC522::PICC_TYPE_MIFARE_MINI && piccType != MFRC522::PICC_TYPE_MIFARE_1K && piccType != MFRC522::PICC_TYPE_MIFARE_4K)
{
return;
}
// 将NUID保存到nuidPICC数组
for (byte i = 0; i < 4; i++)
{
nuidPICC[i] = rfid.uid.uidByte[i];
}
if (nuidPICC[0] == id[0])
{
rfid.PICC_HaltA();
rfid.PCD_StopCrypto1();
return 1;
}
// 使放置在读卡区的IC卡进入休眠状态,不再重复读卡
return 0;
}
void setup()
{
lcd.begin(16, 2);
pinMode(servopin, OUTPUT); //设定舵机接口为输出接口
Serial.begin(9600);//设置波特率为9600
pinMode(buttom, INPUT);
pinMode(inputPin, INPUT);
pinMode(outputPin, OUTPUT);
SPI.begin(); // 初始化SPI总线
rfid.PCD_Init(); // 初始化 MFRC522
}
int temp[4];
int j = 1;
int sysjudge = 1;
void loop()
{
int id;
if (sysjudge)
{
j:
if (getdis() >= 20)
{
delay(5000);
if (getdis() >= 20)
{
if (!isl)
lock();
sysjudge = 0;
return;
}
} else
{
goto j;
}
} else
{
t:
lcd.clear();
lcd.print("wait for signal");
delay(200);
id = rf();
if (id)
goto op;
uu:
if (getdis() <= 10)
{
Serial.print('o');
while (1)
{
id = rf();
if (id)
goto op;
char a='k';
a = Serial.read();
if (a == 'q')
{
break;
}
else if (a == 'k')
{
lcd.clear();
lcd.print("wrong");
delay(500);
goto t;
} else
{
goto t;
}
}
}
else
{
goto uu;
}
op:
if (isl)
unlock();
sysjudge = 1;
}
}
# 上位机部分
from hyperlpr import *
import cv2
import time
import threading
import serial
from goto import with_goto
t = 0
a = 0
def destroyed():
with open('information.txt', 'w') as f:
f.write('')
return 0
def write(s): # 写入车牌信息
with open('information.txt', 'a+') as f:
f.writelines(s + '\n')
return 0
def judge(s): # 判断识别到的车牌号是否开锁
with open('information.txt', 'r') as fr:
list1 = fr.readlines()
for i in range(0, len(list1)):
list1[i] = list1[i].strip('\n')
if s == list1[i]:
print('识别成功') # 加串口传开锁信号
ser.write(b'q')
return True
ser.write(b'k')
return False
def cont():
global t
t = 1
ser = serial.Serial('com4', 9600)
while 1:
print(ser)
while 1:
a = ser.read()
print(a)
if a == b'o':
break
cap = cv2.VideoCapture(0)
while (1):
# get a frame
ret, frame = cap.read()
# show a frame
# cv2.imshow("capture", frame)
cv2.imwrite("demo1.png", frame)
break
cap.release()
cv2.destroyAllWindows()
# 读入图片
image = cv2.imread("demo1.png")
# 识别结果
qqq = HyperLPR_PlateRecogntion(image)
if qqq:
strt = qqq[0][0][1:7]
print(strt)
else:
ser.write(b'k')
strt = ''
ans = strt
jt = 0
judge(ans)
问题
- 串口连接不稳定 过多的数据会存在缓冲区
- 交互方式需要改进