概要
FANUC CNCのイーサネット通信は、FOCAS2プロトコルで通信します。ここでは、C#を使用してFANUC CNCとパソコンをイーサネットで接続してカスタムマクロ変数値を読み出すプログラムの製作方法に関して記します。
尚、本記事とサンプルソフトは、FANUCの取説等を参考にして独自に作成した物でFANUCが公式に発表しているものではありません。記載誤りやサンプルソフトのバグ等に関してはご容赦お願いいたします。
カスタムマクロ変数に関して
FANUC CNCはG言語でカスタムマクロ機能があります。カスタムマクロで使用する変数をカスタムマクロ変数と呼びます。カスタムマクロ変数は#の後に数字を書いたもので、以下のような種類があります。
変数 | 役割 | 解説 |
#1~#33 | ローカル変数 | マクロ内でローカルに使用される変数 |
#100~#199 #500~#999 #98000~#98499 | コモン変数 | メインプログラム、サブプログラム等共通で使用される変数 |
カスタムマクロ変数を使用したプログラム例を示します。
#1=10.0
#2=100.0
G01 X#1 Y#2 F200.0
FOCAS2ライブラリに関して
FANUC CNCとイーサネット接続するソフトウェアを製作するには、FANUCから供給されるFOCAS2 LibraryのAPIを使用します。このAPIはC言語の関数です。FOCAS2 LibraryにはDLLやサンプルコードやドキュメント等の関連ファイルが入っています。
カスタムマクロ変数値を読み出すために使用するAPI
FANUC CNCからイーサネット接続でカスタムマクロ変数値を読み出すために使用するAPIは以下の通りです。(FOCAS2 Libraryの取説より)
関数名 | 用途 | 説明 |
cnc_allclibhndl3() | ライブラリハンドルの取得(Ethernet用) | ライブラリハンドルを取得し、指定されたIPアドレスに接続します |
cnc_freelibhndl() | ライブラリハンドルの解放 | ライブラリで使用するライブラリハンドルを解放します |
cnc_rdmacro() | カスタムマクロ変数のリード | 指定された番号のカスタムマクロ変数を読み出します。 |
cnc_allclibhndl3()
【関数宣言】 #include "fwlib32.h" or "fwlib64.h" FWLIBAPI short WINAPI cnc_allclibhndl3(const char *ipaddr, unsigned short port, long timeout, unsigned short *FlibHndl); 【引数】 ipaddr 接続するCNCのIPアドレス、またはホスト名を示す文字列を指定します。(例"192.168.0.1") port FOCAS2/Ethernet(TCP)機能のポート番号を指定します。 timeout タイムアウトの秒数を指定します。0を指定すると、タイムアウト処理が無効化されて、無限に待つようになります。 FlibHndl ライブラリハンドルを格納する変数へのポインタです。 【戻り値】 EW_SOCKET ソケット通信エラー。 CNCの電源、イーサネットボード、イーサネットケーブルを確認して下さい。 EW_NODLL 機能別DLLが存在しません。 EW_HANDLE ハンドル取得に失敗しました。
cnc_freelibhndl()
【関数宣言】 #include "fwlib32.h" or "fwlib64.h" FWLIBAPI short WINAPI cnc_freelibhndl(unsigned short FlibHndl); 【引数】 FlibHndl 解放するライブラリハンドルを指定します。 【戻り値】 成功するとEW_OKを返し、エラーの場合はEW_OK以外の値を返します。
cnc_rdmacro()
#include "fwlib32.h" or "fwlib64.h" FWLIBAPI short WINAPI cnc_rdmacro(unsigned short FlibHndl, short number, short length, ODBM *macro); 【引数】 FlibHndl ライブラリのハンドルです。 number リードするカスタムマクロ変数の番号を指定します。 length データブロック長を指定します。必ず10 (ODBM構造体のサイズ)を指定します。 macro カスタムマクロ変数を返すODBM構造体へのポインタです。ODBM構造体は次の通りです。 typedef struct odbm { short datano; //カスタムマクロ変数番号 short dummy; //未使用 long mcr_val; //カスタムマクロ変数値 short dec_val; //少数点以下桁数 }ODBM; 【戻り値】 EW_LENGTH データブロック長の誤り EW_NUMBER データ番号の誤り EW_NOOPT オプションなし。CNCにカスタムマクロ機能が必要です。
C#でFOCAS2のAPIを使用する方法
C#でFOCAS2のAPIを使用するためには、32bit UPUではFOCAS2 Libraryに入っているfwlib32.csとFwlib32.dllとfwlib1.dllを使用します。 64bit CPUではfwlib64.csとFwlib64.dll等を使用すると思われますが、今回は32bitでソフト作成したので、以降は32bit用に関して示します。(今回使用したパソコンは64bitの物なので、32bit用に作成しても64bitパソコンで動作可能でした) fwlib32.csではDllInportを使用して各API関数の名前を指定してC#からの呼び出しを可能としています。 例えばcnc_rdmacro()に関しては、public class Focas1の中で次の様に記載されています。 クラスとしてFocas1となっていますが、
/* read custom macro variable */ [DllImport("FWLIB32.dll", EntryPoint="cnc_rdmacro")] public static extern short cnc_rdmacro( ushort FlibHndl, short a, short b, [Out,MarshalAs(UnmanagedType.LPStruct)] ODBM c ); これによってC#プログラムで Focas1.cnc_rdmacro(引数,----); と記述することによってcnc_rdmacro()関数を読み出すことができます。 クラス名がFocas1となっていますが、ファナックの通信規格ではFocas1はFocas2の前のバージョンですが、C#の32bit用のコードではクラス名はFocas1となっています。
具体的な手順
ここでは開発ツールとしてVisual Studio 2022を使用した手順を示します。開発ツールのバージョンが異なると手順が異なることがあります。 Visual Stadio 2022を起動し、「新しいプロジェクトの作成(N)」をクリックします。
「Windowsフォームアプリ」を選択して、「次へ(N)」をクリックします。
プロジェクト名とプロジェクトファイル保管場所を指定して、「次へ(N)」をクリックします。ここではプロジェクト名をWinFormsApp1とします。
プログラミング編集用の初期画面が表示されます。Form1の画像が表示されます。
コンパイラでFOCAS2 Libraryを使用可能とするためにDLL等をプロジェクトフォルダにコピーします。 先ず、FOCAS2ライブラリーの FOCAS2 Library\Fwlib\Dot NET sample フォルダにあるfwlib32.csファイルをプロジェクトフォルダ WinFormsApp1\WinFormsApp1 フォルダにコピーします。
FOCAS2ライブラリーの FOCAS2 Library\Fwlib フォルダにあるFwlib32.dllとfwlib1.dllを最終的にコンパイルして出来る実行可能プログラムのEXEファイルと同じ場所に置きます。 FOCAS2 LibraryのDLLは.NETを使用していないので、依存関係のプロジェクト参照の追加は使用できません。DLLファイルはEXEファイルと同じ場所に置く必要があります。 デバッグモード時では次のフォルダにEXEファイルが出来ます。 WinFormsApp1\bin\Debug\net8.0-windows このフォルダにFwlib32.dllとfwlib1.dllをコピーします。
Visual Studioの画面の、ソリューションエクスプローラでWinFormsApp1を右クリックして「プロパティ」をクリックします。
「ビルド」の「プラットフォームターゲット」をAny CPUからx86に変更します。これは今回使用するDLLが32bit用なので必要です。
ソリューションエクスプローラでWinFormsApp1の下にfwlib32.csが追加されているのを確認します。 追加されてない場合は、ソリューションエクスプローラでWinFormsApp1を右クリックして表示される「追加(D)」をクリックして「既存の項目(D)」をクリックしてfwlib32.csを選んで追加して下さい。
フォームの作成
今回は次のようなフォームを作成しました。
- 「読出変数番号」を入力するTextBox: MacNoTextBox
- 「変数値」を表示するTextBox: ValueTextBox
- 「少数点以下の桁数」を表示するTextBox: DecPosTextBox
- 「読出」Button: ReadButton
【説明】 「読出変数番号」のテキストボックスに、FANUC CNCから読み出すマクロ変数番号を入力します。 マクロ変数値を読み出すAPIでは、変数値の整数値と、その整数値に対する少数点以下の桁数の形で読み出されるので、それらを「変数値」のテキストボックスと「小数点以下の桁数」のテキストボックスに表示します。 読出ボタンを押すとFANUC CNCとイーサネット接続して指定したマクロ変数値を読み出して、変数値と小数点以下の桁数を表示します。
プログラム
以下にForm1クラスのプログラムを示します。
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
//読込ボタン押された
private void ReadButton_Click(object sender, EventArgs e)
{
ushort FlibHndl;
//IPアドレスをユニコードからASCIIコード文字列に直す
string ipAddressTxt = "192.168.0.1"; //FANUC CNCのIPアドレス
byte[] ipaddrByte = Encoding.ASCII.GetBytes(ipAddressTxt);
Array.Resize(ref ipaddrByte, ipaddrByte.Length + 1); //バイトサイズを1文字分拡張
ipaddrByte[ipaddrByte.Length - 1] = 0x00; //文字列の最後にゼロを入れる
//FANAC CNCとイーサネット接続
short result = Focas1.cnc_allclibhndl3(ipaddrByte, 8193, 10, out FlibHndl); //接続
if ((Focas1.focas_ret)result != Focas1.focas_ret.EW_OK)
{
MessageBox.Show("イーサネット接続不良発生");
return;
}
//マクロ変数値読み出し
Focas1.ODBM MacroData = new Focas1.ODBM();
short macNo = Convert.ToInt16(MacNoTextBox.Text); //読み出すマクロ変数番号
result = Focas1.cnc_rdmacro(FlibHndl, macNo, 10, MacroData); //読み出し
if ((Focas1.focas_ret)result != Focas1.focas_ret.EW_OK)
{
MessageBox.Show("マクロ変数値読み出し不良発生");
return;
}
ValueTextBox.Text = Convert.ToString(MacroData.mcr_val); //変数値表示
DecPosTextBox.Text = Convert.ToString(MacroData.dec_val); //少数点以下の桁数
//FANUC CNCとのイーサネット接続を切断
result = Focas1.cnc_freelibhndl(FlibHndl); //切断
if ((Focas1.focas_ret)result != Focas1.focas_ret.EW_OK)
{
MessageBox.Show("イーサネット切断異常発生");
}
}
}
プログラム説明
プログラムに各部に関する説明を以下に記します。
フォームの読込ボタンを押すと起動されるメソッドです。 フォームの編集画面で「読込」ボタンをダブルクリックすると、このメソッドが生成されます
//読込ボタン押された
private void ReadButton_Click(object sender, EventArgs e)
{
ここではイーサネット接続するFANUC CNCのIPアドレスを192.168.0.1とします。 C#では文字コードはユニコードですが、マクロ変数値を読出すAPIの引数へはASCIIコードで渡す必要があるのでユニコードからASCIIコードの文字列に変換しています。
//IPアドレスをユニコードからASCIIコード文字列に直す
string ipAddressTxt = "192.168.0.1"; //FANUC CNCのIPアドレス
byte[] ipaddrByte = Encoding.ASCII.GetBytes(ipAddressTxt);
Array.Resize(ref ipaddrByte, ipaddrByte.Length + 1); //バイトサイズを1文字分拡張
ipaddrByte[ipaddrByte.Length - 1] = 0x00; //文字列の最後にゼロを入
FANUC CNCとイーサネット接続します。8193はポート番号、10はタイムアウト時間で10秒です。FlibHndlは接続後に各APIで指定するハンドルです。 戻り値がFocas1.focas_ret.EW_OK以外の場合はエラー発生です。エラーの場合、エラー内容が分類された値が戻りますので、それらをきちっと処理するのが良いと思われますが、ここでは簡略化のためまとめて異常とします。
//FANAC CNCとイーサネット接続
short result = Focas1.cnc_allclibhndl3(ipaddrByte, 8193, 10, out FlibHndl); //接続
if ((Focas1.focas_ret)result != Focas1.focas_ret.EW_OK)
{
MessageBox.Show("イーサネット接続不良発生");
return;
}
FANUC CNCから指定したカスタムマクロ変数値を読出します。 Focas1.cnc_allclibhndl3()でイーサネット接続した時に値を得たFlibHndlを使用して、macNoで読出したいカスタムマクロ変数の番号を指定します。 読み出されたカスタムマクロ変数値はODBMクラスの変数に読出されます。ODBMクラスの構造を以下に示します。
typedef struct odbm { short datano; //カスタムマクロ変数番号 short dummy; //未使用 long mcr_val; //カスタムマクロ変数値 short dec_val; //少数点以下桁数 }ODBM;
//マクロ変数値読み出し
Focas1.ODBM MacroData = new Focas1.ODBM();
short macNo = Convert.ToInt16(MacNoTextBox.Text); //読み出すマクロ変数番号
result = Focas1.cnc_rdmacro(FlibHndl, macNo, 10, MacroData); //読み出し
if ((Focas1.focas_ret)result != Focas1.focas_ret.EW_OK)
{
MessageBox.Show("マクロ変数値読み出し不良発生");
return;
}
ValueTextBox.Text = Convert.ToString(MacroData.mcr_val); //変数値表示
DecPosTextBox.Text = Convert.ToString(MacroData.dec_val); //少数点以下の桁数
FANUC CNCとのイーサネット接続を解除します。Focas1.cnc_allclibhndl3()でイーサネット接続した時に値を得たFlibHndlを使用します。
//FANUC CNCとのイーサネット接続を切断
result = Focas1.cnc_freelibhndl(FlibHndl); //切断
if ((Focas1.focas_ret)result != Focas1.focas_ret.EW_OK)
{
MessageBox.Show("イーサネット切断異常発生");
}
最後に
以上で、FANUC CNCとイーサネット接続するC#プログラムの説明を終わります。思わぬミスや考え違いがあるかもしれませんがご容赦お願いいたします。