こちらのシリーズではSysmac Studioの様々なFC・FBをプログラム例付きで解説します。今回はFileOpen・FileSeek・FileWrite・FielWriteVar・FileRead・FileReadVar・FileCloseというFBを紹介します。
さ、FAを楽しもう。

前書き
いつも私の技術ブログとYouTubeチャンネルをご覧いただき、心より感謝申し上げます。また、いまFullさん(full@桜 八重 (@fulhause) / X)と共に毎週水曜日の夜にお届けしている「高橋クリス」ラジオ番組を運営しています。
技術は独り占めせず、届けるもの
私たちは工場の生産技術や制御に関する技術情報を、ブログや動画などで無料公開しています。「知識は誰でもアクセスできるべき」という信念のもと、現場で役立つ具体的なノウハウやトラブル事例などを発信してきました。すべて無料で続けているのは、「知らなかったせいで困る人」を少しでも減らしたいからです。
また、もしあなたの現場で…
- 「このPLCとデバイスの組み合わせ、ちゃんと動くのかな?」
- 「EtherCAT通信でうまくいかない部分を検証してほしい」
- 「新しいリモートI/Oを試したいけど社内に検証環境がない」
など、困っている構成や試してみたいアイデアがあれば、ぜひお知らせください。機器の貸出や構成の共有が可能であれば、検証し、記事や動画で発信します(ご希望に応じて匿名対応も可能です)。
支援のかたち
現在、私達の活動はほぼ無償で続けており、記事や動画の制作には、時間と検証環境の整備が必要です。この活動を継続的にコンテンツを提供するためには、皆様の温かいご支援が大変重要です。
メンバーシップ(ラジオの応援)
Fullさんとのラジオをより充実させるための支援プランです。
https://note.com/fulhause/membership/join
Amazonギフトリスト
コンテンツ制作に必要な機材・書籍をリストにしています。
https://www.amazon.co.jp/hz/wishlist/ls/H7W3RRD7C5QG?ref_=wl_share
Patreon(ブログ・動画活動への応援)
月額での小さなご支援が、記事の執筆・検証環境の充実につながります。
https://www.patreon.com/user?u=84249391
Paypal
小さな支援が大きな力になります。
https://paypal.me/soup01threes?country.x=JP&locale.x=ja_JP
知ってたら助かること、届けたいだけです
あなたの応援が、知識の共有をもっと自由で持続可能なものにしてくれます。これからもどうぞよろしくお願いします。
soup01threes*gmail.com
技術はひとりじゃもったいない。
Reference Link
説明
注意事項!
- この命令の実行は、Executeの値がFALSEに変わった場合や実行時間がタスク周期を超えた場合でも、完了するまで継続されます。実行が完了すると、Doneの値がTRUEに変わります。これを使用して処理の正常完了を確認してください。
- FileIDの値を取得するには、事前にFileOpen命令を使用する必要があります。
- FileOpen命令で開いたファイルは、使用終了後、この命令を使用して必ず閉じる必要があります。
- CPUユニットの動作モードがPROGRAMモードに変更された場合、または重大故障レベルのコントローラエラーが発生した場合、開いているファイルはシステムによって閉じられます。進行中の読み取りまたは書き込み操作は最後まで継続されます。
- NJ/NXシリーズCPUユニットの場合、SDメモリカード電源スイッチを押して電源を停止したときにファイルが開いていても、ファイルは破損しません。ただし、ファイルは開いたままになります。FileClose命令を使用してファイルを閉じてください。
- NJ/NXシリーズCPUユニットの場合、ファイルが開いている状態で、SDメモリカード電源スイッチを押す前にSDメモリカードを取り外すと、ファイルの内容が破損する可能性があります。SDメモリカードを取り外す前に、必ず電源をOFFにしてください。
- NJ/NXシリーズCPUユニットの場合、ファイルが開いている状態で、SDメモリカード電源スイッチを押す前にSDメモリカードを取り外すと、ファイルは開いたままになります。FileClose命令を使用してファイルを閉じてください。
- NJ/NXシリーズCPUユニットの場合、電源が停止したとき、またはSDメモリカードが取り外されたときにファイルが開いていると、ファイルは開いたままになりますが、SDメモリカードを再度挿入してもファイルの読み取りや書き込みはできません。ファイルの読み取りや書き込みを行うには、ファイルを閉じてから再度開いてください。
- 同じファイルに同時にアクセスしないでください。ユーザープログラム内でSDメモリカード命令の排他制御を実行してください。
- 以下の場合にエラーが発生します。ErrorがTRUEに変わります。
- SDメモリカードが使用可能な状態ではない。
- FileIDで指定されたファイルが存在しない。
- FileIDで指定されたファイルが既に閉じられている。
- FileIDで指定されたファイルにアクセス中である。
- SDメモリカードへのアクセス中にエラーが発生し、アクセス失敗となる。
FB
次は今回記事で使用するFBを説明します。
FileOpen
FileOpen命令は、SDメモリカード内のFileNameで指定されたファイルを、Modeで指定されたモードで開きます。
結果はファイルID FileIDに出力されます。FileIDは、FileReadやFileWriteなどの他の命令でファイルを指定する際に使用されます。
Modeのデータ型は列挙型_eFOPEN_MODEです。列挙子の意味は以下の通りです:

|
列挙子 |
意味 |
|---|---|
|
READ_EXIST |
この値を使用して、既存のテキストファイルを読み取り用に開きます。ファイルは先頭から読み取られます。 |
|
RDWR_EXIST |
この値を使用して、既存のファイルを読み取りおよび書き込み用に開きます。ファイルは先頭から読み取りおよび書き込みが行われます。 |
|
WRITE_CREATE |
この値を使用して、ファイルを書き込み用に開きます。ファイルが既に存在する場合は、内容が破棄されファイルサイズが0に設定されます。ファイルが存在しない場合は、新しいファイルが作成されます。ファイルは先頭から書き込まれます。ただし、ファイルが既に存在し書き込み保護されている場合は、エラーが発生しファイルは開かれません。 |
|
RDWR_CREATE |
この値を使用して、ファイルを読み取りおよび書き込み用に開きます。ファイルが既に存在する場合は、内容が破棄されファイルサイズが0に設定されます。ファイルが存在しない場合は、新しいファイルが作成されます。ファイルは先頭から読み取りおよび書き込みが行われます。 |
|
WRITE_APPEND |
この値を使用して、ファイルを開きデータを追記します。ファイルが存在しない場合は、新しいファイルが作成されます。データはファイルの末尾に追記されます。ただし、ファイルが既に存在し書き込み保護されている場合は、エラーが発生しファイルは開かれません。 |
|
RDWR_APPEND |
この値を使用して、ファイルを開き読み取りおよびデータ追記を行います。ファイルが存在しない場合は、新しいファイルが作成されます。ファイルは先頭から読み取られます。データはファイルの末尾に追記されます。 |
|
項目 |
意味 |
I/O |
説明 |
有効範囲 |
|---|---|---|---|---|
|
FileName |
ファイル名 |
Input |
開くファイルの名前 |
最大66バイト(65文字の英数字+最後のNULL文字) |
|
Mode |
開くモード |
ファイルを開くモード |
*1 | |
|
FileID |
ファイルID |
Output |
開かれたファイルのID |
データ型に依存 |
FileSeek
FileSeek命令は、SDメモリーカード内の指定されたファイルにおいて、ファイル位置インジケータを設定します。そのファイル位置インジケータとは、FileReadやFileWriteなどの命令が実行された際に、ファイル内の読み取りまたは書き込みを開始する位置を指しています。
例えば、ファイルの先頭から読み取るには、FileSeek命令でファイル位置指示子をファイルの先頭に設定し、その後FileRead命令を実行します。
ファイル位置指示子は、基準位置Originからオフセット分だけ離れた位置に設定されます。
Originのデータ型は列挙型_eFSEEK_ORIGINです。
列挙子の意味は以下の通りです:
|
列挙子 |
意味 |
|---|---|
|
_SEEK_SET |
ファイルの先頭 |
|
_SEEK_CUR |
現在のファイル位置指示子の場所 |
|
_SEEK_END |
ファイルの末尾 |

|
項目 |
意味 |
I/O |
説明 |
|---|---|---|---|
|
FileID |
ファイルID |
Input |
ファイル位置指示子を設定するファイルのID |
|
Offset |
オフセット |
Originからのオフセット | |
|
Origin |
基準位置 |
ファイル位置指示子の基準位置 |
FileWrite
FileWrite命令は、SDメモリカード内の指定されたファイルにデータを書き込みます。この命令は、ファイルID FileIDで指定されたファイルのファイル位置指示子が示す位置にデータを書き込みます。
ファイル位置指示子は、事前にFileSeek命令を使用して目的の場所に設定しておく必要があります。書き込み時には、書き込みバッファWriteBuf[]の内容がファイルに書き込まれます。
書き込まれるデータ量は、WriteBuf[]のデータ型のサイズにSizeを掛けた値、つまりWriteBuf[]のSize個の要素分となります。なお、WriteBuf[]には列挙型または構造体の配列を指定することもできます。

|
項目 |
意味 |
I/O |
説明 |
|---|---|---|---|
|
FileID |
ファイルID |
書き込むファイルのID | |
|
WriteBuf[] (配列) |
書き込みバッファ |
Input |
書き込みデータ |
|
Size |
書き込む要素数 |
書き込む要素数 | |
|
WriteSize |
書き込まれた要素数 |
Output |
実際に書き込まれた要素数 |
FileWriteVar
FileWriteVar命令は、変数WriteVarの値をSDメモリカード内のFileNameで指定されたファイルにバイナリ形式で書き込みます。WriteVarには、列挙型、配列、配列要素、構造体、または構造体メンバーを指定することができます。
FileNameという名前のファイルがSDメモリカードに存在しない場合は、新規に作成されます。FileNameにはパスを含めることができ、指定されたディレクトリがSDメモリカードに存在しない場合は自動的に作成されます。ただし、ディレクトリが作成されるのは、指定されたパスの最下層のディレクトリレベルのみが存在しない場合に限られます。
一方、FileNameという名前のファイルがSDメモリカードに既に存在する場合は、上書き許可OverWriteの値に応じて処理が実行されます。

|
項目 |
意味 |
I/O |
説明 |
有効範囲 |
|---|---|---|---|---|
|
FileName |
ファイル名 |
Input |
変数を書き込むファイルの名前 |
最大66バイト(65文字の英数字+最後のNULL文字) |
|
WriteVar |
変数 |
書き込む変数 | ||
|
OverWrite |
上書き許可 | TRUE: 上書きを許可する。FALSE: 上書きを禁止する。 |
データ型に依存 |
FileRead
FileRead命令は、SDメモリカード内の指定されたファイルからデータを読み取ります。この命令は、ファイルID FileIDで指定されたファイルのファイル位置指示子が示す位置からデータを読み取り、読み取りバッファReadBuf[]に格納します。
ファイル位置指示子は、事前にFileSeek命令を使用して目的の場所に設定しておく必要があります。読み取るデータ量は、ReadBuf[]のデータ型のサイズにSizeを掛けた値、つまりReadBuf[]のSize個の要素分となります。なお、ReadBuf[]には列挙型または構造体の配列を指定することもできます。
実際に読み取られた要素数はReadSizeに格納されます。通常、SizeとReadSizeは同じ値になりますが、ファイル位置指示子からファイルの末尾までのデータ量がSizeより小さい場合でも、エラーは発生せず、ファイルの末尾までのデータがReadBuf[]に格納されます。この場合、ReadSizeの値はSizeの値より小さくなります。
ファイルの末尾までデータが読み取られた場合、ファイル終端EOFがTRUEに変わります。それ以外の場合、EOFの値はFALSEになります。

|
項目 |
意味 |
I/O |
説明 |
|---|---|---|---|
|
FileID |
ファイルID |
Input |
読み取るファイルのID |
|
Size |
読み取る要素数 |
読み取る要素数 | |
|
ReadBuf[] (配列) |
読み取りバッファ |
In-out |
読み取ったデータを書き込むバッファ |
|
ReadSize |
読み取られた要素数 |
実際に読み取られた要素数 | |
|
EOF |
ファイル終端 |
Output | ファイルの末尾に到達したかどうかTRUE: 到達した。FALSE: 到達していない。 |
FileReadVar
FileReadVar命令は、SDメモリカード上の指定されたファイルの内容をバイナリデータとして読み取り、変数に書き込みます。この命令は、SDメモリカードからFileNameで指定されたファイルの内容をバイナリデータとして読み取ります。読み取られた内容は、書き込み先の変数ReadVarに代入されます。
ReadVarには、列挙型、配列、配列要素、構造体、または構造体メンバーを指定することができます。

|
項目 |
意味 |
I/O |
説明 |
|---|---|---|---|
|
FileName |
ファイル名 |
Input |
読み取るファイルの名前 |
|
ReadVar |
書き込み先変数 |
In-out |
読み取った値を書き込む変数 |
FileClose
FileClose命令は、SDメモリカード内の指定されたファイルを閉じます。この命令は、SDメモリカード内のFileIDで指定されたファイルを閉じます。

|
項目 |
意味 |
I/O |
説明 |
|---|---|---|---|
|
FileID |
ファイルID |
Input |
閉じるファイルのID |
関連するシステム定義変数
|
名前 |
意味 |
データ型 |
説明 |
|---|---|---|---|
|
_Card1Ready |
SDメモリカード準備完了フラグ |
BOOL | このフラグは、命令および通信コマンドによってSDメモリカードにアクセスできるかどうかを示します。TRUE: 使用可能。FALSE: 使用不可。 |
|
_Card1Protect |
SDメモリカード書き込み保護フラグ |
BOOL | このフラグは、SDメモリカードが挿入され使用準備が整ったときに、書き込み保護されているかどうかを示します。TRUE: 書き込み保護されている。FALSE: 書き込み保護されていない。 |
|
_Card1Err |
SDメモリカードエラーフラグ |
BOOL | このフラグは、使用できないSDメモリカードがマウントされているか、フォーマットエラーが発生しているかを示します。TRUE: エラー。FALSE: エラーなし。 |
|
_Card1Access |
SDメモリカードアクセスフラグ |
BOOL | このフラグは、SDメモリカードが現在アクセス中かどうかを示します。TRUE: アクセス中。FALSE: アクセス中でない。 |
|
_Card1PowerFail |
SDメモリカード電源遮断フラグ |
BOOL | このフラグは、アクセス中に電源が遮断されて処理の完了時にエラーが発生したかどうかを示します。このフラグは自動的にクリアされません。TRUE: エラー。FALSE: エラーなし。 |
Implementation
それでは実際FILEの読み書きプログラムを実装してみましょう。
SDカードを挿入
オムロンのNX CPUに下記のスロットでSDカードを挿入してください。

プログラム
こちらは今回記事のプログラムで、これからRungことについて説明していきます。

Rung0
Rung0は、SDメモリカードが使用可能な状態かどうかを判定するための論理回路です。
プログラムでは、3つの条件を直列に接続して評価しています。
まず、_Card1Ready(SDメモリカード準備完了フラグ)がONであること、次に_Card1Err(SDメモリカードエラーフラグ)がOFFであること、そして_Card1Protect(SDメモリカード書き込み保護フラグ)がOFFであることを確認しています。
これら3つの条件がすべて満たされた場合、つまりSDメモリカードが準備完了状態で、エラーが発生しておらず、書き込み保護もされていない場合にのみ、出力変数xCardisReadyがTRUEとなります。

Rung1
Rung1は、SDメモリカードが正常に動作しているかどうかを監視するための論理回路です。プログラムでは、2つの条件を直列に接続して評価しています。_Card1Err(SDメモリカードエラーフラグ)がOFFであること、そして_Card1Access(SDメモリカードアクセスフラグ)がOFFであることを確認しています。
これら2つの条件がすべて満たされた場合、つまりSDメモリカードにエラーが発生しておらず、現在アクセス中でもない場合に、出力変数xSDCARDstatusがTRUEとなります。

Rung2
Rung2は、配列のサイズからファイルサイズをバイト単位で計算するための処理です。
プログラムは3つのファンクションブロックを直列に接続して実行されます。まず、SizeOfAry命令で配列arrRealDataの要素数を取得し、結果をuSizeOfAryに格納します。次に、UDINT_TO_UINT命令でuSizeOfAryのデータ型を変換し、temp2に出力します。最後に、MUL命令でtemp2とUINT#4(4バイト)を乗算し、最終的なファイルサイズをFileSizeに格納します。
この一連の処理により、配列の要素数に各要素のサイズ(4バイト)を掛け合わせることで、配列全体のデータサイズをバイト単位で算出しています。これは、ファイルへの書き込みや読み取りを行う際に必要なデータサイズを事前に計算するために使用されます。

Rung3
Rung3は、SDメモリカード内のファイルを開くための処理です。
プログラムの実行条件として、xCardisReady(SDメモリカードが使用可能)がONで、かつxFIleOpen(ファイルオープン指令)の立ち上がりエッジを検出した時に、fbFileOpen(FileOpen命令)が実行されます。
FileOpen命令には、FileName(ファイル名)として’myData.csv’が指定され、Mode(開くモード)として_eFOPEN_MODE#_RDWR_CREATE(読み取り・書き込み用に開き、既存の場合は内容を破棄して新規作成)が設定されています。
命令の実行結果として、Done出力がxfbFileOpenDoneに、Busy出力がxfbFileOpenBusyに、Error出力がxfbFileOpenErrorに、ErrorID出力がufbFileOpenErrorIDに、そしてFileID出力がufbFileOpenFileIDにそれぞれ格納されます。
この処理により、指定されたCSVファイルを読み書き可能な状態で開き、後続の処理で使用するためのファイルIDを取得することができます。

Rung4
Rung4は、ファイルが正常に開かれたかどうかを確認するための処理です。
プログラムの実行条件として、xCardisReady(SDメモリカードが使用可能)がONの時に実行されます。まず、DWORD_TO_INT命令でufbFileOpenFileID(FileOpen命令で取得したファイルID)をINT型に変換し、_iTempに格納します。次に、NE命令で_iTempとINT#0(ゼロ)を比較します。
_iTempがゼロでない場合、つまりファイルIDが有効な値である場合に、xfbFileIsOpened(ファイルが開かれている状態を示すフラグ)がTRUEとなります。
この処理により、FileOpen命令が成功して有効なファイルIDが取得されたことを確認し、後続のファイル操作(読み取りや書き込み)を安全に実行できる状態であることを判断することができます。

Rung5
Rung5は、開かれたファイル内のファイル位置指示子を設定するための処理です。
プログラムの実行条件として、xfbFileIsOpened(ファイルが開かれている)がONで、かつxFileSeek(ファイルシーク指令)の立ち上がりエッジを検出した時に、fbFileSeek(FileSeek命令)が実行されます。
FileSeek命令には、FileID(ファイルID)としてufbFileOpenFileID(FileOpen命令で取得したファイルID)が指定され、Offset(オフセット)としてfbFileSeekOffset、Origin(基準位置)としてfbFileSeekOrgが設定されています。
命令の実行結果として、Busy出力がfbFileSeekBusyに、Error出力がfbFileSeekErrorに、ErrorID出力がfbFileSeekErrorIDにそれぞれ格納されます。
この処理により、指定されたオフセットと基準位置に基づいてファイル位置指示子を移動させ、後続のFileReadやFileWrite命令でファイルの任意の位置からデータの読み取りや書き込みを行えるようになります。

Rung6
Rung6は、開かれたファイルにデータを書き込むための処理です。
プログラムの実行条件として、xfbFileIsOpened(ファイルが開かれている)がONで、かつxFileWrite(ファイル書き込み指令)の立ち上がりエッジを検出した時に、fbFileWrite(FileWrite命令)が実行されます。
FileWrite命令には、FileID(ファイルID)としてufbFileOpenFileID(FileOpen命令で取得したファイルID)が指定され、WriteBuf(書き込みバッファ)としてarrRealData[0]、Size(書き込む要素数)としてtemp2が設定されています。
命令の実行結果として、Done出力がxfbFileWriteDoneに、Busy出力がxfbFileWriteBusyに、Error出力がxfbFileWriteErrorに、ErrorID出力がufbFileWriteErrorIDに、WriteSize(実際に書き込まれた要素数)がufbFileWriteSizeにそれぞれ格納されます。
この処理により、配列arrRealDataの内容を指定されたファイルのファイル位置指示子の位置に書き込むことができます。書き込まれるデータ量はtemp2で指定された要素数分となります。

Rung7
Rung7は、変数の値を直接ファイルに書き込むための処理です。
プログラムの実行条件として、xfbFileIsOpened(ファイルが開かれている)がONで、かつxFileWriteVar(ファイル変数書き込み指令)の立ち上がりエッジを検出した時に、fbFileWriteVar(FileWriteVar命令)が実行されます。
FileWriteVar命令には、FileName(ファイル名)として’myData.csv’が指定され、WriteVar(書き込む変数)としてarrRealData[5]、OverWrite(上書き許可)としてTRUE(上書きを許可)が設定されています。
命令の実行結果として、Done出力がxFileWriteVarDoneに、Busy出力がxFileWriteVarBusyに、Error出力がxFileWriteVarErrorに、ErrorID出力がuFileWriteVarErrorIDにそれぞれ格納されます。
この処理により、配列arrRealDataの特定の要素の値をバイナリ形式で指定されたファイルに直接書き込むことができます。ファイルが既に存在する場合は上書きされます。
FileWriteVar命令はFileOpenやFileSeekを使わずに、単独で変数の値をファイルに保存できる簡便な方法です。

Rung8
Rung8は、開かれたファイルからデータを読み取るための処理です。
プログラムの実行条件として、xfbFileIsOpened(ファイルが開かれている)がONで、かつxFileRead(ファイル読み取り指令)の立ち上がりエッジを検出した時に、fbFileRead(FileRead命令)が実行されます。
FileRead命令には、FileID(ファイルID)としてufbFileOpenFileID(FileOpen命令で取得したファイルID)が指定され、ReadBuf(読み取りバッファ)としてarrRealData[0]、Size(読み取る要素数)としてtemp2が設定されています。
命令の実行結果として、Done出力がFileReadDoneに、Busy出力がxFileReadBusyに、ReadBuf出力がarrRealData1[0]に、Error出力がxFileReadErrorに、ErrorID出力がuxFileReadErrorIDに、ReadSize(実際に読み取られた要素数)がuFileReadReadSizeに、EOF(ファイル終端フラグ)がxFileReadEOFにそれぞれ格納されます。
この処理により、ファイル位置指示子の位置からtemp2で指定された要素数分のデータを読み取り、配列arrRealData1に格納することができます。ファイルの末尾まで読み取った場合は、EOFフラグがTRUEになります。

Rung9
Rung9は、ファイルから変数に直接データを読み取るための処理です。
プログラムの実行条件として、xfbFileIsOpened(ファイルが開かれている)がONで、かつxFileReadVar(ファイル変数読み取り指令)の立ち上がりエッジを検出した時に、fbFileReadVar(FileReadVar命令)が実行されます。
FileReadVar命令には、FileName(ファイル名)として’myData.csv’が指定され、ReadVar(読み取り先変数)としてarrRealData1が設定されています。
命令の実行結果として、Done出力がFileReadVarDoneに、Busy出力がFileReadBusyに、ReadVar出力がarrRealData1に、Error出力がFileReadVarErrorに、ErrorID出力がFileReadVarIDにそれぞれ格納されます。

Rung10
Rung10は、開かれたファイルを閉じるための処理です。
プログラムの実行条件として、xfbFileIsOpened(ファイルが開かれている)がONで、かつxFileClose(ファイルクローズ指令)の立ち上がりエッジを検出した時に、fbFileClose(FileClose命令)が実行されます。
FileClose命令には、FileID(ファイルID)としてufbFileOpenFileID(FileOpen命令で取得したファイルID)が指定されています。
命令の実行結果として、Done出力がFileCloseDoneに、Busy出力がFileCloseBusyに、Error出力がFileCloseErrorに、ErrorID出力がFileCloseErrorIDにそれぞれ格納されます。
この処理により、FileOpen命令で開いたファイルを適切に閉じることができます。ファイルの使用が終了した後は、必ずFileClose命令でファイルを閉じることが重要です。これにより、データの整合性を保ち、SDメモリカードへの書き込みが正常に完了することを保証します。

ダウンロード
最後はプログラムをNX CPUにDownloadしていきましょう。
結果
xCardisReadyがTrueであることは、現在NX CPUはSDカードを認識しています。

Fileが正常に開きました。

xFileSeekをTrueにFILEの読み書き開始位置をセットします。

次はxFileWriteをTrueにし、データをSDカードに書き込みます。

uifbFileWriteSizeが300であり、つまり300個のデータがSDカードに書き込みました。

次はxFileReadをTrueにし、SDカードのデータを読み込んでみましょう。

Done!

最後はSDカードの中身、先程保存したデータのBinary FILEが格納されたことがわかりました。
