• 検索結果がありません。

CanCyclicSendMessage

ドキュメント内 GPC-4851 (ページ 176-186)

第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 周期で、データを送信します。

ドキュメント内 GPC-4851 (ページ 176-186)