らんらん技術日記

日々の学習メモに

Bluetooth meshを試してみたい part3

前回までの話

Bluetooth Meshを試すべく、Laird社のBLEモジュール BL654(USBドングル版)を入手した。マニュアル通りにセットアップすればBluetooth Meshデバイスとして動くだろう、そう思っていた矢先、一つの壁にぶち当たる。ハードウエアの壁である。なんとUSBドングル版はLairdの推奨デバイスではなかったのである。 しかしここで諦める訳にはいかない。苦労の末にハードウエアの問題を解決し、Bluetooth meshデバイスとして動作させることに成功したのだった!

スマホアプリ(nRF mesh)の紹介

前回、BL654にBLE mesh用のプログラムをダウンロードしました。これで電源さえ投入すればBLE meshデバイスとして動作します。
次に行うのは、プロビジョニングという操作になります。BLE meshデバイスをmeshネットワークへ参加させるためには、プロビジョニングによってネットワークの構成要素であることを設定しなくてはいけません。プロビジョニングを実施するデバイスプロビジョナーと呼び、たいていの場合はスマホタブレットが担当するようです。
今回はLairdのアプリケーションノートに則り、iPhonenRF Meshインストールし、これをプロビジョナーとして利用します。nRF MeshはNordic社が出しているアプリでApple Storeから入手できます。もちろんAndroid版もあります。ServerとClient担当のBL654の電源を入れると、nRF Meshで以下のような画面が表示されます。
f:id:yukirunrun:20190211191818p:plain:h500
BLE meshデバイスとしてBL654を認識できているようです!
ここからプロビジョニングを進めていきたいのですがそれは次回の話に。というのも、あの問題に再び直面したのです・・・

ハードウエアの壁 再び

プロビジョニング関連でいろいろ試していると、あることに気づきました。

「autorunから抜け出すことができない・・・!」

LairdのSmartBasicには、起動と同時にプログラムを実行するautorunという仕組みがあるのですが、BL654がautorunから抜け出せなくなっていました。おそらくFirmwareアップグレードの影響と思います(「Bluetooth meshを試してみたい part1 」の記事参照)。autorunから抜け出せないと、データリセットやプログラムの更新ができません。私はプロビジョニングを通してBL654にいろいろ変なデータを設定したせいで、リセットの必要に迫られました。しかしautorunから抜け出せないのでリセットができません。つまり、BL654がいつの間にかただのゴミになっていたのです。

もちろん本来使用すべきDevkitでしたら、アプリケーションノートの指示に従ってautorunから抜け出せるでしょう。しかしUSBドングルでは同じ手順でやっても無理です。何十回も試したので断言します。ついでにUwTerminalXの「BL654 USB Dongle - Exit autorun」ボタンを押しても無意味です。これまた何十回も試したので断言します。

ふざけんなよーーーー!!!(自業自得)
お金返せよ・・・(自業自得)

FT232RのBit Bang Mode

やってられねー、とBL654を放置すること1週間。ふとあることを思いつきます。
「USBドングルでdevkitと同じ状態を再現したらよいのでは・・・?」
ソフトウエア的にではなく、ハードウエア(電気回路)的にです。その観点で調べてみると、次のことがわかりました。

 USBドングル:nAutoRun信号はFT232Rと接続している
 Devkit:nAutoRun信号はジャンクションで選択できる

nAutorunはBL654の機能ピンの一つで、0が入力されている時、電源投入と同時にSmartBasicプログラムが動きます。つまり「FT232RからnAutorun信号を制御することで、USBドングルはautorunから抜け出せる」と推測できます。というわけで、そこらへんも含めて回路図を起こしてみたのが下です。

f:id:yukirunrun:20190218204922p:plain


ここで、FT232Rは一般的なCOM通信のモードではなく、Bitbang Modeで動かします。で、Bitbang Modeとは何か? 私はよく知りません。 なんならさっきその存在を知りましたw 調べてみるといろいろ解説ブログが出てくるので、そちらを参考くださいな。

jsdiy.web.fc2.com

FT232RをBitbang Modeで動かすためのプログラムをC#で書くことにします。C#用のdllファイル(FTD2XX_NET.dll)、サンプルプロジェクトはFTDIのサイトから入手できます。個人的にはExample 3が参考になりました。
https://www.ftdichip.com/Support/SoftwareExamples/CodeExamples/CSharp.htm


C#でコンソールアプリケーションのソリョーションを作成します。参照にFTD2XX_NET.dllを加えます。そしたら、以下のソースコードでSmartBasicから抜け出せると思います!

using System;
using System.Threading;
using FTD2XX_NET;

namespace EEPROM
{
    class Program
    {
        static void Main(string[] args)
        {
            UInt32 ftdiDeviceCount = 0;
            FTDI.FT_STATUS ftStatus = FTDI.FT_STATUS.FT_OK;
            FTDI myFtdiDevice = new FTDI();
            ftStatus = myFtdiDevice.GetNumberOfDevices(ref ftdiDeviceCount);
            if (ftStatus != FTDI.FT_STATUS.FT_OK)
                return;
            if (ftdiDeviceCount == 0)
                return;

            FTDI.FT_DEVICE_INFO_NODE[] ftdiDeviceList = new FTDI.FT_DEVICE_INFO_NODE[ftdiDeviceCount];
            ftStatus = myFtdiDevice.GetDeviceList(ftdiDeviceList);
            ftStatus = myFtdiDevice.OpenBySerialNumber(ftdiDeviceList[0].SerialNumber);
            if (ftStatus != FTDI.FT_STATUS.FT_OK)
                return;

            if (ftdiDeviceList[0].Type == FTDI.FT_DEVICE.FT_DEVICE_232R)
            {
                Console.WriteLine("Exiting autorun mode");
                //RI(bit7) & DCD(bit6) & DTR(bit4) & RXD(bit1) as output 
                myFtdiDevice.SetBitMode(0xD2, FTDI.FT_BIT_MODES.FT_BIT_MODE_ASYNC_BITBANG);
                myFtdiDevice.SetBaudRate(1200);
                UInt32 writtenLength = 0;
                byte[] w1 = { 0x52 }; //RI = low, DCD = high, DTR = high, RXD = high
                byte[] w2 = { 0x12 }; //RI = low, DCD = low,  DTR = high, RXD = high
                byte[] w3 = { 0x52 }; //RI = low, DCD = high, DTR = high, RXD = high
                byte[] w4 = { 0x42 }; //RI = low, DCD = high, DTR = low,  RXD = high
                byte[] w5 = { 0x40 }; //RI = low, DCD = high, DTR = low,  RXD = low
                byte[] w6 = { 0x42 }; //RI = low, DCD = high, DTR = low,  RXD = high
                byte[][] wbuf = { w1, w2, w3, w4, w5, w6 };
                foreach(var buf in wbuf)
                {
                    myFtdiDevice.Write(buf, buf.Length, ref writtenLength);
                    Console.WriteLine("length:" + writtenLength.ToString());
                    Thread.Sleep(500);
                }
                myFtdiDevice.SetBitMode(0x00, FTDI.FT_BIT_MODES.FT_BIT_MODE_RESET);
            }
            myFtdiDevice.Close();
 
            Console.WriteLine("Press any key to continue.");
            Console.ReadKey();
            return;
        }
    }
}

このプログラムを実行したら、FT232Rを通常のCOM通信モードで開きましょう。BL654USBドングルはコマンドモードに入っているはずです。めでたし、めでたし。
以上、今回の記事はこれで終わり。次回こそはBLE meshとしての世界に入っていきたいと思います!