• matthew@hierthinking.com
Control Systems
It’s Time To Focas: CNC Router Programming Tutorial – Part 2

It’s Time To Focas: CNC Router Programming Tutorial – Part 2

View Code on GitHub

ATTENTION!!!!!

We have a newer up to date video version of this tutorial here!

We now offer Consulting, Contract, and Training services for Focas. Check it out here!

If you have a question with something in this series, check out our new forum here!

Let’s Connect

If you have not yet read It’s Time To Focas – Part 1, you should go back and read it first before continuing on with part 2. I list some resources that will be needed, as well as what to expect and what not to expect from this series. If you are reading this, then I am going to assume that you have read part 1, you have downloaded the FwLib32.cs file, and that you have at least browsed the Focas reference website.

This post is going to cover the basics of connecting to the Fanuc control using the Focas API. To start off, we need to understand the methods of connecting to the control that are available to us.

Ethernet

The first method of connection is over Ethernet. The controller will have an IP address that you can use to connect. To find this IP address you will need to be familiar with the Fanuc HMI. It may vary based on a number of factors, however, on controls that I am familiar with, you go to the ‘System’ page on the Fanuc screens, and hit ‘Next Page’ on the vertical tabs until you see ‘Embedded Port’. The IP address will be on the Embedded Port page.

While most people will be familiar with Ethernet, I find that this is not my desired method of connection unless it is the only option. The reason for this, is that communication over Ethernet can be slow and if you are attempting to read from the control at a high rate of speed, this can really be detrimental.

High Speed Serial Bus (HSSB)

The HSSB is the main method of connection that I prefer whenever it is available. HSSB communicates over an optical line that goes from the HMI to the control. All of the Onsrud machines utilize HSSB, however, I am not entirely sure how common it is for other manufacturers.

If you are not sure whether or not you have HSSB, there are a few ways to check, but I will include some code that checks for HSSB connection automatically so that the code chooses the best method of connecting automatically.

HSSB is going to be significantly faster than the standard Ethernet connection and it also reduces the requirements for configuration. The Ethernet connection requires an IP address to be specified, whereas the HSSB connection does not have this requirement.

However, HSSB is only available on the machine HMI because it requires extra hardware to make it function. This means that if you are developing an application that is not going to run on the HMI, you are going to want to use Ethernet communication.

Data Server / Fast Ethernet

Some machines contain a card called the data server. This data server increases the amount of space available to store programs on the machine. Not all machines have a data server because it is an extra-cost option. The data server comes with a fast ethernet option which significantly increases the speed of the Ethernet communication.

Obviously if the machine you are on contains a data server, you will want to use this for ethernet communication over the standard Ethernet.

There is no difference between the standard Ethernet communication and the data server fast Ethernet communication when it comes to our code, but it is important to note that the controller and the data server will have different IP addresses, so you will need to know which IP address to use.

Let’s See Some Code

private ushort _handle;
private short _ret;

// Ethernet Communication
_ret = Focas1.cnc_allclibhndl3(“192.168.1.11”, 8193, 6, out _handle);

// HSSB communication
_ret = Focas1.cnc_allclibhndl(out _handle);

I have listed and commented the code above to show the difference between the calls for Ethernet and HSSB connections. We will not be communicating over both, so this is just for demonstration.

The first thing you will notice is that the Focas calls are static, so we do not need to declare an instance of the Focas1 class. Each of the calls returns a value that will indicate whether or not the call was successful. That value will be store in the _ret variable. The return values will either a negative or positive integer that indicates what the problem was. You can look up the return codes here.

The Ethernet call requires the IP address of the controller or the data server as the first parameter. The second parameter is going to be the port number used for communication. This value is set to 8193 on all of the Onsrud routers but may be different on your machine. You can check this in the same place you found the IP address.

The next argument is going to be the timeout in seconds. You can play around with this value, but I have found 6 seconds to be a good value, so that is what I use.

The last argument is going to be a handle used to make calls to the controller in the future. It is important the you store the handle as a class variable and not a local variable inside your method. When you make calls to the Fanuc controller you will need to pass the handle in as the first argument.

Another note on the handle is that it is thread dependent. This means that if you have a multi-threaded application, you will need to have a different handle for each thread you use to communicate with the controller. A lot of people do not think about it, but if you are using a timer in your application that utilizes the thread pool, you are going to have to make a connection call to the controller and get a new handle each time the timer elapses.

The HSSB call is much simpler than the Ethernet call. As you can see the only thing you need to provide the HSSB call is the handle that you wish to use.

Let’s See an Example

static ushort _handle = 0;  // Handle to communicate with Fanuc
static short _ret = 0;  // Stores our return value

static void Main(string[] args)
{
	string ipaddr = "";

	// If we specified an ip address, get it from the args
	if (args.Length > 0)
		ipaddr = args[0];

	// If we didn't provide an IP address, use HSSB, otherwise use Ethernet
	if (string.IsNullOrEmpty(ipaddr))
	{
		_ret = Focas1.cnc_allclibhndl(out _handle);
	}
	else
	{
		_ret = Focas1.cnc_allclibhndl3(ipaddr, 8193, 6, out _handle);
	}

	// Write the result to the console
	if (_ret == Focas1.EW_OK)
	{
		Console.WriteLine("We are connected!");
	}
	else
	{
		Console.WriteLine("There was an error connecting. Return value: " + _ret);
	}

	// Free the Focas handle
	Focas1.cnc_freelibhndl(_handle);
}

Alright, let’s look at what we have.

The first line is the declaration of our class variable _handle. This is where we will store our handle to be used in future calls to the controller.

The second line is the declaration for the _ret variable that we will used to store the return value of the call. This will be used to help us determine why a call fails.

Next, we have the function declaration. It is the standard main function for a console application.

Finally, we have reached the good stuff. First, we are going to check to see if an IP address was specified at the command line when the program was run. If it was, we will pull the IP address from the command line arguments parameter ‘args’.

Next, we will check to see if the ipaddr variable is empty. If it is, we will connect over HSSB. If the ipaddr variable contains a value, we are going to assume that the user wants to connect over Ethernet, so we will use that call instead.

Then, we are going to check to see if the return value was equal to Focas1.EW_OK. EW_OK is actually equal to 0, so you could just test to see if it was 0, but I think it makes it clearer to use EW_OK. If it is equal to EW_OK, we will display ‘We are connected’ on the console. Otherwise we will display a message saying that there was an error along with the return code so we can look up what error occurred.

Because we are good programmers, the very last thing we are going to do is free the handle. All this does is disconnects from the controller and lets the controller know that we are finished using the handle and that it can be allocated to someone else. If we don’t do this the handle will be unusable until the controller is rebooted, or a timeout occurs.

Alternative Methods

The code above was simple to understand, but there is a problem with it that took me a while to figure out a work around for. The problem is that if you call the HSSB connection method and there is no HSSB hardware module on the device your program is running on, a ton of pop up alerts will appear and you will have to spend a long time clicking ‘ok’ to clear them all before the application can exit.

In the above example, if the user forgot to put in the IP address or one was not in the configuration for the application, then the HSSB function will be called whether or not it is installed on the device.

To fix this, I created a method that detects whether or not the HSSB module is installed and uses HSSB if it is available. If not, it defaults to Ethernet. I like this method more because it doesn’t make a decision based on a user remembering to input an IP address.

I am not going to go into detail on how if functions because that is beyond the scope of this series. Basically, it just checks the Windows device manager to see if the driver is installed. If you want to know what each call is doing, you can find that information on MSDN or stack overflow.

private static ushort _handle = 0;
private static short _ret = 0;

public static void Connect(string[] args)
{
	// If we didn't provide an IP address, use HSSB, otherwise use Ethernet
	if (CNCHardware.HasHSSB())
	{
		_ret = Focas1.cnc_allclibhndl(out _handle);
	}
	else
	{
		string ipaddr = "";

		// If we specified an ip address, get it from the args
		if (args.Length > 0)
			ipaddr = args[0];

		_ret = Focas1.cnc_allclibhndl3(ipaddr, 8193, 6, out _handle);
	}

	// Write the result to the console
	if (_ret == Focas1.EW_OK)
	{
		Console.WriteLine("We are connected!");
	}
	else
	{
		Console.WriteLine("There was an error connecting. Return value: " + _ret);
	}

	// Free the Focas handle
	Focas1.cnc_freelibhndl(_handle);
}

Resources

This is a list of resources for this post.

Focas Library Handle: https://www.inventcom.net/fanuc-focas-library/general/handle

cnc_allclibhndl: https://www.inventcom.net/fanuc-focas-library/handle/cnc_allclibhndl

cnc_allclibhndl3: https://www.inventcom.net/fanuc-focas-library/handle/cnc_allclibhndl3

Focas Errors: https://www.inventcom.net/fanuc-focas-library/general/errcode

Fanuc HSSB: https://www.inventcom.net/fanuc-focas-library/general/hssb

Final Thoughts

This was just a simple introduction to connecting to the Fanuc controller. I know there was a lot of explanation in this post. Future posts will have more code and less time spent explaining what is happening. I just wanted to ensure that everyone had the basics down so that future posts can move along a little more quickly.

I tried to cover a lot of the gotchas that I ran into while I was learning this stuff. If I can save even one person the heartache of spending hours troubleshooting, then this post will be worth the effort put into it.

Be sure to join me next time when we cover some basic calls such as reading the mode and status of the machine.

<– Part 1 …………… Part 3 –>

28 thoughts on “It’s Time To Focas: CNC Router Programming Tutorial – Part 2

Leave a Reply