weixin_44485203 2022-07-12 10:05 采纳率: 0%
浏览 73

C#上位机软件再次连接失败

上位机软件使用C#进行编写。问题上位机第一次可以连接成功,但是在关掉后,第二次无法连接成功,但是在第一次关闭后,可以使用其他上位机软件使用该串口进行连接,并且在使用其他上位机软件进行关闭串口操作后,再次打开问题上位机软件,可以连接成功。请问,按照测试,串口应该已经被释放,其他上位机软件才能再次进行使用,但是问题上位机却无法二次进行连接,这属于什么问题?
代码如下:这种情况该如何解决?

namespace IonosphericScintillationMonitor.UI
{
public partial class ConnectNovatelReceiverStatusForm : Form
{
private string portName;
private int baudRate;

public ConnectNovatelReceiverStatusForm()
{
    InitializeComponent();
    this.FormBorderStyle = FormBorderStyle.FixedDialog;
    //this.ControlBox = false;//不显示最小、最大和关闭按钮   
    this.MinimizeBox = false;
    this.MaximizeBox = false;         
    this.StartPosition = FormStartPosition.CenterScreen;
    InitializeSerialPort();            
}

private void InitializeSerialPort()
{
    //注册表中与串口设置相关的名称/值对的名称
    const string PORTNAME_VALUE = "PortName";
    const string BAUDRATE_VALUE = "BaudRate";          

    string rootName = "HKEY_CURRENT_USER";
    string keyName = rootName + "\\" + "Software" + "\\"
         + "IonosphericScintillationMonitor" + "\\" + "ComSet";

    //读取注册表中串口的默认值
    try
    {
        this.portName = (string)Registry.GetValue(keyName, PORTNAME_VALUE, null);
        this.baudRate = Convert.ToInt32(Registry.GetValue(keyName, BAUDRATE_VALUE, null));                                
    }
    catch (SecurityException e)
    {
        BaseSupportTools.PrintExceptionMessage(e);
    }
    catch (IOException e)
    {
        BaseSupportTools.PrintExceptionMessage(e);
    }
    catch (ArgumentException e)
    {
        BaseSupportTools.PrintExceptionMessage(e);
    }            
}

public void CreateConnect()
{           
    SerialPort serialPort = new SerialPort(portName, 9600, Parity.None, 8, StopBits.One);

    int failConnectCount = 0;
    try
    {
        serialPort.Open();
        bool isConnect = false;                
        this.prgConnectStatus.Value = 20;
        this.prgConnectStatus.Refresh();//ProgressBar控件立即刷新显示
        this.lblConnectStatus.Text = "以9600bps正在尝试连接中。。。";
        this.lblConnectStatus.Refresh();//lable控件立即刷新显示
        //以9600bps的默认速率进行首次连接
        while (!isConnect)
        {
            isConnect = TryConnect(serialPort);
            //间隔1s后重连或进行下一步
            System.Threading.Thread.Sleep(1000);
            failConnectCount++;
            if (failConnectCount > 20)
            {
                if (MessageBox.Show("Novatel接收机连接失败", "警告", MessageBoxButtons.OK, MessageBoxIcon.Error) == DialogResult.OK)
                {
                    //彻底退出程序
                    System.Environment.Exit(0);
                }
            }
        }               
                  
        this.prgConnectStatus.Value = 40;
        this.prgConnectStatus.Refresh();//ProgressBar控件立即刷新显示
        this.lblConnectStatus.Text = "重置通信波特率为" + baudRate + "bps。。。";
        this.lblConnectStatus.Refresh();//lable控件立即刷新显示

        //重置通信速率为 baudRate bps
        TrySerialConfig(serialPort, baudRate);
        serialPort.Close();
        
        this.prgConnectStatus.Value = 60;
        this.prgConnectStatus.Refresh();//ProgressBar控件立即刷新显示
        this.lblConnectStatus.Text = "重置通信波特率为" + baudRate + "bps成功";
        this.lblConnectStatus.Refresh();//lable控件立即刷新显示
        System.Threading.Thread.Sleep(1500);
        
        this.prgConnectStatus.Value = 80;
        this.prgConnectStatus.Refresh();//ProgressBar控件立即刷新显示
        this.lblConnectStatus.Text = "以" + baudRate + "bps正在尝试重新连接中。。。";
        this.lblConnectStatus.Refresh();//lable控件立即刷新显示
        System.Threading.Thread.Sleep(1000);

        //以 baudRate bps的速率进行再次连接
        failConnectCount = 0;
        serialPort.BaudRate = baudRate;
        serialPort.Open();
        while (!isConnect)
        {
            isConnect = TryConnect(serialPort);
            //间隔1s后重连或进行下一步
            System.Threading.Thread.Sleep(1000);
            if (failConnectCount > 5)
            {
                if (MessageBox.Show("Novatel接收机连接失败", "警告", MessageBoxButtons.OK, MessageBoxIcon.Error) == DialogResult.OK)
                {
                    //彻底退出程序
                    System.Environment.Exit(0);
                }
            }
        }

        //开启GPS、北斗系统和关闭GLONASS系统
        serialPort.WriteLine("assignall  gps  auto");
        System.Threading.Thread.Sleep(1000);
        serialPort.WriteLine("assignall  beidou  auto");
        System.Threading.Thread.Sleep(1000);
        serialPort.WriteLine("assignall  glonass  idle");
        System.Threading.Thread.Sleep(1000);
        //发送指令
        serialPort.WriteLine("log bestposb ontime 1");
        System.Threading.Thread.Sleep(1000);
        serialPort.WriteLine("log bestvelb ontime 1");
        System.Threading.Thread.Sleep(1000);
        serialPort.WriteLine("log ionutcb ontime 1");
        System.Threading.Thread.Sleep(1000);
        serialPort.WriteLine("log psrdopb ontime 1");
        System.Threading.Thread.Sleep(1000);
        serialPort.WriteLine("log satvis2b ontime 60");
        System.Threading.Thread.Sleep(1000);
        serialPort.WriteLine("log rangecmpb ontime 0.2");
        System.Threading.Thread.Sleep(1000);

        this.prgConnectStatus.Value = 100;
        this.prgConnectStatus.Refresh();//ProgressBar控件立即刷新显示
        this.lblConnectStatus.Text = "Novatel接收机连接成功!";
        this.lblConnectStatus.Refresh();//lable控件立即刷新显示
        serialPort.Close();//关闭串口
        System.Threading.Thread.Sleep(1000);
        this.Close();//关闭串口

    }
    catch (System.IO.IOException e)
    {
        BaseSupportTools.PrintExceptionMessage(e);
        MessageBox.Show("当前串口已被占用", "警告", MessageBoxButtons.OK, MessageBoxIcon.Error);
        //彻底退出程序
        System.Environment.Exit(0);
    }
}

/// <summary>
/// 尝试以目前的串口设置连接Novatel接收机
/// </summary>
/// <param name="serialPort">串口实例</param>
/// <returns></returns>
private static bool TryConnect(SerialPort serialPort)
{
    serialPort.Write("log versionb once");//发送指令
    serialPort.Write("\r");
    serialPort.Write("\n");
    System.Threading.Thread.Sleep(1000);//延迟1s
    int bytesCount = serialPort.BytesToRead;
    int tempData = 0;
    bool isFindHeaderSync1 = false;
    bool isFindHeaderSync2 = false;
    bool isFindHeaderSync3 = false;
    bool isConnect = false;
    int headerLength = 0;
    int availableByteCount = 0;//有效字节计数   
    byte[] temp2Bytes = new byte[2];
    for (int ix = 0; ix < bytesCount; ix++)
    {
        tempData = serialPort.ReadByte();
        //寻找帧头
        if (!isFindHeaderSync1)
        {
            if (tempData == 0xAA)
            {
                isFindHeaderSync1 = true;
            }
        }
        else if ((isFindHeaderSync1) && (!isFindHeaderSync2))
        {
            if (tempData == 0x44)
            {
                isFindHeaderSync2 = true;
            }
        }
        else if ((isFindHeaderSync1) && (isFindHeaderSync2) && (!isFindHeaderSync3))
        {
            if (tempData == 0x12)
            {
                isFindHeaderSync3 = true;
                availableByteCount = 3;//帧头3个字节检测成功了
                continue;
            }
        }

        //判断帧头是否寻找成功
        if ((isFindHeaderSync1) && (isFindHeaderSync2) && (isFindHeaderSync3))
        {
            if (availableByteCount == 3)
            {
                headerLength = tempData;
                availableByteCount++;
            }
            else if (availableByteCount == 4)
            {
                temp2Bytes[0] = (byte)tempData;
                availableByteCount++;
            }
            else if (availableByteCount == 5)
            {
                temp2Bytes[1] = (byte)tempData;
                int messageId = BitConverter.ToInt16(temp2Bytes, 0);
                if (messageId == 37)//即VERSION
                {
                    isConnect = true;//连接成功                           
                }
                availableByteCount++;
            }

        }
    }
    return isConnect;
}

/// <summary>
/// 尝试重置Novatel接收机的波特率
/// </summary>
/// <param name="serialPort">串口实例</param>
/// <param name="baudRate">重置后的波特率</param>
/// <returns></returns>
private static bool TrySerialConfig(SerialPort serialPort, int baudRate)
{
    bool isSerialConfig = false;
    string command = "serialconfig com1 " + baudRate + " n 8 1 n on";
    serialPort.Write(command);//发送指令           
    serialPort.Write("\r");
    serialPort.Write("\n");
    System.Threading.Thread.Sleep(1000);//延迟1s
    bool isSendSuccess1 = false;
    bool isSendSuccess2 = false;
    bool isSendSuccess3 = false;
    int bytesCount = serialPort.BytesToRead;
    int tempData = 0;
    for (int ix = 0; ix < bytesCount; ix++)
    {
        tempData = serialPort.ReadByte();
        if (!isSendSuccess1)
        {
            //寻找'<'
            if (tempData == 0x3C)
            {
                isSendSuccess1 = true;
            }
        }
        else if ((isSendSuccess1) && (!isSendSuccess2))
        {
            //寻找'O'
            if (tempData == 0x4F)
            {
                isSendSuccess2 = true;
            }
        }
        else if ((isSendSuccess1) && (isSendSuccess2) && (!isSendSuccess3))
        {
            //寻找'K'
            if (tempData == 0x4B)
            {
                isSendSuccess3 = true;
            }
        }

        //判断“<OK”是否寻找成功
        if ((isSendSuccess1) && (isSendSuccess2) && (isSendSuccess3))
        {
            isSerialConfig = true;
        }
    }
    return isSerialConfig;
}

}
}

如果想要在本次连接成功关闭后,可以直接进行第二次连接并成功,应该如何进行代码修改?

  • 写回答

2条回答 默认 最新

  • 於黾 2022-07-12 10:12
    关注

    这代码让你写的稀碎
    主线程里各种发送接收也就罢了,怎么还频繁打开关闭串口
    给你个例子自己下载了看吧
    https://download.csdn.net/download/z65443344/8251513
    此外,你执行了Open,如果没有报错,那么串口就已经打开了
    你的问题大概率是出在tryconnect里面的逻辑有问题

    评论 编辑记录

报告相同问题?

问题事件

  • 创建了问题 7月12日

悬赏问题

  • ¥15 Altair EDEM中生成一个颗粒,并且各个方向没有初始速度
  • ¥15 系统2008r2 装机配置推荐一下
  • ¥500 服务器搭建cisco AnyConnect vpn
  • ¥15 用大厂网站防红自己网站
  • ¥15 悬赏Python-playwright部署在centos7上
  • ¥15 psoc creator软件有没有人能远程安装啊
  • ¥15 快速扫描算法求解Eikonal方程咨询
  • ¥20 我的是道格手机,重置后屏幕右上角出现红色字的未写入tee key 和未写入google key请问怎么去掉啊
  • ¥15 校内二手商品转让网站
  • ¥20 高德地图聚合图层MarkerCluster聚合多个点,但是ClusterData只有其中部分数据,原因应该是有经纬度重合的地方点,现在我想让ClusterData显示所有点的信息,如何实现?