Tag Archives: mtconnect

MTConnect Agent – FANUC Macro Variables

Macro variables are used in just about every shop process because of their flexibility and utility.  Being able to read them is a critical part of any data collection system.  As MTConnect focuses on standardization, the variables are excluded.  It is however simple to add them to any MTConnect connection to a FANUC CNC control.  Once the Adapter is setup to read macro variables ( see tutorial here) It’s time to setup the Agent.

The MTConnect agent setup is surprisingly simple.  Almost too simple.  Initially I struggled for hours trying to learn and understand how to extend the agent schema files to accept the macro variables.  I used this tutorial here as a base.  It turns out the only necessary step is to add the following line to the device xml file…


<DataItem type="VARIABLE" category="EVENT" id="mc1" name="whale">

That’s it…  That’s That and That’s all.  The type and id can be anything you like.  In this example I’ve used VARIABLE” and “mc1“.  The agent simply matches the value of the name property, with the matching name that is output from the adapter. 


port = 7878
service = MTC Focus 1

host =

whale = 500

SspeedOvr = 30
Fovr = 12

Macro variable 500 is tied to  the name “whale” at the adapter.  The agent matches the name “whale” and continues to pass it on to the client.

macro screen

Too easy.

MTConnect Blog Posts

MTConnect Links

As the number of posts increases, some are getting lost.  Just to keep things organized here is a list of posts grouped by topic.




MTConnect FANUC Adapter on Ubuntu Linux

MTConnect Adapter for Windows

MTConnect FANUC Adapter PMC Addresses

MTConnect-FANUC Macro Variables


MTConnect Agent on Ubuntu Linux

MTConnect Agent – FANUC Macro Variables


This would be a great place to make any requests for tutorials or posts.  I’m happy to entertain.  Of course the target should be MTConnect :)

MTConnect – FANUC Macro Variables

Updating the FANUC Adpater for Stable Macro Variables

The current edition of the FANUC MTConnect adapter as of this writing was unstable on my platform.  Any time a macro variable was entered in the adapter.ini file, the adapter crashed shortly after connection.  This seems to be related to threading and access to the datum.  To rectify this I rewrote the getMacros() function of fanuc_adapater.  It no longer supports the multipath macro’s and is less efficient, however it works consistently without any errors.  Additionally, I was feeling lazy and included the <math.h> header to properly calculate the decimal point in the variable.

fanuc_adapter.cpp,  rewritten getMacros():

#include <math.h>
 void FanucAdapter::getMacros()
    if (!mConnected)
    for (int i = 0; i < mMacroSampleCount; i++)
       ODBM macro;
       short ret = cnc_rdmacro(mFlibhndl, mMacroSample[i]->getNumber(), sizeof(ODBM), &macro);
       if (ret == EW_OK)
          double rational = macro.mcr_val;
          double decimal = macro.dec_val;
          double exp = pow( 10, decimal );
          double resultant = rational / exp;
          printf("Could not retrieve PMC data at %d for %s: %d\n", mMacroSample[i], mMacroSample[i]->getNumber(), ret);

Now if we put a macro variable in the adapter.ini file as such:


port = 7878
service = MTC Focus 1
host =
whale = 500
cabbage = 501
SspeedOvr = 30
Fovr = 12

the adapter will correctly pass on the named macro variables:


2014-07-14T17:04:00.057Z|avail|AVAILABLE|part_count|7|whale|1.23456789|cabbage|2|SspeedOvr|0|Fovr|0|turkey|0|tool_id|0|program|3.0|line|0|block|O0000%|path_feedrate|0|path_position|0.0000000000 0.0000000000 0.0000000000|active_axes|X Y Z|mode|MANUAL_DATA_INPUT



2014-07-14T17:04:00.057Z|logic|FAULT|100|||PARAMETER ENABLE SWITCH ON

Which matches our FANUC FS0iD control:

macro screen

Cool Eh?  Macro variables are a critical part of any modern CNC shop, and being able to read them via MTConnect opens tremendous possibilities.  Custom parts counts can be made, operation conditions can be read,  etc.  The possibilities are endless.

MTConnect FANUC Adapter PMC Addresses

The current version of FANUC MTConnect adapter only supports PMC G address.  From a standardization point of view this is a great decision. The other PMC addresses including R,K,D,C and T are used by the machine tool builders and are assigned differently between machines.  Conversely the G Addresses are defined by FANUC and consistent between machines.  However, in practical terms, much can be gleaned about the machine condition through these addresses when customized to the machine.  With just a small modification to the existing FANUC MTConnect adapter, it can support all addresses.

By default, the addresses are defined in the adapter.ini file under the [pmc] section.  The sample adapter.ini file has two addresses mapped, G12-Feedrate override and

Firstly, the source file fanuc_adapter.cpp has one line of code that reads pmc addresses over FOCAS.  The FOCAS call expects the address type as an integer, G=0, F=1, Y=2, X=3, and so on.  In order to read addresses other than G we will need to specify the address.  The easiest was to achieve this is to pass an append the integer of the address to the front of the address.  For example, pmc address Y0078 would become 20078.  Then it’s just a simple matter of separating the prefix from the address.  Additionally, the orginal adapter incorrectly handles a negative value.  The code below is correct so the PMC address is reported properly if it is negative return. Here is the code:

void FanucAdapter::getPMC()
 if (!mConnected)
 for (int i = 0; i &lt; mPMCCount; i++)
 // Seperate the data type
 int pmcType = mPMCAddress[i]/10000;
 int pmcAddress = mPMCAddress[i]%10000;
 short ret = pmc_rdpmcrng(mFlibhndl, pmcType, 0 /* byte */,
 pmcAddress, pmcAddress, 8 + 1,
 if (ret == EW_OK)
 if (buf.u.cdata[0] < 0)
 mPMCVariable[i]->setValue(-buf.u.cdata[0] + 128);
 printf("Could not retrieve PMC data at %d for %s: %d\n",
 mPMCAddress[i], mPMCVariable[i]->getName(), ret);

Now that the source code will properly read any PMC address, we just need to modify the addresses in the adapter.ini file as below:

port = 7878
service = MTC Focus 1
host =
# PMC Types G=0, F=1, Y=2, X=3, A=4, R=5, T=6, K=7, C=8, D=9
# PMC Address G22 would by 00022, R99 would be 50099 etc.
SspeedOvr = 00030
Fovr = 00012
turkey = 50033

This creates the following stream output from the MTConnect FANUC adapter:  Address R33 was 10000000 in binary, which correctly output as turkey|127 in decimal.

output of adapter at  http://some.ip.address:7878/
2014-07-10T15:12:52.633Z|part_count|7|SspeedOvr|0|Fovr|0|turkey|127|tool_id|0|program|3.0|line|0|block|O0000%|path_feedrate|0|path_position|0.0000000000 0.0000000000 -0.0010000000|mode|MANUAL_DATA_INPUT
2014-07-10T15:12:52.633Z|logic|FAULT|100|||PARAMETER ENABLE SWITCH ON

That’s it.  This same procedure will work for all controls including the FANUC FS30/31/32 and FS16/18/21 controls.  However, the address to number conversions may have to be re-arranged.

If you use this post please write a comment below.  Thanks.

MTConnect for FANUC Overview



When first starting developing with MTConnect all of the pieces can be very overwhelming.  I thought it might be helpful to break down the pieces and the connection between them.  Even though the MTConnect Adapter for FANUC and the MTConnect agent are complete from the GitHub repository, when developing client applications or setting up the pieces an overview is helpful.


Click the picture for a larger view


Setting up MTConnect starts at the FANUC control.  The control must have an Ethernet connection and the optional FOCAS function.  Most modern controls have FOCAS available from the factory via an embedded Ethernet port on the main board of the CNC control.  Check this blog post here to setup the FOCAS connection.

The adapter and agent are best run on a server based on either Linux or Microsoft Windows.  Additionally, running the adapter on a low cost Linux platform located directly in the CNC can help reduce server and network load.


The FANUC control only speaks FOCAS, a very robust and powerful API that personal computers use to read and write information on the CNC.  The MTConnect adapter does all the heavy lifting and converts FOCAS to an MTConnect data stream.   The adapter streams data to the agent via http protocol which is human readable from Internet Explorer.  Here is the sample output from the FANUC adapter:  http://adapter.ip.address:7878/



As all of the pieces of MTConnect are based on some type of TCP communication, the devices find each other by knowing the IP Address and port number of the previous device.  The client knows the IP address of the agent, the agent knows the adapter, and the adapter knows the FANUC CNC.


Ultimately the client will consume XML requested from the agent.  The structure of the XML is determined by the schema specified for each machine.  The agent takes adapter data and matches the schema name‘s with adapter stream labels.  It records the stream into a buffer.  It is that buffer of data that is served when the client requests the XML.


MTConnect FANUC Adapter on Ubuntu Linux


The FANUC FOCAS shared library from the FANUC FOCAS CD A02B-0207-K737 version 4.1 or higher  must first be installed and registered in Ubuntu 14.04 LTS.

$ sudo cp libfwlib32.so.1.0.0 /usr/local/lib/libfwlib32.so.1.0.0
$ sudo ldconfig
$ sudo ln -s /usr/local/lib/libfwlib32.so.1.0.0 /usr/local/lib/libfwlib32.so

Next up we need to get the MTConnect adapter from GitHub.

$ cd ~ 
$ git clone https://github.com/mtconnect/adapter.git

We only actually need a limited subset of files from the adapter downloaded from GitHub.  For convenience in building the binary we will copy all the needed files to the same directory. (Note, so wildcards can be used more than the needed files are copied.)

$ mkdir fanuc
$ cp ~/adapter/fanuc/adapter.ini ~/fanuc/adapter.ini
$ cp ~/adapter/fanuc/fanuc.xml ~/fanuc/fanuc.xml
$ cp ~/adapter/fanuc/*.cpp ~/fanuc/
$ cp ~/adapter/fanuc/*.hpp ~/fanuc/
$ cp ~/adapter/src/*.cpp ~/fanuc/
$ cp ~/adapter/src/*.hpp ~/fanuc/
$ cp ~/adapter/minIni_07/*.c ~/fanuc/
$ cp ~/adapter/minIni_07/*.h ~/fanuc/

Once the files are in the ~/fanuc/ directory, we need to modify the source code.  The GitHub adapter was meant for Windows, and their are several functions that need to be modified.

$ sudo nano ~/fanuc/fanuc_adapter.cpp
    Remove: #include <excpt.h>
    Change: __try and __exception to try/catch(...)

    Change: Sleep(5000) to sleep(5)

    Change: _strnicmp() to strncasecmp()

    Add Before : short ret = :: cnc_allclibhndl3...

    long level = 3;
    std::string filename = "focas.log";
    const char * c =  filename.c_str();
    short log = ::cnc_startupprocess(level, c);

    Add After: cnc_freelibhndl....


Finally the header file for Linux from the FOCAS cd is copied to the directory.  Note the name change required as the source files refer to to Fwlib32.h.

$ sudo cp fwlib32.h ~/fanuc/Fwlib32.h

With the source code modified, its time to compile the binary.  Sorry for the sloppy g++ command, this could be cleaned up with a nice CMakeLists.txt.

$ cd ~/fanuc/
$ g++ minIni.c device_datum.cpp fanuc_axis.cpp fanuc_path.cpp service.cpp condition.cpp cutting_tool.cpp string_buffer.cpp logger.cpp client.cpp server.cpp adapter.cpp fanuc_adapter.cpp FanucAdapter.cpp -lfwlib32 -lpthread -o adapter

Finally setup the adapter.ini file with the appropriate settings for your machine and run the binary.

$ ./adapter debug adapter.ini

Conclusion I’m certain one day the source code for the Linux FANUC adapter will be available from GitHub as the code is just a slight adaptation from the Windows version.  Until then, I hope you enjoyed this tutorial!

MTConnect FANUC Adapter for Windows

In this tutorial we install the MTConnect FANUC Adapter in Windows and connect to a FANUC FS0iD control.  The source code is downloaded and compiled before some settings are made to establish a connection to the machine.

1.  Download the MTConnect Adapter source code from:  https://github.com/mtconnect/adapter

2.  Extract the source code to your PC

3.  Copy the appropriate  Fwlib32.h file from FANUC FOCAS cd into the /adapter/fanuc/ directory for the control we are connecting to.

4.  Copy all of the .dll and library files from the FANUC FOCAS cd into the /adapter/fanuc/ directory on your PC.

4.5  Copy the Fwlib32.dll file from the FOCAS cd to C:\Windows\System32\

5.  Open the /fanuc/fanuc.sln solution file in Microsoft Visual C++ 2010.

6.  Right click on the project and open the properties dialog from the context menu.

7.  Select Linker->Input from the left menu.

c++ properties dialog

8.  Change the Configuration drop down box to Release 0iD

9.  Remove the /fwlib/ from the additional dependencies so they properly point to the libraries.

10.  Close the properties dialog.

11.  Change the build drop down to Release 0iD

Visual c++ configuration

12.  Press F7 to build the solution.

13.  Copy /adapter/fanuc/adapter.cfg to /adapter/fanuc/Release0iD/adapter.cfg

14.  Open the adapter.cfg file with a text editor and change the IP Address to match the machine we are connecting to.

15.  From the command prompt, run the compiled binary with the option debug.

c:\adapter\fanuc\release0id\fanuc_0id debug

adapter dos run

16.  Test by having your agent connect to this adapter!  Once the adapter is tested it can be installed into windows by running:

c:\adapter\fanuc\release0id\fanuc_0id install

Good Luck!


Confirm FOCAS is installed

FOCAS is an optional function.  If it is installed, the setting screen will be available.  The screen is located under the system hard key; followed by the continuous menu soft key several times.


continuous menu softkey

Keep scrolling through the available softkeys until the [Embed Port] soft key is displayed.  All of the available ethernet interfaces will be shown.

ethernet softkeys

Of the three listed here, [Ether Board] is the best choice.   It is an add on hardware board for Ethernet communication.  Press the [Ether Board] soft key.  If the [FOCAS2] softkey is now displayed, FOCAS is installed !!!  Plug your Ethernet cable into the add on boards RJ45 plug.

focas2 softkey

If you didn’t find the [FOCAS2] softkey, then check to see if it exists under the [Embed Port] softkey.  If it does, then connect your Ethernet cable into the RJ45 plug directly on the mainboard of the FS0iD contol.   Setting FOCAS2 In order to set the FOCAS settings, we first need to be in MDI mode.  Parameter Write Enable (PWE) is then enabled under the <OFS/SET> hard key [SETTING] softkey.

set PWE

Once PWE is set the IP Address of the control is set by <SYSTEM>, [Ethe Board], [COMMON].  The IP address will be a fixed address assigned by the network administrator.

IPAddress Setting

Finally the TCP Port number is set under the [FOCAS2] settings.  This port is typically 8193, however, any valid TCP port number can be used.

TCPPort setting


If everything is set correctly the FANUC FS0iD CNC should be reachable from any computer on the same network.  In Microsoft Windows, start a new command prompt and ping the CNC.


You are now ready to use FANUC FOCAS to read and write information to the CNC.  Although the FOCAS drivers and libraries is a programming interface for C/C++ or Visual Basic, there are many available options that don’t require programming such as MTConnect and OPC converters to FOCAS.

Good Luck!

MTConnect Agent on Ubuntu Linux


Before MTConnect can be installed some prerequisites must be in place.  A clean install of Ubuntu 14.04 LTS will not have many of the packages required.  Install these packages using the apt-get command.

$ sudo apt-get install libxml2 libxml2-dev cmake git libcppunit-dev build-essential screen ruby

After all the required packages are in place, the MTConnect source code needs to be downloaded from GutHub.  The source code should compile without any modifcation using cmake and make.

$ cd ~
$ git clone https://github.com/mtconnect/cppagent.git
$ cd cppagent
$ cmake .
$ make

MTConnect Agent Installation

Now that binaries are compiled from the MTConnect source, they just need to be put into appropriate directories.   The agent binary and the configuration file are first.

$ sudo mkdir /etc/mtconnect
$ sudo cp ~/cppagent/agent/agent.cfg /etc/mtconnect/
$ sudo cp ~/cppagent/agent/agent /bin/agent

The source from GitHub contains a script to run MTConnect as a daemon.  I instead opted to write a BASH script that suited my needs a little better.  The script is available at the end of blog.  The blog downloads it from this server.  After it is downloaded it is given permission to execute and added to the startup scripts.

$ cd ~
$ wget http://www.ellisware.com/downloads/agent.sh
$ sudo mv ~/agent.sh /etc/init.d/agent
$ sudo chmod +x /etc/init.d/agent
$ sudo update-rc.d agent defaults

The script requires the user ‘mtconnect’.  So we need to add that user.  Pick a password that is appropriate for you.  For security reasons, you probably should pick a different username and change it in the script, however, this blog uses the default.

$ sudo adduser mtconnect

MTConnect Simulator Installation

The default configuration file that was downloaded with the source code defines a simulator.  For the MTConnect agent to start, it needs to connect to all devices listed in its configuration file.  So now we setup the simulator device.

$ sudo mkdir /etc/mtconnect/simulator
$ sudo rsync -avr ~/cppagent/simulator/ /etc/mtconnect/simulator/

The default configuration file expects the simulator adapter to be one directory above where we placed it.  To correct this, edit the agent.cfg file and point to the correct path for the simulator.

$ sudo nano /etc/mtconnect/agent.cfg

Original Path::  “Devices = ../simulator/VMC-3Axis.xml”

New Path:: “Devices = ./simulator/VMC-3Axis.xml”

Finally, the simulator is started up in a fresh screen.  The simulator blocks the process so just detach the screen using control A, D, after it is up and running.

$ screen -S simulator
$ cd /etc/mtconnect/simulator
$ ruby -v run_scenario.rb -l VMC-3Axis-Log.txt

<cntrl><a> followed by <d>


Testing the MTConnect agent is very simple.  First the agent is started using the script we created, if the script completes successfully we can make sure it is listening for incoming connections.

$ sudo service agent start
$ netstat - tcp -l

Active Internet connections (only servers)
tcp 0 0 *:7878 *:* LISTEN
tcp 0 0 *:5000 *:* LISTEN

With the default configuration the agent is listening on port 5000 and the simulator is listening on port 7878.  If these are listed in the netstat, then everything is good.   For the final confirmation, any browser can be used as client.

agent.ellisware.com:5000/ or agent.ellisware.com:5000/probe






Please let me know any mistakes, omissions or improvements in the code.  It took a great deal of patience to get this up and running, so feel free to ask any questions in the comments.


###### agent.sh #######

 # /etc/init.d/agent
 # version 0.0.1 2014-05-09 (YYYY-MM-DD)
 # Provides: agent
 # Required-Start: $local_fs $remote_fs
 # Required-Stop: $local_fs $remote_fs
 # Should-Start: $network
 # Should-Stop: $network
 # Default-Start: 2 3 4 5
 # Default-Stop: 0 1 6
 # Short-Description: MtConnect server
 # Description: Starts the MTConnect Agent server

as_user() {
if [ "$USERNAME" != "$ME" ]; then
  su - $USERNAME -c "$1"
  bash -c "$1"

mc_start() {
if netstat - tcp -l | grep -q 5000
  echo "$SERVICE is already running!"
  echo "Starting $SERVICE..."
  as_user "cd $CONFIGPATH && screen -dmS agent $INVOCATION"
  sleep 10
  if netstat - tcp -l | grep -q 5000
    echo "$SERVICE is now running."
    echo "Error! Could not start $SERVICE!"

mc_stop() {
if netstat - tcp -l | grep -q 5000
  echo "Stopping $SERVICE"
  as_user "screen -p 0 -S agent -X stuff \"^C\""
  sleep 10
  echo "$SERVICE was not running."
if netstat - tcp -l | grep -q 5000
  echo "Error! $SERVICE could not be stopped."
  echo "$SERVICE is stopped."

#Start-Stop here
case "$1" in
if netstat - tcp -l | grep -q 5000
  echo "$SERVICE is running."
  echo "$SERVICE is not running."
echo "Usage: $0 {start|stop|status|restart}"
exit 1
exit 0