最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

modbus rtu通訊發(fā)送數(shù)據(jù)優(yōu)化方式

 更新時間:2025年07月23日 14:36:09   作者:老農(nóng)民編程  
使用NModbus4庫發(fā)送數(shù)據(jù)時出現(xiàn)IO操作中止,可能因串口參數(shù)不一致、RS485收發(fā)切換未正確配置或超時設(shè)置不當(dāng)導(dǎo)致,建議檢查通信參數(shù)一致性、添加收發(fā)控制代碼并適當(dāng)調(diào)整超時時間以解決沖突

前言

最近,編程遇到一個情況,使用NModbus4庫實現(xiàn)通訊并發(fā)送數(shù)據(jù)給別一個設(shè)備,報IO操作已中止。

具體情況:使用Modbus Poll發(fā)送,在另一個設(shè)備的Modbus Poll可以接收到。使用NModbus4庫的通訊程序發(fā)送,在同一個設(shè)備上能接收,在不同的設(shè)備上的Modbus Poll不可以接收到。

一、IO操作中止可能原因分析

IO操作已中止,可能原因有如下幾點:

1.物理連接問題(傳輸線問題)

  • 因為使用調(diào)試工具能夠成功連接并發(fā)送數(shù)據(jù),排除其原因。

2.串口配置不一致

(兩臺電腦的串口參數(shù)(波特率、數(shù)據(jù)位、停止位、校驗位)必須完全一致。)

  • 檢查兩臺電腦串口參數(shù)是否一致。

3.收發(fā)方向控制(RS485特有)

  • 1)問題根源:

RS485是半雙工,需通過RTS或DE/RE引腳控制收發(fā)切換。若未正確切換,會導(dǎo)致沖突或數(shù)據(jù)丟失。

  • 2)解決方案:
// 啟用RTS控制(部分USB轉(zhuǎn)485芯片需要)
serialPort.RtsEnable = true;
// 或手動控制(根據(jù)轉(zhuǎn)換器文檔)
serialPort.Handshake = Handshake.RequestToSend;

添加上述代碼的其中一條。

4.超時或數(shù)據(jù)沖突

1)調(diào)整超時時間(避免無限等待):

serialPort.ReadTimeout = 1000; // 毫秒(1秒超時)
serialPort.WriteTimeout = 1000;

目的:確保兩臺設(shè)備不會同時發(fā)送數(shù)據(jù)(RS485同一時刻只能一個發(fā)送方)。

2)單獨設(shè)置Modbus超時

master = ModbusSerialMaster.CreateRtu(serialPort);
master.Transport.ReadTimeout = 1000; // 單獨設(shè)置 Modbus 超時 1秒

二、具體實現(xiàn)

1.使用NModbus4庫實現(xiàn)串口連接(使用NModbus2.1.0版本)

使用NModbus4庫,創(chuàng)建RS485通訊類,代碼如下:

using Modbus.Device;
using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TestConsole.Serivces
{
    class RS485Service
    {
        //從站地址
        byte slaveAddress = 1;

        public IModbusMaster master;
        public SerialPort serialPort = null;

        public RS485Service()
        {

        }

        public void Connect()
        {
            if (serialPort == null)
            {
                try
                {
                    //Serial port
                    string portName = "COM6";
                    int baudRate = 9600;
                    Parity parity = Parity.None;
                    int dataBits = 8;
                    StopBits stopBits = StopBits.One;
                    serialPort = new SerialPort(portName, baudRate, parity, dataBits, stopBits);
                    //serialPort.DataReceived += SerialPort_DataReceived;

                    serialPort.ReadTimeout = 1000; // 1秒超時
                    serialPort.WriteTimeout = 1000;
                    // 啟用RTS控制(部分USB轉(zhuǎn)485芯片需要)
                    serialPort.RtsEnable = true;

                    serialPort.Open();

                    if (serialPort.IsOpen)
                    {
                        master = ModbusSerialMaster.CreateRtu(serialPort);
                        master.Transport.ReadTimeout = 1000; // 單獨設(shè)置 Modbus 超時

                        Console.WriteLine("串口通訊連接成功!");
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine("串口通訊未連接!" + ex.Message);
                }
            }
        }

        #region 地址寫值

        //寫單個線圈(功能碼 0x05)
        //如果需要控制單個 IO 點(例如一個繼電器),可以使用 WriteSingleCoil 方法
        public void WriteCoil(ushort coilAddress, bool value)
        {
            master.WriteSingleCoil(slaveAddress, coilAddress, value);
        }

        //寫多個線圈(功能碼 0x0F)
        //如果需要同時控制多個 IO 點,可以使用 WriteMultipleCoils 方法
        public void WriteMultCoils(ushort startAddress, bool[] values)
        {
            master.WriteMultipleCoils(slaveAddress, startAddress, values);
        }

        //寫單個保持寄存器(功能碼 0x06)
        //如果需要寫入單個寄存器(例如一個數(shù)字量輸出),可以使用 WriteSingleRegister 方法
        public void WriteRegister(ushort registerAddress, ushort value)
        {
            master.WriteSingleRegister(slaveAddress, registerAddress, value);
        }

        //寫多個保持寄存器(功能碼 0x10)
        //如果需要寫入多個寄存器,可以使用 WriteMultipleRegisters 方法
        public void WriteMultRegisters(ushort startAddress, ushort[] values)
        {
            master.WriteMultipleRegisters(slaveAddress, startAddress, values);
        }

        #endregion
    }
}

2.控制臺Main函數(shù)實現(xiàn)

在Main函數(shù)中實現(xiàn)通訊并發(fā)送數(shù)據(jù),代碼如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using TestConsole.Serivces;

namespace TestConsole
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                RS485Service rs485Trans = new RS485Service();
                rs485Trans.Connect();

                ushort[] tempList = {1,2,3,4};
                // 寫入操作
                rs485Trans.WriteMultRegisters(0, tempList);
                Console.WriteLine("寫入成功");
            }
            catch (Exception ex)
            {
                Console.WriteLine("發(fā)生錯誤" + ex.Message);
            }
    
            Console.ReadLine();
        }
    }
}

總結(jié)

IO操作已中止問題,大概率就是IO超時,如上述方法數(shù)據(jù)傳輸沒有完全過來,可以調(diào)整上述超時時間(調(diào)大一點)。

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • C# char類型字符轉(zhuǎn)換大小寫的實現(xiàn)代碼

    C# char類型字符轉(zhuǎn)換大小寫的實現(xiàn)代碼

    以下是對C#中char類型字符轉(zhuǎn)換大小寫的示例代碼進(jìn)行了介紹,需要的朋友可以過來參考下哦
    2013-07-07
  • 使用VS2010 C#開發(fā)ActiveX控件(上)

    使用VS2010 C#開發(fā)ActiveX控件(上)

    最近做讀卡器的B/S應(yīng)用程序開發(fā),由于讀卡器廠商提供的手冊都是C/S版本的,而且只有一個原始的Dll包,并沒有web版的,那么就只好自己動手,豐衣足食了
    2011-05-05
  • C#程序集的主版本號和次版本號的實現(xiàn)

    C#程序集的主版本號和次版本號的實現(xiàn)

    C# 程序集的版本號和次版本號是程序集的一部分,用于標(biāo)識程序集的不同版,本本文主要介紹了C#程序集的主版本號和次版本號的實現(xiàn),具有一定的參考價值,感興趣的可以了解一下
    2024-04-04
  • C#路徑,文件,目錄及IO常見操作匯總

    C#路徑,文件,目錄及IO常見操作匯總

    這篇文章主要介紹了C#路徑,文件,目錄及IO常見操作,較為詳細(xì)的分析并匯總了C#關(guān)于路徑,文件,目錄及IO常見操作,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-09-09
  • C#生成code128條形碼的方法

    C#生成code128條形碼的方法

    這篇文章主要介紹了C#生成code128條形碼的方法,是C#程序設(shè)計中一個很實用的技巧,需要的朋友可以參考下
    2014-08-08
  • C#?RichTextBox制作文本編輯器

    C#?RichTextBox制作文本編輯器

    這篇文章主要為大家詳細(xì)介紹了C#?RichTextBox制作文本編輯器的方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-04-04
  • C#如何使用XmlDocument訪問XML文件

    C#如何使用XmlDocument訪問XML文件

    本文介紹了XML文件的特點、用途、格式、示例、解析和處理方式,以及在C#中使用XmlDocument類進(jìn)行增刪改查操作的方法,XML文件是一種靈活的數(shù)據(jù)描述和存儲方式,適用于各種應(yīng)用場景,在C#中,通過XmlDocument類可以方便地對XML文件進(jìn)行操作
    2024-12-12
  • Winform在DataGridView中顯示圖片

    Winform在DataGridView中顯示圖片

    本文主要介紹在DataGridView如何顯示圖片,簡單實用,需要的朋友可以參考下。
    2016-05-05
  • C#使用反射(Reflect)獲取dll文件中的類型并調(diào)用方法

    C#使用反射(Reflect)獲取dll文件中的類型并調(diào)用方法

    這篇文章主要為大家詳細(xì)介紹了C#使用反射(Reflect)獲取dll文件中的類型并調(diào)用方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-10-10
  • ZooKeeper 實現(xiàn)分布式鎖的方法示例

    ZooKeeper 實現(xiàn)分布式鎖的方法示例

    這篇文章主要介紹了ZooKeeper 實現(xiàn)分布式鎖的方法示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-06-06

最新評論

莎车县| 原平市| 长乐市| 大姚县| 漠河县| 平罗县| 封开县| 昌平区| 南郑县| 平阴县| 平山县| 石台县| 岫岩| 西昌市| 塔河县| 城固县| 衡水市| 和平县| 洛川县| 建阳市| 南丰县| 丘北县| 静海县| 白山市| 闽侯县| 晋江市| 青岛市| 平度市| 嵊泗县| 新巴尔虎左旗| 凤冈县| 石河子市| 盐山县| 霍城县| 文成县| 长治县| 盐津县| 兴国县| 印江| 彩票| 玉溪市|