CollinsCombustion

MrPLC Member
  • Content count

    6
  • Joined

  • Last visited

Community Reputation

0 Neutral

About CollinsCombustion

  • Rank
    Newbie

Contact Methods

  • Website URL http://www.collinscombustion.com

Profile Information

  • Gender Male
  • Country United States
  • Interests Combustion Tuning, Industrial Boilers, Control System Programming, HMI Programming
  1. VPN vs RDP

    VPN uses OPC on your local machine and tunnels through the internet all communication between your machine to the private network then to the PLC processor. All programming software stays on your machine therefore the internet connection better be good or you risk the chance that you will drop out in the middle of a download. For programming industrial boiler control systems this was unacceptable for me. Remote Desktop uses OPC locally on a machine to connect to the PLC processor and stays connected if you have a internet connection issue and drop out, therefore you simply reconnect and continue where you left off because locally it stays connected. This gives you the option to call someone on the phone and walk them through it if need be. For this I recommend Real VNC because it allows the local user to watch what you are doing and take over. Windows RDP logs off the local session. This is what I ended up with and have had good success. Understanding both issues, why not VPN and use it to RDP if you need to? The University of Chicago uses Cisco and has both provided for me to log in when the utilities plant needs something. I like the ability to drop HMI updates in to the machines with VPN and then using RDP to reboot the machines.
  2. AB PLC data vía C++ function

    Here's a code snippet for addressing the canonical data types... plop it in Visual Basic 2010 and get the OPC library.. ' >>>>>>>>>> ACTIVE SYNC WRITE 1 BOOL True then False w Adjustable Delay <<<<<<<<<<< Private Sub Label_LP01buttonAMselectASW_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Label_LP01buttonAMselectASW.Click Dim aswItemNumber As Short 'Item handle we write to Dim aswNumItems As Short 'How many Items to Write Short is 16 bits and can be converted to many data types Dim aswItemValue As String 'Value of item to write Dim isTrue As String 'Bool value True Dim isFalse As String 'Bool vlaue False isTrue = 1 isFalse = 0 'Which item handle to write "One" Based Array Size aswItemNumber = 2 'Second Server Handle starting from 1 'How many Items to Write aswNumItems = 1 'What will we Write? aswItemValue = isTrue 'Use of string is universal for user input >>> Labels and Text Boxes <<<, Process figures out how to convert.... Call aswProcess_DataType(aswItemNumber, aswNumItems, aswItemValue) ' Process Canocal Data Types and send Sync Write Delay(0.75) 'Which item handle to write "One" Based Array Size aswItemNumber = 2 'How many Items to Write aswNumItems = 1 'What will we Write? aswItemValue = isFalse Call aswProcess_DataType(aswItemNumber, aswNumItems, aswItemValue) End Sub ' >>>>>>>>>> PROCESS ACTIVE SYNC WRITE Request for Canonical Data Types <<<<<<<<<<< Private Sub aswProcess_DataType(ByRef aswItemNumber As Short, ByRef aswNumItems As Short, ByRef aswItemValue As String) If Not OPCGroup Is Nothing Then Dim aswValue(NumItems) As Object Dim aswItem(NumItems) As Integer aswValue(aswItemNumber) = aswItemValue Try Dim SyncItemServerErrors As System.Array Dim AnOPCItem As OPCAutomation.OPCItem aswServerHandles(1) = ServerHandles(aswItemNumber) AnOPCItem = OPCGroup.OPCItems.GetOPCItem(ServerHandles(aswItemNumber)) Dim ItsAnArray As Array Dim CanonDT As Short CanonDT = AnOPCItem.CanonicalDataType() ' If it is an array, figure out the base type If CanonDT > vbArray Then CanonDT -= vbArray End If Select Case CanonDT Case CanonicalDataTypes.CanonDtByte If aswItem(aswItemNumber) > 0 Then ItsAnArray = Array.CreateInstance(GetType(Byte), aswItem(aswItemNumber)) If Not aswLoadArray(ItsAnArray, CanonDT, aswValue(aswItemNumber)) Then Return End If aswItemValues(1) = CObj(ItsAnArray) Else aswItemValues(1) = Convert.ToByte(aswValue(aswItemNumber)) End If ' End case Case CanonicalDataTypes.CanonDtChar If aswItem(aswItemNumber) > 0 Then ItsAnArray = Array.CreateInstance(GetType([SByte]), aswItem(aswItemNumber)) If Not aswLoadArray(ItsAnArray, CanonDT, aswValue(aswItemNumber)) Then Return End If aswItemValues(1) = CObj(ItsAnArray) Else aswItemValues(1) = Convert.ToSByte(aswValue(aswItemNumber)) End If ' End case Case CanonicalDataTypes.CanonDtWord If aswItem(aswItemNumber) > 0 Then ItsAnArray = Array.CreateInstance(GetType(UInt16), aswItem(aswItemNumber)) If Not aswLoadArray(ItsAnArray, CanonDT, aswValue(aswItemNumber)) Then Return End If aswItemValues(1) = CObj(ItsAnArray) Else aswItemValues(1) = Convert.ToUInt16(aswValue(aswItemNumber)) End If ' End case Case CanonicalDataTypes.CanonDtShort If aswItem(aswItemNumber) > 0 Then ItsAnArray = Array.CreateInstance(GetType(Int16), aswItem(aswItemNumber)) If Not aswLoadArray(ItsAnArray, CanonDT, aswValue(aswItemNumber)) Then Return End If aswItemValues(1) = CObj(ItsAnArray) Else aswItemValues(1) = Convert.ToInt16(aswValue(aswItemNumber)) End If ' End case Case CanonicalDataTypes.CanonDtDWord If aswItem(aswItemNumber) > 0 Then ItsAnArray = Array.CreateInstance(GetType(UInt32), aswItem(aswItemNumber)) If Not aswLoadArray(ItsAnArray, CanonDT, aswValue(aswItemNumber)) Then Return End If aswItemValues(1) = CObj(ItsAnArray) Else aswItemValues(1) = Convert.ToUInt32(aswValue(aswItemNumber)) End If ' End case Case CanonicalDataTypes.CanonDtLong If aswItem(aswItemNumber) > 0 Then ItsAnArray = Array.CreateInstance(GetType(Int32), aswItem(aswItemNumber)) If Not aswLoadArray(ItsAnArray, CanonDT, aswValue(aswItemNumber)) Then Return End If aswItemValues(1) = CObj(ItsAnArray) Else aswItemValues(1) = Convert.ToInt32(aswValue(aswItemNumber)) End If ' End case Case CanonicalDataTypes.CanonDtFloat If aswItem(aswItemNumber) > 0 Then ItsAnArray = Array.CreateInstance(GetType(Single), aswItem(aswItemNumber)) If Not aswLoadArray(ItsAnArray, CanonDT, aswValue(aswItemNumber)) Then Return End If aswItemValues(1) = CObj(ItsAnArray) Else aswItemValues(1) = Convert.ToSingle(aswValue(aswItemNumber)) End If ' End case Case CanonicalDataTypes.CanonDtDouble If aswItem(aswItemNumber) > 0 Then ItsAnArray = Array.CreateInstance(GetType(Double), aswItem(aswItemNumber)) If Not aswLoadArray(ItsAnArray, CanonDT, aswValue(aswItemNumber)) Then Return End If aswItemValues(1) = CObj(ItsAnArray) Else aswItemValues(1) = Convert.ToDouble(aswValue(aswItemNumber)) End If ' End case Case CanonicalDataTypes.CanonDtBool If aswItem(aswItemNumber) > 0 Then ItsAnArray = Array.CreateInstance(GetType(Boolean), aswItem(aswItemNumber)) If Not aswLoadArray(ItsAnArray, CanonDT, aswValue(aswItemNumber)) Then Return End If aswItemValues(1) = CObj(ItsAnArray) Else aswItemValues(1) = Convert.ToBoolean(aswValue(aswItemNumber)) End If ' End case Case CanonicalDataTypes.CanonDtString If aswItem(aswItemNumber) > 0 Then ItsAnArray = Array.CreateInstance(GetType(String), aswItem(aswItemNumber)) If Not aswLoadArray(ItsAnArray, CanonDT, aswValue(aswItemNumber)) Then Return End If aswItemValues(1) = CObj(ItsAnArray) Else aswItemValues(1) = Convert.ToString(aswValue(aswItemNumber)) End If ' End case Case Else MsgBox("Write Fail>>Unknown Data Type", MsgBoxStyle.Exclamation) Return ' End case End Select ' Invoke the SyncWrite operation. Remember this call will not wait until completion OPCGroup.AsyncWrite(aswNumItems, aswServerHandles, aswItemValues, SyncItemServerErrors, TransactionID, CancelID) ' Server Error handling If SyncItemServerErrors(1) <> 0 Then MsgBox("SyncItemServerError: " & SyncItemServerErrors(1)) End If Catch ex As Exception ' Write Error handling Timer_LP01_UP.Enabled = False Timer_LP01_DN.Enabled = False MessageBox.Show("Write Tag Failed: " + ex.Message, "Exception", MessageBoxButtons.OK) End Try End If End Sub ' >>>>>>>>>> LOAD ARRAY SCRIPT <<<<<<<<<<< Private Function aswLoadArray(ByRef AnArray As System.Array, ByVal CanonDT As Short, ByRef wrTxt As String) As Boolean Dim ii As Integer Dim loc As Integer Dim Wlen As Integer Dim start As Integer Try start = 1 Wlen = Len(wrTxt) For ii = AnArray.GetLowerBound(0) To AnArray.GetUpperBound(0) loc = InStr(start, wrTxt, ",") If ii < AnArray.GetUpperBound(0) Then If loc = 0 Then MsgBox("Write Value: Incorrect Number of Items for Array Size?", MsgBoxStyle.Exclamation) Return False End If Else loc = Wlen + 1 End If Select Case CanonDT Case CanonicalDataTypes.CanonDtByte AnArray(ii) = Convert.ToByte(Mid(wrTxt, start, loc - start)) ' End case Case CanonicalDataTypes.CanonDtChar AnArray(ii) = Convert.ToSByte(Mid(wrTxt, start, loc - start)) ' End case Case CanonicalDataTypes.CanonDtWord AnArray(ii) = Convert.ToUInt16(Mid(wrTxt, start, loc - start)) ' End case Case CanonicalDataTypes.CanonDtShort AnArray(ii) = Convert.ToInt16(Mid(wrTxt, start, loc - start)) ' End case Case CanonicalDataTypes.CanonDtDWord AnArray(ii) = Convert.ToUInt32(Mid(wrTxt, start, loc - start)) ' End case Case CanonicalDataTypes.CanonDtLong AnArray(ii) = Convert.ToInt32(Mid(wrTxt, start, loc - start)) ' End case Case CanonicalDataTypes.CanonDtFloat AnArray(ii) = Convert.ToSingle(Mid(wrTxt, start, loc - start)) ' End case Case CanonicalDataTypes.CanonDtDouble AnArray(ii) = Convert.ToDouble(Mid(wrTxt, start, loc - start)) ' End case Case CanonicalDataTypes.CanonDtBool AnArray(ii) = Convert.ToBoolean(Mid(wrTxt, start, loc - start)) ' End case Case CanonicalDataTypes.CanonDtString AnArray(ii) = Convert.ToString(Mid(wrTxt, start, loc - start)) ' End case Case Else MsgBox("Write Value Unknown data type", MsgBoxStyle.Exclamation) Return False End Select start = loc + 1 Next ii Return True Catch ex As Exception MsgBox("Write Value generated Exception: " & ex.Message, MsgBoxStyle.Exclamation, "UNI_LOOP Exception") Return False End Try End Function ' >>>>>>>>>>>HANDLE OPC ERRORS CALL TO THIS ROUTINE - NOT AN EVENT<<<<<<<<<<<<< Private Sub DisplayOPC_COM_ErrorValue(ByVal OPC_Function As String, ByVal ErrorCode As Long) 'Handles displaying any OPC/COM/VB errors that are caught by the exception handler Dim Response Dim ErrorDisplay As String ErrorDisplay = "The OPC Function '" + OPC_Function + "' Has Returned an Error of " + Str(ErrorCode) + " or Hex 0x" + Hex(ErrorCode) Response = MsgBox(ErrorDisplay, vbOKOnly, "OPC Function Error") End Sub
  3. AB PLC data vía C++ function

    Did this with Windows 7 many moons ago. If I remember correctly, I used Visual Studio sample code from Kepware and figured out how to address the canonical data types with the Kepware OPC server first. Then I made subroutines that would query the canonical data type for any of the read write functions. Really interesting how much is going on in the background for an HMI when reading and writing to an analog value. I posted a program here (4 or 5 years ago) called UNI LOOP which was a universal loop controller. It would work with RSLinx Classic and Kepware OPC servers. It had drop down menus for all of the tags (e.g. PV SP CV locked auto manual) and drop down menu's for which type of OPC server you plan to use. I posted it for free and nobody really understood what it was for or even tried it. It would support multiple instances so I could open it up ten times or more and run ten different loops in an Allen Bradly Compact Logix or Control Logix PLC. Heck I showed a co-worker at the University of Chicago and he couldn't believe it. Here on my desktop was all the active loops he was running the west campus plant with on Invensys Wonderware..... Not rocket science..... I also had it working with RSLinx Classic. After Visual Studio is talking, you can work on getting C++ talking.
  4. CompactLogix L35E BootP

    haha... Ken I think I sparked an old post. sorry for that man..
  5. CompactLogix L35E BootP

    Boot P can be disabled with the Boot P Utility.... and... RSLinx.. have you tried both? As previously stated, do all of your devices have the same IP configs e.g. network, mask etc.? Try connecting with a Serial Cable, then after all is good with disabling Boot P with serial connection, connect laptop on same Ethernet network as PLC and open the internal web page for the PLC by typing the IP address in internet explorer which will prove RSLinx can communicate. All should be good at that point.. FYI I have never had a CompactLogix or ControlLogix PLC die unless the power supply fried from an assumed poor ground and assumed welding nearby, the serial port is your friend...
  6. Wiring Diagram

    very common for AC and DC to share ground when building control panels, just more so in the control panel and not out in the field like this drawing is showing.