AdvancedHMI Software

General Category => Support Questions => Topic started by: gfoster@sdsma.com on June 04, 2019, 04:56:27 PM

Title: Ethernet.Write error when writing large numbers to a DINT
Post by: gfoster@sdsma.com on June 04, 2019, 04:56:27 PM
Cannot find anything that addresses this problem.

Using CompactLogix PLC ...
Application requires writing 12 ASCII characters into a DINT array. (4 characters per DINT) Why ask why?

When HMI (VB / AdvancedHMI) writes a number > 10,000,000 to PLC, then 1 or 2 right most digits are incorrect. and sometimes, left digits change in what appears to be a round-up. I have not discovered any pattern it goes through as the number becomes larger. Tho, If the right 2 digits of the incoming number are '00' then there is no error.

FYI: I discovered the 10,000,000 limit by repetitive testing.

This error does not happen when writing from PanelView.

Any clues?

At this point, I'll code a work around in the PLC. I sure would like to know why or whats happening with the AdvHMI PLC driver.

Thank you
GF
Title: Re: Ethernet.Write error when writing large numbers to a DINT
Post by: Archie on June 04, 2019, 05:00:57 PM
What VB code are you using the change the 12 characters to the array of integers?
Title: Re: Ethernet.Write error when writing large numbers to a DINT
Post by: Noe on June 04, 2019, 06:46:11 PM
Cannot find anything that addresses this problem.

Using CompactLogix PLC ...
Application requires writing 12 ASCII characters into a DINT array. (4 characters per DINT) Why ask why?

When HMI (VB / AdvancedHMI) writes a number > 10,000,000 to PLC, then 1 or 2 right most digits are incorrect. and sometimes, left digits change in what appears to be a round-up. I have not discovered any pattern it goes through as the number becomes larger. Tho, If the right 2 digits of the incoming number are '00' then there is no error.

FYI: I discovered the 10,000,000 limit by repetitive testing.

This error does not happen when writing from PanelView.

Any clues?

At this point, I'll code a work around in the PLC. I sure would like to know why or whats happening with the AdvHMI PLC driver.

Thank you
GF

Maybe if you write those ASCII into a string in PLC, then convert the string into DINT. I know is not the best solution, but it should solve the rounding problem if you are in a hurry while Archie can take a look at the issue, when he has some time to.
Title: Re: Ethernet.Write error when writing large numbers to a DINT
Post by: Archie on June 05, 2019, 05:30:37 PM
I tried this by writing a 10,000,000  then 12,000,000 and finally 15,000,000

All 3 numbers worked as expected.

What version of AdvancedHMI are you using?
Title: Re: Ethernet.Write error when writing large numbers to a DINT
Post by: gfoster@sdsma.com on June 13, 2019, 02:22:13 PM
in debug mode, I can confirm that the number in the ethernet.write statement uses the desired number.

Fr'instance
825373492 goes our via ethernet.write. 825373500 shows up in PLC.
889192448 goes out.889192400 shows up.

There no PLC logic in my test setup. Just tag table.

Yeah. I'm gonna do a workaround for time being. I am concerned that the problem may show up elsewhere, but not so obviously.

I noticed that large numbers with trailing zeroes (decimal format) do not exhibit the problem. and not all large numbers result in the problem. it seems to want to 'round off' decimal numbers to the nearest 100.

thank you
GF
Title: Re: Ethernet.Write error when writing large numbers to a DINT
Post by: gfoster@sdsma.com on June 13, 2019, 02:25:34 PM
Here's the code to generate ASCII stuffed integers:

    Public Sub Convert_KeySeries()
        'PanelView wants a DINT array
        Dim K_Series(12) As Integer

        'initialize values = 0
        For i = 0 To Key_Series.Length
            K_Series(i) = 0
        Next

        ' pack Key Series digits into DINT as ASCII characters
        For i = 0 To Key_Series.Length - 1
            K_Series(i) = Asc(Key_Series.Substring(i, 1))
            K_Series(i) = K_Series(i) << ((3 - i Mod 4) * 8)
        Next

        Print_Code(1) = K_Series(0) Or K_Series(1) Or K_Series(2) Or K_Series(3)
        Print_Code(2) = K_Series(4) Or K_Series(5) Or K_Series(6) Or K_Series(7)
        Print_Code(3) = K_Series(8) Or K_Series(9) Or K_Series(10) Or K_Series(11)

        ConvertPrintCodeToHex()
    End Sub

    Public Sub ConvertPrintCodeToHex()
        Try
            Dim hi As String
            Dim lo As String

            hi = Hex(Print_Code(1) Mod 2 ^ 16)
            lo = Hex(Print_Code(1) / (2 ^ 16))
            Print_Code_Hex(1) = hi & lo

            hi = Hex(Print_Code(2) Mod 2 ^ 16)
            lo = Hex(Print_Code(2) / (2 ^ 16))
            Print_Code_Hex(2) = hi & lo

            hi = Hex(Print_Code(3) Mod 2 ^ 16)
            lo = Hex(Print_Code(3) / (2 ^ 16))
            Print_Code_Hex(3) = hi & lo

        Catch ex As Exception
            Print_Code_Hex(1) = "FFFFFFFF"
            Print_Code_Hex(2) = "FFFFFFFF"
            Print_Code_Hex(3) = "FFFFFFFF"

            'MsgBox("Convert Print Code to hex: " & vbCrLf & ex.Message)
        End Try
    End Sub
Title: Re: Ethernet.Write error when writing large numbers to a DINT
Post by: Archie on June 14, 2019, 09:51:53 AM
I tried this with the value you posted, but not able to reproduce the problem. This is the setup I am using:

- AdvancedHMI V3.99y Beta 32
- CompactLogix L16  V24
- EthernetIPforCLXCom1.Write("DINTTag", "825373492")
Title: Re: Ethernet.Write error when writing large numbers to a DINT
Post by: Archie on June 14, 2019, 10:24:52 AM
Just an FYI, there is a function that is part of AdvancedHMI that can do the leg work of Convert_KeySeries

This should produce the same results:
Code: [Select]
        Dim i() As Integer = Drivers.Common.CalculationsAndConversions.StringToWords(KeySeries)

        '* Combine 16bit integers into 32 bit
        Print_Code(1) = (i(0) << 16) + i(1)
        Print_Code(2) = (i(2) << 16) + i(3)
        Print_Code(3) = (i(4) << 16) + i(5)
Title: Re: Ethernet.Write error when writing large numbers to a DINT
Post by: Archie on June 14, 2019, 12:39:51 PM
In your conversion to hex, are you intentionally reversing the first 2 characters with the last 2?

"ABCD" = "43444142"

In non-reversed order it should be:
"ABCD"="41424344"

Without reversing you could use:

Print_Code_Hex(1)= Print_Code(1).ToString("X")
Title: Re: Ethernet.Write error when writing large numbers to a DINT
Post by: gfoster@sdsma.com on June 26, 2019, 10:00:49 AM
Archie,
The problem is not in the conversion.

Here's how I'm testing:
All PLC comms live in a list: PLC_Pair.Key, PLC_Pair.Value

I set a breakpoint at the line with: Ethernet.Write(PLC_Pair.Key, var)
.Key and var each contain their correct value.

I let the code continue. It breaks at the same place for the next PLC_Pair.
The incorrect value appears at the PLC.

There's no logic in between the the send and the PLC. There's no logic in the PLC> Just data tables.

Help Mr. Wizard.

regards
GF
Title: Re: Ethernet.Write error when writing large numbers to a DINT
Post by: Archie on June 26, 2019, 10:05:38 AM
The problem is not in the conversion.

Here's how I'm testing:
All PLC comms live in a list: PLC_Pair.Key, PLC_Pair.Value

I set a breakpoint at the line with: Ethernet.Write(PLC_Pair.Key, var)
.Key and var each contain their correct value.

I let the code continue. It breaks at the same place for the next PLC_Pair.
The incorrect value appears at the PLC.
Try this same test I did 2 post above with:

EthernetIPforCLXCom1.Write("DINTTag", "825373492")

Replacing DintTag with a tag in your PLC. When I run that code then look in RSLogix, it shows the correct value.
Title: Re: Ethernet.Write error when writing large numbers to a DINT
Post by: gfoster@sdsma.com on June 26, 2019, 10:13:09 AM
Archie,
I just this minute discovered, once again, that I R A Idiot.

I'm sending a variety of data to the PLC in the same loop.
For each item: I declare the var type as object then load var with the converted value (Integer, Decimal).
I failed to include these new tags in the test to determine how to convert the value to var. They default to type Decimal. var holds the correct value. But when treated as decimal by the downstream logic it is converted to decimal.
Once I let the code now these values were integer, all is well.


:-P
regards
GF