Author Topic: Writing value with modbusrtu function code 16  (Read 2380 times)

Martinus

  • Newbie
  • *
  • Posts: 27
    • View Profile
Writing value with modbusrtu function code 16
« on: November 06, 2014, 05:33:25 AM »
Hello,

I'm hoping that some one can help me a bit on the way

When i'm retreiving a value from a register i'm using this code:

Dim ValueM As String
        ValueM = ModbusRTUCom1.Read("l41557", 1)(0)
        BasicLabel1.Text = ValueM

Now i also want to be able to write to this same register.

I tried the folowing code but this won't work

ModbusRTUCom1.Write("L161557", "100")

Can some one please explain what i'm doing wrong

greets

Martinus

Archie

  • Administrator
  • Hero Member
  • *****
  • Posts: 5269
    • View Profile
    • AdvancedHMI
Re: Writing value with modbusrtu function code 16
« Reply #1 on: November 06, 2014, 05:48:40 AM »
You use the same address to write with as you do the read. Modbus address is confusing because it is a standard that isn't really standard. Maybe this code will help, it is the address parser:

Code: [Select]
                    Select Case CInt(AddressFirstDigit)
                        Case 0 : m_ReadFunctionCode = 1
                            WriteSingleFunctionCode = 5
                            WriteMultiFunctionCode = 15
                            m_BitsPerElement = 1
                        Case 1 : m_ReadFunctionCode = 2
                            WriteMultiFunctionCode = 0 '* Invalid
                            m_BitsPerElement = 1
                        Case 3 : m_ReadFunctionCode = 4
                            WriteMultiFunctionCode = 0
                            m_Element = CInt(Address.Substring(1)) - 1
                            m_BitsPerElement = 16
                        Case 4 : m_ReadFunctionCode = 3
                            WriteSingleFunctionCode = 6
                            WriteMultiFunctionCode = 16
                            m_Element = CInt(Address.Substring(1)) - 1
                            m_BitsPerElement = 16

Martinus

  • Newbie
  • *
  • Posts: 27
    • View Profile
Re: Writing value with modbusrtu function code 16
« Reply #2 on: November 08, 2014, 03:15:25 PM »
Hi archie,

The given code helped me a bit further, i'm able to read and write values to the drive.
Only 1 piece won't give....

I need to write different bits in different stages of the drive.
The parameter  is 6914:
Code: [Select]
DCOMcontrol
-
-
Drivecom control word (165)
For bit coding, see Chapter on operation,
operating states
Bit0: Switch On
Bit1: Enable Voltage
Bit2: Quick Stop
Bit3: Enable Operation
Bit4..6: op. mode specific
Bit7: Fault Reset
Bit8: Halt
Bit9..15: reserved (must be 0)
-
-
0
-
UINT16
UINT16
R/W
-
-
CANopen 6040:0h
Modbus 6914

Normaly i would write a value of "0 15" which is in bitcode "0000 1111"

I tried this with a modbus.write action but it keeps writing the wrong value
On the bus monitor i can see  this value:
01 10 1B 02 00 02 04 00 00 41 70 FD 32
while it should be:           
01 10 1B 02 00 02 04 00 00 00 0F 8C 82 

Where am i making a thinking error

Greets

Martinus

Archie

  • Administrator
  • Hero Member
  • *****
  • Posts: 5269
    • View Profile
    • AdvancedHMI
Re: Writing value with modbusrtu function code 16
« Reply #3 on: November 08, 2014, 03:58:38 PM »
Are you preceding the address with a "F" or "L"? If you are using an "F" it will convert it to the floating point representation. This could potentially be a bug where the code is converting the long into a float unintentionally. I will look into this a little more later on today.

Martinus

  • Newbie
  • *
  • Posts: 27
    • View Profile
Re: Writing value with modbusrtu function code 16
« Reply #4 on: November 08, 2014, 04:13:37 PM »
Hi Archie,

Thanks for your answer.... i tried both... with a L and F in front.

Both give the same outcome 

Martinus

Archie

  • Administrator
  • Hero Member
  • *****
  • Posts: 5269
    • View Profile
    • AdvancedHMI
Re: Writing value with modbusrtu function code 16
« Reply #5 on: November 08, 2014, 04:50:36 PM »
Try going to line 633 in ModbusRTUCom.vb and change the code to this:
Code: [Select]
            ElseIf address.BitsPerElement = 32 Then
                '* Floating point or Long
                Dim x(3) As Byte
                For i As Integer = 0 To dataToWrite.Length - 1
                    If address.Address.Trim.ToUpper(System.Globalization.CultureInfo.CurrentCulture).Substring(0, 2) = "F4" Then
                        '* Floating point
                        x = BitConverter.GetBytes(CSng(dataToWrite(i)))
                    Else
                        '* Long (4 bytes)
                        x = BitConverter.GetBytes(CInt(dataToWrite(i)))
                    End If
                    dataPacket.Add(x(1))
                    dataPacket.Add(x(0))
                    dataPacket.Add(x(3))
                    dataPacket.Add(x(2))
                Next

Martinus

  • Newbie
  • *
  • Posts: 27
    • View Profile
Re: Writing value with modbusrtu function code 16
« Reply #6 on: November 09, 2014, 05:35:38 AM »
Hi Archie,

Thanks for the reply :-)

Made a small change to your code to get it to work
Code: [Select]
dataPacket.Add(x(3))
                    dataPacket.Add(x(2))
                    dataPacket.Add(x(1))
                    dataPacket.Add(x(0))

Now it works

Thanks

Martinus