#include <karacrix.h>
main(argc,argv)
int argc;
char *argv[];
{
int sockid,len,adval,pwmval; /*先頭部では変数宣言*/
struct sockaddr_in sndaddr,rcvaddr;
char sndbuff[512],rcvbuff[512];
char seq[64],ans[64];
char di_s[16],dti_s[16],do_s[8];
int pi[6],ai[4],ao[2];
int objid,di001,do001;
int objid_di001,objid_do001;
int objid_pi001,objid_ai001,objid_ao001;
double fval,hi,low;
KcxIntFlt_t udata;
/* 初期設定 */
kcxinit( argc, argv ); /*←KaracrixBuilder初期必須宣言*/
/* ソケットの作成 */
sockid = socket( AF_INET, SOCK_DGRAM, 0 ); ※S 以下
memset( (void *)&sndaddr, 0, sizeof(sndaddr) );
sndaddr.sin_family = AF_INET;
sndaddr.sin_port = htons ( 20000 ); /*リモートIOのポート番号*/ ※A
sndaddr.sin_addr.s_addr = inet_addr( "192.168.0.200" ); /*リモートIOのIPアドレス*/ ※A
memset( (void *)&rcvaddr, 0, sizeof(rcvaddr) );
rcvaddr.sin_family = AF_INET;
rcvaddr.sin_addr.s_addr = htonl( INADDR_ANY );
rcvaddr.sin_port = htons( 30000 ); /*自分(PC)のポート番号*/
bind( sockid, (struct sockaddr *)&rcvaddr, sizeof(rcvaddr) ); ※S 以上
/* ポイント・オブジェクトID取得 */
objid_di001 = kcxobj_open( "di001" ); ※B ※C
objid_do001 = kcxobj_open( "do001" ); ※B ※C
objid_pi001 = kcxobj_open( "pi001" ); ※B ※C
objid_ai001 = kcxobj_open( "ai001" ); ※B ※C
objid_ao001 = kcxobj_open( "ao001" ); ※B ※C
while( 1 ){ /*←無限ループの意味*/
/* == TK0040A状態監視 == */
/* コマンド送信&応答受信 */
strcpy( sndbuff, "123A mix" ); /*←状態読取コマンド*/
len = karacrix_com( sockid, &sndaddr, &rcvaddr,
sndbuff, strlen(sndbuff), rcvbuff, sizeof(rcvbuff) ); ※J
if( len <= 0 ){ sleep(1); continue; } /*←エラー時戻り*/
/* 応答パケット展開&データ取得 */
rcvbuff[len] = (char)0;
sscanf( rcvbuff, "%s%s%s%s%d%d%d%d%d%d%s%d%d%d%d%d%d",
seq, ans, di_s, dti_s,
&pi[0],&pi[1],&pi[2],&pi[3],&pi[4],&pi[5],
do_s, &ai[0],&ai[1],&ai[2],&ai[3], &ao[0],&ao[1] );
/* ポイント・オブジェクト値設定 */
if( di_s[0] == (int)'1' ) di001 = 1; /* Di01→ON 判定 */
else di001 = 0; /* Di01→OFF判定 */
if( do_s[0] == (int)'1' ) do001 = 1; /* Do01→ON 判定 */
else do001 = 0; /* Do01→OFF判定 */
kcxobj_stat_iwt( objid_di001, di001 ); /* Di01値設定 */ ※D
kcxobj_stat_iwt( objid_do001, do001 ); /* Do01値設定 */ ※D
kcxobj_stat_iwt( objid_pi001, pi[0] ); /* Pi01値設定 */ ※D
kcxobj_scale_frd( objid_ai001, &hi, &low ); /* Ai01スケール取得 */ ※F
fval = ( hi - low ) * (double)ai[0] / 1024.0 + low; /* AD値→単位値変換 */
kcxobj_stat_fwt( objid_ai001, fval ); /* Ai01値設定 */ ※E
kcxobj_scale_frd( objid_ao001, &hi, &low ); /* Ao01スケール取得 */ ※F
fval = ( hi - low ) * (double)ao[0] / 256.0 + low; /* DA値→単位値変換 */
kcxobj_stat_fwt( objid_ao001, fval ); /* Ao01値設定 */ ※E
/* == TK0040A操作 == */
/* 送信データ蓄積検査と取得(オブジェクトIDとデータ(整数or実数)) */
switch( kcxobj_sndstat_fromkcx( &objid, &udata ) ){ ※G
case KcxINTEGER: /* デジタル型→Do型 */
if( objid == objid_do001 ){
/* do001のID検査パス、そしてdo001制御データのみ(他は現状維持)送信 */
if( udata.i == 1 ) sprintf( sndbuff, "123A dout 1---" ); /*←操作コマンド*/
else sprintf( sndbuff, "123A dout 0---" ); /*←操作コマンド*/
karacrix_com( sockid, &sndaddr, &rcvaddr,
sndbuff, strlen(sndbuff), rcvbuff, sizeof(rcvbuff) ); ※K
}
break;
case KcxFLOAT: /* アナログ型→Ao型 */
if( objid == objid_ao001 ){
/* ao001のID検査パス、そしてao001制御データ(DA値)のみ(他は現状維持)送信 */
kcxobj_scale_frd( objid_ao001, &hi, &low ); ※F
adval = (int)( 256.0 * ( udata.f - low ) / ( hi - low ) );
if( adval < 0 ) adval = 0; /*制限チェック*/
if( adval > 255 ) adval = 255; /*制限チェック*/
sprintf( sndbuff, "123A aout %d -1", adval ); /*←操作コマンド*/
karacrix_com( sockid, &sndaddr, &rcvaddr,
sndbuff, strlen(sndbuff), rcvbuff, sizeof(rcvbuff) ); ※K
/** 以下アナログ出力をRC/PWMにも連動出力させています **/
pwmval = (int)( 10000.0 * ( udata.f - low ) / ( hi - low ) );
if( pwmval < 0 ) pwmval = 0; /*制限チェック*/
if( pwmval > 10000 ) pwmval = 10000; /*制限チェック*/
sprintf( sndbuff, "123A pwmout %d -1 -1", pwmval ); /*←操作コマンド*/
karacrix_com( sockid, &sndaddr, &rcvaddr,
sndbuff, strlen(sndbuff), rcvbuff, sizeof(rcvbuff) ); ※K
}
break;
default: break;
}
/* == ウエイト == */
kcxtim_tsleep( 100000 ); /* CPU負荷和らげるため必ず必要(100msec) */ ※H
}
}
/*以下興味ない方→karacrix_com()関数を汎用的にご使用下さい*/
/*以下興味ある方→C言語ソケットライブラリ参照後に参照下さい*/
/* IPデータ送信し応答受けるプログラム(以下興味有る方はBSDソケットライブラリ参照) */
karacrix_com( sockid,sndaddr,rcvaddr,sndbuff,sndlen,rcvbuff,rcvlen )
int sockid; /* ソケットID */
struct sockaddr *sndaddr; /* 送信アドレス */
struct sockaddr *rcvaddr; /* 受信アドレス */
char sndbuff[]; /* 送信データバッファ */
int sndlen; /* 送信データ長 */
char rcvbuff[]; /* 受信データバッファ */
int rcvlen; /* 受信データバッファ長 */
{
int len,retry;
char snd_frameidname[128];
char rcv_frameidname[128];
sscanf( sndbuff, "%s", snd_frameidname );
for( retry = 0; retry < (5); retry ++ ){
rcv_frameidname[0] = (char)0;
rcvbuff [0] = (char)0;
len = karacrix2_com( sockid,sndaddr,rcvaddr,sndbuff,sndlen,rcvbuff,rcvlen );
if( len <= 0 ){ sleep( 1 ); continue; }
rcvbuff[len] = (char)0;
sscanf( rcvbuff, "%s", rcv_frameidname );
if( strcmp( snd_frameidname, rcv_frameidname ) == 0 ){
return len; /*正常終了*/
}else{
sleep( 1 ); continue;
}
}
return (-1); /*失敗終了*/
}
karacrix2_com( sockid,sndaddr,rcvaddr,sndbuff,sndlen,rcvbuff,rcvlen )
int sockid;
struct sockaddr *sndaddr;
struct sockaddr *rcvaddr;
char sndbuff[];
int sndlen;
char rcvbuff[];
int rcvlen;
{
int i,len,fds,addrlen;
fd_set fdset;
struct timeval tm;
/*受信バッファクリア*/
for(i=0;i<100;i++){
fds = 1 + sockid;
FD_ZERO( &fdset );
FD_SET ( sockid, &fdset );
tm.tv_sec = tm.tv_usec = (0);
if( select( fds,&fdset,(fd_set *)NULL,(fd_set *)NULL,&tm ) <= 0 ){
break;
}
addrlen = sizeof(struct sockaddr);
(void)recvfrom( sockid,(void *)rcvbuff,rcvlen,0,rcvaddr,&addrlen );
}
/* 送信チェック */
fds = 1 + sockid;
FD_ZERO( &fdset );
FD_SET ( sockid, &fdset );
tm.tv_sec = (1);
tm.tv_usec = (0);
if( select( fds,(fd_set *)NULL,&fdset,(fd_set *)NULL,&tm ) <= 0 ){
return 0;
}
/* データ送信 */
addrlen = sizeof(struct sockaddr);
(void)sendto( sockid,(void *)sndbuff,sndlen,0,sndaddr,addrlen );
/* 受信チェック */
FD_ZERO( &fdset );
FD_SET ( sockid, &fdset );
tm.tv_sec = (5); /*要調整(ハング回避:無線LAN介入時等遅延可能性大の場合は20〜30)*/ ※T
tm.tv_usec = (0);
if( select( fds,&fdset,(fd_set *)NULL,(fd_set *)NULL,&tm ) <= 0 ){
return 0;
}
/* データ受信 */
if(( len = recvfrom( sockid,(void *)rcvbuff,rcvlen,0,rcvaddr,&addrlen )) < 0 ){
return 0;
}
return len; /*受信データ長*/
}
|