3Dセンサーのプログラム
「ぷろぐらむとか」のTDControl2(C++)を参考に,C#でTDS01Vのデータを取得するプログラムを作っていましたが,とりあえず,ボタンを押すたびにデータを取得するプログラムができました。エラー処理とか,タイミングとか細かいところは全く見ていませんので,自己責任で試してみてください。フォームに必要なのは
- シリアルポート選択用のコンボボックス(cboPort)
- シリアルポート接続用ボタン(btnConnect)
- 計測開始用ボタン(btnStart)
- 計測表示用ボタン(btnMeasure)
- 表示用テキストボックス(txtDisplay)
の五つです。ボタンを押す代わりにタイマー起動させるようにすれば,定期的にデータを取得できます。
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;
namespace TDS01V
{
public partial class frmMain : Form
{
private TDControl tds;
private AllData meas = new AllData();
private const int INTERVAL = 0; // 1 time
private const int BAROMETER = 10133; // 1013.3 hPa
private const int VARIATION = 3540; // W6 deg
public frmMain()
{
InitializeComponent();
}
private void frmMain_Load(object sender, EventArgs e)
{
tds = new TDControl ();
btnConnect.Text = "Connect";
btnStart.Text = "Start";
}
private void btnConnect_Click(object sender, EventArgs e)
{
if (btnConnect.Text == "Connect") {
tds.Open(cboPort.Text);
btnConnect.Text = "Disconnect";
} else {
tds.Close();
btnConnect.Text = "Connect";
}
}
private void cboPort_Click(object sender, EventArgs e)
{
string[] ports = SerialPort.GetPortNames();
Array.Sort(ports);
cboPort.Items.Clear();
foreach (string s in ports)
cboPort.Items.Add(s);
}
private void btnStart_Click(object sender, EventArgs e)
{
if (btnStart.Text == "Start") {
if (tds.Init(INTERVAL, BAROMETER, VARIATION)) {
btnStart.Text = "Stop";
}
} else {
tds.Stop();
btnStart.Text = "Start";
}
}
private void btnMeasure_Click(object sender, EventArgs e)
{
meas = tds.Measure();
txtDisplay.Text = meas.DirDeg.ToString() + " " + meas.Altitude.ToString();
}
}
}
3Dセンサーは改行コードがCR+LFになっています。SerialPort.WriteLine()は行末にNewLineを出力するので文字列にCRだけを付加しています。コマンドは文字列で与えてもいいのですが,整数値を16進数に変換するようにしました。受け取ったデータも整数値ですので,値によっては10.0で割る必要があります。コマンドを送って,データを受け取るまでに,待つ必要があるはずですが,とりあえず動作しているので,放置しています。もしかしたら,1回分遅れたデータを取得しているのかもしれません。ステータスを見て変換終了を確認するべきだと思います。
using System;
using System.Collections.Generic;
using System.Text;
using System.IO.Ports;
namespace TDS01V
{
public struct AllData
{
public int MagVX, MagVY, MagVZ;
public int DirDeg;
public int AccVX, AccVY, AccVZ;
public int RollDeg, PitchDeg;
public int Barometer, Altitude;
public int Temp, Volt;
}
class TDControl
{
private const int CMD_SET_CONDITION = 0x05;
private const int CMD_SET_SENSORTYPE = 0x0D;
private const int CMD_RESET = 0x0F;
private const int CMD_START = 0x21;
private const int CMD_STOP = 0x23;
private const int CMD_MAGINIT = 0x27;
private const int CMD_READ = 0x29;
private const int CMD_CHECK = 0x2B;
private const int CMD_ROMVER = 0x5F;
private const string CRLF = "\r";
public SerialPort port = new SerialPort();
private bool opened;
public TDControl()
{
opened = false;
port.WriteTimeout = 2000; // timeout 2000ms
port.ReadTimeout = 2000; // timeout 2000ms
}
public bool Open(string com)
{
port.PortName = com;
port.BaudRate = 9600;
port.Parity = Parity.None;
port.DataBits = 8;
port.StopBits = StopBits.One;
try {
port.Open();
}
catch (Exception ex) {
System.Diagnostics.Trace.WriteLine("Trouble opening the SerialPort! " + ex.ToString());
return false;
}
opened = true;
return true;
}
public bool Close()
{
try {
port.Close();
}
catch (Exception ex) {
System.Diagnostics.Trace.WriteLine("Trouble closing the SerialPort! " + ex.ToString());
return false;
}
opened = false;
return true;
}
public bool Init(int interval, int hpa, int variation)
{
if (opened) {
for (int i = 0; i < 3; i++) {
if (GetCommand(CMD_CHECK) != "") break;
if (i == 2) return false;
}
if (!Command(CMD_RESET))
return false;
GetCommand(CMD_CHECK);
GetCommand(CMD_CHECK);
GetCommand(CMD_ROMVER);
if (!SetCommand(CMD_SET_CONDITION, interval.ToString("X2") + hpa.ToString("X4") + variation.ToString("X4")))
return false;
if (!SetCommand(CMD_SET_SENSORTYPE, "F7"))
return false;
if (!Command(CMD_MAGINIT))
return false;
} else {
return false;
}
return true;
}
public bool Stop()
{
if (opened) {
if (!Command(CMD_STOP))
return false;
} else {
return false;
}
return true;
}
public AllData Measure()
{
AllData meas = new AllData();
if (opened) {
Command(CMD_START);
string data = GetCommand(CMD_READ);
meas.MagVX = Convert.ToInt16(data.Substring(0, 4), 16);
meas.MagVY = Convert.ToInt16(data.Substring(4, 4), 16);
meas.MagVZ = Convert.ToInt16(data.Substring(8, 4), 16);
meas.DirDeg = Convert.ToInt16(data.Substring(12, 4), 16);
meas.AccVX = Convert.ToInt16(data.Substring(16, 4), 16);
meas.AccVY = Convert.ToInt16(data.Substring(20, 4), 16);
meas.AccVZ = Convert.ToInt16(data.Substring(24, 4), 16);
meas.RollDeg = Convert.ToInt16(data.Substring(28, 4), 16);
meas.PitchDeg = Convert.ToInt16(data.Substring(32, 4), 16);
meas.Barometer = Convert.ToInt16(data.Substring(36, 4), 16);
meas.Altitude = Convert.ToInt16(data.Substring(40, 4), 16);
meas.Temp = Convert.ToInt16(data.Substring(44, 4), 16);
meas.Volt = Convert.ToInt16(data.Substring(48, 4), 16);
}
return meas;
}
private bool Command(int cmd)
{
string _cmd = cmd.ToString("X2") + CRLF;
try {
port.WriteLine(_cmd);
}
catch (Exception ex) {
System.Diagnostics.Trace.WriteLine("Trouble writing the SerialPort! " + ex.ToString());
return false;
}
string status;
try {
status = port.ReadLine();
}
catch (Exception ex) {
System.Diagnostics.Trace.WriteLine("Trouble reading the SerialPort! " + ex.ToString());
return false;
}
if (cmd + Convert.ToInt16(status.Substring(0, 2), 16) != 255)
return false;
return true;
}
private bool SetCommand(int cmd, string data)
{
string _cmd = cmd.ToString("X2") + data + CRLF;
try {
port.WriteLine(_cmd);
}
catch (Exception ex) {
System.Diagnostics.Trace.WriteLine("Trouble writing the SerialPort! " + ex.ToString());
return false;
}
string status;
try {
status = port.ReadLine();
}
catch (Exception ex) {
System.Diagnostics.Trace.WriteLine("Trouble reading the SerialPort! " + ex.ToString());
return false;
}
if (cmd + Convert.ToInt16(status.Substring(0, 2), 16) != 255)
return false;
return true;
}
private string GetCommand(int cmd)
{
string _cmd = cmd.ToString("X2") + CRLF;
try {
port.WriteLine(_cmd);
}
catch (Exception ex) {
System.Diagnostics.Trace.WriteLine("Trouble writing the SerialPort! " + ex.ToString());
return "";
}
string data;
try {
data = port.ReadLine();
}
catch (Exception ex) {
System.Diagnostics.Trace.WriteLine("Trouble reading the SerialPort! " + ex.ToString());
return "";
}
return data;
}
}
}
| 固定リンク
「プログラミング」カテゴリの記事
- 2点の緯度・経度から距離を求める(PocketPC対応)(2008.06.21)
- 地形の3D表示プログラム(頂点座標作成)(2007.02.22)
- R8C/TinyマイコンでLED2個の調光ができた(2007.04.30)
- R8C/TinyマイコンでRCサーボモータが動いた(2007.05.03)
- PocketPCのPaintイベント(2008.06.23)
「電子工作」カテゴリの記事
- 秋月の3DセンサーをRS-232Cで使いたい(2008.06.01)
- 1PPSで写真撮影(2009.06.07)
- マイコンのプログラム(2007.04.29)
- R8C/TinyマイコンでLED2個の調光ができた(2007.04.30)
- R8C/TinyマイコンでRCサーボモータが動いた(2007.05.03)


コメント
こんにちは、今僕もTDS01VをJAVAを使って制御するプログラムを書いています!
まだ全然エラーばっかりですが。。。
投稿: mori | 2008/10/30 16:11
JAVAはさっぱり分かりません。苦労話も含め、WEBでぜひ公開してください。
投稿: Nori-chan | 2008/10/30 16:54
自分も今四苦八苦中です。。。
完成したら是非公開させてもらいたいと思います☆
投稿: mori | 2008/10/30 17:37