单片机设计系列4——低成本物联网硬件ESP8266 D1mini的应用(自助停车场项目实践部分)
简介说明
承接上文单片机设计3(视觉部分),本文接着来写自助停车场项目的主控部分。主控采用的是低成本物联网开发硬件——ESP8266单片机。在设计3中完成对车牌的视觉识别之后,接下来将得到的数据串口传输给主控,来完成这个项目的剩余部分功能。
单片机设计系列3——视觉模块MaixCAM项目之车牌识别-CSDN博客https://blog.csdn.net/2301_81315771/article/details/145464249?spm=1001.2014.3001.5501https://blog.csdn.net/2301_81315771/article/details/145464249?spm=1001.2014.3001.5501
芯片介绍
ESP8266 D1mini是一款基于ESP8266芯片的开源硬件开发板,上图是引脚分配以及尺寸标准。
基本特性
芯片与架构:采用乐鑫科技的ESP8266芯片,这是一款超低功耗的UART-WiFi透传模块,内置Tensilica L106超低功耗32位微型MCU,主频支持80MHz和160MHz。
存储与内存:通常配备4M字节的闪存,部分版本如D1 Mini V3则配备了16M字节的闪存,具备较大的存储空间用于程序和数据的存储。
工作电压:工作电压为3.3V,使用Micro-B type USB线进行连接。
功能特点
通信能力:支持802.11 b/g/n协议,WiFi @ 2.4 GHz,支持WPA/WPA2安全模式,内置TCP/IP协议栈,可轻松实现设备的无线网络连接。
多种工作模式:支持STA/AP/STA+AP工作模式,还支持Smart Config功能(包括Android和iOS设备),方便设备的无线配置。
丰富接口:包含11个数字IO引脚以及1个模拟输入引脚,除了D0口其他口都支持interrupt/PWM/I2C/one-wire等功能。
低功耗设计:深度睡眠保持电流为10uA,关断电流小于5uA,2ms之内唤醒、连接并传递数据包,待机状态消耗功率小于1.0mW。
开发环境与编程支持
兼容Arduino IDE:可以使用Arduino IDE对其进行开发,开发者可以通过简单的配置在Arduino IDE中选择相应的开发板进行编程。
支持MicroPython:除了Arduino IDE,D1mini还支持MicroPython编程语言,为开发者提供了更多的选择。
应用场景
物联网项目:由于其具备WiFi功能和易于开发的特点,广泛应用于各种物联网项目中,如智能家居设备、可穿戴设备、传感器网络等。
教育与学习:作为一款低成本且功能丰富的开发板,非常适合电子爱好者和学生进行学习和实验,帮助他们快速上手物联网开发。
功能实现
项目介绍
本设计采用ESP8266 D1mini开发板作为核心主控,以LicheeRV Nano(见上一篇博客)开发板作为视觉方案,构造了一个成本极低、识别准确、功能强大的电子停车场自助管理系统。本设计采用合理的PCB板设计,实现以下功能:
- 当车牌号出现在摄像头前时,系统自动识别车牌号,并发送给主控芯片,主控芯片控制LED灯亮起、起落杆打开、蜂鸣器发声、OLED屏幕显示来车信息,并显示“欢迎到来”。
- 即刻将车牌信息上传到网页,记录“存在”状态并开始实时计时(计费),当车辆进入停车场车位(PCB板指定位置)后,触发红外感应装置,对应车位的指示灯亮起,表示此处已有车辆。
- 当同样的车牌再次出现在摄像头时,OLED显示对应车牌号以及“下次再见”,起落杆抬起,网页上更新车辆状态为“离开”。
本设计了实现一个低成本的停车场自助管理系统,功能丰富稳定可靠。
代码设计
对ESP8266 D1mini的程序要求如下:
-
通过串口接收车牌号信息。
-
记录车牌的进入和离开时间。
-
显示停车时长和状态。
-
通过Web服务器提供实时数据和HTML界面展示。
代码构建
第一步,连接WIFI:
#include <ESP8266WiFi.h>
const char* ssid = "WIFI_SSID";
const char* password = "PASSWORD";
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi...");
}
Serial.println("WiFi connected");
Serial.println("IP address: " + WiFi.localIP().toString());
-
使用ESP8266WiFi库连接WiFi。
-
连接到指定的WiFi网络(SSID和密码)。
-
如果连接失败,程序会在控制台输出连接提示。
-
连接成功后,打印本地IP地址。
第二步,创建Web服务器:
#include <ESP8266WebServer.h>
ESP8266WebServer server(80);
server.on("/", handleRoot);
server.on("/data", handleData);
server.begin();
-
使用ESP8266WebServer库创建一个Web服务器,监听端口80。
-
定义两个路由:
-
/
:返回一个包含车牌记录的HTML页面。 -
/data
:返回一个JSON格式的实时数据接口。
-
-
启动Web服务器。
第三步,OLED显示:
#include <U8g2lib.h>
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
-
使用U8g2lib库控制一个I2C接口的OLED屏幕(SSD1306型号)。
-
初始化OLED屏幕,设置分辨率为128×64。
-
显示以下内容:
-
欢迎信息(10秒后切换为停车数)。
-
车牌号(当有车牌进入或离开时)。
-
第四步,车牌记录管理:
struct PlateRecord {
String plateNumber;
unsigned long startTime;
unsigned long duration;
bool isActive;
};
PlateRecord records[MAX_RECORDS];
int recordCount = 0;
-
使用一个结构体
PlateRecord
存储车牌信息,包括:-
车牌号(
plateNumber
)。 -
开始时间(
startTime
)。 -
持续时间(
duration
)。 -
是否处于活动状态(
isActive
)。
-
-
最大记录数为10(
MAX_RECORDS
)。 -
使用一个数组
records
存储所有车牌记录,recordCount
记录当前已存储的记录数。
第五步,LED灯控制:
const int ledPin = 2;
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, HIGH);
delay(1000);
digitalWrite(ledPin, LOW);
-
使用GPIO2(D4)控制LED灯。
-
当有车牌记录添加或更新时,LED灯会亮起1秒。
第六步, 数据处理:
void handlePlate(String plateNumber) {
int index = findPlateIndex(plateNumber);
if (index == -1) {
// 添加新记录
records[recordCount].plateNumber = plateNumber;
records[recordCount].startTime = millis();
records[recordCount].duration = 0;
records[recordCount].isActive = true;
recordCount++;
showWelcomeMessage(plateNumber);
} else {
// 更新现有记录
if (records[index].isActive) {
// 车牌离开
records[index].duration = millis() - records[index].startTime;
records[index].isActive = false;
showGoodbyeMessage(plateNumber);
} else {
// 车牌重新进入
records[index].startTime = millis();
records[index].isActive = true;
showWelcomeMessage(plateNumber);
}
}
}
-
当通过串口接收到车牌号时,调用
handlePlate()
函数。 -
检查车牌是否已存在:
-
如果不存在,添加新记录。
-
如果存在,根据当前状态(
isActive
)更新记录:-
如果是活动状态,标记为离开并记录时长。
-
如果是非活动状态,重新启动计时。
-
-
第七步,OLED显示更新:
void showWelcomeMessage(String plateNumber) {
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_wqy16_t_gb2312);
u8g2.drawUTF8(0, 16, "欢迎到来!");
u8g2.drawUTF8(0, 32, plateNumber.c_str());
u8g2.sendBuffer();
}
void showGoodbyeMessage(String plateNumber) {
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_wqy16_t_gb2312);
u8g2.drawUTF8(0, 16, "下次再见!");
u8g2.drawUTF8(0, 32, plateNumber.c_str());
u8g2.sendBuffer();
}
-
显示欢迎信息或再见信息,包含车牌号。
-
使用中文字体(
u8g2_font_wqy16_t_gb2312
)在OLED屏幕上显示文本。
第八步,计时更新:
void updateTimers() {
for (int i = 0; i < recordCount; i++) {
if (records[i].isActive) {
records[i].duration = millis() - records[i].startTime;
}
}
}
每次循环时,更新所有活动记录的持续时间(保证网页的计时时长实时更新)。
第九步,Web界面生成:
void handleRoot() {
// 生成HTML页面
server.send(200, "text/html; charset=UTF-8", html);
}
-
当访问路径
/data
时,返回一个JSON格式的实时数据。 -
JSON数据包含所有车牌记录的车牌号、时长和状态。
第十步,数据接口:
void handleData() {
// 创建JSON数据
server.send(200, "application/json", jsonResponse);
}
-
当访问路径
/data
时,返回一个JSON格式的实时数据。 -
JSON数据包含所有车牌记录的车牌号、时长和状态。
依赖库
ESP8266WiFi
:用于WiFi连接。ESP8266WebServer
:用于Web服务器。ArduinoJson
:用于处理JSON数据。U8g2lib
:用于控制OLED屏幕。
TIPS
ESP8266/ESP32设备均只支持2.4GHz频段的WIFI连接,如果手机使用热点连接,会优先使用5Ghz频段的WIFI,如果出现ESP设备WIFI连接超时或者连接失败的情况,请尝试更换频段或者更换热点设备。
项目创新点/关键技术指标
1.车牌识别数据准确快速,识别置信度高。本设计在低成本单片机LicheeRV Nano上部署了AI视觉模型,实现高帧率稳定OCR文字识别,并以正则化表达式筛选正确的车牌格式传输到主控。
2.网页信息可视化服务。本系统可以实时展示停车场数据并在网页显示,包括停车数量、车牌号,以及实时停车时间计时,简单高效。
3.极低成本以及高片上资源利用率。主控采用成本不到10元的D1 mini芯片,既能驱动GPIO,也能实现串口通信,还能实现网页服务器建设,整块主控的内存利用率和引脚利用几乎极致。同时,视觉模块LicheeRV Nano单片机的成本也仅有59元,便能高效稳定地运行车牌视觉识别模型。
相关实物产品展示:
其他
本项目目前还在半成品阶段,还差最后的装配和应用环节,预计将在25.3前完成,届时整个项目的成果我会发在CSDN上,具体的EDA文件(PCB)、ESP8266代码、MaixCAM代码,整个项目的文件材料我也会分享,有需要可以联系作者邮箱lingui_fzu@qq.com。
本设计非常适合新手接触完整的项目,整体结构简单,适合零基础或有初步认识的同学学习制作。
作者:南檐巷上学