Page 1 of 1

Time line for more Documents

Posted: Sat Nov 16, 2024 7:58 pm
by Ryan Patterson
Now that I have a working project connected to CNC12, I'm excited to explore its capabilities further. However, I’ve encountered challenges due to limited documentation and example code. Some of the existing class examples seem to produce errors, such as:

Code: Select all

"Ambiguous because multiple kinds of members with this name exist in."
I’d like to know if there are plans to release more detailed documentation or updated examples to help developers leverage the API more effectively.

Here are a few specific tasks I’m looking to accomplish:

* Sending a G-code file to the controller.
* Detecting when a job has completed.
* Retrieving the current location values of an axis.
* Accessing the states of input switches.

Any guidance or examples on these topics would be greatly appreciated.

Re: Time line for more Documents

Posted: Sun Nov 17, 2024 10:52 am
by Centroid_Jacob
Hi Ryan,

Updated documentation should be coming in the next three weeks depending on my workload.

That Error can be avoided by adding an Imports line to the top of your file that is the class that has the ambiguous name.

I see you figured out DRO position, that's awesome!

Below is my clsPipeManager that should show you how to do the other tasks you asked about with a bonus, how to start whatever job is loaded (because I assumed that might be your next step after loading the job). Instead of using Job.Load you could also use Job.RunCommand() and send a G65 call with your CNC File. See the manual for more information there.

You can copy the code below into a new class or place it at the bottom of an existing class (after the End Class) or just take the relevant parts out, whatever you want to do.

Code: Select all


'****************************************************************************
'
' Title:        clsPipeManager.vb
' Author(s):    Jacob Holes
' Start Date:   11-04-24
' Purpose: Class that manages a single pipe connection so we don't exceed the CNC12 pipe limit by reconnecting 
'                and offers some helpful functions when working with cnc12
'
' Environment/platform  ( Windows 10/11, Visual Basic .net)
'
' Last Update:  10-17-24 - JDH - Added RunJob, LoadJob, and IsRunningJob
' Prior Update: 11-06-24 - JDH - Added GetCNC12WorkingDirectory() 
' Prior Update: 11-05-24 - JDH - Added header and comments
' Prior Update: 11-04-24 - JDH - Created clsPipeManager, added Pipe and GetCNC12WorkingDirectory()
'****************************************************************************

Imports System.IO
' Import class to avoid ambiguous issue
Imports CentroidAPI.CNCPipe.Plc
Imports CentroidAPI.CNCPipe.Job


Public Class PipeManager
    ' our pipe holder
    Private m_pipe As CNCPipe

    ''' <summary>
    ''' Class New() Initilization, creates new pipe for communicating with CNC12
    ''' </summary>
    Sub New()
        ' when we initilize a new pipe manager, give it a new pipe
        m_pipe = New CNCPipe
    End Sub

    ''' <summary>
    ''' Gets the currently active cnc pipe
    ''' </summary>
    ''' <returns>Returns the currently active cnc pipe</returns>
    Public Property Pipe As CNCPipe
        Get
            ' return our pipe holder
            Return m_pipe
        End Get
        Set(value As CNCPipe)
            ' assign the set value to our pipe holder
            m_pipe = value
        End Set
    End Property

    ''' <summary>
    ''' This function checks to see if any of oour known processes are running, then extracts the working directory from the process
    ''' </summary>
    ''' <returns>The directory our current version of CNC12 (Normal, or Offline) is running from</returns>
    Public Function GetCNC12WorkingDirectory() As String
        ' Define the list of process names to check
        Dim processNames As String() = {"cncm", "cnct", "cncr", "cncp", "MillDemo", "LatheDemo"}

        Dim allProcesses As Process() = Process.GetProcesses
        For Each processName As String In processNames

            ' Get all processes with the specified name
            Dim processes As Process() = Process.GetProcessesByName(processName)

            ' Loop through each instance of the process
            For Each proc As Process In processes
                Try
                    ' Attempt to get the executable path and working directory
                    Dim executablePath As String = proc.MainModule.FileName
                    Dim workingDirectory As String = Path.GetDirectoryName(executablePath)
                    Return workingDirectory
                Catch ex As Exception

                End Try
            Next
        Next
        Return "Unknown"
    End Function

    ''' <summary>
    ''' Checks the connection status of the CNC12 pipe and tries to recreate it when it fails. 
    ''' </summary>
    ''' <returns>True if connected to CNC12 Pipe; False otherwise.</returns>
    Public Function ConnectedToCNC12() As Boolean
        ' IMPORTANT: On Error Resume Next tells the compiler to ignore errors, be careful as it may cause unintended side effects.
        ' A Try Catch would be better here but the debugger breaks on errors inside of the try catch and this bypasses that
        ' Since param.GetMachineParameterValue(1, paramValue) will cause an 'object reference not set to instance of an object'
        ' error when called on a dead pipe. 
        On Error Resume Next
        ' Check if the pipe exists and is constructed
        If m_pipe IsNot Nothing AndAlso m_pipe.IsConstructed Then
            Dim paramValue As Double = 0
            Dim param As New CentroidAPI.CNCPipe.Parameter(m_pipe)
            Dim returnCode As CentroidAPI.CNCPipe.ReturnCode = param.GetMachineParameterValue(1, paramValue)

            Select Case returnCode
                Case CNCPipe.ReturnCode.SUCCESS
                    ' Successfully connected to CNC12
                    Return True
                Case CNCPipe.ReturnCode.ERROR_PIPE_IS_BROKEN
                    ' Recreate the pipe if it is broken
                    m_pipe = New CentroidAPI.CNCPipe()
                Case CNCPipe.ReturnCode.ERROR_CLIENT_LOCKED
                    ' client locked means we are still connected but the client is locked, don't treat this as a disconnection
                    Return True
                Case Else
                    ' Any other error means disconnection
                    Return False
            End Select
        Else
            ' Pipe is not constructed; try to recreate it
            m_pipe = New CentroidAPI.CNCPipe()
        End If


        ' Return false if connection is not established
        Return False
    End Function
    ''' <summary>
    ''' This function checks the PLC to see if a program is running
    ''' </summary>
    ''' <returns>Returns true if program is running per pc system variable bit</returns>
    Function IsRunningJob() As Boolean
        If ConnectedToCNC12() Then
            Dim CNCPLC As New CentroidAPI.CNCPipe.Plc(m_pipe)
            Dim programRunning As CentroidAPI.CNCPipe.Plc.IOState
            CNCPLC.GetPcSystemVariableBit(PcToMpuSysVarBit.SV_PROGRAM_RUNNING, programRunning)
            Select Case programRunning
                Case IOState.IO_LOGICAL_0
                    ' return false if we aren't running a job
                    Return False
                Case IOState.IO_LOGICAL_1
                    ' return true if we are running a job
                    Return True
                Case IOState.IO_STATE_UNKNOWN
                    ' return true for safety
                    Return True
            End Select
        End If
        ' return false because we're not connected
        Return False
    End Function

    ''' <summary>
    ''' Loads a job into CNC12 but does not start the job.
    ''' </summary>
    ''' <param name="jobLocation">The full or relative path of the file</param>
    ''' <returns>Returns a ReturnCode</returns>
    Function LoadJob(ByVal jobLocation As String) As CentroidAPI.CNCPipe.ReturnCode
        ' check that the file exists and that we are connected to CNC12
        If IO.File.Exists(jobLocation) Then
            If ConnectedToCNC12() Then
                ' reference to Job class
                Dim cmd As New CentroidAPI.CNCPipe.Job(m_pipe)
                ' return the return code for Load, check it for SUCCESS
                Return cmd.Load(jobLocation, GetCNC12WorkingDirectory)
            Else
                ' warn that we aren't connected to cnc12
                MessageBox.Show("Error: Not Connected to CNC12")
                ' return error code if we want to check against SUCCESS or other code instead of handling error with a messagebox here
                Return CNCPipe.ReturnCode.ERROR_SEND_COMMAND
            End If
        Else
            ' warn that file not found
            MessageBox.Show("Error: Job File Not Found")
            ' return error code if we want to check against SUCCESS or other code instead of handling error with a messagebox here
            Return CNCPipe.ReturnCode.ERROR_SEND_COMMAND
        End If
    End Function

    ''' <summary>
    ''' Uses Skinning Events to emulate cycle start, warning this will start the job if CNC12 is on a screen that allows cycle start. 
    ''' Use with Caution. Operators should have to press cycle start to being machine motion.
    ''' </summary>
    ''' <returns>Returns a ReturnCode</returns>
    Function RunJob() As CentroidAPI.CNCPipe.ReturnCode
        ' reference to Plc class
        Dim cncPLC As New CentroidAPI.CNCPipe.Plc(m_pipe)
        ' we are using SetSkinEventState to simulate a button press of cycle start by passing the state of 1 (pressed)
        If cncPLC.SetSkinEventState(50, 1) = CNCPipe.ReturnCode.SUCCESS Then
            'then we sleep for 50 miliseconds so the PLC has a chance to see the button press
            Threading.Thread.Sleep(50)
            ' then we return the result of setting the state to 0 (unpressed)
            Return cncPLC.SetSkinEventState(50, 0)
        End If
    End Function
End Class

The PipeManger replaces your pipe, CNC12 has a limited number of API pipes available so the PipeManager allows you to keep the same pipe in a class that can be passed to other forms.


Use it like so:

Code: Select all


' create pipe
Dim CNCPipeManager As PipeManager
' create thread for monitoring if cnc12 is running
Dim cnc12_isRunning_thread As Threading.Thread

''' <summary>
''' This sub is called when this form is created, we use it to initialize the cnc pipe
''' </summary>
Sub New()

    ' This call is required by the designer.
    InitializeComponent()

    ' Add any initialization after the InitializeComponent() call.

    ' initialize pipe so we can communicate with CNC12
    CNCPipeManager = New PipeManager()
End Sub

''' <summary>
''' Sends a G1 command using xDistance as X axis distance and FeedRate as desired FeedRate
''' </summary>
''' <param name="xDistance">Distance to move X Axis</param>
''' <param name="FeedRate">Speed at which to move X Axis</param>
''' <returns></returns>
Function SendXMoveCommand(ByVal xDistance As Double, Optional ByVal FeedRate As Double = 50)
    ' check that pipe is initialized
    If CNCPipeManager.ConnectedToCNC12 Then
        ' reference to Job class
        Dim cmd As New CentroidAPI.CNCPipe.Job(CNCPipeManager.Pipe)
        ' return the result of the command after building the command and sending it to cnc12
        Return cmd.RunCommand("G1 X" & xDistance & " F" & FeedRate, CNCPipeManager.GetCNC12WorkingDirectory, False)
    End If
    ' if we failed, send back an unknown error
    Return CentroidAPI.CNCPipe.ReturnCode.ERROR_UNKNOWN
End Function
I will push these changes to the GitHub tomorrow.

Re: Time line for more Documents

Posted: Sun Nov 17, 2024 11:11 am
by Ryan Patterson
The "imports" is what I had thought also but the error persisted. I just posted some example code to get the DRO machine coordinates that is avoiding the Ambiguous error. Please take a look to see if the code is as you would have it.

Re: Time line for more Documents

Posted: Sun Nov 17, 2024 11:47 am
by Centroid_Jacob
Did you remove the CentroidAPI.CNCPipe.Class from the line with the error where Class is Plc, Job, etc. from the line where the error was? Imports removes the need to reference the whole name and since we're importing the Class that was ambiguous, it should avoid the error.

Please attach a picture of the line with the error and I can provide a direct solution. I'll take a closer look at your DRO code in a little bit.

Re: Time line for more Documents

Posted: Sun Nov 17, 2024 7:45 pm
by Centroid_Jacob
I forgot to include input and output checking, my bad.
It's very similar to the other calls and functions I've shown.

Code: Select all


Function IsInputOn(ByVal iInput As Integer) As Boolean
    ' use your own method of checking for a connection if not using the PipeManager class. 
    If CNCPipeManager.ConnectedToCNC12() Then
        Dim cncPLC As New CentroidAPI.CNCPipe.Plc(CNCPipeManager.Pipe)
        Dim inputState As CentroidAPI.CNCPipe.Plc.IOState
        ' this call returns the input state for whatever iInput is
        cncPLC.GetInputState(iInput, inputState)
        Select Case inputState
            Case IOState.IO_LOGICAL_0
                Return False
            Case IOState.IO_LOGICAL_1
                Return True
        End Select
    End If
    Return False
End Function

Function IsOutputOn(ByVal iOutput As Integer) As Boolean
    ' use your own method of checking for a connection if not using the PipeManager class. 
    If CNCPipeManager.ConnectedToCNC12() Then
        Dim cncPLC As New CentroidAPI.CNCPipe.Plc(CNCPipeManager.Pipe)
        Dim outputState As CentroidAPI.CNCPipe.Plc.IOState
         ' this call returns the output state for whatever iOutput is
        cncPLC.GetOutputState(iOutput , outputState )
        Select Case outputState 
            Case IOState.IO_LOGICAL_0
                Return False
            Case IOState.IO_LOGICAL_1
                Return True
        End Select
    End If
    Return False
End Function
And to use them you pass the input or output you want, 1-8 for just an Acorn, or 1-16 for AcornSix, see the Install Manual for the board and possible expansion boards you are going to work with and Operator's Manual for the software version (Mill, Lathe, Router, Plasma) you are plan on using your API application with for more info.

Code: Select all


If IsInputOn(1) Then
   ' Input 1 is on code goes here
End If

If IsOutputOn(2) Then 
   ' Output 2 is on code goes here
End If


Re: Time line for more Documents

Posted: Sun Nov 17, 2024 8:09 pm
by Ryan Patterson
Thank you for the examples. Very help in getting started. Once I have a little more time I will share the code that is producing the Ambiguous errors. But it could have just been me using it in the wrong way. I do understand about the imports I usually do not use them and reference the class by full name. I have run into issues where using imports and not the full name that two separate classes use the same names that cause issues.