我是靠谱客的博主 曾经棒球,这篇文章主要介绍从零搭建树莓派远程监控小车,udp视频传输,qt上位机前言一、材料准备二、连线方式三、软件编程,现在分享给大家,希望可以做个参考。

目录

前言

一、材料准备

二、连线方式

三、软件编程

软件编程主要有一下几个方面

(1)树莓派视频传输

(2)esp8266代码

(3)上位机编程

 四、总结



前言

最近刚准备完期末机器人驱动的课设,本来是做远程监控无人机的,但是第一次玩无刷电机,烧坏了两个电调,所以就索性将无人机改成了无人车,接下来我将详细介绍一下我的准备以及设计过程。


一、材料准备

树莓派4b

esp8266模块(这个是用来驱动无刷电机,其实树莓派一个也能完成,但是最近树莓派价格太贵了,烧不起啊,所以单独选用esp8266来驱动电机接受指令)

树莓派官方摄像头

2个sg90舵机(这个舵机是真的不好用,强烈建议大家更换金属齿轮的舵机,由于在家中材料限制不得不使用sg90)

无刷电机两个

无刷电调两个

航模锂电池12v

部分3d打印件(云台以及地盘,轮子模型都是我自己通过solidwroks设计的,需要的我将链接放在最后)

二、连线方式

esp8266 5号引脚和4号引脚连接两个sg90舵机

0号和2号引脚连接两个无刷电调

无刷电调三根线分别连接无刷电机的三根线,顺序随便,后期调整方向即可


三、软件编程

软件编程主要有一下几个方面

1.树莓派的视频传输编程

2.接收端上位机的编程

3.esp8266接受上位机指令驱动舵机和无刷电机的编程

(1)树莓派视频传输

在视频传输上我考虑过很多个方法,tcp协议,udp协议,mjpg-streamer插件,最后选择的是udp协议,tcp由于需要三次握手三次挥手,传输精度高,但是效率低,我们做视频传输更在乎的是延迟,所以不需要握手的udp更加适合,mjpg-streamer由于我配置了opencv环境,所以起冲突了,不考虑,但是这个插件传输的延迟也很低,效率高,在GitHub上也获得了不少的star,大家也可以尝试一下

mjpg-steamer链接

以下是树莓派代码:

是用qt写的发送端,配置了opencv环境,编译了可能不会直接通过,可以先配置一下qt的opencv环境,代码量较多,仅展示cpp源代码,其他的放在文末资料内

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include "mainwindow.h" #include "ui_mainwindow.h" #include <opencv2/highgui.hpp> #include <opencv2/imgcodecs.hpp> #include <QHostAddress> using namespace cv; MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); udpSocket = new QUdpSocket(this); udpSocket->bind(QHostAddress::Any,8083); connect(&fps_timer,SIGNAL(timeout()),this,SLOT(VideoSend())); } MainWindow::~MainWindow() { delete ui; } void MainWindow::on_pushButton_clicked() { camera.open(0); fps_timer.start(33); } void MainWindow::on_pushButton_2_clicked() { fps_timer.stop(); camera.release(); this->close(); } void MainWindow::VideoSend() { QHostAddress ipp=(QHostAddress)(ui->lineEdit->text()); quint16 portt=ui->lineEdit_2->text().toInt(); Mat frame; camera.read(frame); cvtColor(frame,frame,COLOR_BGR2RGB); QImage image((unsigned char *)(frame.data),frame.cols,frame.rows,QImage::Format_RGB888); ui->label_video->setPixmap(QPixmap::fromImage(image)); ui->label_video->resize(image.width(),image.height()); QByteArray byte; QBuffer buff(&byte); buff.open(QIODevice::WriteOnly); image.save(&buff,"JPEG"); QByteArray ss = qCompress(byte,5); udpSocket->writeDatagram(ss,ipp,portt); }

(2)esp8266代码

这一部分使用的tcp协议进行传输,然后通过阿里云进行转发,具体请看我上一篇博文,代码如下:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#include "ESP8266WiFi.h" #include "Servo.h" const char* ssid="*******";//wifi账号 const char* password="******";//wifi密码 Servo wushua1; Servo wushua2; int Max=2000; int Min=1000; int pos=Min; int sign=0; Servo servo1; Servo servo2; int sor=50; int sorr=50; void setup() { servo1.attach(5); servo1.write(sor); servo2.attach(4); servo2.write(sorr); wushua2.attach(2); wushua1.attach(0); wushua2.write(Max); wushua1.write(Max); delay(5000); wushua1.write(Min); wushua2.write(Min); delay(5000); //模拟遥控器给无刷电机进行校准 Serial.begin(115200); WiFi.mode(WIFI_STA); WiFi.begin(ssid,password); while(WiFi.status()!=WL_CONNECTED) { delay(1000); Serial.println("waiting to connect..."); } Serial.println("connecting!!!"); Serial.print("ip address is :"); Serial.print(WiFi.localIP()); } void loop() { WiFiClient tcpclient; if(!tcpclient.connect("8.130.51.57",8000)) { Serial.println("connect to aliyun is failed"); delay(5000); } Serial.println("Connect to aliyun is successful"); tcpclient.println("hello,i am esp8266"); while(1) { while(tcpclient.available()==0); Serial.println("i recive:"); char ch=static_cast<char>(tcpclient.read()); Serial.println(ch); if(ch=='1') {sor=sor+20; servo1.write(sor); delay(500); } else if(ch=='2') { sor=sor-20; servo1.write(sor); delay(500);} else if(ch=='3') {sorr=sorr+20; servo2.write(sorr); delay(500); } else if(ch=='4') { sorr=sorr-20; servo2.write(sorr); delay(500); } else if(ch=='5') { wushua1.write(1500); wushua2.write(1500); delay(500); } else if(ch=='6') { wushua1.write(800); wushua2.write(800); delay(500); } else if(ch=='7') { wushua1.write(800); wushua2.write(1500); delay(500); } else if(ch=='8') { wushua1.write(1500); wushua2.write(800); delay(500); }}}

(3)上位机编程

上位机也是通过qt写的,主要接受udp视频以及用tcp发送指令给esp8266 

cpp代码如下:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#include "mainwindow.h" #include "ui_mainwindow.h" #include<QHostAddress> #include<QPixmap> #include<QImageReader> #include<QBuffer> #include<QHostAddress> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); receiver.bind(QHostAddress::Any,8083); connect(&receiver,SIGNAL(readyRead()),this,SLOT(video_receive_show())); // setWindowTitle("无人车远程监控平台"); ui->connect->setEnabled(true); m_tcp=new QTcpSocket(this); connect(m_tcp,&QTcpSocket::readyRead,this,[=]() { QByteArray date=m_tcp->readAll(); // } ); connect(m_tcp,&QTcpSocket::connected,this,[=]() { ui->jiaohu->append("已经成功连接到了无人车,可以进行控制"); }); } MainWindow::~MainWindow() { delete ui; } void MainWindow::video_receive_show() { quint64 size = receiver.pendingDatagramSize(); QByteArray buff; buff.resize(size); QHostAddress adrr ; quint16 port; receiver.readDatagram(buff.data(),buff.size(),&adrr,&port); buff = qUncompress(buff); QBuffer buffer(&buff); QImageReader reader(&buffer,"JPEG");//可读入磁盘文件、设备文件中的图像、以及其他图像数据如pixmap和image,相比较更加专业。 //buffer属于设备文件一类, QImage image = reader.read();//read()方法用来读取设备图像,也可读取视频,读取成功返回QImage*,否则返回NULL ui->label->setPixmap(QPixmap::fromImage(image)); ui->label->resize(image.width(),image.height()); } void MainWindow::on_connect_clicked() { QString ip=ui->ip->text(); unsigned short port=ui->port->text().toUShort(); m_tcp->connectToHost(QHostAddress(ip),port); ui->jiaohu->append("客户端向无人车发起了连接请求"); } void MainWindow::on_yunleft_clicked() { m_tcp->write("1"); ui->jiaohu->append("客户端发出了云台左转的命令"); } void MainWindow::on_yunright_clicked() { m_tcp->write("2"); ui->jiaohu->append("客户端发出了云台右转的命令"); } void MainWindow::on_yunup_clicked() { m_tcp->write("3"); ui->jiaohu->append("客户端发出了云台上调的命令"); } void MainWindow::on_yundown_clicked() { m_tcp->write("4"); ui->jiaohu->append("客户端发出了云台下调的命令"); } void MainWindow::on_go_clicked() { m_tcp->write("5"); ui->jiaohu->append("小车前进中"); } void MainWindow::on_down_clicked() { m_tcp->write("6"); ui->jiaohu->append("小车暂停运行"); } void MainWindow::on_left_clicked() { m_tcp->write("7"); ui->jiaohu->append("小车左转"); } void MainWindow::on_right_clicked() { m_tcp->write("8"); ui->jiaohu->append("小车右转"); }

 四、总结

由于使用了tcp中转,所以小车不受距离的限制,只要接入了互联网,即可受到上位机的控制。后期可以加入人脸识别,变成人脸监控小车,然后写好代码让小车自动在家里巡航,当发现陌生人后可以通过app报警,这也是我接下来的研究方向。

资料下载:

链接:https://pan.baidu.com/s/1xNbzBkFHaO1DzDlhp44Tlw?pwd=w94s 
提取码:w94s 
--来自百度网盘超级会员V3的分享

最后

以上就是曾经棒球最近收集整理的关于从零搭建树莓派远程监控小车,udp视频传输,qt上位机前言一、材料准备二、连线方式三、软件编程的全部内容,更多相关从零搭建树莓派远程监控小车内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(75)

评论列表共有 0 条评论

立即
投稿
返回
顶部