第4章 リファレンス
6. CanCyclicSendMessage
●Visual Basic .NET(x86、x64 共用)
Declare Function CanCyclicSendMessage Lib "IFCan.DLL"( _ ByVal DeviceHandle As IntPtr, _
ByRef CanMessage As CAN_MESSAGE _ ) As Integer
●Visual Basic .NET(x86 専用)
Declare Function CanCyclicSendMessage Lib "IFCan.DLL"( _ ByVal DeviceHandle As Integer, _
ByRef CanMessage As CAN_MESSAGE _ ) As Integer
【パラメータ】
hDeviceHandle
CanOpenPort 関数で取得したデバイスハンドルを指定してください。
pCanMessage
送信するメッセージを格納した構造体のポインタを指定してください。
CanCyclicSendMessage 関数では、CAN_MESSAGE 構造体の ulTime に送信を行う周期を 10μs 単位で設定します。設定可能範囲は 1~1FFFFFh(10μs~20,971,510μs)です。1FFFFFh より大きい値を設定しても、自動的に 1FFFFFh に設定されます。
PCI-485420P、CPZ-485420P、PEX-485420、CSI-485420、PEX-H485940P で使用する場合には、
設定可能範囲は 5~FFFFh(50μs~655,350μs)になります。FFFFh より大きい値を設定 しても、自動的に FFFFh に設定されます。5 より小さい値を設定しても、自動的に 5 に設 定されます。
本関数では、送信するメッセージは 1 つのみ設定できます。
CAN_MESSAGE構造体の説明については、『4.3 構造体説明』をご参照ください。
【戻り値】
正常終了した場合は、IFCAN_ERROR_SUCCESSが返されます。
IFCAN_ERROR_SUCCESS以外の値が返された場合については、『4.4 戻り値一覧』をご参照くださ い。
【備考】
1. データの送信時間よりも、周期時間を短く設定した場合、指定された時間に送信ができず、周 期実行は停止します。例えば、データの送信に 80msかかるのに、周期時間を 50msに設定した場 合、50ms経過したときに、まだデータが送信中なので、周期実行が停止します。
周期実行の停止は、CanSetEvent関数、CanSetEventMask関数での設定を行っている場合、イベ ントにより通知されます。
また、アービトレーションロストにより、指定した周期にデータを送信できない場合もありま す。アービトレーションロストが発生し、データを再送しているときに、次の周期時間が来る と、上記と同じように、周期実行が停止します。
例)周期を 50ms に設定した場合
データ送信中
時間 データ送信中
50ms 50ms
・・・
周期送信開始
例)周期を 50ms に設定したが、その周期よりもデータ送信時間が長い場合
データ送信中
時間 50ms
周期送信開始
前回のデータが、まだ送信完了して いないため、次のデータが送れずに 周期送信は停止します。
周期送信実行中でも、周期送信を行いたいデータの更新、周期の更新を行えます。更新したデ ータは、次の周期から反映されます。
例)周期送信を行うデータや周期を更新したい場合
データ A 送信中
時間 50ms
・・・
周期送信開始
データ B 送信中
80ms
データ、周期の更新はいつでも可能です。
ただし、反映されるのは次の周期からになります。
例えば、この時点で、周期送信を行うデータを B に、周期を 80ms に更 新したとすると、前回の設定周期の 50ms が経過してから、データ B が 80ms 周期で送信されるようになります。
優先順位の高いメッセージを短い周期で送信していると、アービトレーションにより、それよ り優先順位の低いメッセージが送信されにくくなりますので、ご注意ください。
2. 本関数は、スタンダード版 CAN 製品では使用することはできません。
【注意事項】
CAN コントローラへのアクセスが競合すると、指定された時間に送信できず、周期送信が停止 する場合があります。
その場合、CanGetStatus 関数によるステータスの読み出しや、データ受信と競合した場合等に 現象が発生しますので、周期送信を行うポートに対して下記のような対策をご検討下さい。
・メッセージを受信しないよう、受信フィルタを設定する。
・ステータスのポーリングを行わない。
【使用例】
●C 言語 INT nRet;
CAN_MESSAGE CanMessage;
HANDLE hDeviceHandle;
unsigned long ulSendValue;
hDeviceHandle = CanOpenPort(“IFCAN1”);
: :
// 送信メッセージ長のセット CanMessage.ulLength = 4;
// 送信メッセージの ID をセット
CanMessage.ulID = 0x01 | CAN_EXT_FRAME;
// フラグの設定
CanMessage.ulFlag = 0;
// 300ms 周期
CanMessage.ulTime = 300*100;
// 送信メッセージの内容をコピー
*(unsigned long*)CanMessage[i].bData = ulSendValue;
nRet = CanActivate(hDeviceHandle);
// 300ms 周期で送信
nRet = CanCyclicSendMessage(hDeviceHandle, CanMessage);
●Visual Basic
Dim lpszName As String Dim hDeviceHandle As Long Dim CanMessage As CAN_MESSAGE Dim bSendValue(0 To 3) As Byte Dim nRet As Long
lpszName = "IFCAN1" & Chr( 0 )
hDeviceHandle = CanOpenPort(lpszName) :
:
‘ 送信メッセージ長のセット CanMessage.ulLength = 4
‘ 送信メッセージの ID をセット
CanMessage.ulID = &H01 Or CAN_EXT_FRAME
‘ フラグの設定
CanMessage.ulFlag = 0
‘ 300ms 周期
CanMessage.ulTime = 300*100
‘ 送信メッセージの内容をコピー
CanMessage.bData(0) = bSendValue(0) CanMessage.bData(1) = bSendValue(1) CanMessage.bData(2) = bSendValue(2) CanMessage.bData(3) = bSendValue(3) nRet = CanActivate(hDeviceHandle)
‘ 300ms 周期で送信
nRet = CanCyclicSendMessage(hDeviceHandle, CanMessage)
●Delphi var
lpszName: String;
hDeviceHandle: THandle;
CanMessage: CAN_MESSAGE;
bSendValue: array[0..3] of Byte;
nRet: Integer;
i: Integer;
lpszName := ‘IFCAN1’;
hDeviceHandle := CanOpenPort(lpszName);
: :
// 送信メッセージ長のセット CanMessage.ulLength := 4;
// 送信メッセージの ID をセット
CanMessage.ulID := $01 | CAN_EXT_FRAME;
// フラグの設定
CanMessage.ulFlag := 0;
// 300ms 周期
CanMessage.ulTime := 300*100;
// 送信メッセージの内容をコピー CanMessage.bData[0] := bSendValue[0];
CanMessage.bData[1] := bSendValue[1];
CanMessage.bData[2] := bSendValue[2];
CanMessage.bData[3] := bSendValue[3];
nRet := CanActivate(hDeviceHandle);
// 300ms 周期で送信
nRet := CanCyclicSendMessage(hDeviceHandle, CanMessage);
●Visual C# .NET uint Ret;
IFCCAN_ANY.CAN_MESSAGE CanMessage = new IFCCAN_ANY.CAN_MESSAGE();
IntPtr DeviceHandle;
DeviceHandle = IFCCAN_ANY.CanOpenPort(“IFCAN1”);
: :
// Data 配列の初期化
CanMessage.InitializezArray();
// 送信メッセージ長のセット CanMessage.Length = 4;
// 送信メッセージの ID をセット
CanMessage.ID = 0x01 | IFCCAN_ANY.CAN_EXT_FRAME;
// フラグの設定 CanMessage.Flag = 0;
// 300ms 周期
CanMessage.Time = 300*100;
// 送信メッセージの内容をセット CanMessage.Data[0] = 0x01;
CanMessage.Data[1] = 0x02;
CanMessage.Data[2] = 0x03;
CanMessage.Data[3] = 0x04;
Ret = IFCCAN_ANY.CanActivate(DeviceHandle);
// 300ms 周期で送信
Ret = IFCCAN_ANY.CanCyclicSendMessage(DeviceHandle, ref CanMessage);
●Visual Basic .NET
Dim DeviceHandle As Integer
Dim CanMessage As IFCCAN_ANY.CAN_MESSAGE = New IFCCAN_ANY.CAN_MESSAGE Dim Ret As Integer
DeviceHandle = IFCCAN_ANY.CanOpenPort(“IFCAN1”) :
‘ Data 配列の初期化
CanMessage.InitializeArray()
‘ 送信メッセージ長のセット CanMessage.Length = 4
‘ 送信メッセージの ID をセット
CanMessage.ID = &H01 Or IFCCAN_ANY.CAN_EXT_FRAME
‘ フラグの設定 CanMessage.Flag = 0
‘ 300ms 周期
CanMessage.Time = 300*100
‘ 送信メッセージの内容をコピー CanMessage.Data(0) = &H01 CanMessage.Data(1) = &H02 CanMessage.Data(2) = &H03 CanMessage.Data(3) = &H04
Ret = IFCCAN_ANY.CanActivate(DeviceHandle)
‘ 300ms 周期で送信
Ret = IFCCAN_ANY.CanCyclicSendMessage(DeviceHandle, CanMessage)
●Visual C++ CLR プロジェクト unsigned int Ret;
IFCCAN_ANY::CAN_MESSAGE CanMessage;
IntPtr DeviceHandle;
DeviceHandle = IFCCAN_ANY::CanOpenPort(“IFCAN1”);
: :
// Data 配列の初期化
CanMessage.InitializezArray();
// 送信メッセージ長のセット CanMessage.Length = 4;
// 送信メッセージの ID をセット
CanMessage.ID = 0x01 | IFCCAN_ANY::CAN_EXT_FRAME;
// フラグの設定 CanMessage.Flag = 0;
// 300ms 周期
CanMessage.Time = 300*100;
// 送信メッセージの内容をセット CanMessage.Data[0] = 0x01;
CanMessage.Data[1] = 0x02;
CanMessage.Data[2] = 0x03;
CanMessage.Data[3] = 0x04;
Ret = IFCCAN_ANY::CanActivate(DeviceHandle);
// 300ms 周期で送信
Ret = IFCCAN_ANY::CanCyclicSendMessage(DeviceHandle, CanMessage);
デバイス名「IFCAN1」の CAN インタフェースから 300ms 周期で、データを送信します。