It’s Time To Focas: CNC Router Programming Tutorial – Part 2
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.
28 thoughts on “It’s Time To Focas: CNC Router Programming Tutorial – Part 2”
Leave a Reply
You must be logged in to post a comment.
[…] Previous postNext post […]
[…] <– Part 2 […]
I have a question: will you be using FOCAS1? Isn’t it some sort of obsolete?
Hi Hiram,
So if you notice I am not accessing the DLL directly when using the function calls in .Net. I am actually using a .cs file that does all the importing of functions from the DLL. So while the DLL has the Focas2 library, the cs file has a namespace of Focas1, which I suspect was just never changed. When I have asked Fanuc about the .cs file in the past, in regards to some of the focas calls missing, they responded that the .cs file was meant to be a sample and that if additional focas calls were needed I would have to add them manually. So my suspicion is that the CS file was made a long time ago and the namespace was just never changed when they released Focas2.
Alright. Then it works with model 0i-MF? Im worried because the samples are from 2002.
Hi Hiram,
The focas library is going to work with the 0i-MF, but some of the function calls might not work. They have compatibility charts at the end of the page for each function call. I have had a lot of luck with getting calls to work on the 0i-model F. That is what we use primarily and what I write 90% of my code for. I usually use 30i in the compatibility chart to see whether or not a focas call is going to work since they are pretty close in that regard.
Another question I have: By just copying the file into my same ‘Program.cs’ directory did not work. I could only manage to run this using your code available on github. I’ve also noticed that your project uses .NET Framework (Instead of .NET core, which i had used). Is that a requirement? Are there any other thinks to set up?
Thanks.
Hi Hiram,
I am not entirely sure what file you are referring to. I am assuming that you are talking about the fwlib32.cs file. You need to add that file to your project inside visual studio if you haven’t done that. To do that you simply need to right-click on the project name in the Solutions pane, highlight “Add” and select “Existing Item…” and select the fwlib32.cs file. This will add it to your project. After you have done that you can just call Focas1.[method name].
That being said, I have honestly not tried this with a .Net core project. I would assume that this work, but there may be something that is causing an incompatibility. I will do some testing this evening to see if I can get it to work and I will let you know when I find something out.
*** Update ***
I just tried it out and it seems to be working in .Net core. Let me know if adding the file to your project doesn’t work and I will try to see if I can help you.
Hi Versex,
Can I please have your help to show the steps required to change solution from .net framework to .net core? Thank you
Hello,
For some Fanuc CNC’s we observe Focas2 inside PCMCIA option. It doesn’t has EMBED option and not even the embedded ethernet port. In such cases, how to connect and collect data using Focas2 library?
Hi Chirag,
Unfortunately, I have never use PCMCIA on a machine before. Now a quick Google search is bringing up a document that shows that it should be possible. I will link it below. Looking at it, there are some parameters that can be changed that may help. I do not know what model of control you have, so some of the parameters may not apply. If you let me know what model of controller you are looking at, I may be able to find some more relevant information. Take a look through this document and see if this is any help. Let me know what you find!
https://www.cnc1.com/hubfs/fanuc-library/Fanuc_30i_Ethernet_Settings.pdf
It is a Fanuc Oi-Mate TD controller. The newer Oi-Mate TD has EMBED option by default (controller’s manufactured from 2014). But Fanuc controller’s before that say from 2010 uptil 2014 has this Focas2 inside PCMCIA.
Thanks for your reply.
Hello Sir,
It is a Fanuc Oi-Mate TD controller. The newer Oi-Mate TD has EMBED option by default (controller’s manufactured from 2014). But Fanuc controller’s before that say from 2010 uptil 2014 has this Focas2 inside PCMCIA.
Thanks for your reply.
I am working with Fanuc Oi -MD model. Does it supports FOCAS. As well as, which method, Ethernet or serial communication can be used for data acquisition from this machine. Also is it possible to interface with ARM or ATmega series or any other controller.
Hi Prashant,
It really depends on whether or not your CNC has a Windows-based HMI. If you only have a hand pad then you will need to use Ethernet communication. If you have an HMI with Windows on it, you should be able to use HSSB. To check whether or not you have the hardware to communicate over HSSB, you can go to the HMI, open the Device Manager in Windows, and you should see HSSB (High-Speed Serial Bus) in there. If you do not, then you will need to use Ethernet. Those are the only two communication methods that I am aware of. I am sure that on older CNCs you could probably do some RS232 communication, but I have never run into a machine that old.
Hello sir, thank you for the effort you put in this tutorial. I tried to use it to establish a connection to a series 31I cnc but I cannot succeed, I keep getting error code -15, which according to the documentation means there is an issue with the dll. The dll I got is the one fwlib32.cs file refers to, which is fwlib32.dll… what am I missing here? Thank you in advance for your time, much appreciated 🙂
Hi Versex,
I have problem to get the C# project reference to ‘Fwlib32.dll’. Visual Studio does not allowed me to add reference to ‘Fwlib32.dll’ using standard way (right click project ‘Reference’ folder & add reference), with following error:
“Fwlib32.dll could not be added. Please make sure that the file is accessible, and that it is a valid assembly or COM component”
I resolve this issue by pasting ‘Fwlib32.dll’ directly into debug folder, but error code -15 (DLL file error) received when I try to establish connection using ‘cnc_allclibhndl3’. Does it mean there is something wrong with my ‘Fwlib32.dll’? Can I please have your advice on this?
Thank you.
Hi James,
For a C# project you do not add the dll as a reference. You need to add the fwlib32.cs file that is linked at the bottom of the first post. The dlls will reside in the machine panel. If you need to run the app on a regular computer, you will need to copy the dlls to the SysWow64 folder on whatever computer you want to run the application on. Let me know if you need help with anything.
Hi, Is is possible to feed back or write data in real time into Macros / programs with fanuc FOCAS?
or is it possible to read the macros ?
Sanjay,
While there is a method to edit an active program, I am not sure that you can edit it while it is in a “Running” state. With that said, you would not want to do that anyway because it greatly increases the risk of you crashing your machine can causing damage to the machine or the operator running the machine.
With that said, one of the things you can do is use macro variables to make the program more dynamic. For instance, you could check the state of a macro variable to see if it is set to 1 and then have it do something different if it is set to 1 instead of 0. You can even prompt the user to enter in a value at runtime. I hope this helps. If you have specific questions, I highly suggest using the Forum located at https://hierthinking.com/forum/forum/cnc-focas/
Thanks for creating such a site.
I’m trying to run the example I downloaded from your site. When I run it I get the result of -3. When I check the error from the inventcom site, the site says that I am missing a driver. But I loaded all the dll files into the SYSWOW64 file.
[…] It’s Time to Focas – Part 2: https://hierthinking.com/2020/04/27/its-time-to-focas-p2/ […]
so i followed all the instructions and i got this error ” Unable to load DLL ‘FWLIB32.dll’: The specified module could not be found. (Exception from HRESULT: 0x8007007E)” but i’ve copied all the dll files as mentioned to C: windows\system32 folder, but i did’nt not get those files from the fanuc machine hmi (didnt know how to get, could you please help in doing so), but i’ve copied the dll files from github page, which was trying to create an mtconnect adapter for focas machine, here’s the link: https://github.com/hehuang26/fanuc , Can you please help me out
I always get it mixed up. Try loading all the DLLs into C:\Windows\SysWow64 and then try running your program. Let me know if that works
[…] It’s Time to Focas – Part 2: https://hierthinking.com/2020/04/27/its-time-to-focas-p2/ […]
[…] It’s Time to Focas – Part 2: https://hierthinking.com/2020/04/27/its-time-to-focas-p2/ […]
[…] It’s Time to Focas – Part 2: https://hierthinking.com/2020/04/27/its-time-to-focas-p2/ […]
[…] It’s Time to Focas – Part 2: https://hierthinking.com/2020/04/27/its-time-to-focas-p2/ […]