Twitter

最近のトラックバック

無料ブログはココログ

« 16F88(ただの日記) | トップページ | カラクラ2復活計画 »

2008年3月20日 (木)

TDControl2(テスト版)

*追記
*なんと、Macへの移植に挑戦して下さっている方がいます。
*興味のある方は是非ご覧ください。
http://d.hatena.ne.jp/akio0911/20080320/1206026739

「tdc2.lzh」をダウンロード

だいぶ前に作ったTDControlですが、色々バグも有ったので、少し作り直してみました。

まだまだテスト中なので、バグが有るかもしれません。
もし、何か見つけた方は遠慮なくコメント等でお知らせください。
申し訳ないです。

さて、今回は自動で出来る処理を増やしてみました。

まず、オープンと初期化ですが、

bool Open(int com);
bool Init(float alt,float henkaku);

この二つだけで実行できます。
但し、初期化の方は少しだけ時間がかかります。
altとhenkakuについては、前までのバージョンと同じです。

次に受信ですが、

bool Recv(void);

だけで出来るようにしてみました。

これはコマンド送信、受信全て行います。
そして、データを受信した時だけtrueが戻ります。
なので、スレッドやメインループの中で、次のように使ってください
(tdcとして宣言した場合)

if(tdc.Recv()){
  
// 何か受信処理
}

結果は今までどおり、RecvData構造体に入ります。
必要なデータを10か100で割って使ってください。

詳しくは前のバージョンの解説ページをご覧ください。
前バージョン

まだまだ未完成なのでマニュアルもありません。
申し訳ないです。
なので、何か疑問や質問があったら遠慮なくお知らせください。
出来る限り答えようと思います。

■ 関数一覧

bool Open(int com)
bool Close(void)
bool Init(float alt,float henkaku)
bool Recv(void)
+今までのマニュアル操作関数
(但し、AutoStartはInitに置き換わっています)

■ 変数一覧

RECVDATA RecvData
int romver
BYTE check

« 16F88(ただの日記) | トップページ | カラクラ2復活計画 »

TDS01V制御クラス」カテゴリの記事

コメント

バージョンアップされたのですね。
早速ダウンロードさせていただきました。

ダウンロードありがとうございます。

前バージョンと基本的には変わっていないのですが、自動化出来るところは自動化しています。
それと、COMポートの制御が分離されているので前バージョンより移植し易いかもしれないです。

応援してます!

JAVAを使って制御プログラムを書いていたので大変参考になりました!

質問させて下さい!プログラム中のCMD_SET_CONDITION『Ox3530』の値はどの様に決められたのでしょうか?

返事が送れて申し訳ありません!
その辺りの定数は全て、CDに付属の「ソフトウェア開発者ガイド」を参考にして設定しています。
例えば、SET_CONDITIONは開発者ガイドの6、7ページの「計測条件設定」にあたるものです。
ここで、その数値をみてみると「0x05」となっていますよね?
これをTDS01Vへシリアルで送ると、条件設定が出来ます。
ただし、ココで注意しなければならないのが「ASCIIコードに変換して送る」と言う点です。
つまり、「05」を文字として送信しなければなりません。
そこで、ASCIIコードに変換すると「 0 = 0x30 5 = 0x35 」となります。
これでほとんど完成なんですが、これをメモリーに確保して送信する場合、「0x3035」としてしまうと、先に「0x35」が送信されてしまい、TDS01V側には「50」と送られてしまいます。
これでは大問題なので、順番を逆にして「0x3530」としています。

・・・とこんな感じです。
変な文章でもうしわけないです!
分からない部分があったらまた聞いてくださいねっ
他にも質問等ありましたら、メールやコメントでいつでもどうぞ!

ちなみに、逆になる理由は、多分x86系のCPUがリトルエンディアンだからだと思います。

なるほど!!ありがとうございます☆
今javaを使ってTDS01Vにコマンドを送っていたんですが、普通に開発者ガイドに記載されているコマンドで送っていてもうまくいかなかったもので、、、、
大変参考になりました!また何か分からないことがありましたらよろしくお願いします☆

javaですかぁ~、いいですね!
またいつでもどうぞ!

お久しぶりです!
受信データから10進数化する際の質問なんですが、「ソフトウェア開発者ガイド」にあるのですが、受け取った地磁気センサのベクトルデータが「0xFFE3」の時、どうして10進数化すると「-29」になるのでしょうか?
質問ばかりですみません。。。

お久しぶりです!
これ僕も少し悩みました。
まず重要なのが、この値は正と負の値をとる、つまりsignedな変数だということです。
コンピューターの世界では、基本的に負の数を表現する時に、2の補数表現を使っています。
ある正の数のマイナス符号の値は、その数の2の補数を取ることで表されます。
こうした理由は色々あるようですが、とにかくこうすることで、あるビット幅で正の数と負の数がかぶることなく表現されています。
2の補数に関しては、wikipediaが参考になります。
http://ja.wikipedia.org/wiki/2の補数

・・・つまり、今回の「0xFFE3」は、2の補数で表現された負の数だったわけです。
試しにこれを、正の数になおしてみます。
まず、「0xFFE3」を2進数表現すると
「1111111111100011」
となります。
次に、2の補数をとります。
各ビットを反転させ、1を足します。
「0000000000011101」
こうなりました。
計算すればわかりますが、ちゃんと29になっています。

・・・とこんな感じです。
あんまりうまく説明できてないかもしれません、申し訳ないです。

また何かあったら聞いてくださいね!

ちなみに、プログラムで変換するときは2の補数とかは考えず、short型にキャストすれば勝手に変換してくれます(cの場合ですが)

ありがとうございます!!
そういう事だったんですか☆ できたら開発者ガイドにも書いておいて欲しいものですね笑
javaでは変換できないみたいなので早速変換プログラムを書いてみます。
本当にいつもいつも助かります(´∀`)

確かに開発者ガイドはちょっと使いにくいですね。
多分企業向けだったんでしょうね
ちなみに、今は製造中止とのこと・・・
もったいないですよねぇ~・・・

javaではだめでしたかぁ
一応、古いバージョンのtdcontrolでは関数で変換しているので、良かったら参考にどうぞ。
ConvNumberと言う関数です。

int TDControl::ConvNumber(WORD num)
{
  if((num & 0x8000) != 0){
    WORD buf;
    int ret;
    buf = ~(num - 1);
    ret = buf;
    ret = -ret;
    return ret;
  }else{
    return num;
  }
}

本当製造中止は残念です。。。価格もお手頃ですし。
とりあえず値を出すプログラムを書きました☆本当汚いですけど笑
本当にいつもいつもありがとうございます!

はじめまして、masaと申します。物自体が発売から相当年数が経っていますが、今から使ってみようと思い、情報をかき集めていたら、当サイトを見つけた次第です。

ここの情報を元にMicrosoft Visual C++ .NET2003を使って、センサ情報をprintfにて表示するところまで、いけました。今後は、角度情報をGUIで表示してみたいと思っています。
そこで質問なのですが、MitakaPointerのところに角度のGUIがあるようですが、どのようにして表示しているのでしょうか?

はじめまして.
コメントありがとうございます.

TDControl2を参考にしていただき,ありがとうございます.
C++どころかCもろくに勉強していない時のものなので,
むちゃくちゃな部分が多いうえに,そのまま放置してしまい申し訳ないです.
少しでもお役に立てたのであれば幸いです.

角度情報を表示されたい,とのことですが,TDS01Vを向けた方位(北や南の向きの角度)のことでよろしいでしょうか?
方位角の情報は,TDControl2では,
tdc.RecvData.DirDeg
に入っています.
自分の書いたマニュアルによれば,DirDegはint型であると書いていますが,今確認するとfloat型ですね・・・すいません.
もし,printfされるのであれば,%d指定では正しい値が出力されないと思われます.
%fを指定してみてください.
今僕の使っている環境では,TDS01Vを試すことができないのですが,おそらくこの値を10で割り算すれば方位角になるはずです.

GUIに表示ついてですが,僕は開発環境にC++Builderというものを使用しているので,VisualC++についてはお役に立てそうにないです.
ですが,例えばこちらのサイト
http://www.geocities.jp/kokoronoiinnkai/page0008.html
にあるように,タイマーを使って,定期的にTDS01Vの角度値を読み込み,ラベルのテキストを書き換える,
という処理を行えば,ひとまずGUI上で角度を表示できると思います.

返信ありがとうございます。VisualC++でも公開されているソースで角度読み込みできたので、C++Builderと環境は似てるのかもしれませんね。

初めてprintfで出力したときは、tdc.RecvData.DirDegのデータを、4桁出力してきたので驚きました。その後に10で割ることに気づき、方位角になりましたが。。。

紹介していただいたサイトを参考にすると方位角が数字として出力されそうですね。
試してみます。

こんにちわ。masaです。
気になった場所がありまして以下の場所です。
// 受信処理
for(int i=0; i<100; i++){
Sleep(100);
// 受信

ここのSleep(100)は、100msごとにデータ受信ってことでしょうか?
できれば、Sleep関数を削除したいのですが削除するとpress any key~~と、そもそもソースが流れません・・・・。

こんにちは.
tdc2の作者のfutrです.

tdc2のサンプルコードのSleepの部分は,受信間隔ではなく,受信処理の試行待ち時間を意味しています.
つまり,100msに一回データーが送られてくる保証はなく,とりあえず100msに一回受信されているか確認して,受信できていれば
if ( tdc.Recv() )
の中に入って受信結果を表示する,という仕組みになっています.
tdc.Recv()の戻り値が0でなければ受信が完了したことを意味しています.

よって,もちろんSleepは削除していいのですが,TDS01Vが結果を送ってくるまではtdc.Recv()を実行し続けなければ一度も結果が出力されません.

もし確実に100回受信させ,100回表示させたければ,
for ( i = 0; i < 100; i++ ) {
while( !tdc.Recv() );
std::cout << "ALT " << tdc.RecvData.Altitude << std::endl;
}
のようにすることでおそらく実現することができます.

しかし,この方法ではOSやGUIスレッドに負荷がかかる可能性があるので,
もし問題が発生する場合は,別スレッドで実行しSleep(0)を定期的に呼んであげるか,
タイマーなどで定期的にtdc.Recv()の結果を見て,0でなければ出力するなどの対処が考えられます.

こんにちわ。masaです
約2ヶ月ほど経ちましたが、opencvを使って電子コンパスのGUIを(粗悪なものですが)
完成しました。これからは、より分かりやすいGUIへと改良するべく進んでいきます。

futrさん ご助言ありがとうございました。

こんにちは。
masaさん。
tdc2の作者のfutrです。

うまく作成できたようで何よりです。少しでもお役に立てたのであれば嬉しいです。
今後も開発頑張ってください。

はじめまして。peroと申します。
プログラム初心者ではありますがこちらのサイトを見てTDS01Vの制御に興味を持ち現在コードリーディング中です。
質問があるのですが、このライブラリを使用して一つのPCに接続した複数のTDS01Vの制御は可能でしょうか。
また、可能であればどのような処理を施すかなども教えて頂ければ大変助かります。

はじめまして,peroさん.
tdc2の作者のfutrです.

tdc2を参考にしていただきありがとうございます.
コードリーディング中とのことですが,このプログラムは当時の私の非常に拙い知識で書かれているので,可能であればtdc2の制御方法を参考にご自分でライブラリを書かれたほうが良いかもしれません.
もちろん,tdc2をそのまま利用していただいても問題ありません.

ご質問の件ですが,まず私がTDS01Vを複数台持っていないのでこちらで実験できていません,もしかしたら以下の方法では実現できないかもしれません.もしダメだったらごめんなさい.

パソコンにTDS01Vを複数接続し,それがデバイスマネージャーで異なるCOMとして認識されていれば,恐らく利用可能です.
tdc2についても,特に1台制御用と限定されるような記述はしてなかったと記憶しているので恐らく動作します.

プログラムについては,TDControlのインスタンスを複数作成し,それぞれについて,初期化・受信処理を行えば良いと思います.
sample.cppで言えば
TDControl tdc;

TDControl tdc,tdc2;
のようにします.

残りのプログラムについては,
tdc.Open(buf)
であれば,
tdc2.Open(buf2)
を追加し,それぞれtdc2についてもtdcと同様のプログラムを追加してみてください.
当然,buf2にはbufとは異なるTDS01VのCOMポート番号を指定してください.
この方法だとTDS01Vが増えるほどプログラムが長くなるので,配列にしても良いかもしれません.
TDControl tdc[3];
のような感じです.

少しsample.cppとは違いますが,以下にサンプルコードを書いて見ました.
現在手元に試せる環境が無いので,もし動かなかったらごめんなさい.
https://gist.github.com/futr/32d1fd9bcbe30acd2666

何かわからない点などがあれば,遠慮無くコメントください.
それでは,開発頑張ってください.

こんにちは。peroです。
返信ありがとうございました。

詳しい解説だけでなくサンプルコードまで書いていただき、本当に助かりました!
サンプルコードは実行してみたところ、きちんと動きました。

現在使用しているマシンの性能も影響しているのでしょうが、受信回数を1000回に増やして10秒間の受信を試みようとすると、動作が重くなってしまい最後の受信を終えるまでに10秒以上かかりました...現在は並列処理のプログラムを書いてやれば少しは早くなるかな?と思ってコードを書いています。

開発、頑張っていきたいと思います!

こんばんは、peroさん。
tdc2の作者のfutrです.

サンプルコードがお役に立ったようで何よりです。

サンプルコードは、受信時にSleepを使いプログラムを止めているので、あまり良い方法ではありません。
10ミリ秒も正確に10ミリ秒ではなく、さらにRecv関数の処理時間等もあるので、10秒位上かかっているのだと思います。
プログラムを止めている影響で、GUIを扱うプログラムが含まれているとマウスの応答やキーボードの応答が停止してしまいます。

対処方法としては、Sleep(10)をSleep(1)等に変更し、他のスレッドでRecvを繰り返し呼び出して、受信が完了するのを待つか、何らかのタイマーを使って、一定時間ごとにRecv関数を呼び出し、受信完了するのを待つ方法などがあります。
Recvは受信完了するまではfalseを返し、受信完了するとtrueを返すので、Recvの戻り値で受信完了を判断することができます。

ユーザーの入力を待つ場合や、GUIを使いたい場合は、並列処理は良い対処方法だと思います。

質問等がありましたらまたコメントください。
それでは。

この記事へのコメントは終了しました。

トラックバック


この記事へのトラックバック一覧です: TDControl2(テスト版):

» TDControl2をMac用に改造する [佐藤伸吾のフィジカル/ユビキタスコンピューティングblog]
ぷろぐらむとか: TDControl2(テスト版) で公開されているTDControl2というライブラリをMac上で動作するように改造しようとしています。 % wget http://futr.cocolog-nifty.com/blog/files/tdc2.lzh % lha x TDControl.lzh % cd tdc2 % ls comc.h sample.cpp sample.exe tdc2... [続きを読む]

» [tds01v]TDS01Vを制御するプログラムを書く [佐藤伸吾(akio0911)のフィジカル/ユビキタスコンピューティングblog]
ひとまずぷろぐらむとか: TDControl2(テスト版)を参考に、リセットを行うプログラムを書いてみた。 /lang/c/tds01v/sample.c - CodeRepos::Share - Tracにも上げてあります。 /* MacでUSB経由にてTDS01Vの値を取得する */ #includestdio.h #includestdlib.h... [続きを読む]

» 3Dセンサーのプログラム [around gps]
「ぷろぐらむとか」のTDControl2(C )を参考に,C#でTDS01Vの [続きを読む]

« 16F88(ただの日記) | トップページ | カラクラ2復活計画 »