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

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

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

1.硬件准备

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

2.软件准备

Keil5
Maixpy
Mx-yolov3

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

[En]

If the above modules and software, you have not learned or can not be proficient in using, you can first understand each module.

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篇

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);

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  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);

    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);

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

    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

语音播报模块用于指示车辆应停放的停车位。

[En]

The voice broadcast module is used to indicate the parking space where the vehicle should park.

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

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

升降杆由舵机控制,并对二极管的功能进行指示、引导和警告。

[En]

The lifting rod is controlled by the steering gear, and the function of the diode is indicated, guided and warned.

我把完整的工程代码放在主页上,如果你需要的话,可以下载它。

[En]

I put the complete engineering code on the home page, and you can download it if you need it.

这就是这个博客的结尾。谢谢你看了最后一行。

[En]

This is the end of this blog. Thank you for seeing the last line.

大概做这个项目花了不到一天的时间,车牌识别的准确率还是很稳定的,最后的效果也还可以,写这个博客也记录了自己的大学项目。同样,我想给你一句话。

[En]

Probably took less than a day to do this project, license plate recognition accuracy is still very stable, the final effect is also OK, write this blog also record their own university projects. In the same way, I would like to give you a word.

星路撒下的光芒,是承载过努力的力量。你的汗水与努力,最终会化作一切的美好,回报给你!加油,未来可期。

Original: https://blog.csdn.net/qq_51963216/article/details/121318805
Author: 我与nano
Title: 智能停车场(可检测车牌通过oled屏幕显示车牌号)语音+LED灯提示该车辆所停车位

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/498318/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球