(株)キーエンスのシーケンサーと通信をするライブラリー KV COM+ Library Ver.1 DLL用サンプル

実行画面 

キーエンスのシーケンサーとDelphiを使用して、通信をしてシーケンサーを動作させる場合、RS232Cにより動作させる事が一般的ですが、USB、LAN、Bluetooth等を使用して、通信コントロールが出来るライブラリーが、用意されています。
対応言語として、Visual Basic Visual C++ 2010/2008... EXCEL Acces 等々となっていますが、このライブラリーのActiveXが、Delphiではうまく使用出来ないようです。(よくある事なのですが)
AnsiCoadのDelphiの場合は、接続対象とか、トリガの関連付けをコードで書く必要があり、UniCoadのDelphiだと、エラーになって、パッケージとして取り込めないようです。(エラーになる部分を無効にして、接続対象とか、トリガの関連付けをコードで書く必要あり)
Dllもあるのですが、Delphi用には用意されていません。
Dllを使用した場合、トリガーを使用する為には、トリガー用のルーチンを作成する必要があります。
タイマーを利用して、周期的にデーターのサンプリングをして、変化のチェックをするようにしますが、通信速度に注意を払う必要があります。

 そこで、DllをDelphiから利用する為のユニットを作成し、通信のテストをする事にしました。
全てのテストをしたわけでは無いのですが、問題なく通信が出来ています、トリガー用のルーチンのテストはしていません。
通信用のユニットの作成は、C++用のヘッダファイルと、マニュアルを参考にしました。
残念ながら、此処でヘッダファイル、マニュアル等を公開できません、必要であれは、キーエンスより、KV COM+ Libraryを入手してください。
キーエンスのシーケンサーを使用しない限り必要の無いものです。
C++からDelphiに変換する多少の参考になるかも知れませんが。

 サンプルプログラムは、実際に装置を動かすようにはなっていません、キーエンスのマニュアルにあるDLL関数の例題を確認したものです。
LAN、Bluetoothに関しては、使用したパソコンと、相手のシーケンサーに用意されていなかった為、通信の確認がされていません。

プログラムを起動したら、まず最初にiniボタンをクリックします、次に、connectUSBか、connectRS232Cボタンで接続します。
終了する場合は、discnnect ボタンで接続を終了します。
シーケンサーのメモリー、リレー番号等は、プログラムの内容を修正して下さい。
メモリー、リレーの番号は各シーケンサーのマニュアルを参照する必要がありますが、一応 DBPlcdef.pas にコメントとして表示してあります。

ヘッダファイルの内容の変換について
#define  DB_BITDEV_RW_MAX 16
#defineについては、
const DB_BITDEV_RW_MAX = 16;
の様に定数として宣言

LONG,PLONGは、LONGINT,PLONGINTを使用すればよいのですが、変更を少なくするため LONG,PLONGを宣言

 LONG = LONGINT; // LONG 追加 Int32
PLONG = ^LONG;

typedef void* DBHCONNECT; // 接続ハンドル
ハンドルなので、整数とそのポインターを宣言

DBHCONNECT = Cardinal;
PDBHCONNECT = ^DBHCONNECT;

typedef enum {        // 動作モード
  ......,
  } DBMode;
この形の宣言は、Delphiに無いので、列挙型として実行文で工夫をするか、CONSTとして定数宣言をします。
DBModeに関しては、列挙型にするだけで、DLLとリンクできました。


{$SCOPEDENUMS ON}   // TDBMode スコープ 無くても可
TDBMode =
 DB_MODE_INVALID = 0,
 .......
);
{$SCOPEDENUMS OFF}
PDBMode = ^TDBMode;


typedef enum {         //通信速度
  DBCOMBAUD_9600 = 9600,
  .......
} DBComBaud;
通信速度はDBComBaudを整数として渡すので、
DBComBaud = integer;
と宣言
速度の宣言は列挙型で
 TDBComBaud = (          //通信速度
  DBCOMBAUD_9600 = 9600,
  .......
  );
の様にして、値は、
Speed := integer(DBCOMBAUD_115200)  // Delphi では、直接値を参照しない
のようにして設定しますが、Constで宣言した方が、簡単に済みます。
const
 DBCOMBAUD_9600 = 9600;
 ........

typedef struct {           // デバイス情報
   WORD wKind;         // デバイス種別
   .....
} DBDevInfo;
これは、Delphiのrecord型と同じなので
type
TDBDevInfo = record
 wKind : WORD;
 ........
end;
 PDBDevInfo = ^TDBDevInfo;


enum DBPlcId {
 DBPLC_DKV3000 = 0x0203,
 .......
}
この場合も Const 宣言の方が簡単ですが列挙型を使用
DBPlcId = integer;
TDBPlcId = (
  DBPLC_DKV3000 = $0203,
  DBPLC_DKV5000 = $0203,
  .....
  );
DBPlcI を integer として宣言
DBPlcI := integer(DBPLC_DKV3000)
の様にして使用。

他の部分の宣言も殆ど同じです、変換したDatabuilder.pas  DBPlcdef.pas を参照すればわかります。


DLLのルーチンには、ansicahr 用と widechar 用があるので、$IFDEF UNICODE で呼び出しルーチンを選択
function DBConnect(lpszDestName: PCHAR; PlcId: TDBPlcId; phConnect: PDBHCONNECT): DBERROR;
var
 iPlcId : DBPlcId; // integerと同じ
begin
 iPlcId := ord(PlcId); // ord は smallint; integer(Plcid)でも良い 列挙型 を 整数に変換して次に渡す
{$IFDEF UNICODE}
  Result := DBConnectW(lpszDestName,iPlcId,phConnect);
{$ELSE}
  Result := DBConnectA(lpszDestName,iPlcId,phConnect);
{$ENDIF}
end;

 エラーがエラーコードしか帰らないので、コードからエラーの内容を取得するルーチン、モードコードからモード文字取得ルーチン、通信モードコードから通信モード文字を取得するルーチンを追加して、実行時のデバッグを容易に出来る様にしました。
 function DBERRSTRING(DBERRCOAD: LONG): string;  // エラー番号から文字データー取得
 function KVModeString(KvMode: TDBMODE): string;   // KVモードから文字コード取得
 function CominfoTypeNoComtypestr(ComTypNo: DBComtype): string; // 通信モード番号から文字情報取得

ストップウォッチ ユニットには、ストップウォッチを追加して、コマンド送信してから、応答が帰るまでの時間を測定するようになっていますが、あくまでも確認用であり、実際には必要ありません。
Stopwatch コンポーネントも一緒にダウンロードできるので、インポートして使用して下さい。


プログラムの開始時にマルチメディアタイマーの精度を最小値に設定、終了したら元へ戻します。
COMスピードを正しく設定するのに必要らしいのですが、原因は不明です。
これ以外のDLLでは、この様な事をしたことはありません。

var
 MMPeriodF: Boolean;    // timeBeginPeriod set Flag
 MMMin: Cardinal;         // MMTime 最小値
 TMinMax: TIMECAPS;

// これを設定しないと正しくCOMスピード設定されない
procedure TForm1.FormCreate(Sender: TObject);
begin
 TimeGetDevCaps(@TMinMax,sizeof(TMinMax)); // MMTIMの仕様取得
 MMMin := TMinMax.wPeriodMin;                     // 最小値の取得
 if timeBeginPeriod(MMMin) = 0 then MMPeriodF := true; // MMTIMEの最小値が設定できたらTrue 解除用
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
 if MMPeriodF then timeEndPeriod(MMMin);  // MMTIMEの最小値が設定されていたら解除
end;


   download KeyenceCom.zip

   最初に戻る