从零搭建树莓派远程监控小车,udp视频传输,qt上位机

2023-10-27

目录

前言

一、材料准备

二、连线方式

三、软件编程

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

(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源代码,其他的放在文末资料内

#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协议进行传输,然后通过阿里云进行转发,具体请看我上一篇博文,代码如下:

#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代码如下:

#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的分享

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

从零搭建树莓派远程监控小车,udp视频传输,qt上位机 的相关文章

随机推荐