今天通過自己的學習,我做了一個智能停車場,首先先來介紹一下他的功能,通過識別車輛的車牌號并在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;′í?ó,??D??aê??óê?
}
}
}
}
#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.舵機和二極管
通過舵機控制升降桿升降,二極管的作用的提示,引導與警示,
完整的工程代碼我放到主頁里了,有需要可以去下載,
到這里,這篇博客就結束了,感謝大家能夠看到最后一行,
總結
大概用了不到一天的時間將這個專案做了出來,車牌識別準確率還是很穩定的,最后的效果也還可以,寫這篇博客也記錄自己大學做過的專案,同樣還是送給大家一句話,
星路撒下的光芒,是承載過努力的力量,你的汗水與努力,最侄訓化作一切的美好,回報給你!加油,未來可期,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/357226.html
標籤:其他
