智能停车场(可检测车牌通过oled屏幕显示车牌号)语音+LED灯提示该车辆所停车位

今天通过自己的学习,我做了一个智能停车场,首先先来介绍一下他的功能,通过识别车辆的车牌号并在OLED屏幕上显示车牌号,然后升降杆升起,并通过语音播报提示车辆所去的车位,同时会有绿色指示灯提示该车位位置,当此车位停放车辆后,红色指示灯亮起提示该车位已经有车。下面是演示视频。效果还看的过去。

智能车库

文章目录

  • 前言
  • 一、前期准备
    • 1.硬件准备
    • 2.软件准备
  • 二、具体步骤
    • 1.K210篇
    • 2.STM32篇
      • 1.接收数据
      • 2.SYN6288语音播报
      • 3.OLED
      • 4.舵机和二极管
  • 总结

前言

相信各位看了这个视频也很想做出一个类似的智能停车场,其实很简单,就是基本的32单片机的知识,和K210的目标检测,接下来我们进入正文。

一、前期准备

1.硬件准备

STM32F103ZET6最小系统板X1
K210开发板X1
SYN6288语音播报X1
0.96寸四角OLED显示屏X1
MG945舵机X1
碳素管X2
木板X1
二极管、杜邦线若干

2.软件准备

Keil5
Maixpy
Mx-yolov3

如果以上的模块和软件,你还没有学习过或者不能熟练使用,可以先去了解各个模块。

二、具体步骤

1.K210篇

首先K210端要做的是识别车牌号并将数据通过串口传送到STM32单片机端,怎么训练模型,怎么实现目标检测,怎么进行串口通信,这些在我之前的博客已经写的很详细了,如果你还不会的话,可以去看我之前的博客。这里附上K210端的源码。

import sensor,image,lcd,time
import KPU as kpu
from machine import UART
from fpioa_manager import fm
lcd.init(freq=15000000)
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.set_hmirror(0)
sensor.run(1)
task = kpu.load("/sd/chepai.kmodel")
f=open("anchors.txt","r")
anchor_txt=f.read()
L=[]
for i in anchor_txt.split(","):
    L.append(float(i))
anchor=tuple(L)
f.close()
f=open("lable.txt","r")
lable_txt=f.read()
lable = lable_txt.split(",")
f.close()
fm.register(10, fm.fpioa.UART1_TX, force=True)
fm.register(11, fm.fpioa.UART1_RX, force=True)
uart_A = UART(UART.UART1, 115200, 8, 1, 0, timeout=1000, read_buf_len=4096)
anchor = (0.1746, 0.1022, 0.2411, 0.3491, 0.2240, 0.5854, 1.0228, 0.9837, 2.128, 1.6843)
sensor.set_windowing((224, 224))
a = kpu.init_yolo2(task, 0.5, 0.3, 5, anchor)
classes=["京N·2B945","苏E·42J68","苏E·82L84" ]
while(True):
     img = sensor.snapshot()
     code = kpu.run_yolo2(task, img)
     if code:
         for i in code:
             a=img.draw_rectangle(i.rect())
             a = lcd.display(img)
             list1=list(i.rect())
             b=(list1[0]+list1[2])/2
             c=(list1[1]+list1[3])/2
             uart_A.write(classes[i.classid()]+'\r\n')
     else:
         a = lcd.display(img)
uart_A.deinit()
del uart_A
a = kpu.deinit(task)

以上便是K210的源码,仅供大家参考。

2.STM32篇

1.接收数据

K210识别到车牌号后需要经32单片机接收数据然后处理数据才可以使用,之前的博客并没有教大家32单片机端如何接收,只是顺带提了一下。这里附上32单片机串口的代码。

uart.c

#include "sys.h"
#include "usart.h"	  
#if SYSTEM_SUPPORT_OS
#include "includes.h"			 
#endif

#if 1
#pragma import(__use_no_semihosting)                            
struct __FILE 
{
      
	int handle; 

}; 

FILE __stdout;       
_sys_exit(int x) 
{
      
	x = x; 
} 
 
int fputc(int ch, FILE *f)
{
           
	while((USART1->SR&0X40)==0);
    USART1->DR = (u8) ch;      
	return ch;
}
#endif  
#if EN_USART1_RX  
	
u8 USART_RX_BUF[USART_REC_LEN];    

u16 USART_RX_STA=0;      

void USART3_SendData(u8 data)
{
     
	while((USART3->SR & 0X40) == 0);
	USART3->DR = data;
}

void USART3_SendString(u8 *DAT, u8 len)
{
     
	u8 i;
	for(i = 0; i < len; i++)
	{
     
		USART3_SendData(*DAT++);
	}
}
void uart_init(u32 bound){
     

  GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	 
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);	
  
	//USART1_TX   GPIOA.9
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
   
  //USART1_RX	  GPIOA.10
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_Init(GPIOA, &GPIO_InitStructure); 

  //Usart1 NVIC 
  NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;		
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			
	NVIC_Init(&NVIC_InitStructure);	

	USART_InitStructure.USART_BaudRate = bound;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	USART_InitStructure.USART_Parity = USART_Parity_No;
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;	

  USART_Init(USART1, &USART_InitStructure);
  USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
  USART_Cmd(USART1, ENABLE);                   

}

void USART1_IRQHandler(void)                	
	{
     
	u8 Res;
#if SYSTEM_SUPPORT_OS 		
	OSIntEnter();    
#endif
	if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  
		{
     
		Res =USART_ReceiveData(USART1);	
		
		if((USART_RX_STA&0x8000)==0)
			{
     
			if(USART_RX_STA&0x4000)
				{
     
				if(Res!=0x0a)USART_RX_STA=0;
				else USART_RX_STA|=0x8000;
				}
			else 
				{
     	
				if(Res==0x0d)USART_RX_STA|=0x4000;
				else
					{
     
					USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;
					USART_RX_STA++;
					if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;´íÎó,ÖØпªÊ¼½ÓÊÕ	  
					}		 
				}
			}   		 
     } 
#if SYSTEM_SUPPORT_OS 	
	OSIntExit();  											 
#endif
} 
#endif	
 #if EN_USART3_RX 
 	
u8 USART3_RX_BUF[];    
u16 USART3_RX_STA=0;  
void USART3_Init(u32 bound)
{
     
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
	//USART3_TX   GPIOC.10
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	
	GPIO_Init(GPIOB, &GPIO_InitStructure);

	//USART3_RX	  
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_Init(GPIOB, &GPIO_InitStructure);

	//USART3 NVIC
	NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3 ; 
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;		
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;		
	NVIC_Init(&NVIC_InitStructure);	


	USART_InitStructure.USART_BaudRate = bound;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	USART_InitStructure.USART_Parity = USART_Parity_No;
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

	USART_Init(USART3, &USART_InitStructure);
	USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
	USART_Cmd(USART3, ENABLE);                 
	USART3_RX_STA = 0;		
	TIM_Cmd(TIM3, DISABLE);		
}

void USART3_IRQHandler(void)              
{
     
	u8 Res;
	if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)
	{
     
		Res = USART_ReceiveData(USART3);	
		if((USART3_RX_STA & 0x8000) == 0) 
		{
     
			if(USART3_RX_STA < USART3_REC_LEN)
			{
     
				TIM_SetCounter(TIM3, 0);           				
				if(USART3_RX_STA == 0) 				
				{
     
					TIM_Cmd(TIM3, ENABLE); 
				}
				USART3_RX_BUF[USART3_RX_STA++] = Res;	
			}
			else
			{
     
				USART3_RX_STA |= 1 << 15;			
			}
		}
	}
}
#endif	

uart.h

#ifndef __USART_H
#define __USART_H
#include "stdio.h"	
#include "sys.h" 

#define USART_REC_LEN  	200  	
#define EN_USART1_RX 	1	
#define USART3_REC_LEN  200  	
#define EN_USART3_RX 	1		
	  	
extern u8  USART3_RX_BUF[USART3_REC_LEN]; 
extern u16 USART3_RX_STA;         		
void USART3_SendString(u8 *DAT,u8 len);
void USART3_SendData(u8 data);
void USART3_Init(u32 bound);  	
extern u8  USART_RX_BUF[USART_REC_LEN]; 
extern u16 USART_RX_STA;         		
void uart_init(u32 bound);
#endif

2.SYN6288语音播报

语音播报模块用来提示车辆应该停的车位
SYN6288.c

#include "syn6288.h"
#include "usart.h"
#include "string.h"
#include "delay.h"

void SYN_FrameInfo(u8 Music, u8 *HZdata)
{
     
 
  unsigned  char  Frame_Info[50];
  unsigned  char  HZ_Length;
  unsigned  char  ecc  = 0;  			
  unsigned  int i = 0;
  HZ_Length = strlen((char*)HZdata); 			

  Frame_Info[0] = 0xFD ; 			
  Frame_Info[1] = 0x00 ; 			
  Frame_Info[2] = HZ_Length + 3; 		
  Frame_Info[3] = 0x01 ; 			
  Frame_Info[4] = 0x01 | Music << 4 ; 

 
  for(i = 0; i < 5; i++)   			
  {
     
    ecc = ecc ^ (Frame_Info[i]);		
  }

  for(i = 0; i < HZ_Length; i++)   	
  {
     
    ecc = ecc ^ (HZdata[i]); 			
  }

  memcpy(&Frame_Info[5], HZdata, HZ_Length);
  Frame_Info[5 + HZ_Length] = ecc;
  USART3_SendString(Frame_Info, 5 + HZ_Length + 1);
}


void YS_SYN_Set(u8 *Info_data)
{
     
  u8 Com_Len;
  Com_Len = strlen((char*)Info_data);
  USART3_SendString(Info_data, Com_Len);
}

uart.h

#ifndef __SYN6288_H
#define __SYN6288_H

#include "sys.h"


void SYN_FrameInfo(u8 Music, u8 *HZdata);
void YS_SYN_Set(u8 *Info_data);

#endif

3.OLED

OELD用来显示识别到的车牌号
oled代码太多了,包括汉字库,字符库。如果有需要可以去我主页下载。

4.舵机和二极管

通过舵机控制升降杆升降,二极管的作用的提示,引导与警示。
完整的工程代码我放到主页里了,有需要可以去下载。

到这里,这篇博客就结束了,感谢大家能够看到最后一行。

总结

大概用了不到一天的时间将这个项目做了出来,车牌识别准确率还是很稳定的,最后的效果也还可以,写这篇博客也记录自己大学做过的项目。同样还是送给大家一句话。
星路撒下的光芒,是承载过努力的力量。你的汗水与努力,最终会化作一切的美好,回报给你!加油,未来可期。

你可能感兴趣的:(语音识别,人工智能,stm32)