Visual Basic中的Modbus RTU(vb.net) [英] Modbus rtu in visual basic (vb.net)

查看:367
本文介绍了Visual Basic中的Modbus RTU(vb.net)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好,
我正试图创建一个Modbus RTU主程序...我发现了很多代码,但是使用C#.当我尝试在Visual Basic(vb.net 2010)中进行转换时,它不起作用... PLC无法应答.
我认为serialport.write(< byte> ;,< int> ;,< int>)函数存在问题.有人可以帮助我吗?

遵循代码

 公共 功能 SendFc3( ByVal 地址 As  字节 ByVal 开始 As   UShort  ByVal 注册 As   UShort  ByRef  As  简短())

         Dim 标志 As  布尔值 = 错误
        ' 确保端口已打开:
        如果(Sp.IsOpen)然后

            ' 清除输入/输出缓冲区:
            Sp.DiscardOutBuffer()
            Sp.DiscardInBuffer()
            ' 功能3请求始终为8个字节:
             Dim 消息 As   Byte ()= 新建 字节( 7 ){}
            ' 功能3响应缓冲区:
             Dim 响应 As   Byte ()= 新建 字节((< 5  +  2  *寄存器)- 1 ){}
            ' 构建传出的Modbus消息
            BuildMessage(地址, CByte ( 3 ),开始,寄存器,消息)
            ' 将Modbus消息发送到串行端口:
            尝试

                sp.Write(message, 0 ,message.Length)
                ' 评估消息:
                如果(GetResponse(响应,sp,值))然后
                    标志= 正确
                结束 如果

            捕获错误 As 异常
                modbusStatus = "  + err.Message
                标志= 错误
            结束 尝试
        其他

            modbusStatus = " 
            标志= 错误
        结束 如果
        返回标志

    结束 功能 



 公共  Sub  BuildMessage( ByVal 地址 As  字节 ByVal 类型 As  字节 ByVal 开始 As   UShort  ByVal 注册 As   UShort  ByRef 消息字节())

       ' 接收CRC字节的数组:
        Dim  CRC  As   Byte ()= 新建 字节( 2 ){}

       message( 0 )= 字节 .Parse(地址)
       message( 1 )= 字节 .Parse(类型)
       message( 2 )= 字节.Parse(开始>>  3 )= 字节 .Parse(开始)
       message( 4 )= 字节.Parse(注册>>  5 )= 字节 .Parse(寄存器)

       GetCRC(消息,CRC)
       message(message.Length- 2 )= 字节 .Parse( 84 )'  CRC(0)
       message(message.Length- 1 )= 字节 .Parse( 10 )'  CRC(1)

   结束  



 公共 功能 GetResponse( ByRef 响应 As  字节(), ByRef  spModbus  As  SerialPort, ByRef  As  简短())

         Dim  i  As  整数 =  0 
        '  Thread.Sleep(300)
        同时(spModbus.BytesToRead<>  0 )
            response(i)= 字节 .Parse(spModbus.ReadByte())
            '  Thread.Sleep(200)
            我+ =  1 
            '  Application.DoEvents()
        结束 同时

        ' 验证消息
        如果(CheckResponse(response))然后

            '  Ritorno il valore dei registri richiesti 
            对于 i =  0  ((响应.Length- 5 )/ 2 )- 1 

                response(i)= response( 2  * i +  3 )
                响应(i)<< =  8 
                响应(i)+ =响应( 2  * i +  4 )
                值(i)=响应( 2  * i +  3 )
                values(i)<< =  8 
                值(i)+ =响应( 2  * i +  4 )

            下一步

            返回 真实

        其他

            返回 错误

        结束 如果

    结束 功能 




感谢

解决方案

C#和VB.NET之间的串行端口类没有问题.无论您选择哪种语言,它都运行完全相同的代码.

问题很可能是您的BuildMessage和GetResponse代码中的转换问题,或那些方法正在调用的问题,尽管我不知道它是什么,因为我不知道ModBus或您的PLC需要什么. >

鉴于您说有问题的功能是serialport.write(xxx),我知道您的Modbus PLC不能与Modbus TCP一起使用,因此您可以使用232或485 ......

您确定要与之通信的Modbus PLC已配置为使用232吗?

如果不是这样,您将需要在PC上使用232到485的适配器.

除此之外,最好是使用MODBUS嗅探器将其连接到您的网络,并查看发送/接收的包中发生了什么...

看看那些链接:
http://qmodbus.sourceforge.net/ [ ^ ]

http://www.aggsoft.com/serial-port-monitor/plugins.htm [ ^ ]

http://www.windmill.co.uk/serial.html [
PS:请记住,Modbus(几乎所有的现场总线都在其中)要求地址位置正确……请仔细检查.

我在使用Modbus时遇到的典型问题是:

1.错误的地址.
2.电阻放置错误.

祝你好运!


Hi all,
i''m tring to create a modbus rtu master program... i found a lot of code but in C#. when i try to convert it in visual basic (vb.net 2010) it doesn''t work... the PLC doesn''t answer.
i think that there is a problem with the serialport.write(<byte>, <int>, <int>) function. someone can help me?

follow the code

Public Function SendFc3(ByVal address As Byte, ByVal start As UShort, ByVal registers As UShort, ByRef values As Short())

        Dim flag As Boolean = False
        'Ensure port is open:
        If (Sp.IsOpen) Then

            'Clear in/out buffers:
            Sp.DiscardOutBuffer()
            Sp.DiscardInBuffer()
            'Function 3 request is always 8 bytes:
            Dim message As Byte() = New Byte(7) {}
            'Function 3 response buffer:
            Dim response As Byte() = New Byte((5 + 2 * registers) - 1) {}
            'Build outgoing modbus message
            BuildMessage(address, CByte(3), start, registers, message)
            'Send modbus message to Serial Port:
            Try

                sp.Write(message, 0, message.Length)
                'Evaluate message:
                If (GetResponse(response, sp, values)) Then
                    flag = True
                End If

            Catch err As Exception
                modbusStatus = "Error in read event: " + err.Message
                flag = False
            End Try
        Else

            modbusStatus = "Serial port not open"
            flag = False
        End If
        Return flag

    End Function



Public Sub BuildMessage(ByVal address As Byte, ByVal type As Byte, ByVal start As UShort, ByVal registers As UShort, ByRef message As Byte())

       'Array to receive CRC bytes:
       Dim CRC As Byte() = New Byte(2) {}

       message(0) = Byte.Parse(address)
       message(1) = Byte.Parse(type)
       message(2) = Byte.Parse(start >> 8)
       message(3) = Byte.Parse(start)
       message(4) = Byte.Parse(registers >> 8)
       message(5) = Byte.Parse(registers)

       GetCRC(message, CRC)
       message(message.Length - 2) = Byte.Parse(84) 'CRC(0)
       message(message.Length - 1) = Byte.Parse(10) 'CRC(1)

   End Sub



Public Function GetResponse(ByRef response As Byte(), ByRef spModbus As SerialPort, ByRef values As Short())

        Dim i As Integer = 0
        'Thread.Sleep(300)
        While (spModbus.BytesToRead <> 0)
            response(i) = Byte.Parse(spModbus.ReadByte())
            'Thread.Sleep(200)
            i += 1
            'Application.DoEvents()
        End While

        'Verifico il messaggio
        If (CheckResponse(response)) Then

            'Ritorno il valore dei registri richiesti
            For i = 0 To ((response.Length - 5) / 2) - 1

                response(i) = response(2 * i + 3)
                response(i) <<= 8
                response(i) += response(2 * i + 4)
                values(i) = response(2 * i + 3)
                values(i) <<= 8
                values(i) += response(2 * i + 4)

            Next

            Return True

        Else

            Return False

        End If

    End Function




Thanks

There''s nothing wrong with the serial port class between C# and VB.NET. It''s the exact same code you''re running no matter which language you chose.

The problem is most likely conversion problems in your BuildMessage and GetResponse code, or something those methods are calling, though I have no idea what it is because I don''t know what ModBus or your PLC requires.


Given the fact you say the problematic function is serialport.write(xxx), I understand your Modbus PLC is not working with Modbus TCP, so you can be under 232 or 485...

Are you sure that the Modbus PLC you are trying to communicate to is configured to use 232?

If not you will need an adaptor from 232 to 485 in your PC.

Apart of that, it would be a good idea to get a MODBUS sniffer to attach it to your network and see what is happening with the packages that are sent/received...

Take a look at those links:
http://qmodbus.sourceforge.net/[^]

http://www.aggsoft.com/serial-port-monitor/plugins.htm[^]

http://www.windmill.co.uk/serial.html[^]

I''ve searched "Modbus sniffer" in google to find them.

PS: keep in mind that Modbus (as almost all the fieldbusses out there) require that the addresses are well positioned... double check them.

The typical problems I encountered working with Modbus have been:

1. bad addresses.
2. resistors wrong placed.

Good luck!


这篇关于Visual Basic中的Modbus RTU(vb.net)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆