C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[1]: WiiバランスボードのデータをExcelに書き出したい


(過去ログ 140 を表示中)

[トピック内 2 記事 (1 - 2 表示)]  << 0 >>

■82229 / inTopicNo.1)  WiiバランスボードのデータをExcelに書き出したい
  
□投稿者/ もりぞー (1回)-(2016/12/19(Mon) 14:54:34)

分類:[C#] 

2016/12/19(Mon) 15:09:04 編集(投稿者)

初めて書き込みします。
素人丸出しの者ですが、必要に駆られてVisualStudioでWiiバランスボードの
データを記録するプログラムを作っています。

やりたいことは、PCにBluetooth接続したバランスボードから送られてくるデータを、
30秒間測定して、Excelファイルに書き出すことです。

http://www.kosaka-lab.com/tips/2009/02/wiiwii-fit.php
↑の記事をベースに改変しました。
PCとバランスボードの通信には、Wiimotelibというプログラムを使用しています。

目的は果たせたのですが、
測定を繰り返した場合に、2回目以後の測定でデータの記録間隔が1回目よりも長く、不整になってしまうのです。
1回目の測定では1秒間にほぼ100回記録されるのですが、
2回目以後は60回くらいになります。

この現象は、比較的低スペックのPCでのみ起きるので、
Excelを起動して終了した際に、プロセスの終了等がきちんとできておらず、
リソースを食ってるのかな等々考えたのですが、うまくいきません。
(finishTest() の部分がExcelを起動してファイルを書き込み、Excelを閉じる部分です)

もし原因がわかりましたら、ご指摘いただければ幸いです。
長いコードで申し訳ありません。

開発環境:Visual Studio community 2015
文字数オーバーのため、次のレスでソースを貼ります。
色々、基本的なところがわかっていないと思いますが、ご容赦ください。

引用返信 編集キー/
■82230 / inTopicNo.2)  Re[1]: WiiバランスボードのデータをExcelに書き出したい
□投稿者/ もりぞー (2回)-(2016/12/19(Mon) 14:57:12)
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using WiimoteLib;
using Excel = Microsoft.Office.Interop.Excel;
using Office = Microsoft.Office.Core;
using Microsoft.Office.Interop.Excel;
using TM = System.Timers;


namespace WBB2
{
    
    public partial class Form1 : Form
    {
        Wiimote wm = new Wiimote();
        float[] TLCalib = new float[100];
        float[] TRCalib = new float[100];
        float[] BRCalib = new float[100];
        float[] BLCalib = new float[100];
        float[] BWCalib = new float[100];
        float CalibratedTL = 0;
        float CalibratedTR = 0;
        float CalibratedBR = 0;
        float CalibratedBL = 0;
        float AveTL = 0;
        float AveTR = 0;
        float AveBR = 0;
        float AveBL = 0;
        float AveTLkg = 0;
        float AveTRkg = 0;
        float AveBRkg = 0;
        float AveBLkg = 0;
        float AveBW = 0;
        float COPx = 0;
        float COPy = 0;
        int CTimes = 0;
        object[,] datas = new object[3500, 21];//データ格納用の配列を宣言
        int d = 0;//データ取得回数
        int t = 1;//検査施行回数
        string path = "C:\\WiiData\\";//データ保存場所
        System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();//時間経過測定用

        public Form1()
        {
            InitializeComponent();
            Control.CheckForIllegalCrossThreadCalls = false;

            //データラベルを二次元配列の1行目に格納
            datas[0, 0] = "Num";
            datas[0, 1] = "1/1000sec";
            datas[0, 2] = "CoPx";
            datas[0, 3] = "CoPy";
            datas[0, 4] = "TL";
            datas[0, 5] = "TR";
            datas[0, 6] = "BR";
            datas[0, 7] = "BL";
            datas[0, 8] = "Weight";
            datas[0, 9] = "RawTL";
            datas[0, 10] = "RawTR";
            datas[0, 11] = "RawBR";
            datas[0, 12] = "RawBL";
            datas[0, 13] = "ZeroTL";
            datas[0, 14] = "ZeroTR";
            datas[0, 15] = "ZeroBR";
            datas[0, 16] = "ZeroBL";
            datas[0, 17] = "IntCalTL";
            datas[0, 18] = "IntCalTR";
            datas[0, 19] = "IntCalBR";
            datas[0, 20] = "IntCalBL";

        }

        private void button1_Click(object sender, EventArgs e)
        {
            
            //データ取得回数を初期化
            d = 0;

            //接続
            this.wm.Connect();

            //タイマー開始
            sw.Start();

            //イベントハンドラ登録
            this.wm.WiimoteChanged += wm_WiimoteChanged;

        }

        private void button2_Click(object sender, EventArgs e)
        {
            if (d == 0) return;
            //接続を停止
            this.wm.Disconnect();
            //イベントハンドラを停止
            this.wm.WiimoteChanged -= wm_WiimoteChanged;

            finishTest();
        }

        void finishTest()
        {
            //datasの内容をExcelファイルに書き出し
            DateTime dtNow = DateTime.Now;
            string dtStr = dtNow.ToString();
            string dtStrR = dtStr.Replace("/", "_");
            string dtStrRR = dtStrR.Replace(":", "_");
            string FileName = textBox1.Text + "_" + t + "_" + dtStrRR;

            Microsoft.Office.Interop.Excel.Application ExcelApp
              = new Microsoft.Office.Interop.Excel.Application();
            ExcelApp.Visible = false;
            Workbook wb = ExcelApp.Workbooks.Add();

            Worksheet ws1 = wb.Sheets[1];
            ws1.Select(Type.Missing);

            Excel.Range rgn = ws1.Range[ws1.Cells[1, 1], ws1.Cells[d+2, 21]];
            rgn.Value2 = datas;
            d = 0;

            wb.SaveAs(path + FileName);
            wb.Close(SaveChanges:false);
            ExcelApp.Quit();

            t++;
            sw.Reset();

            //オブジェクトを開放
            System.Runtime.InteropServices.Marshal.ReleaseComObject(wb);
            System.Runtime.InteropServices.Marshal.ReleaseComObject(ws1);
            System.Runtime.InteropServices.Marshal.ReleaseComObject(rgn);
            System.Runtime.InteropServices.Marshal.ReleaseComObject(ExcelApp);
            wb = null;
            ws1 = null;
            rgn = null;
            ExcelApp = null;

            //ガーベッジコレクションを実行
            System.GC.Collect();

            MessageBox.Show("Data recorded Successfully!", "Info", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);

        }

        void wm_WiimoteChanged(object sender, WiimoteChangedEventArgs args)
        {
                  
            //WiimoteStateからデータ取得
            WiimoteState ws = args.WiimoteState;

            //COP点を表示
            this.DrawForms(ws);

            //体重の表示
            this.label1.Text = ws.BalanceBoardState.WeightKg - AveBW + "kg";

            //経過時間の表示
            this.label2.Text = "TimePassed:" + sw.ElapsedMilliseconds.ToString();

            CalibratedTL = ws.BalanceBoardState.SensorValuesKg.TopLeft - AveTLkg;
            CalibratedTR = ws.BalanceBoardState.SensorValuesKg.TopRight - AveTRkg;
            CalibratedBR = ws.BalanceBoardState.SensorValuesKg.BottomRight - AveBRkg;
            CalibratedBL = ws.BalanceBoardState.SensorValuesKg.BottomLeft - AveBLkg;

            COPx = (43 / 2) * (CalibratedTR + CalibratedBR - CalibratedTL - CalibratedBL)
               / (CalibratedTR + CalibratedBR + CalibratedTL + CalibratedBL);
            COPy = (24 / 2) * (CalibratedTL + CalibratedTR - CalibratedBR - CalibratedBL)
               / (CalibratedTR + CalibratedBR + CalibratedTL + CalibratedBL);

     
            //二次元配列datasにデータを格納
            datas[d, 0] = d - 1;
            datas[d, 1] = sw.ElapsedMilliseconds;
            datas[d, 2] = COPx;
            datas[d, 3] = COPy;
            datas[d, 4] = CalibratedTL;
            datas[d, 5] = CalibratedTR;
            datas[d, 6] = CalibratedBR;
            datas[d, 7] = CalibratedBL;
            datas[d, 8] = ws.BalanceBoardState.WeightKg - AveBW;
            datas[d, 9] = ws.BalanceBoardState.SensorValuesRaw.TopLeft;
            datas[d, 10] = ws.BalanceBoardState.SensorValuesRaw.TopRight;
            datas[d, 11] = ws.BalanceBoardState.SensorValuesRaw.BottomRight;
            datas[d, 12] = ws.BalanceBoardState.SensorValuesRaw.BottomLeft;

            if (d == 3100)
            {

                //接続を停止
                this.wm.Disconnect();
                //イベントハンドラを停止
                this.wm.WiimoteChanged -= wm_WiimoteChanged;

                this.finishTest();

            }
            
            d++;

        }

        public void DrawForms(WiimoteState ws)
        {
            Graphics g = this.pictureBox1.CreateGraphics();
            g.Clear(Color.Aquamarine); 
            
            //X、Y座標
            float x =
               COPx/10 * 8 + 175;
            float y =
               -COPy/10 * 8 + 100;

            this.label4.Text = "X:" +COPx;
            this.label5.Text = "Y:" +COPy;

            if (ws.BalanceBoardState.WeightKg < -0.5)
            {
                g.FillEllipse(Brushes.Red, 175, 100, 20, 20);
            }
            else
            {
                g.FillEllipse(Brushes.Navy, x, y, 20, 20);

                g.Dispose();
            }
        }

        private void button3_Click(object sender, EventArgs e)
        {

                //Wiimoteの接続
                this.wm.Connect();

                //イベント関数の登録
                this.wm.WiimoteChanged += wm_Calibration;
            
        }

    }
}

引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -