目录
我们最近想开发一款图传小车,先用最简单最易上手的硬件,来自AI-Thinker的esp32cam来做图像采集、发送端,并使用树莓派来接收并显示吧。
小车端使用了esp32cam,这个模块非常好用,集成了wifi和摄像头,初测wifi性能还不错,在办公室环境下传480x320p的图像很流畅,偶尔卡顿是因为被水泥墙遮挡。
接收端使用树莓派4B加一块3.5寸的GPIO屏,这边应该是LCD屏走的SPI接口的原因就比较拉跨了,刷新率基本每秒一帧吧,后续换成HDMI的屏幕应该会好一些。不过好歹系统搭起来了,以此文档记录一下。主程序如下:
#include <WiFi.h>
#include "esp32_car.h"
void Camera_Initialization ();
void Wifi_setup();
void Streaming();
void setup() {
Serial.begin(115200);
Serial.setDebugOutput(true);
delay(1000);
Camera_Initialization ();
Wifi_setup();
Streaming();
}
void loop() {
}
具体实现分成以下几个部分:
1. 小车端摄像头及wifi初始化
这里我们使用的是esp32cam自带的ov2640摄像头,性能一般。小白如我最好选用AI Thinker官配的那个摄像头(短排线),因为我们更换了一个排线长度7.5cm的同样型号的ov2640摄像头以后就出现了各种莫名其妙的错误,如
- camera: Timeout waiting for VSYNC
- SCCB_Write(): SCCB_Write Failed addr:0x30, reg:0xe1, data:0x67, ret:263
网上搜到相关报错,基本是说自己配的摄像头质量太差,建议换回官配摄像头。但其实导致这些错误的根本原因是
- 数据量太大(例程里使用的QVGA分辨率太高);
- 摄像头频率太高(XCLK默认20MHz);
- 主板带不动这么长的排线(信号经过太长的排线传输后损耗过大,以至达不到所需的电平阈值)。
知道了这些,解决起来就有头绪了,无非是降低摄像头分辨率frame_size,以及降低摄像头的时钟频率xclk_freq_hz。根据我们的实验结果,降低其中一个参数即可。时钟频率xclk这个参数比较微妙一些,我们测试最低也只能到5MHz。
config.frame_size = FRAMESIZE_HVGA;
config.xclk_freq_hz = 10000000;
实验测试时,我们还是会零星观察到之前提到的两个问题(VSYNC和SBBC)。为了提高程序的可靠性,我们加了一段代码,若摄像头初始化不成功,则过一秒重启系统。
while (esp_camera_init(&config) != ESP_OK) {
Serial.println("Camera initalization failed");
esp_deep_sleep(1000000); // Restart after 1 second
}
摄像头初始化告一段落,接下来就是初始化wifi。道理很简单,就是创立一个AP热点wifi,取名esp32cam,到时候让树莓派终端连到这个wifi就可以了。
为了使用方便,我们为树莓派端代码加入了自动连接小车wifi的功能,这里需要先在树莓派使用pip3 install下载所需的两个python3的库,分别为pywifi和comtypes。树莓派连接wifi参考的是python pywifi模块——暴力破解wifi - komomon - 博客园
具体实现分为以下几个步骤:
- 获取无线网卡相关信息
- 断开现有wifi
- 连接esp