Author Topic: Using Modbus Register Bits in Controls  (Read 15029 times)

DougLyons

  • Jr. Member
  • **
  • Posts: 68
    • View Profile
Using Modbus Register Bits in Controls
« Reply #15 on: December 04, 2014, 08:14:07 AM »
andrew_pj,

Yes. I get this same error. You can enter "-1" and you will see "65535" displayed with all bits set.
This appears to be just the difference in whether the 16-bit number is considered signed or unsigned.
In version 3.85 and before both inputs and outputs were handled as signed integers.
Now with version 3.86 it appears that the outputs are handled as unsigned integers and the inputs as signed integers.
Visual Basic has always had problems because of the fact that it is not a strongly typed language.
In the past there was no way to make an integer be unsigned. It was defaulted to signed.
There was no unsigned 16-bit declaration character or way to DIM the variable to unsigned.
This may have improved lately, but I do not know. I am very new to VB.net with much experience in VB6.

As you can imagine you can use "-1" through "-32768" on the keypad to get the full range of numbers with the high bit set.
It would be great if we were allowed to decide whether to use signed or unsigned integers for inputs and outputs.
Maybe this would be a good feature request.

Archie

  • Administrator
  • Hero Member
  • *****
  • Posts: 5262
    • View Profile
    • AdvancedHMI
Re: Using Modbus Register Bits in Controls
« Reply #16 on: December 04, 2014, 02:12:01 PM »
Modify ModbusUtilities.vb, in the AdvancedHMIDrivers project, at line 22 to be this code:
Code: [Select]
        '* Loop through extracting each value AND avoid exceeding the number of bytes in the RawData
        While (ResultingValuesIndex < address.NumberOfElements) AndAlso (startByte + (Math.Ceiling(ResultingValuesIndex * (address.BitsPerElement / 8))) + BytesPerElement - 1) <= (rawData.Count)
            '* Bit or byte read?
            If address.BitsPerElement > 1 Then
                'Dim Result As Integer = 0
                Dim ValueDataBytes(CInt(address.BitsPerElement / 8) - 1) As Byte
                '* Ensure there is enought data to process
                If rawData.Count >= (startByte + ResultingValuesIndex * BytesPerElement + BytesPerElement) Then
                    For i = 0 To BytesPerElement - 1
                        ValueDataBytes(i) = rawData(startByte + ResultingValuesIndex * BytesPerElement + i)
                    Next

                    If address.Address.IndexOf("F4", 0, System.StringComparison.InvariantCultureIgnoreCase) >= 0 Then
                        '* F4 address designates it is a floating point type
                        ModbusUtilities.SwapBytes(ValueDataBytes, 0)
                        ModbusUtilities.SwapBytes(ValueDataBytes, 2)
                        ResultingValues(ResultingValuesIndex) = CStr(BitConverter.ToSingle(ValueDataBytes, 0))
                    ElseIf address.Address.IndexOf("L4", 0, System.StringComparison.InvariantCultureIgnoreCase) >= 0 Then
                        '* Convert bytes to a long integer
                        ModbusUtilities.SwapBytes(ValueDataBytes, 0)
                        ModbusUtilities.SwapBytes(ValueDataBytes, 2)
                        ResultingValues(ResultingValuesIndex) = CStr(BitConverter.ToInt32(ValueDataBytes, 0))
                    Else
                        ModbusUtilities.SwapBytes(ValueDataBytes, 0)
                        ResultingValues(ResultingValuesIndex) = CStr(BitConverter.ToInt16(ValueDataBytes, 0))
                    End If

                    '* Is a bit number designated?
                    If address.BitNumber >= 0 Then
                        ResultingValues(ResultingValuesIndex) = CStr(CBool((CInt(2 ^ address.BitNumber) And CInt(ResultingValues(ResultingValuesIndex))) > 0))
                    End If

                End If
            Else
                '* It is a bit read, so extract from the byte
                '* Byte 0 Bit 0 is always the first bit specified in the address
                Dim ByteNumber As Integer = CInt(Math.Floor((ResultingValuesIndex) / 8))
                Dim BitNumber As Integer = CInt(((ResultingValuesIndex) / 8 - ByteNumber) * 8)
                ResultingValues(ResultingValuesIndex) = CStr(((rawData(ByteNumber + startByte)) And CByte(2 ^ BitNumber)) > 0)
            End If

            ResultingValuesIndex += 1
        End While

DougLyons

  • Jr. Member
  • **
  • Posts: 68
    • View Profile
Using Modbus Register Bits in Controls
« Reply #17 on: December 04, 2014, 08:20:24 PM »
Archie,

This code does seem to fix the ranges.
I noticed that this is a bit shorter than the old code and leaves out some checks for "F4" and "L4".
Does that mean that you do not handle the Floats and Longs anymore?

Also since the multi-threading improvements I have been getting error messages in the IDE.
when I use the "X" in the upper right-hand window to shut down the running project I received errors such as these:

A first chance exception of type 'System.ArgumentOutOfRangeException' occurred in mscorlib.dll
A first chance exception of type 'System.InvalidOperationException' occurred in System.Windows.Forms.dll
An unhandled exception of type 'System.InvalidOperationException' occurred in System.Windows.Forms.dll

I am guessing that the main form is closing out before some of the threads have a chance to close.
I do not know what happens when the EXE file is run, but I suspect that it would be fine.

I just wanted to let you know about this in case you have a solution.
The result is that you wind up in a debugging mode and then you have to use the "Stop" button to shut the program down.

I think that the poll time is defaulting to a very minimal value because my mod_RSSim shows lots of polls.
Also, my hard disk drive light stays busy and I think that the system is buffering lots of poll data.

Thanks again so much.

Doug Lyons

Archie

  • Administrator
  • Hero Member
  • *****
  • Posts: 5262
    • View Profile
    • AdvancedHMI
Re: Using Modbus Register Bits in Controls
« Reply #18 on: December 04, 2014, 10:55:43 PM »
This code does seem to fix the ranges.
I noticed that this is a bit shorter than the old code and leaves out some checks for "F4" and "L4".
Does that mean that you do not handle the Floats and Longs anymore?
The longs and floats are still handled the same. The code was just rearranged and simplified.

Version 3.87 is now posted that rolls up all of these recent drivers modifications.

andrew_pj

  • Jr. Member
  • **
  • Posts: 77
    • View Profile
Re: Using Modbus Register Bits in Controls
« Reply #19 on: December 09, 2014, 01:11:44 AM »
Just download and tested in version 3.89, the attached error appears.
Test the same thing in version 3.87, it works fine.
Please advise, Thank you.


Best regards,
Andrew

Archie

  • Administrator
  • Hero Member
  • *****
  • Posts: 5262
    • View Profile
    • AdvancedHMI
Re: Using Modbus Register Bits in Controls
« Reply #20 on: December 09, 2014, 05:07:20 AM »
Change the line of code to this:

DisplayError("INVALID VALUE RETURNED")

Archie

  • Administrator
  • Hero Member
  • *****
  • Posts: 5262
    • View Profile
    • AdvancedHMI
Re: Using Modbus Register Bits in Controls
« Reply #21 on: December 09, 2014, 08:58:11 PM »
Just download and tested in version 3.89, the attached error appears.
Test the same thing in version 3.87, it works fine.
A version 3.90 has been posted that should catch and handle this error properly.

andrew_pj

  • Jr. Member
  • **
  • Posts: 77
    • View Profile
Re: Using Modbus Register Bits in Controls
« Reply #22 on: December 10, 2014, 05:14:46 AM »
Thanks Archie, fixed the problem.
A minor issue here, everytime starts the program, there is error message occurs on all objects in the form:
"Com Error - 999. No values return"

This error holds about 5 seconds, then disappear and no longer appears.
But it comes everytime the program starts.
The MOD_RSsim software is running though.


Best regards,
Andrew

Archie

  • Administrator
  • Hero Member
  • *****
  • Posts: 5262
    • View Profile
    • AdvancedHMI
Re: Using Modbus Register Bits in Controls
« Reply #23 on: December 10, 2014, 08:00:39 AM »
A minor issue here, everytime starts the program, there is error message occurs on all objects in the form:
"Com Error - 999. No values return"

This error holds about 5 seconds, then disappear and no longer appears.
But it comes everytime the program starts.
The MOD_RSsim software is running though.
I think this is the same problem here:

http://advancedhmi.com/forum/index.php?topic=527.0

Try that code change and let me know if it resolves it.

andrew_pj

  • Jr. Member
  • **
  • Posts: 77
    • View Profile
Re: Using Modbus Register Bits in Controls
« Reply #24 on: December 10, 2014, 08:44:27 PM »
Unfortunately the error still appears.
Trying to debug and identifying the location from the Call Stack, in SubscriptionHandler.vb Line 134.
It seems the IF condition doesn't meet so it will directly point to ELSE which is assigning e.ErrorId = -999
It should be correct that e.Values is Nothing and e.Values.Count is 0 when program just started.
So, perhaps need some additional handler here.


Best regards,
Andrew

Archie

  • Administrator
  • Hero Member
  • *****
  • Posts: 5262
    • View Profile
    • AdvancedHMI
Re: Using Modbus Register Bits in Controls
« Reply #25 on: December 10, 2014, 08:46:25 PM »
I'll get an updated posted in a few hours that may fix this

andrew_pj

  • Jr. Member
  • **
  • Posts: 77
    • View Profile
Re: Using Modbus Register Bits in Controls
« Reply #26 on: December 11, 2014, 10:24:18 PM »
Archie, this problem still exists in version 3.91 and 3.92
Always during program starts, this error appears.


Best regards,
Andrew

MrPike

  • Sr. Member
  • ****
  • Posts: 297
    • View Profile
Re: Using Modbus Register Bits in Controls
« Reply #27 on: December 12, 2014, 07:26:06 AM »
Seems you're having the same issues as I am. Don't know if this helps but v3.87 does not show this error. There are other issues with 3.87 (3.92 has the same issues)but it seems to the most stable version so far.

Archie

  • Administrator
  • Hero Member
  • *****
  • Posts: 5262
    • View Profile
    • AdvancedHMI
Re: Using Modbus Register Bits in Controls
« Reply #28 on: December 12, 2014, 09:11:51 AM »
Version 3.93 is now posted. Sorry for all the revisions this week. Implementing bit level access and read optimizing at the same time really opened a can of worms. But I do appreciate the testing and feedback from everyone.

andrew_pj

  • Jr. Member
  • **
  • Posts: 77
    • View Profile
Re: Using Modbus Register Bits in Controls
« Reply #29 on: December 14, 2014, 11:11:58 PM »
Tested version 3.93, result is OK for BasicIndicator with address bit (e.g 40001.0, 40001.1, 40001.2, ...)
However, address 40001, 40002, 40003, etc for DigitalPanelMeter still indicates "Com Error -999" in the beginning.
I try tested with other indicators: Tank, Gauge. Result is same.


Best regards,
Andrew