FlashAir を.NET Gadgeteerで使ってみた

東芝が販売しているFlashAir(https://www.toshiba.co.jp/p-media/flashair/ )、.NET Gadgeteerから見れば、SDカードメモリそのものなので、各種センサーの値をSDメモリーカードに書き込んでいけば、FlashAirにWiFiでつながっているPCやスマートフォン、タブレットから、書き込んだ内容が見れるわけですね。逆にPC、スマートフォン、タブレットからWiFiを通じて、FlashAir側に命令などを書き込んだファイルをアップロードしてあげれば、.NET Gadgeteer側にデータを与えることが出来るってこと。

で、とりあえず、加速度センサーで計測した値をFlashAirを通じてPCに送るプログラムを試してみました。

回路図は、以下の通り。

この通りにボードを結線してSDカードリーダーにFlashAirを装着すれば準備完了。

Program.csの、ProgramクラスのProgramStartedメソッドを、以下のようなコードにして、

        void ProgramStarted()
        {
            /*******************************************************************************************
            Modules added in the Program.gadgeteer designer view are used by typing
            their name followed by a period, e.g.  button.  or  camera.
           
            Many modules generate useful events. Type +=<tab><tab> to add a handler to an event, e.g.:
                button.ButtonPressed +=<tab><tab>
           
            If you want to do something periodically, use a GT.Timer and handle its Tick event, e.g.:
                GT.Timer timer = new GT.Timer(1000); // every second (1000ms)
                timer.Tick +=<tab><tab>
                timer.Start();
            *******************************************************************************************/

            sdCard.MountSDCard();

            Thread.Sleep(500);

            new Thread(WorkerThread).Start();

            // Use Debug.Print to show messages in Visual Studio's "Output" window during debugging.
            Debug.Print("Program Started");
        }

で、Programクラスに、以下の変数と、WorkerThreadメソッドを追加。

        string rdName;
        string dxFileName = @"\dataexchange.txt";
        
        public void WorkerThread()
        {
            rdName = sdCard.GetStorageDevice().RootDirectory;
            if (!System.IO.File.Exists(rdName + dxFileName))
            {
                fs = System.IO.File.Create(rdName + dxFileName);
            }
 
            GT.Timer timer = new GT.Timer(10000);
            timer.Tick += timer_Tick;
            timer.Start();
        }

WorkerThreadメソッドでは、SDカードのルートディレクトリ名を取得して、データ交換の為のファイルが無ければ生成、で、タイマーを起動、をやっている。

timer_Tickメソッドは、以下の通り。

        void timer_Tick(GT.Timer timer)
        {
            var accel = accelerometer.RequestMeasurement();

            using (fs = new FileStream(rdName + dxFileName, FileMode.Open, FileAccess.Write))
            {
                fs.Seek(0, SeekOrigin.End);
                var writer = new StreamWriter(fs);
                writer.WriteLine("Accelerometer:x=" + accel.X + ",y=" + accel.Y + ",z=" + accel.Z + " @" + DateTime.Now.ToString());
                writer.Flush();
            }

         }

 はい、これで出来上がり。コード見れば何となくわかりますね。一応解説しておくと、accelerometerが加速度センサーで、RequestMeasurementメソッドで現在値を取得、データ交換用ファイルを開いて、書き込み位置を最後に移動(Seekメソッド)、加速度センサーの値を現在時刻とともに格納。タイマーの時間間隔ごとにこれが繰り返されるわけ。

次は、逆方向(PCなどから.NET Gadgeteerに送る)のプログラムを試してみる。多分だが、以下のコードでファイルのアップロード時刻を監視していれば、PCなどからファイルが更新されたか判断できるはず。

            var fi = new FileInfo(rdName + dxFileName);
            var currentLastAccessTile = fi.LastAccessTime;
            if (currentLastAccessTile > lastFileAccessTime)
            {
                // file changed! this means that file has been updated by external device.
            }

あ、using宣言は適宜追加してくださいね。

PS
FlashAirのミドルウェアが何を使っているか知らないのですが、FlashAirそのものに、.NET Micro Frameworkが載っていて、開発用PCにSDカードを差し込んで、いろんなアプリをFlashAir上で動かせると素敵なんですけどね…