LoginSignup
1
1

CODESYSの共用体とビット指定

Last updated at Posted at 2023-09-08

はじめに

仕事でCODESYSを使うことになったので気づいたことのメモです。
MELSEC等の従来からあるPLCなら簡単なのですが、IEC61131-3準拠のCODESYSとかだとビット操作などが結構めんどいです。
(まあラダーも絶望的に書きづらいのでSTで書けという戦略なのでしょうか…MELSECがラダーをポコポコ書きやすすぎるという気もしますが)
ちなみにIEC61131-3は呼びにくい名前ですが「イレブンサーティワン」という呼び方もあるそうです。最近知りました。CODESYSがなんぞや見たいな説明はしません。もっと良い解説ページがあると思うから。
(めんどくさがりの言い訳)

ちなみにこれはCODESYSとOMRONのNX-EIC202(EtherNet/IP)と通信してる動画です。

Orange Pi R1 Plus LTSという5000円くらいのSingle Board Computerです。
OSはArmbianを使用しています。

共用体(UNION)

ビット操作をしたい、こういう場合に使うのは共用体(UNION)です。共用体についての詳しい説明については省きますが、
要するに同じメモリ領域を2重で定義してWORDでアクセスしたりBITでアクセスしたりというものです。
MELSECだと[SET M0]だとBITで指定、[MOV K1 K4M0]だと桁指定でWORDで簡単にアクセスできるから楽なんですがねぇ~ はぁ…

失敗例

まずは失敗例です。なにが駄目なのか考えようのコーナー!

TYPE union_BIT16:
UNION
    nBit : ARRAY[0..15] OF BOOL;
    nByte : ARRAY[0..1] OF BYTE;
    nWord : ARRAY[0..0] OF WORD;
END_UNION
END_TYPE
TYPE union_BIT32:
UNION
    nBit : ARRAY[0..31] OF BOOL;
    nByte : ARRAY[0..3] OF BYTE;
    nWord : ARRAY[0..1] OF WORD;
	nDword : ARRAY[0..0] OF DWORD;
END_UNION
END_TYPE

image.png

image.png

data1はunion_BIT16として、data2はunion_BIT32としてグローバル変数として定義。

union_BIT32はこいういイメージですねDWORDの1つの箱をDWORD,WORD,BYTE,BITで好きなように配列としてアクセスしようとする計画です。では動かしてみましょう。

image.png

nBit[0] オレンジ を TRUEにすると、nByte[0]が1に、 nBit[1] 緑 を TRUEにすると、nByte[1]が1に…
おかしいですね…
image.png

BITとBOOLの違い。

BITとBOOLどちらもTRUE/FALSEしか状態が格納できません。
じゃあなんで2つもおなじ役目の物があるねんということですが以下が違いです。

・BITは配列が作れない、BOOLは配列が作れる。
・BITは1つでメモリを1BIT使用する、BOOLは1つで1BYTE使用する。
※これはCODESYSの場合であり他のPLCも同じとは限りません

という違いがあります。
じゃあBITの方がメモリ節約できるじゃんとなりますが、問題は読み書きに時間がかかります。
コンピュータから見るとアドレスの指定はBYTE単位の方が処理しやすいからです。
BOOLでないと配列にできないのはコンピュータが処理しやすいからですね。

ではデータのサイズを見てみましょう。
SIZEOFでは変数のサイズを見れます。バイトのサイズが出力される関数です。
data1はboolが16個あるから 1Byte * 16 = 16になります。
data2はboolが32個あるから 1Byte * 32 = 32になります。
image.png

正解例

image.png

TYPE struct_BIT16 :
STRUCT
	b00:BIT;
	b01:BIT;
	b02:BIT;
	b03:BIT;
	b04:BIT;
	b05:BIT;
	b06:BIT;
	b07:BIT;
	b08:BIT;
	b09:BIT;
	b0A:BIT;
	b0B:BIT;
	b0C:BIT;
	b0D:BIT;
	b0E:BIT;
	b0F:BIT;
END_STRUCT
END_TYPE
TYPE struct_BIT32 :
STRUCT
	b00:BIT;
	b01:BIT;
	b02:BIT;
	b03:BIT;
	b04:BIT;
	b05:BIT;
	b06:BIT;
	b07:BIT;
	b08:BIT;
	b09:BIT;
	b0A:BIT;
	b0B:BIT;
	b0C:BIT;
	b0D:BIT;
	b0E:BIT;
	b0F:BIT;
	b10:BIT;
	b11:BIT;
	b12:BIT;
	b13:BIT;
	b14:BIT;
	b15:BIT;
	b16:BIT;
	b17:BIT;
	b18:BIT;
	b19:BIT;
	b1A:BIT;
	b1B:BIT;
	b1C:BIT;
	b1D:BIT;
	b1E:BIT;
	b1F:BIT;
END_STRUCT
END_TYPE

image.png

TYPE union_BIT16:
UNION
    nBit :struct_BIT16;
    nByte : ARRAY[0..1] OF BYTE;
    nWord : ARRAY[0..0] OF WORD;
END_UNION
END_TYPE
TYPE union_BIT32:
UNION
    nBit :struct_BIT32;
    nByte : ARRAY[0..3] OF BYTE;
    nWord : ARRAY[0..1] OF WORD;
	nDword : ARRAY[0..0] OF DWORD;
END_UNION
END_TYPE

nBitのところが配列から構造体のstruct_BIT16/32になって構造体の中身はBITを16個,32個並べています。
ではこれで試してみましょう。

image.png

下位2BITがONなので3,BYTE,WORD,DWORDに3が入りましたねめでたしめでたし。

image.png

SIZEOFのデータサイズも正しいですね。
image.png

CODESYSのデータ型については以下に説明があります

他のBIT指定方法。

CountはWORDで定義しています。ほしいビットを.1などをつけるだけで使えます。
MELSECとかと同じですね。WORDだと.0~.15が指定できます

image.png

CODESYSの説明ページ(Index access to bits integer variables)

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1