草庐IT

STM32+ESP8266连接电脑Qt网络上位机——QT篇

_拾贰_ 2023-05-18 原文

本文简单介绍下手写网络调试器并连接ESP8266模块

上篇  STM32+ESP8266连接电脑Qt网络上位机——准备工作

目录

一、部分Qt代码及实现过程

二、实现过程——使用ESP8266连接上位


一、部分Qt代码及实现过程

最终效果

        本上位机结合了主机和服务器两种模式,在断开连接的时候可以切换模式。当作为服务器时,本机电脑的ip为该上位机的ip,可以使用ipconfig查看ip地址。最后新增了连接状态现实,以下矢量图均来自阿里。下方评论发源码->邮箱或 自行下载 Git -> https://gitee.com/guo-lingran/tcp_-server-and-clienthttps://gitee.com/guo-lingran/tcp_-server-and-client百度网盘下载https://pan.baidu.com/s/1sSVkUJrMqN9fP4x1uSrDtA  提取码:qt92

代码部分

   在QT中基于TCP的通信会使用到两个类:

  • QTcpServer:   服务器类,用于监听客户端连接以及与客户端连接
  • QTcpSocket:  客户端、服务端都需要用到

构造函数

        在构造函数里添加connect操作,当有新的连接时,tcpServer会有一个newConnection的信号,将执行槽函数(newConnection_Slot())。以下都是对界面的初始化。

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    tcpServer = new QTcpServer(this);
    tcpSocket = new QTcpSocket(this);
    
    //默认使用主机模式,等待新的连接
    connect(tcpServer,SIGNAL(newConnection()),this,SLOT(newConnection_Slot()));

    setFixedSize(480,420);
    //默认端口号 8080
    ui->portEdit->setText("8080");
    ui->ipED->setText("192.168.3.13");
    setWindowTitle("--局域网络调试器-- 测试版  V4.0 22-0905     制作:拾贰");
}

newConnection_Slot槽函数

        获取到新的连接后,调用 nextPendingConnection去接收一个等待的连接,并修改界面的状态图标为”在线“状态。当tcpServer发出readyRead信号后,将接收数据,由接收槽函数(readyRead_Slot())去处理。

        这里再写一个connect,若断开连接,tcpServer发出断开连接的信号,同样的去处理断联的槽函数。

void Widget::newConnection_Slot(){

    tcpSocket=tcpServer->nextPendingConnection();//得到通信的套接字对象
    connect(tcpSocket,SIGNAL(readyRead()),this,SLOT(readyRead_Slot()));
    connect(tcpSocket,SIGNAL(disconnected()),this,SLOT(disconnected_Slot()));
    //建立连接后,修改界面的状态的信息——在线的图标
    ui->label_3->setStyleSheet("border-image: url(:/new/prefix1/connect.png)");
}

readyRead_Slot槽函数

        把接收到的数据全部读出来,这里防止乱码,将把收到的数据转化一下。tcpSocket->readAll()为客户端发来的数据,最后显示到接受框内。

void Widget::readyRead_Slot(){
    QByteArray receiveDate;
    QTextCodec *tc = QTextCodec::codecForName("GBK");  

    while(!tcpSocket->atEnd()){
        receiveDate = tcpSocket->readAll();
    }
    if (!receiveDate.isEmpty())
    {
        QString strBuf=tc->toUnicode(receiveDate);         
         ui->RecvEdit->appendPlainText(strBuf);
    }
    receiveDate.clear();
}

disconnected_Slot槽函数

        断联后将关闭tcpSocket,同样的修改界面的状态图标为”离线“状态

//服务器或客户机连接状态
void Widget::disconnected_Slot(){
    tcpSocket->close();
    ui->label_3->setStyleSheet("border-image: url(:/new/prefix1/discon.png)");
}

网络监听

        获取控件里的端口,调用listen接口,第一个参数,QHostAddress::Any:服务器将侦听所有网络接口,第二个参数:端口号。若当前状态为客户机,将connectToHost目标主机,创建一个connect,若有连接,执行connnect_Slot()槽函数。其余为优化界面的操作。

//打开网络/关闭网络
void Widget::on_openBt_clicked()
{
    flag_Sw=!flag_Sw;
    if(flag_Sw){
        //选择主机
        if(MS) {       
            tcpServer->listen(QHostAddress::Any,ui->portEdit->text().toUInt());
        }
        else//客户机 {
            tcpSocket->connectToHost(ui->ipED->text(),ui->portEdit->text().toUInt());
            connect(tcpSocket,SIGNAL(connected()),this,SLOT(connected_Slot()));
        }
        ui->openBt->setStyleSheet("border-image: url(:/new/prefix1/open.png)");
        ui->wifi->setStyleSheet("border-image: url(:/new/prefix1/wifi_on.png)");
    }
    else{
        tcpServer->close();
        tcpSocket->close();
        ui->openBt->setStyleSheet("border-image: url(:/new/prefix1/close.png)");
        ui->wifi->setStyleSheet("border-image: url(:/new/prefix1/wifi_off.png)");
    }
}

connnect_Slot槽函数

//客户机连接
void Widget::connected_Slot(){
    connect(tcpSocket,SIGNAL(readyRead()),this,SLOT(readyRead_Slot()));
    ui->label_3->setStyleSheet("border-image: url(:/new/prefix1/connect.png)");
    connect(tcpSocket,SIGNAL(disconnected()),this,SLOT(disconnected_Slot()));
}

主机\客户机切换函数

//主副机切换
void Widget::on_ms_clicked()
{
 if(!flag_Sw){
    tcpServer->close();
    tcpSocket->close();
    if(MS){
        MS=false;
        ui->label->setText("客户机模式");
        ui->ms->setStyleSheet("border-image: url(:/new/prefix1/client.png);");
    }
    else {
        MS=true;
        ui->label->setText("主机模式");
        ui->ms->setStyleSheet("border-image: url(:/new/prefix1/server.png);");
    }
 }
 else
    QMessageBox::critical(this,"提示","请先关闭网络,再切换模式类型");
}

发送数据

       通过tcpSocket接口write函数发送数据

void Widget::on_sendBt_clicked()
{
    QString SendCon =  ui->sendEdit->text().toLocal8Bit().data();
    if(flag_Sw){
        if(SendCon!=""){
            //封装编码
            QByteArray receiveDate;
            QTextCodec *tc = QTextCodec::codecForName("GBK");  
            //对发送框编码
            receiveDate =  ui->sendEdit->text().toLocal8Bit().data();
            QString strBuf=tc->toUnicode(receiveDate);
            //整合符号 ->
            QString  str="->";
            QString str2 =str.append(strBuf);
             //向输出框打印发送的数据
            ui->RecvEdit->appendPlainText(str2);
            tcpSocket->write(ui->sendEdit->text().toLocal8Bit().data());
        }
        else
         QMessageBox::critical(this,"警告","不能发送空白信息");
   }
    else
         QMessageBox::critical(this,"提示","发送失败,网络尚未连接");
}

其他槽函数不再一一介绍...

二、实现过程——使用ESP8266连接上位机

工具:           

        CH340串口调试器

        网络调试器

        ESP8266(这里我将使用正点原子的ESP-12F,效果都一样)

实现目标:

        用AT指令使ESP8266连接刚才的上位机,测试上位机是否好用,方便以后和STM32通信

接下来将一步一步接入网络调试器

       这里上位机作为服务器,ip地址为192.168.3.13,8266作为客户机连接到电脑的热点,接入服务器

  1.  测试AT,返回OK,保证模块没有问题
  2. 打开电脑热点

     3.  AT+CWJAP="Lng","12345678"                          连接当前的热点

    4.  AT+CIPSTART="TCP","192.168.3.13",8080      与服务器建立TCP连接

    5.  AT+CIPMODE=1                                                传输模式为透传

    6.  AT+CIPSNED                                                     开启透传模式,向服务器发送数据

     

到此处8266已经连接上了网络助手,这里随便输入字符,测试结果如下:

  

到这里呢ESP8266模块已经和此上位机正常通信了,接下来将会搭载STM32,敬请期待...

【开源、应用】QT—TCP网络上位机的设计https://blog.csdn.net/qq_53734051/article/details/127034796?spm=1001.2014.3001.5501

有关STM32+ESP8266连接电脑Qt网络上位机——QT篇的更多相关文章

  1. ruby - 续集在添加关联时访问many_to_many连接表 - 2

    我正在使用Sequel构建一个愿望list系统。我有一个wishlists和itemstable和一个items_wishlists连接表(该名称是续集选择的名称)。items_wishlists表还有一个用于facebookid的额外列(因此我可以存储opengraph操作),这是一个NOTNULL列。我还有Wishlist和Item具有续集many_to_many关联的模型已建立。Wishlist类也有:selectmany_to_many关联的选项设置为select:[:items.*,:items_wishlists__facebook_action_id].有没有一种方法可以

  2. ruby - 无法在 60 秒内获得稳定的 Firefox 连接 (127.0.0.1 :7055) - 2

    我使用的是Firefox版本36.0.1和Selenium-Webdrivergem版本2.45.0。我能够创建Firefox实例,但无法使用脚本继续进行进一步的操作无法在60秒内获得稳定的Firefox连接(127.0.0.1:7055)错误。有人能帮帮我吗? 最佳答案 我遇到了同样的问题。降级到firefoxv33后一切正常。您可以找到旧版本here 关于ruby-无法在60秒内获得稳定的Firefox连接(127.0.0.1:7055),我们在StackOverflow上找到一个类

  3. 电脑0x0000001A蓝屏错误怎么U盘重装系统教学 - 2

      电脑0x0000001A蓝屏错误怎么U盘重装系统教学分享。有用户电脑开机之后遇到了系统蓝屏的情况。系统蓝屏问题很多时候都是系统bug,只有通过重装系统来进行解决。那么蓝屏问题如何通过U盘重装新系统来解决呢?来看看以下的详细操作方法教学吧。  准备工作:  1、U盘一个(尽量使用8G以上的U盘)。  2、一台正常联网可使用的电脑。  3、ghost或ISO系统镜像文件(Win10系统下载_Win10专业版_windows10正式版下载-系统之家)。  4、在本页面下载U盘启动盘制作工具:系统之家U盘启动工具。  U盘启动盘制作步骤:  注意:制作期间,U盘会被格式化,因此U盘中的重要文件请注

  4. Qt Designer的简单使用 - 2

    在前面两节的例子中,主界面窗口的尺寸和标签控件显示的矩形区域等,都是用C++代码编写的。窗口和控件的尺寸都是预估的,控件如果多起来,那就不好估计每个控件合适的位置和大小了。用C++代码编写图形界面的问题就是不直观,因此Qt项目开发了专门的可视化图形界面编辑器——QtDesigner(Qt设计师)。通过QtDesigner就可以很方便地创建图形界面文件*.ui,然后将ui文件应用到源代码里面,做到“所见即所得”,大大方便了图形界面的设计。本节就演示一下QtDesigner的简单使用,学习拖拽控件和设置控件属性,并将ui文件应用到Qt程序代码里。使用QtDesigner设计界面在开始菜单中找到「Q

  5. STM32读取串口传感器数据(颗粒物传感器,主动上传) - 2

    文章目录1.开发板选择*用到的资源2.串口通信(个人理解)3.代码分析(注释比较详细)1.主函数2.串口1配置3.串口2配置以及中断函数4.注意问题5.源码链接1.开发板选择我用的是STM32F103RCT6的板子,不过代码大概在F103系列的板子上都可以运行,我试过在野火103的霸道板上也可以,主要看一下串口对应的引脚一不一样就行了,不一样的就更改一下。*用到的资源keil5软件这里用到了两个串口资源,采集数据一个,串口通信一个,板子对应引脚如下:串口1,TX:PA9,RX:PA10串口2,TX:PA2,RX:PA32.串口通信(个人理解)我就从串口采集传感器数据这个过程说一下我自己的理解,

  6. ruby - 我的 Ruby IRC 机器人没有连接到 IRC 服务器。我究竟做错了什么? - 2

    require"socket"server="irc.rizon.net"port="6667"nick="RubyIRCBot"channel="#0x40"s=TCPSocket.open(server,port)s.print("USERTesting",0)s.print("NICK#{nick}",0)s.print("JOIN#{channel}",0)这个IRC机器人没有连接到IRC服务器,我做错了什么? 最佳答案 失败并显示此消息::irc.shakeababy.net461*USER:Notenoughparame

  7. ruby-on-rails - 连接字符串时如何在 <%=%> block 内输出 html_safe? - 2

    考虑一下:现在这些情况:#output:http://domain.com/?foo=1&bar=2#output:http://domain.com/?foo=1&bar=2#output:http://domain.com/?foo=1&bar=2#output:http://domain.com/?foo=1&bar=2我需要用其他字符串输出URL。我如何保证&符号不会被转义?由于我无法控制的原因,我无法发送&。求助!把我的头发拉到这里:\编辑:为了澄清,我实际上有一个像这样的数组:@images=[{:id=>"fooid",:url=>"http://

  8. ruby - Faye WebSocket,关闭处理程序被触发后重新连接到套接字 - 2

    我有一个super简单的脚本,它几乎包含了FayeWebSocketGitHub页面上用于处理关闭连接的内容:ws=Faye::WebSocket::Client.new(url,nil,:headers=>headers)ws.on:opendo|event|p[:open]#sendpingcommand#sendtestcommand#ws.send({command:'test'}.to_json)endws.on:messagedo|event|#hereistheentrypointfordatacomingfromtheserver.pJSON.parse(event.d

  9. ruby-on-rails - 什么会导致与 APNS 的连接间歇性断开连接? - 2

    我有一个ruby​​脚本可以打开与Apple推送服务器的连接并发送所有待处理的通知。我看不出任何原因,但当Apple断开我的脚本时,我遇到了管道损坏错误。我已经编写了我的脚本来适应这种情况,但我宁愿只是找出它发生的原因,这样我就可以在第一时间避免它。它不会始终根据特定通知断开连接。它不会以特定的字节传输大小断开连接。一切似乎都是零星的。您可以在单个连接上发送的数据传输或有效负载计数是否有某些限制?看到人们的解决方案始终保持一个连接打开,我认为这不是问题所在。我看到连接在3次通知后断开,我看到它在14次通知后断开。我从未见过它能超过14点。有没有人遇到过这种类型的问题?如何处理?

  10. ruby - 如何断开现有的 ruby​​ 续集与数据库的连接? - 2

    我的意思是之前建立的那个DB=Sequel.sqlite('my_blog.db')或DB=Sequel.connect('postgres://user:password@localhost/my_db')或DB=Sequel.postgres('my_db',:user=>'user',:password=>'password',:host=>'localhost')等等。Sequel::Database类没有名为“disconnect”的公共(public)实例方法,尽管它有一个“connect”。也许有人已经遇到过这个问题。我将不胜感激。 最佳答案

随机推荐