OMRON#Sysmac StudioのFILE操作FBを使ってみよう

こちらのシリーズでは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

https://x.com/3threes2

技術はひとりじゃもったいない。

Reference Link

http://soup01.com/ja/category/omron%e3%82%aa%e3%83%a0%e3%83%ad%e3%83%b3/sysmac-studio-instruction-list/

説明

注意事項!

  • この命令の実行は、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に変わります。

    1. SDメモリカードが使用可能な状態ではない。
    2. FileIDで指定されたファイルが存在しない。
    3. FileIDで指定されたファイルが既に閉じられている。
    4. FileIDで指定されたファイルにアクセス中である。
    5. 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が格納されたことがわかりました。

シェアする

  • このエントリーをはてなブックマークに追加

フォローする