Skip to content

RSLogix 5000 Hex String To Decimal and Back

//HEX STRING TO DECIMAL STRUCTURED TEXT ROUTINE
 sbr(_HSTOD_Hex);

size(_HSTOD_Convert,0,_HSTOD_Length);
if _HSTOD_Hex.LEN <_HSTOD_Length then
 _HSTOD_Length:=_HSTOD_Hex.LEN;
end_if;
_HSTOD_Length:=_HSTOD_Length-1;

for _HSTOD_Index:=0 to _HSTOD_Length do
 case _HSTOD_Hex.Data[_HSTOD_Index] of
 48: _HSTOD_Convert[_HSTOD_Index]:=0;
 49: _HSTOD_Convert[_HSTOD_Index]:=1;
 50: _HSTOD_Convert[_HSTOD_Index]:=2;
 51: _HSTOD_Convert[_HSTOD_Index]:=3;
 52: _HSTOD_Convert[_HSTOD_Index]:=4;
 53: _HSTOD_Convert[_HSTOD_Index]:=5;
 54: _HSTOD_Convert[_HSTOD_Index]:=6;
 55: _HSTOD_Convert[_HSTOD_Index]:=7;
 56: _HSTOD_Convert[_HSTOD_Index]:=8;
 57: _HSTOD_Convert[_HSTOD_Index]:=9;
 65: _HSTOD_Convert[_HSTOD_Index]:=10;
 66: _HSTOD_Convert[_HSTOD_Index]:=11;
 67: _HSTOD_Convert[_HSTOD_Index]:=12;
 68: _HSTOD_Convert[_HSTOD_Index]:=13;
 69: _HSTOD_Convert[_HSTOD_Index]:=14;
 70: _HSTOD_Convert[_HSTOD_Index]:=15;
 end_case;
end_for;

_HSTOD_Temp:=0;
for _HSTOD_Index:=0 to _HSTOD_Length do
 _HSTOD_RevIndex:=_HSTOD_Length - _HSTOD_Index;
 _HSTOD_Temp:=_HSTOD_Temp + _HSTOD_Convert[_HSTOD_Index]*16**_HSTOD_RevIndex;
end_for;

_HSTOD_Dec:=_HSTOD_Temp;
ret(_HSTOD_Dec);




//DECIMAL TO HEX STRING STRUCTURED TEXT ROUTINE
 sbr(_DTOHS_Dec);

dtos(_DTOHS_Dec,Temp_String);
_DTOHS_Length:=Temp_String.len - 1;

for _DTOHS_Index:=0 to _DTOHS_Length do
 if _DTOHS_Index=0 then
 _DTOHS_Remainder := _DTOHS_Dec mod 16;
 _DTOHS_Quotient := _DTOHS_Dec / 16;
 else
 _DTOHS_Remainder := _DTOHS_Quotient mod 16;
 _DTOHS_Quotient := _DTOHS_Quotient / 16;
 end_if;

 case trunc(_DTOHS_Remainder) of
 0:_DTOHS_Convert[_DTOHS_Index]:=48;
 1:_DTOHS_Convert[_DTOHS_Index]:=49;
 2:_DTOHS_Convert[_DTOHS_Index]:=50;
 3:_DTOHS_Convert[_DTOHS_Index]:=51;
 4:_DTOHS_Convert[_DTOHS_Index]:=52;
 5:_DTOHS_Convert[_DTOHS_Index]:=53;
 6:_DTOHS_Convert[_DTOHS_Index]:=54;
 7:_DTOHS_Convert[_DTOHS_Index]:=55;
 8:_DTOHS_Convert[_DTOHS_Index]:=56;
 9:_DTOHS_Convert[_DTOHS_Index]:=57;
 10:_DTOHS_Convert[_DTOHS_Index]:=65;
 11:_DTOHS_Convert[_DTOHS_Index]:=66;
 12:_DTOHS_Convert[_DTOHS_Index]:=67;
 13:_DTOHS_Convert[_DTOHS_Index]:=68;
 14:_DTOHS_Convert[_DTOHS_Index]:=69;
 15:_DTOHS_Convert[_DTOHS_Index]:=70;
 end_case;
end_for;

for _DTOHS_Index:=0 to _DTOHS_Length do
 _DTOHS_RevIndex:=_DTOHS_Length - _DTOHS_Index;
 _DTOHS_Hex.Data[_DTOHS_Index]:=_DTOHS_Convert[_DTOHS_RevIndex];
end_for;
_DTOHS_Hex.LEN:=_DTOHS_Length + 1;

ret(_DTOHS_Hex);

Easy 8 Step HTML To SQL Data Transfer in a ASP.NET Web Form using jQuery, JSON, XML, Web Methods, node() Methods and Extension Methods.

This article uses 8 steps to create example of how to read and write from html to a SQL database in a .NET web application using jQuery, JSON and XML. This example is very streamlined, it only uses the absolutely the parts that essential to the actual data transfer. I intentionally left out all security, validation and error checking.

I have read many books, articles and blogs on data transfer and this example is an attempt to tie all of that together in one easy to understand example

HTML

Step 1: Create a new website in Visual Studio and add a web form with the following code. This website will update a very basic contact list. The webpage contains an insert div and an update div. It contains the very minimum code I could use to accomplish the data transfer.

    
<div style="width: 600px">
    <div style="float: left; width: 300px">
        <label>Insert</label>
        <div>
            <label for="txtFirstName_i">First Name</label>
            <input id="txtFirstName_i" type="text" />
        </div>
        <div>
            <label for="txtLastName_i">Last Name</label>
            <input id="txtLastName_i" type="text" />
        </div>
        <div>
            <label for="txtCompany_i">Company</label>
            <input id="txtCompany_i" type="text" />
        </div>
        <input id="btnInsert" type="button" value="Insert" />
    </div>
    <div style="float: left; width: 300px">
        <label>Update/Delete</label>
        <div>
            <label for="cboContacts">Contacts</label>
            <select id="cboContacts">
                <option></option>
            </select>
        </div>
        <div>
            <label for="txtFirstName_u">First Name</label>
            <input id="txtFirstName_u" type="text" />
        </div>
        <div>
            <label for="txtLastName_u">Last Name</label>
            <input id="txtLastName_u" type="text" />
        </div>
        <div>
            <label for="txtCompany_u">Company</label>
            <input id="txtCompany_u" type="text" />
        </div>
        <div>
            <input id="btnUpdate" type="button" value="Update" />
            <input id="btnDelete" type="button" value="Delete" />
        </div>
    </div>
</div>

Step 2: Download the latest jQuery and JSON2 libraries and add them to your new website.

SQL

Step 3: Create our sql table.

 
CREATE TABLE [dbo].[_Contacts](Contacts](
    [ContactID] [bigint] IDENTITY(1,1) NOT NULL,
    [FirstName] [varchar](50) NULL,
    [LastName] [varchar](50) NULL,
    [Company] [varchar](50) NULL,
 CONSTRAINT [PK_Contacts] PRIMARY KEY CLUSTERED 
(
    [ContactID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, 
    ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [) ON [PRIMARY]

Step 4: Once we have the project setup we start with our SQL code and create the one stored procedure that we will need to update and insert data into our datatable. This stored procedure takes the xml data that we pass it and stores it in a temp datatable using a nodes() method. Once the data is in the temp table if the entry exists it will update our new datatable and if it does not it will insert it into our new datatable.

 
CREATE PROCEDURE [dbo].[_UpdateContact]teContact]
    @XML XML
AS 
    SET NOCOUNT ON
    
    --Create a temp table to store the xml data that was passed    
    DECLARE	@Temp TABLE ([ContactID] BIGINT, [FirstName] VARCHAR(50), 
                        [LastName] VARCHAR(50), [Company] VARCHAR(50))   
    --Insert the data from the xml variable into the temp table using nodes() method.
    INSERT	INTO @Temp
        SELECT	x.value('(ContactID/text())[1]', 'bigint'), 
            x.value('(FirstName/text())[1]', 'varchar(50)'), 
            x.value('(LastName/text())[1]', 'varchar(50)'), 
            x.value('(Company/text())[1]', 'varchar(50)')
        FROM	@XML.nodes('//Contact') IDX ( x ) 
    
    --If the ContactID is null then it is new id and we need to insert it
    IF EXISTS ( SELECT * FROM @Temp	WHERE [ContactID] IS NULL ) 
        BEGIN
            INSERT	INTO dbo.[_Contacts] ( FirstName, LastName, Company )
            SELECT	FirstName, LastName, Company
            FROM	@Temp 
        END
    --If the ContactID is not null then if the id exist the update any columns that are not null in the temp table. I do this so you can pass only the parameters that need to be updated.
    ELSE 
        BEGIN 	
            UPDATE t1
            SET t1.[FirstName] = ISNULL(t2.[FirstName], t1.[FirstName]), 
            t1.[LastName] = ISNULL(t2.[LastName], t1.[LastName]),
            t1.[Company] = ISNULL(t2.[Company], t1.[Company])
            FROM _Contacts t1 
            JOIN @Temp t2 ON t1.[ContactID] = t2.[ContactID]
        END    

    --Return the new updated table
    SELECT	ContactID, FirstName, LastName, Company
    FROM	dbo._Contacts

.NET

Step 5: In order to simplify our conversions we need create a helper module that uses Extension Methods to convert the class properties to XML and datatables to JSON data.

 
Public Module Convert
    <Extension()> _
    Public Function XML(ByVal Record As Object, RecordType As System.Type) As String
        Using sw As New StringWriter()
            Using xw As XmlWriter = XmlWriter.Create(sw, New XmlWriterSettings() With {.OmitXmlDeclaration = True})
                Dim x As New XmlSerializer(RecordType)
                x.Serialize(xw, Record)
                Return sw.ToString
            End Using
        End Using
    End Function

    <Extension()> _
    Public Function JSON(ByVal dt As DataTable) As String
        Dim l As New List(Of Dictionary(Of String, Object))()
        For Each dr As DataRow In dt.Rows
            Dim dic As New Dictionary(Of String, Object)
            For Each dc As DataColumn In dt.Columns
                dic.Add(dc.ColumnName, dr(dc.ColumnName).ToString())
            Next
            l.Add(dic)
        Next

        Dim js As New JavaScriptSerializer
        Return js.Serialize(l)
    End Function
End Module

Step 6: Next we will create a data class to handle all of the .NET data functions (select, insert, update and delete). The update and insert are combined into one function that passes back the updated table. The select function is standard query. The delete function also passed back the updated table.

 
Public Class Contact
    Public Property ContactID() As String = ""
    Public Property FirstName() As String = ""
    Public Property LastName() As String = ""
    Public Property Company() As String = ""

    Private Shared Conn As String = "data source=localhost\SQLEXPRESS; initial catalog=scadoosh;Trusted_Connection=True;"
    Shared Function GetTable() As DataTable
        GetTable = New DataTable
        Using cmd As New SqlCommand("SELECT ContactID, FirstName, LastName, Company FROM dbo.[_Contacts]", New SqlConnection(Conn))
            cmd.Connection.Open()
            GetTable.Load(cmd.ExecuteReader(CommandBehavior.CloseConnection))
        End Using
    End Function

    Shared Function Update(ByVal Record As Contact) As DataTable
        Update = New DataTable
        Using cmd As New SqlCommand("_UpdateContact", New SqlConnection(Conn)) With {.CommandType = CommandType.StoredProcedure}
            cmd.Parameters.Add(New SqlParameter("@XML", SqlDbType.Xml)).Value = Record.XML(GetType(Contact))
            cmd.Connection.Open()
            Update.Load(cmd.ExecuteReader(CommandBehavior.CloseConnection))
        End Using
    End Function

    Shared Function Delete(ByVal ContactID As String) As DataTable
        Delete = New DataTable
        Using cmd As New SqlCommand("DELETE	FROM dbo.[_Contacts] WHERE ContactID = @ContactID; " &
                            "SELECT ContactID, FirstName, LastName, Company FROM  dbo.[_Contacts]",
                            New SqlConnection(Conn))
            cmd.Parameters.AddWithValue("@ContactID", ContactID)
            cmd.Connection.Open()
            Delete.Load(cmd.ExecuteReader(CommandBehavior.CloseConnection))
        End Using
    End Function
End Class

Step 7: The last part of the .NET code is to add Web Methods that we can call from the JavaScript.

 
Partial Class _Default
    Inherits System.Web.UI.Page

    <WebMethod()> _
    Public Shared Function GetContacts() As String
        Return Contact.GetTable.JSON
    End Function

    <WebMethod()> _
    Public Shared Function UpdateRecord(ByVal record As Contact) As String
        Return Contact.Update(record).JSON()
    End Function

    <WebMethod()> _
    Public Shared Function DeleteContact(ByVal ContactID As String) As String
        Return Contact.Delete(ContactID).JSON()
    End Function
End Class

JavaScript

Step 8: The final step is to add the following JavaScript to the header of the web form. You can either add the code as is or you could put the code in a js file and add a reference to the header. This script initially populates the options in a select tag with the current contact list and sets up the change and click events for the controls on the page.

    
<script src="jquery.js" type="text/javascript"></script>
<script src="json2.js" type="text/javascript"></script>
<script language="javascript" type="text/javascript">
    var contacts
    $(document).ready(function () {
        getContacts();
        $('#cboContacts').change(function () {
            $('select option[value=""]').remove();
            var contactid = $("#cboContacts").val()
            $.each(contacts, function () {
                if (this.ContactID == contactid) {
                    $("#txtFirstName_u").val(this.FirstName);
                    $("#txtLastName_u").val(this.LastName);
                    $("#txtCompany_u").val(this.Company);
                    return;
                }
            });
        });
        $("#btnUpdate").click(function () {
            if ($("#cboContacts").val() != "") {
                var record = {};
                record.ContactID = $("#cboContacts").val();
                record.FirstName = $("#txtFirstName_u").val();
                record.LastName = $("#txtLastName_u").val();
                record.Company = $("#txtCompany_u").val();
                updateContact(record);
            }
        });
        $("#btnInsert").click(function () {
            var record = {};
            record.FirstName = $("#txtFirstName_i").val();
            record.LastName = $("#txtLastName_i").val();
            record.Company = $("#txtCompany_i").val();
            insertContact(record);
        });
        $("#btnDelete").click(function () {
            if ($("#cboContacts").val() != null)
                deleteContact();
        });
    });
    function getContacts() {
        var url = location.pathname + "/GetContacts"
        getJSON(url, null, function (response)
        { contacts = response; populateContacts(); })
    }
    function populateContacts() {
        var options = $("#cboContacts");
        options.empty();
        options.append($("<option />").val("").text(""));
        $.each(contacts, function () {
            options.append($("<option />")
            .val(this.ContactID)
            .text(this.LastName + ", " + this.FirstName));
        });
    }
    function insertContact(record) {
        var contactid = $("#cboContacts").val()
        var url = location.pathname + "/UpdateRecord"
        var data = JSON.stringify({ "record": record });
        getJSON(url, data,
        function (response) {
            contacts = response;
            populateContacts();
            $("#txtFirstName_i").val("");
            $("#txtLastName_i").val("");
            $("#txtCompany_i").val("");
            if (contactid != "")
                $("#cboContacts").val(contactid).change();
        })
    }
    function updateContact(record) {
        var contactid = $("#cboContacts").val()
        var url = location.pathname + "/UpdateRecord"
        var data = JSON.stringify({ "record": record });
        getJSON(url, data,
        function (response) {
            contacts = response;
            populateContacts();
            if (contactid != "")
                $("#cboContacts").val(contactid).change();
            alert("Data Saved");
        })
    }
    function deleteContact() {
        var url = location.pathname + "/DeleteContact"
        var data = JSON.stringify({ "ContactID": $("#cboContacts").val() });
        getJSON(url, data,
        function (response) {
            contacts = response;
            populateContacts();
            $("#cboContacts").val("");
            $("#txtFirstName_u").val("");
            $("#txtLastName_u").val("");
            $("#txtCompany_u").val("");
        })
    }
    function getJSON(url, data, success) {
        $.ajax({
            type: "POST",
            url: url,
            data: data,
            contentType: "application/json; charset=utf-8",
            datatype: "json",
            success: function (response) {
                success(eval(response.d));
            },
            error: function (response) {
                alert(response.responseText);
            }
        });
    }
</script>

DO NOT BUY a My Net N900 Central

I made a huge mistake. I was researching a NAS (Network Attached Storage) drive for my home network and I came across the Western Digital My Net N900 Central 2TB HD Dual-Band Storage Router and I thought what a great idea. I was having trouble with our router and the combination HDD and router seemed like a good fit. I did some research on the router and what I did find was all positive. In retrospect that seems unbelievable.

I had trouble with the wireless connection right out of the box. The Wi-Fi kept cutting out and the only way to get it back online was to reboot the unit. Not long after I started having trouble with Wi-Fi, the internal hard drive started disappearing and getting it back was not as easy as a reboot. Many factory resets and reboots later it would show back up briefly and then disappear again. So I called support, the customer service rep gave me an RMA and mailed me a new one. I got the new one in the mail, plugged it in, set it up, started copying files and the Wi-Fi dropped out. So I rebooted and when it came back up the internal hard drive was gone.

I won’t bore you with details of the fiasco that was Western Digital customer support but it did not make the situation any better.

DO NOT BUY THIS PRODUCT!!!

Super Easy Modal Div

     
    .popupclass
    {     
        left: 50%;
        top: 50%;
        height: 170px;
        width: 300px;
        position: absolute;
        background-color: #333;
        border: 8px solid #444;
        color: White;
        padding: 12px;
        display: none;
        text-align: center;
        z-index: 50;
    }
    .backgroundclass
    {
        display: none;
        position: absolute;
        left: 0px;
        top: 0px;
        width: 100%;
        height: 100%;
        background-color: #ffffff;
        opacity: 0.6;
        filter: alpha(opacity=60); /* For IE8 and earlier */
        z-index: 25;
    } 
   
$(document).ready(function () {
   $(window).resize(function () {
      $('.popupclass').css({
         position: 'absolute',
         left: ($(window).width() - $('.popupclass').outerWidth()) / 2,
         top: ($(window).height() - $('.popupclass').outerHeight()) / 2
      });
   });
   $(window).resize();
});
function showModal() {
    $("#backgroundid").show()
    $("#popupid").show()
}
function hideModal() {
    $("#backgroundid").hide()
    $("#popupid").hide()
}
  
    <div id="backgroundid" class="backgroundclass" onclick="hideModal()">
    </div>
    <div id="popupid" class="popupclass">
    </div>

VB.Net – Socket Communications (Works in HyperTerminal, Won’t work in .Net)

I recently worked on an application using a Serial to WiFi device (B&B Electronics/Quatech ABDG-SE-IN5410) to collect data. I was able to talk to the device through HyperTerminal with no problem and I thought it would be a snap. I was wrong. I searched the internet for days and tried every variation of the code I could find and nothing worked. I got it working and this is what I did:

1. Download SmartSniff
2. Open SmartSniff and goto Options->Display Filter and add a filter for your remote device. Example – include:remote:99.99.999.99:9999 (ip address:port)
3. Click OK and Set Display Mode to Hex Dump (F4) and then Start Capture (F5)
4. Open HyperTerminal and connect to your device and send your command
5. SmartSniff will display all of the characters that are passed

From this I was able to determine what format the device was looking for. As it turns out, it was sending and receiving each individual character of my command string. The code I used is listed below.

    ReadOnly BUFFER_SIZE As Integer = 1024 * 1024
    Const SERVER_ADDR As String = "99.99.9999.99"
    Const SERVER_PORT As Integer = 9999
    ReadOnly buffer As Byte() = New Byte(BUFFER_SIZE - 1) {}

    Private Function Send(ByRef socket As Socket, ByVal outString As String, ByRef inString As String) As Boolean
        Send = True
        inString = String.Empty
        Try
            Dim err As SocketError = SocketError.Success
            Dim inLength As Integer = 0
            Dim bytes As Byte() = ASCIIEncoding.ASCII.GetBytes(outString)

            socket.Send(bytes, 0, bytes.Length, SocketFlags.None, err)
            rtb.AppendText(String.Format("Error Code:{0}{1}", err, ControlChars.CrLf))

            Dim t As Integer = Environment.TickCount
            Do
                inLength = socket.Receive(buffer, buffer.Length, SocketFlags.None)
                inString &= Encoding.ASCII.GetString(buffer, 0, inLength)
            Loop Until inString.Contains(outString) OrElse Environment.TickCount - t > 1000

            If Not inString.Contains(outString) Then
                Send = False
            End If
        Catch ex As Exception
            Send = False
        End Try
    End Function

    Private Function SendWord(ByVal word As String, ByRef inString As String) As Boolean
        SendWord = True
        Using socket As Socket = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
            Dim ip As IPAddress = IPAddress.Parse(SERVER_ADDR)
            socket.Connect(New IPEndPoint(ip, SERVER_PORT))
            For Each c As Char In word
                Send(socket, c, inString)
                rtb.AppendText(inString & ControlChars.CrLf)
            Next
        End Using
    End Function

    Private Sub btnSend_Click(sender As Object, e As EventArgs) Handles btnSend.Click
        Dim inString As String = String.Empty
        SendWord("COMMAND" & ControlChars.Cr, inString)
    End Sub

.Net – Find Checked Radiobutton in GroupBox

'Pre-Linq
For Each c As Control In gb.Controls
   If Not (TypeOf c Is RadioButton AndAlso DirectCast(c, RadioButton).Checked) Then Continue For
   'Do something here
   Exit For
Next

'Linq
For Each rb As RadioButton In gb.Controls.OfType(Of RadioButton)
   If Not rb.Checked Then Continue For
   'Do something here
   Exit For
Next

.Net – Loop Through ALL Controls On Form

Dim c As Control = Me
Do
   c = GetNextControl(c, True)

   If TypeOf c Is NumericUpDown Then
      AddHandler TryCast(c, NumericUpDown).ValueChanged, AddressOf txt_ValueChanged
   End If
Loop Until c Is Nothing