QT获取ESP32-CAM视频流的同时,给ESP32-CAM发送字符串数据
1、前言
使用QT获取ESP32-CAM视频流的原理是在QT模拟浏览器发送http请求,然后ESP32-CAM返回视频流,当QT界面接收到数据后,对数据进行解析,然后合成图片进行显示。但是,如果我们也想通过http方法方式给ESP32-CAM发送字符串数据,这种方法是不可取的,因为他会影响视频流的传输。
这里的解决方法是,在QT软件上面,创建一个TCP Server,监听一个端口,等待ESP32-CAM的连接。等他连接上就可以给他发送消息了。这里使用socket编程。
2、ESP32-CAM端的代码
const char* serverIP = "192.168.137.1"; //TCP Server的IP地址
const uint16_t serverPort = 1234; //端口
void setup() {
Serial.begin(115200);
Serial.setDebugOutput(true);
Serial.println();
WiFiClient client;
//.....此处省略摄像头初始化代码
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
startCameraServer();
Serial.print("Camera Ready! Use 'http://");
Serial.print(WiFi.localIP());
Serial.println("' to connect");
}
void loop() {
// put your main code here, to run repeatedly:
delay(10);
if (!client.connected()) { //检测连接状态
Serial.println("Connecting to server...\n");
if (client.connect(serverIP, serverPort)) {
Serial.println("Connected to server");
client.print("Hello, server!");
client.flush();
} else {
Serial.println("Connection failed");
}
}
if (client.available()) { //如果接收到TCP Server传过来的消息,就打印
String response = client.readStringUntil('\n');
Serial.print("Received response: ");
Serial.println(response);
}
}
2、QT端的代码
当ESP32-CAM连接上QT上位机后,上位机每隔500ms给ESP32-CAM发送一个字符串“ABCD”和“6666”。
//MainWindow.h文件里的程序
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
void SendData();
public:
QTcpServer server;
QTcpSocket* socket = nullptr;
private:
Ui::MainWindow *ui;
};
//MainWindow.c文件里的程序
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
if (!server.listen(QHostAddress::Any, 1234)) { //监听端口1234
qDebug() << "Failed to listen on port 1234";
return;
}
// ESP32-CAM连接成功时触发void SendData()函数
QObject::connect(&server, &QTcpServer::newConnection, [&]()
{
socket = server.nextPendingConnection();
qDebug() << "Client connected: " << socket->peerAddress().toString();
QTimer *timer = new QTimer;
// 实现定时器中断
connect(timer, &QTimer::timeout, this, &MainWindow::SendData);
// 设置定时时间间隔
timer->start(500); //1s
});
}
/*********************************************************************************
* 函数: void SendData()
* 功能:把数据发送给ESP32-CAM
* 输入:NONE
* 输出: NONE
*********************************************************************************/
void MainWindow::SendData()
{
if(QR_STAT == 0 && Car_Flag == 0) return; //没有识别到车牌,也没有识别到健康码
QString ipAddress = ui->ipEdit_B->text();
if (socket != nullptr)
{
socket->write("AAAABB\n"); //注意,需要加“\n”,ESP32-CAM以此判断是否接收完成
socket->write("66666\n");
}
}
3、运行结果
这里是一边接收ESP32-CAM的视频流,并且一边给它发送数据。当ESP32-CAM接收到数据后,通过串口打印。