PLCnext EngineerでC++のシンプル/複合データ型をマスターする
こんにちは皆さん、
このブログ記事では、C++とPLCnext Engineerにおけるシンプルおよび複合データ型について探求します。シンプルな演習と複合的な演習の2部構成です。
このチュートリアルは、C++とPLCnext Engineerのある程度の経験があることを前提としています。
準備
まず必要なツールを揃えます:C++エディタ、PLCnext Engineerソフトウェア、実行用のPhoenix Contact PLC。私が使用した環境は以下の通りです:
- AXC F 2152(ファームウェアバージョン 2021.0.3)
- PLCnext Engineerバージョン 2021.0.2
- Visual Studio 2019 Communityバージョン 16.9.4
私はC++エディタとしてVisual Studioを選びましたが、Eclipseも使用可能です。チュートリアルへのリンク:
PLCnext Engineerは当社Webサイトから入手できます。
シンプルな演習
最初の例では、PLCから送られた数値が正しいかチェックする小さなアプリケーションを作ります。新しいC++プロジェクトを作成し、ヘッダーファイル([ProjectName].hppのような名前)を開きます。[ProjectName]component.hppというファイルもありますが、これは使用しません。ヘッダーファイルには大量のコードがありますが、心配いりません。まずポートを定義します。1つ入力、1つ出力。シンプルなデータ型の場合は以下のように定義します:
//#port
//#attributes(Input)
//#name(InputTest)
int64 InputTest = 0;
//#port
//#attributes(Output)
//#name(OutputTest)
int64 OutputTest = 0;
次に実装ファイル([ProjectName].cpp)に移り、実際のコーディングを行います。最初は中身がほぼ空ですが、これから変更します。入力値をチェックして出力を設定するコードを追加します。if文やswitch文どちらでも構いません。ここではif文を使用:
void PLMProjectReadInputProgram::Execute() {
if (InputTest == 1) {
OutputTest = 15;
}
if (InputTest == 2) {
OutputTest = 150;
}
if (InputTest == 3) {
OutputTest = 1500;
}
if (InputTest == 4) {
OutputTest = 15000;
}
}
PLCnext Engineerに移る前に、このC++プロジェクトをPLCが理解できるライブラリにビルドする必要があります。画面上部の「Build」をクリックするだけです。少し実行され、ライブラリ完成の通知が出ます。不明な場合は上記のチュートリアルを参照してください。

コンポーネントタブの「Programming(プログラミング)」フォルダ内の「Local(ローカル)」からメインプログラムに移動し、メイン画面で「Variables(変数)」を選択してPLC内の変数を見ます。ここで名前、データ型、用途を選択できます。PLCnext Engineerのデータ型はC++プログラムと同じものにする必要があります。対応表はこちら。用途で、変数がローカルか、外部プログラム/変数とのデータ送受信用かを決めます。

新しいライブラリを追加した後、変数を接続します。手順は以下の通り:
作成したライブラリはプロジェクトのbinフォルダにあります。これをPLCnext Engineerのライブラリフォルダにコピーします。場所は通常:
C:\Users\Public\Documents\PLCnext Engineer\Libraries
PLCnext Engineerに戻り、コンポーネントタブのライブラリボックスを開き、ライブラリを右クリックして「Add user library(ユーザーライブラリ追加)」を選択。先ほどのフォルダが開くので、使用するライブラリを選んで続行。

次にプログラムをタスクに追加します。画面左側のプラントエリアでPLCnextをダブルクリック。中央に開くので、「Tasks and Events(タスクとイベント)」タブでMainInstanceの後に新しいプログラムを追加。プログラムタイプを選択するか、コンポーネントエリアの「PLCnext Components & Programs」からドラッグ&ドロップします。

「Port List(ポートリスト)」タブ(Tasks and Eventsタブの隣)を開くと、C++とPLCnextのすべての変数が表示されます。こんな感じ:

正しくできていれば、PLCのOUTポートをC++プログラムのINポートに接続できます(逆も可能)。こんな感じになります。うまくいかない場合はデータ型を確認してください。

ダミー値を変数に設定するため、コンポーネントタブのメインプログラムで「Code(コード)」を選択し、メイン画面でコードを追加します。出力側の変数を数値(ここでは1)に設定します。

プロジェクトをPLCにデプロイすると、C++コードから15という応答が返ってくるはずです。変数は先ほどの「Ports List」で確認できます。
複合的な演習
この例では、構造体の配列をPLCとの間でやり取りするアプリケーションを作ります。新しいC++プロジェクトを作成し、ヘッダーファイル([ProjectName].hpp)を開きます。[ProjectName]component.hppは使用しません。ヘッダーファイルには大量のコードがありますが、心配いりません。まず構造体を作ります。ここでは車(Car)の構造体を例にします:
public: // typedefs
struct StrCar {
StaticString<80> sbrand;
int16 iHorsepower;
int16 iYear;
boolean xInsured;
};
重要! C++とPLCnext Engineerで名前と型が完全に一致している必要があります。データ型対応表はこちら。
次にポートを定義します。データのリストなので配列として定義します。また『車』のリストであることが重要です:
//#port
//#attributes(Input)
//#name(CarIn)
StrCar CarToC[2];
//#port
//#attributes(Output)
//#name(CarOut)
StrCar CarFromC[2];
実装ファイル([ProjectName].cpp)で実際のコーディングを行います。車1と車2の値を変更します:
// PLCからの車リストの最初の要素を2番目の車に設定
CarFromC[0].sbrand = CarToC[1].sbrand;
CarFromC[0].iHorsepower = CarToC[1].iHorsepower;
CarFromC[0].iYear = CarToC[1].iYear;
CarFromC[0].xInsured = CarToC[1].xInsured;
// 2番目の要素にダミー値(最初の車)を設定
CarFromC[1].sbrand = CarToC[0].sbrand;
CarFromC[1].iHorsepower = CarToC[0].iHorsepower;
CarFromC[1].iYear = CarToC[0].iYear;
CarFromC[1].xInsured = CarToC[0].xInsured;
再度ビルドしてライブラリを作成します。

PLCnext Engineerで変数を作る前に、独自のデータ型(構造体CarとCarのリスト)を作成する必要があります。データ型ファイルは以下で見つけたり作成したりできます:

このファイルを開き、独自の構造体を作成します:
TYPE
StrCar:
STRUCT
sBrand: STRING;
iHorsepower: INT;
iYear: INT;
xInsured: BOOL;
END_STRUCT
END_TYPE
重要! C++とPLCnext Engineerで名前と型が完全に一致している必要があります。データ型対応表はこちら。
構造体作成後、同じファイルでこの型の配列を作成します:
TYPE
carList: ARRAY[0..1] OF StrCar;
END_TYPE
コンポーネントタブの「Programming」→「Programs」フォルダ内のメインプログラムで「Variables」を選択し、PLCの変数を見ます。ここで名前を決め、データ型として先ほど作ったカスタム型「carList」を選択します。

ライブラリを追加して変数を接続します(手順はシンプルな演習と同じ)。

プログラムをタスクに追加します(手順はシンプルな演習と同じ)。

「Port List」タブを開くと、すべての変数が表示されます。

正しければ、PLCのOUTポートをC++プログラムのINポートに接続できます(逆も可能)。こんな感じ。うまくいかない場合はデータ型と変数名を確認してください。

ダミー値を設定するため、メインプログラムで「Code」を選択し、コードを追加します。出力側の変数に車の仕様を設定します。データ型に合わせて適当な値を選んでください(文字列には文字列を、など)。
CarToC[0].sBrand := 'Audi';
CarToC[0].iHorsepower := 200;
CarToC[0].iYear := 2020;
CarToC[0].xInsured := TRUE;
CarToC[1].sBrand := 'Mazda';
CarToC[1].iHorsepower := 120;
CarToC[1].iYear := 2001;
CarToC[1].xInsured := FALSE;
この例をデプロイすると、出力側のリストが入力側のリストと入れ替わった状態で返ってきます。変数は「Ports List」で確認できます。
産業技術
- 非ゼロ初期条件を持つDCリアクティブ回路の高度解析
- デジタル手順書作成:シンプル、効率的、信頼性が高い
- PLCnextデバイスでgrpcurlを用いた安全なリモートgRPCアクセス
- C#でPLCnextコンソールアプリケーションを開発:初心者ガイド
- PLCnext LinuxにAPTパッケージマネージャをインストール:ステップバイステップガイド
- C++構造体とクラス:組み込み開発者のための実践ガイド
- 広がるクラウドの地平:新ゾーン、コンテナ、マルチクラウド戦略
- C# 入出力の基礎:ユーザー入力と出力の基本をマスター
- C++クラスとオブジェクト完全ガイド:オブジェクト指向プログラミングの実践
- C++ポインタと配列:関係性をマスターする
- C++日付と時刻の完全ガイド:ctimeライブラリの活用