NI製品ディスカッション

キャンセル
次の結果を表示 
次の代わりに検索 
もしかして: 

LabVIEWのUDPにおけるC/C++言語との通信について

解決済み
解決策を見る

UDP通信に関する質問です.

 

現在,LabVIEWのUDP通信を使い,他のパソコンとの相互通信を考えています.

 

Labo viewの送信にはDAQmxから得たAIやDIOなどの値の情報を,

受信にはDAQmxへAO,DIOなどの値を書き込むと言った具合です.

 

相互通信するPCではC/C++言語を用いて,

 

typedef struct {

    float finput[4];

    bool binput[32];

}NIINPUT;

 

typedef struct {

    float foutput[8];

    bool boutput[32];

}NIOUTPUT;

 

などのような構造体を文字列に変換して,送受信を考えています.

 

そこで,LabVIEWにおいて,

http://zone.ni.com/reference/ja-XX/help/371361M-0112/lvhowto/using_the_flatten_to_string_function/

を参考に送受信の数値を文字列に変換しようと思っています.

 

 

しかしながら,上記のDocumentにある

「平坦化されたLabVIEWデータをバイナリ文字列形式から英数字文字列形式に変換」

の仕方が今ひとつわかりません.

 

上記の変換の仕方について方法またはSampleなどありましたら,

お教えいただけたら嬉しいです.

 

また,上記の変換以外の方法でもC/C++と構造体の文字列のような(上記イタリック体部分)

ものと通信が可能な方法がありましたらご教授いただけたら幸いです.

 

宜しくお願い致します.

0 件の賞賛
メッセージ1/6
5,752件の閲覧回数

クラスタデータを一度文字列に変換され、C++側で構造体に変換されることが目的でしょうか?

このサンプルがお役にたてればよいのですがいかがでしょう。

 

Community: クラスタを数値に変換 - National Instruments

 

上記サンプルは文字列に変換後、さらに数値データに変換していますが、

下記のように数値変換の部分を削除すれば、クラスタを文字列に変換して受け渡すことが可能です。

 

Snippet.png

メッセージ2/6
5,720件の閲覧回数

Ytochigiさん

返信ありがとうございます.

 

添付のデータをクラスタデータにし,文字列に変換するところ

についてはとても参考になりました.

 

クラスタデータを文字列に変換までのプロセスは上記のやり方で行いたいと思います.

 

 

しかし,上記のやり方ですと,文字列に平滑化した後の文字列を用いてUDP通信を行うと,

C/C++側で文字列をうまくデコードできませんでした.

 

原因としては,LabVIEWで「文字列に平滑化」すると文字列が "LabVIEW文字列" 

になるため,C/C++側ではうまくデコードできなかったのではと考えています.

参考1:http://zone.ni.com/reference/ja-XX/help/371361M-0112/lvhowto/using_the_flatten_to_string_function/

 

 

そこで,

LabVIEWで16進数からASCIIへ(または、ASCIIから16進数へ)変換するにはどうすれば良いですか?

を参考に

 

クラスタデータを文字列に変換までのプロセスの後に,

一度10進数にキャストし,その後10進数を16進数変数文字列にしてから

UDP通信を行うようにしました.

 

ですが,現状変わらずで,C/C++側ではうまくデコードできず,

デタラメな値となってしまっています.

 

スクリーンショット 2016-02-03 18.00.53.png

図1 型変換のイメージ

 

 

ここで新たな疑問なのですが,

 参考1の「平坦化されたLabVIEWデータをバイナリ文字列形式から英数字文字列形式に変換」

とは図1の手順で正しいのでしょうか?

また,LabVIEWで用いられている数字や文字は英数字文字列形式に変換した場合,

C/C++と同様の型なのでしょうか?

例えば,図1のピンク色の文字列 = C/C++でのchar型,

図1の緑色のbool型 = C/C++でのbool型

 

この辺りで何か知見のある方がいらっしゃいましたら,

お教えいただけたらと思います.

 

宜しくお願い致します.

0 件の賞賛
メッセージ3/6
5,684件の閲覧回数

図1の手順ではなく、以下のようになると思います。 

160203-sample1.png

図1のだと、長い文字列を得ても、数値1個にしかcastできないので、ほとんどの情報が失われます。

(参照なさったやりかたは、「1文字」だけ変換する方法です)

 

平坦化文字列を、U8の配列に変換し、それを、配列丸ごと(=要素1個1個順に)16進数文字列に変換します。

このとき、16進数文字列の幅を「2」にしておくことを忘れないようにします。

最後に、出てきた文字列配列を全部くっつければ、英数字文字列形式になります。

このままC/C++に渡してもいいかと思いますが(たしか、最後にnull文字はくっついた状態になるので)、

気になる場合はさらに末尾にnull文字を付けても良いかと思います。

 

参考まで、これを、元に戻すところもつけたviを添付します。

(C/C++で処理するだけで、戻すのは要らないのかも知れませんが・・・・)

 

メッセージ4/6
5,674件の閲覧回数

ちと失礼します。

 

>C/C++側で文字列をうまくデコードできませんでした.
・データ型が合っていない
・構造体内の変数の位置が合っていない
・LabVIEW側で配列を使って受渡している
・バイト順の違いによる影響(ちなみにLabVIEWは、big-endian)

が考えられる原因かと思います。
(C/C++とLabVIEWでデータの受け渡しが合っていない)

*LabVIEW側がどのようにデータが格納される(ている)かは下記URL参照

 

C/C++側が
・float(32bit単精度浮動小数点数)
・bool(8bit:0=False/1:True?)
・little-endian
だとして

配列要素がそれほど多くなければ、UDP受信後の処理はサンプルになるかと思います。

 

・平坦化・非平坦化でC/C++側のバイト順を指定
・LabVIEW側で送受信するクラスタは配列を使用しない(配列使う場合は、C/C++側でLabVIEW側に合わせた構造体で *要注意)

 

後、送受信データ(C/C++/LabVIEW両方)を16進数でDumpしてデータを確認することをお勧めします。

 

*LabVIEW側は、文字列の表示スタイルを変更

 

LabVIEWのデータストラクチャ
http://www.ni.com/getting-started/labview-basics/ja/data-structures#boolean

 

LabVIEW数値データタイプ表
http://zone.ni.com/reference/ja-XX/help/371361J-0112/lvhowto/numeric_data_types_table/

 

0 件の賞賛
メッセージ5/6
5,638件の閲覧回数
解決策
トピック作成者shibaura04B25が受理

返信が遅くなりました.
検討に少し時間がかかりました

 

M.Shiraishiさん
16進数への変換サンプルありがとうございました.

 

su-sann5073
アドバイスとサンプルをありがとうございました.

 

自己解決いたしました!
ここで頂いたサンプルやアドバイスを参考にして
下記で通信できることを確認しました.

 

 


 

LabVIEW送信の図

スクリーンショット 2016-03-28 12.05.28.png

 

C/C++で受信するための構造体
typedef struct {
  double dValue[16];
  bool bValue[32];
  char mojihead[4];
  char moji[8];
}RECV;

 



LabVIEW受信の図

スクリーンショット 2016-03-28 13.00.33.png

 

C/C++で送信するための構造体

typedef struct {
  double dValue[4];
  bool bValue[32];
}SEND;

 



C/C++との通信で気をつける点は
・文字列にフォーマットする際のバイト順の指定(little-endianにする)
・配列からクラスタに変換する場合は,必ずクラスタサイズを変更する.(デフォルトサイズは9)
・LabVIEW配列の型をC/C++側と同じ型にする.
 http://zone.ni.com/reference/ja-XX/help/371361L-0112/lvhowto/numeric_data_types_table/
 上記リンクを参考に,C/C++側がdoubleであればLabVIEW側でも倍精度浮動小数点数(DBL)型にする.
・LabviewからC/C++側で文字列を受信する場合は,LabVIEW文字列に合わせた形で受信する.
 http://www.ni.com/white-paper/4877/ja/
 上記リンクの図3を参考に,C/C++側では最初に4byte分の文字列配列を作り読み飛ばす.
 送信は確認していませんが,逆に4byte分の文字列サイズを加えて送信すればOKだと思います.



すべてをダウンロード
メッセージ6/6
5,159件の閲覧回数