ラベル マイコン の投稿を表示しています。 すべての投稿を表示
ラベル マイコン の投稿を表示しています。 すべての投稿を表示

2019年8月8日木曜日

ANT->BLEブリッジの製作

ANTで無線送信されたパワー計の値をBLEに変換して無線送信するデバイスを製作しました。



Zwiftという、仮想空間内に自分のアバターをおき、サイクリングするソフトがあります。


PCに挿すANTドングルで自転車のパワー値を受信して、仮想空間内を進みますが、受信が安定しないことがあります。

ZwiftをインストールしたCPUの性能は、あまり関係しないようです。
2スレッドCPUのタブレットPCで安定する場合もあれば、16スレッドCPUのデスクトップでもANT受信に失敗し、0w(--w)表示となることもあります。
周囲の電波状況が大きく影響するによう感じます。

まじめに踏んでるときに0w表示になると萎えるので、これを解決するため
ANT無線信号をBLEに変換し、BLE信号をZwiftに受信させ安定通信するためのデバイスを作った次第です。

副作用として、このデバイスを使えば、ANTチップ非搭載のsmartphoneでも、BLE対応の市販アプリでパワー値を受信・表示できます。


動作は以下のとおりです。

- AP2モジュールで、近くのANTパワー値を受信、UART txピンでnRF52840に送信

- nRF52840のUART rxピンでANTデータを受信
 nRF52840でパワー値を算出。
 スイッチがON(PIN 20がLOW(GND接地))ならパワー値に約100wを追加。
 ジャスト100wにせず、1~12の乱数を足して合計100数wを追加することとします。
 増加値に数ワットの揺らぎを持たせ、ANTパワーが0wのときでも100+数wで人間がペダリングしているように見せかけることができます。
 これで峠の麓までは、ペダリングしなくとも勝手にアバターに移動してもらう、という自動運転ができます。

- nRF52840にてパワー値を:
 1. ANTフォーマットにしてUARTでAP2に送信、AP2からANTで無線送信
 2. BLEで無線送信

Bluetoothで定義されるCyclePowerService対応でパワー値を送信するのは初めてでした。
Adafruitが公開している心拍計センサーのソースコードを流用し、パラメータを若干追加修正したら動作しました。


ここで利用したnRF52840 Dongleなるものがリリースされていることを信州Maker管理人様から教えていただきました。

調べてみると、これはArduinoIDEでプログラムできる環境が整っていることを発見しました。
Adafruit社がBootloaderやライブラリを作ってくれており、ATMEGA32xと同じ感覚で簡単にプログラムを書き込めます。

ただし、nRF52840 DongleにAdafruit Boot Loaderを書き込む必要があります。

以下のサイトに今回のデバイスのソースコードを置きました(本日の日付をファイル名としています)。

(実際にアクセスする場合、末尾の000を削除して1138で終わるようURLを修正する必要があります。ロボット除けのためで、お手数をお掛けします)

ttps://sites.google.com/site/myfiles1138000


2019年4月19日金曜日

ArduinoとANT無線中継機とZWIFTオーバーテイクボタン

ArduinoマイコンでANT+規格の無線信号を送受信するための備忘録です。

ANT+で無線通信するモジュールとしてAP2と呼ばれるものがありました。

PINOUTも独特です。


これにUART接続(送信用Tx線と受信用Rx線の2線でデバイス間を接続)してコマンドを投げると、ANT+規格の無線信号を送信および受信できます。

nRF24AP2を利用したAP2モジュールはEOLのようで、私の入手した互換モジュールはこちら



◆左はAP2のコピー品
安定して動いてくれましたが、非通電状態でも、一度雨に濡れたら、動作不能となりました。

◆真ん中は、D52モジュール
AP2の後継で、チップは、nRF52832、PINOUTは互換。
でもソフト的には、完全互換ではなかったです。
正常動作のためには
- UART通信速度は9600bps以下で利用すること、
- コマンドを送ったら最低500ms待つこと
が必要なようです。

◆右は、最近みかけるAP2の変形バージョン
よくみるnRF24L01モジュールそっくりですが、これはnRF24AP2です。

PINOUTとschematic


ピンク印がBaudRate設定で、全部GNDに接続すると、
以下のチャートの通り通信速度が4800bpsに設定されます。
BR3 BR2 BR1 Baud Rate
0 0 0 4800
0 1 0 19200
0 0 1 38400
0 1 1 50000
1 0 0 1200
1 1 0 2400
1 0 1 9600
1 1 1 57600


手持ちのAP2互換モジュールは、8ch対応です。
つまり、チャンネル1でANT+のPower(ワット)信号を受信し、
チャンネル2でそのパワー値を送信することが可能です。

自宅のZWIFT用ANTレシーバは感度が低く、よく通信が切れるため、
クランクのパワー計のANT信号を中継してZWIFTに転送するデバイスを作りました。


Arduino ProMini(3.3v動作品)とAP2の接続図
UARTで、
ArduinoのTxをAP2のRxへ
ArduinoのRxをAP2のTXへ

ArduinoUno(3.3v動作に改造済)でも動作


ANTのパワー値を一度受信して、受信した数値を転送してます。
転送する際にパワー値をゴニョゴニョすると、オーバーテイクボタンを作れます。
「ボタンを押すと燃料の混合比が変わってプラス50馬力出力でマンセルをオーバーテイク」することはできませんが、ボタンを押すと、受信した生データに+100wの値を増加してZWIFTに転送、ZWIFT上で絡まれたくない相手を楽に振り切る、ということはできます。
チートとみなされると、まずいことになると思いますが、早速、中継器として動作実験開始・・・

ANTのシミュレータ上では、オーバーテイクボタンを押すと、283wの出力に100wを足して383wを受信できました。

でもなぜか途中で止まったり、ANT信号の受信に失敗したり。

どうもArduino UnoやProMiniで、SoftwareSerialを使ってANTモジュールと通信すると、安定せず、途中停止するようです。
ハードserialが2chあるArduino Microの3.3v対応品を取り寄せて、再度実験予定です。
2019/8/8更新:ArduinoMicroが思うように動かないため、nRF52をArduino化して実験しました(2019/8/8付けで投稿しました)が、やはり途中停止することがあり、ANTの受信は、途中停止を検出して、リセットする必要があると思います。

ANTの受信と送信を同時に行う今回のソースコードをUPLOADしました。
また、このコードでは、ZWIFT上で、ANTシミュレータの結果と異なり、0wの表示しかしませんでした。
ZWIFTは、たまにANT信号の受信に失敗し、0w表示となる問題があります。
今回のANT信号中継器を改良して、ZWIFTの0w表示問題も解決できればと思います。


2018年9月26日水曜日

スピード計の製作(ハブ巻き付け型)

GARMINの自転車用スピードセンサーで、ハブに巻き付けるタイプがあります。

これを真似てBLE送信するものを製作してみました。
これはマグネット不要で、簡単に他のホイールに付け替えられるので、従来のマグネットセンサーのものより便利です。
精度は劣るようですが、私は、スピード計に精度は求めないので、こちらの方がお気に入りです。

GARMINの偽物のようなものが格安で売られたりしており、経済的には自作するより購入した方がよいのですが、自己満足度が高いので、製作してみました。

ハード構成は、BL652無線マイコンに、秋月の3軸加速度センサモジュール ADXL335を取り付けました。
配線は、BL652のアナログ入力4番ピンとADXL335のY軸出力を結線しただけです。
tmpdata=GpioRead(4)
この一行で、ADXL335のアナログ出力値をtmpdataに代入できます。
システム全体の消費電力が低いのでボタン電池CR2032で駆動可能です。

消費電力は、無線送信込みで、1秒間に100回ADコンバートして、0.8mA、
2000回ADコンバートすると、1.7mA程度でした。
1秒間に100回のサンプリングでは、明らかに精度が足りませんが、電池寿命を優先しています。センサー類の電池切れは、自転車でもっとも残念なイベントの一つと思ております。

ADXL335は、加速度をアナログ出力するので、BL652のADコンバータでデジタル値に変換し、角度情報を得ます。

実験中、スピード計をハブにつけたり、はがしたりが面倒なので、「ハブ回転シミュレータ」を開発しました。
↓こちらです。サラダ水切り器です。

これは、上のハンドルを回すと、中身のザルが回転し、遠心力で、サラダの水切りができます、というデバイスです。
これに今回のスピード計をいれてテープで固定、ハブ回転方向にグルグルすると、センサー角度に応じて、センサーから値が得られました。
1回転すると、最大値が490以上、最小値が340以下でした。最大値、最小値ともにけっこうブレ幅があります。この辺を詰めないと、精度はでないと思いますが、とりあえずテストしてみます。
アルゴリズムは、ADXL335の読み取り値が345を下回ったら、1回転したと判定します。
1回転したら、1回転に要した時間をミリ秒単位で算出し、
BLEデバイスのデバイス名の最後に、16進数の文字列として設定し、
デバイス名をBLEのAdvertise送信します。
これをBLE対応のAndroid端末で独自アプリで受信、デコードして、スピードとして表示します。
受信側はAndroidでなく、BL652でも可能です。
BL652で受信して、Nokia5110液晶に表示すれば省電力スピードメーターの完成です。

システム全体が小さいので100均のLEDライトに仕込むとキレイに収まりそうです。

まだ、収納できる段階でないので、
とりあえず、ハブにガムテープで巻いて走行しました。

結果・・・そこそこ動きました。
サラダ水切り器シミュレータでも40Km/h以上では不安定でしたが、
実走でも、かなり不安定で、しばしば10Km/h以上低く表示されたりと
アルゴリズムを考え直す必要がありそうです。
個人的には、このくらいでも、無いよりマシと感じます。

スマホ表示

0x:0000019A0000000B7C
と数字ばかり並んでますが、これが今回のスピードセンサーから無線Advertise送信されたBLEデバイス名です。
最後のB7Cは、10進数に直すと2940、つまり1回転に2940ミリ秒を要した、という意味です。
これをもとにスピードを算出してます。

このAndroidアプリは、AndroidStudioのBluetooth Le Gattというサンプル・プログラムを改変してます。

AndroidStudioでダウンロードしたサンプルコードですが、Android6以上では、なんと動きません。
サンプル・コードが動かないとか、意味が分からないのですが、なぜかAndroidでは、頻発するので、敷居が高く感じます。
以下のPermissionをmanifestとアクティビティのOnCreateにそれぞれ追加するとAndroid6でも動作しました
<uses-permission android:name="android.permission.BLUETOOTH"/><uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /><uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

    if(Build.VERSION.SDK_INT >= 23)
    {
        this.requestBlePermission();    }




@TargetApi(23)
private void requestBlePermission(){
    if(checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED){
        requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION        },1);    }
}

今回は、暫定的にAndroidアプリを作りましたが、Androidアプリは、スマホをサイクル・コンピュータとして利用する際に汎用的に利用できるよう、もっと汎用性のあるつくりにしたいと考えております。

今回のスピードセンサー用BL652のソースコード、および
Androidのスピード表示アプリのソースコードを
以下のサイトに置きました(本日の日付をファイル名としています)。

(実際にアクセスする場合、末尾の000を削除して1138で終わるようURLを修正する必要があります。ロボット除けのためで、お手数をお掛けします)

ttps://sites.google.com/site/myfiles1138000

公開ソースコードは備忘録として利用しているため、スピードセンサーに関係ないコード(実験中のパワーメーターのコード)も混ざっており大変読みにくくなっております。











2018年9月20日木曜日

BL652 - BLEマイコンで温度センサー(ソフトウェア編)

BLEモジュールのBL652を用いて、温度を計測しスマホにBLEで送るデバイスを作りました。
BL652は、Noridic社のSDKを使わずにsmartBASICと称する BASIC言語でソフト開発が可能で、開発時間を短縮できます。

今回の温度計測は、BL652のベースであるnRF528チップの内蔵温度計を使用しています。
データシート上、計測誤差が±4度と、温度計としては実用範囲外ですが、Garmin等のサイコンの温度表示もこのレベルかと思います。

smartBASICでは、簡単に温度を計測できる関数がありました。
i=SYSINFO(2024)
これで変数iに温度(摂氏×10倍)が代入されます。



1.任意のテキスト エディタでBASICコードを書きます。
特に開発環境に指定はありません。

















// Definitions
//******************************************************************************
//#define TEMP_MANTISSA                        2711
#define TEMP_EXPONENT                        -2
#define UUID_HEALTH_THERMOMETER_SERVICE      0x1809

//#define UUID_HEALTH_THERMOMETER_SERVICE      0x1818

#define ENABLE_DEBUG_PRINTS                  1
#define BLE_DISCOVERABILITY_GENERAL          2
#define BLE_APPEARANCE                       0
#define MAX_DEVNAME_CHRS                     20
#define BLE_CHARVAL_AD_TAG                   0x16

#define ADV_SCAN_IND                         2
#define ADV_FILTERPOLICY_ANY                 0

        //Advertise interval
#define ADV_INTERVAL_MS                      250
        //Advertise timeout
#define ADV_TIMEOUT_MS                       0
        //Whitelist Policy in Adverts
#define ADV_WHITELIST_FILTER_POLICY          ADV_FILTERPOLICY_ANY

//******************************************************************************
// Global Variable Declarations
//******************************************************************************
dim rc         //Result code
dim devName$   //Device name
dim hChar      //Characteristic handle
dim hSvc       //Service handle
DIM  TEMP_MANTISSA

//Example :: BleVSpWrite.sb (See in BL652CodeSnippets.zip)
#define GPIO_TEMP_SENS           3 

DIM tx$,scRpt$,adRpt$,addr$,hndl,cnt,iToggle,adc
DIM iInterval,iTimerCount,startTick,prevTick,veloTick,iGcounter
iInterval=1
iGcounter=0
DIM tmpdata, data
DIM i 
DIM iCrankPass, iPower
//------------------------------------------------------------------------------
// For debugging
// --- rc = result code
// --- ln = line number
//------------------------------------------------------------------------------
Sub AssertRC(rc,ln)
    if rc!=0 then
        print "\nFail :";integer.h' rc;" at tag ";ln
    endif
EndSub
//------------------------------------------------------------------------------
// Register Error Handler as early as possible
//------------------------------------------------------------------------------
sub HandlerOnErr()
  if (ENABLE_DEBUG_PRINTS!=0) then
    print "\n OnErr - ";GetLastError();"\n"
  endif
endsub

//------------------------------------------------------------------------------
// This subroutine gets called first
//------------------------------------------------------------------------------
sub OnStartup()

endsub

//******************************************************************************
// Handler definitions
//******************************************************************************

//Example :: TimerRunning.sb
FUNCTION HandlerTimer0()
DIM rc,dvcNme$,nmeWrtble,apprnce,MinConnInt,MaxConnInt,ConnSupTO,sL,sTgt$,tmp$
DIM addr$ : addr$=""

DIM discovMode : discovMode=0 
DIM advAppearance : advAppearance = 1
DIM maxDevName : maxDevName = 22
DIM advRpt$ : advRpt$=""
DIM scRpt$ : scRpt$=""

    dim scnRpt$  //Empty scan report

//----------------------
nmeWrtble = 0             //Device name will not be writable by peer
apprnce = 768             //The device will appear as a Generic Thermometer
MinConnInt = 500000        //Minimum acceptable connection interval is 0.5 seconds
MaxConnInt = 1000000       //Maximum acceptable connection interval is 1 second
ConnSupTO = 4000000        //Connection supervisory timeout is 4 seconds
sL = 0                   //Slave latency--number of conn events that can be missed

PRINT "\nSystmp 2024    = ";SYSINFO(2024) 

i=SYSINFO(2024) 

//---Advertise

SPRINT #tmp$, " ";integer.h' i
tmp$=RIGHT$(tmp$, strlen(tmp$)-4)
sTgt$=tmp$
dvcNme$="temp.="+sTgt$

nmeWrtble = 0                
apprnce = 768            
MinConnInt = 500000          
MaxConnInt = 1000000         
ConnSupTO = 4000000      
sL = 0                      

rc = BleGapSvcInit(dvcNme$,nmeWrtble,apprnce,MinConnInt,MaxConnInt,ConnSupTO,sL)

IF BleAdvRptInit(advRpt$, discovMode, advAppearance, maxDevName)==0 THEN
 PRINT "\nAdvert report initialised"
endif

PRINT BleAdvRptAddUuid16(advRpt$, 0x180F,0x180A, -1, -1, -1, -1)
PRINT BleAdvRptsCommit(advRpt$, scRpt$)

//rc =BleScanStart(20000, 0)
PRINT "\n --- New DevName : "; BleGetDeviceName$()
IF BleAdvertStart(0,addr$,25,60000,0)==0 THEN   
    PRINT "\nAdverts Started\n" 
endif

ENDFUNC 1         //remain blocked in WAITEVENT
        //exit from WAITEVEN if end func ZERO0
//----------------------------MAIN C----------------------------------
ONEVENT EVTMR0 CALL HandlerTimer0

//setups------------------------------------------------------------------------------------------------
TIMERSTART(0,1000,1)  //4 NG 14 work    //start a 1000 millisecond recurring timer
PRINT "\nWaiting for Timer 0"
//Remove resistor 
PRINT GpioSetFunc(GPIO_TEMP_SENS, 1, 2)  
//Analogue in 
PRINT GpioSetFunc(GPIO_TEMP_SENS, 3, 0)

WAITEVENT

PRINT "\nExiting..."
2.オンラインコンパイラで、BL652(とfirmwareのバージョン)を指定し、上記で書いたBASICのファイルを選択し、XCompileボタンを押すと、ソースがコンパイルされ、実行ファイルがダウンロードされます。
エラーがあると、ブラウザにエラー箇所が表示されます。




Laird社推奨のUwTerminalXを使用して、上記の実行ファイルをBL652に書き込みます。
まず、COMポートの設定を行います。


続いてTerminalタブで右クリックー>LOAD+RUNー>ファイル選択
でBL652に書き込む実行ファイルを指定すると、書き込めます。
 LOADとRUN・・・懐かしい。



書き込みが完了すると、自動的に実行ファイルがRUNされます。
PRINT文の出力は、Terminalに表示されます。


“Systmp 2024=”の値が温度です。(摂氏×10倍)
“New DevName” は、BL652モジュールがBLEデバイスとしてAdvertiseしてる名前です。


↓スマホ側の表示です。
BLEデバイスをスキャンすると、以下のようにtemp.=として温度(摂氏×10倍)が16進数でデバイス名として表示され、プログラム通りにスマホに無線送信(Advertise)されていることが確認できます。



BL652のsmartBASIC開発は、 オンライン・コンパイラを利用するため、面倒なSDKの開発環境を構築する必要がありません。
一見お手軽ですが、オンラインコンパイラが閉鎖されると、BASICでは何も開発できないリスクは感じます。
ただ、最後は、Nordic社の開発環境を利用して、ソフト開発はできるので、購入したBL652がゴミになるリスクはないと思います。


2019/05/24追記

BL652を腕時計型デバイスに組み込めるか。
BL652は、以下のように小型です。
素手ではんだ付けができる限界サイズといえる小ささです。






腕時計型デバイスを作成するにあたり、
今回のようにBLEのAdvertiseによってデータを送信し、
XperiaZシリーズで受信するのであれば、
何ら問題ないとおもいます。
消費電力も小さくCR2032で賄える(2ma以下)で動作可能と記憶してます。

しかし、BL652でAdvertiseし、BL652でスキャン/受信すると
データの受信にタイムラグ(4秒程度)が生じます。
原因は調査中ですが、ややインパクトがあるので、
BL652間通信は、VSP(VirtualSerialProtocol)と称する
BLE上でUART通信する技術を用いることとなるかと思います。
この場合、マイコンのリソース/パワーの多くを無線通信にもっていかれるため、
心拍センサーとのI2C通信が安定的に行えるか、やや不安がございます。

BL652でI2Cは行ったことはございませんが、万一、安定しない場合、
I2Cの制御用にBL652を一つと、無線送信用にBL652をもう一つと、
2CPU体制にすることで解決は可能かと思います。








2018年8月16日木曜日

BL652 - BLEマイコン(ハードウェア編)

BL652というBluetooth Low Energy対応の小型マイコン・モジュールを入手しました(約900円@digikey)。


搭載されているマイコン自体はnRF52ですが、Laird社独自のsmartBASICでプログラムを書き込めるのがウリです。
nRF52は、Nordic社のSDKが不思議な出来栄えで、素人には使いこなすのが厳しかったですが、smartBASICを使えば、このようなSDK不要、開発環境構築不要、と謳ってます。

BL652への書き込みは、115200bpsでUART接続で行いました。
書き込みに使用したUSB-シリアル変換は、秋月のArduinoUno互換ボードAE-ATMEGAです。
これは、良くできていて、USB-シリアル変換のラインのジャンパを外すことにより、USBーシリアルの信号を外部に取り出して、外部のマイコン(ArduinoProMini、BL652等)にも接続・書き込みが可能です。








































BL652から引き出す最低限必要な配線は:
-GND, VDD (電源)
-UART RX, TX(データの有線送受信。それぞれUSB-シリアルのTX, RXへ接続)
-Reset(リセット。GNDに通電するとリセット動作)

半田づけするには基盤のピッチが狭く、45歳以上の方は老眼鏡必須レベルです。
フラックスを使えば、手で半田づけできるレベルでもあります。


はんだ付けを終え、テストプログラムを書いてみます。
BL652は、温度センサを内蔵しているので、温度を計測し、smartphoneで表示することとします。
BLEの通常のプロトコルでは、smartphoneからデバイスを検索=>接続(connect)=>温度データ読み取り、となります。
しかし、BLEは、ここの“接続”ができない、ないし勝手に切断され、不安定と感じます。

ANT+通信では、このような“接続”がなく、ANTセンサーはブロードキャストを行い、受信機はそれを拾って表示するだけです。当然、エラーで拾いもれも発生しますが、大勢に影響はありません。
この結果、接続がきれました、とかエラー表示され通信ができない自体は回避されてます。

そこで、BLEでも、このブロードキャスト方式で送信を行うこととしました。
Beaconとかいうプロトコルがこれに該当するようですが、制約が面倒なので、独自のプロトコルとします。

BLEの子機は、親機に対して、自分の名前とアドレスをAdvertise送信します。
これを受けて親機(smartphone等)からBLEスキャンをかけると周囲の子機が以下のように表示されます。
今回は、この子機の名前文字列に温度データを乗せてしまおう、という作戦です。
これなら、親機が子機に接続する必要もなく、子機がブロードキャストしてるデータを親機が拾うだけで、ANTと同じ安定動作が期待できます。

実際にやってみた図です。


名前欄に“Dgrade#1=369”と表示されてますが、ここの369の数値が温度データでリアルタイムに変化し、表示されます。(Dgrade#1は勝手につけたデバイス名です。とくに命名ルールはないようです)
36.9度の屋外で実験してるわけではないので、温度データがおかしいのですが、原因は後日究明するか、もっと精度の高い温度センサーを実装しようと思います。

この方式のメリットは、BLE子機と接続(コネクション)を張る必要がないので、複数のBLE子機のデータを1親機で拾ったり、逆に1つの子機のデータを複数の親機で拾うことが可能です。

BLE子機からパワー計のデータを送信し、smartphoneで受信・表示しながら、他の親機でも受信し、ANTプロトコルに変換してGARMINに送信、とかできてしまいます。

応答性もまあまあで、シフトレバーにスイッチを付け、スイッチオンで“Dgrade#1=SHIFTDOWN_ON”、スイッチオフで“Dgrade#1=SHIFTDOWN_OFF”を送信し、受信機でリアルタイムにスイッチのON/OFFを把握できます。
これを使えば、Di2のシフトスイッチを無線化できるうえ、SRAMのeTapのように、左右のレバー同時押しで、フロント変速とかも自由自在です。

NGな用途は、無線で部屋の照明全部消し等をするセキュリティに影響のある分野です。
子機のスイッチの状態を複数の親機に無線伝達できるため、照明ON/OFFや鍵のLock/unlockとか技術的には可能ですが、セキュリティ的に相当マズイと思います。

ソフトのコンパイル・書き込みは方法は、ソフトウエア編で紹介いたしました。




2018年7月24日火曜日

Bluetoothモジュール比較

秋月にてBLE(BluetoothLowEnergy)の通信モジュールAE-TYBLE16を発見しました。

http://akizukidenshi.com/catalog/g/gK-12339/

これは有線のUARTインターフェースに接続すると、UARTのデータを勝手にBLE規格で無線送信してくれる優れモノです。

使い手は、難しいBLEのお作法を勉強することなく、既存のUARTインターフェスにこのモジュールを接続するだけでBLE上でデータを送受信できます。

パワー計を自作する場合、クランクとハンドルバーの表示器の送受信にこの無線機を使うと便利そうです。
(図は、シマノの特許出願図面です。)















実際、使ってみました。




上の動画のGarmin表示は、PowerTapハブのデータ、スマートフォン表示は試作した3000円パワー計のデータです。
AE-TYBLE16を使用して、クランク上のマイコンで算出したパワー&ケイデンス値をスマートフォンにBLE送信してます。

モジュールの製造元の太陽誘電が本モジュール対応のAndroidアプリのソースコードを配布しているので、ユーザはこれを改造して動画内のタコメータアプリとかも簡単に作れます。

従来は、Bluetoothクラッシックのモジュールを使用してましたが、消費電流が20mAを超えるため、単四電池では10時間持たない感じでした。



手持ちのBluetoothモジュールの3.3v駆動時の消費電流を計測しました。
HC-05(20mA), SPP-CA(9mA), AE-TYBLE16(1.8mA), HM-10(8mA)

AE-TYBLE16単体であれば、ボタン電池で駆動できるレベルです。

これをマイコンに接続する際は、
Rx ー>Tx
Tx ー>Rx
Vcc  ー>Vcc
GNDー>GND
のように接続するだけです。


同様のモジュールに、Nordic社のNordicUartServiceを搭載したモジュールを過去に使用しましたが、BLEが原因なのか不安定でした。

AE-TYBLE16をジャンクで入手したXperia Z3、Z4、AQUOS PHONE ZETA、およびAQUOS SERIE SHV32でテストしたところ、(検証が必要ですが)Androidのバージョンが重要なようでVer.5未満では接続が不安定になることがありました。





2017年9月3日日曜日

スマホ、サイコン化計画

サイクルコンピュータには、GARMINを利用してきましたが、どうも文字が小さく「老眼の人は使わないで結構です」といわんばかりです。

そこで、Smartphoneをサイクルコンピュータ化してみました。
技術的には、ANT心拍/パワー/速度等の各センサーの情報をスマートフォンにWiFiで転送するデバイスを製作してみました、というものです。

現状品
















スマートフォンのブラウザで各センサーのデータを表示します。
スマホなので、画面の拡大、縮小やスクロールが楽です。
ピンチ操作で拡大してみました。




サイクルコンピュータは、ボタンを押しにくいものが多く、よく不便に感じてましたが、だいぶ改善できたと思います。

また、夏は、信号ストップでサイコンを見て「今、気温43度!熱すぎるー」と空騒ぎするのが自転車の楽しみですが、GARMINは温度表示がかなりいい加減です。

感覚的に誤差が±4度くらいあり、誤差範囲がANTチップ内蔵の温度センサーと重なることから、ANT受信チップ内蔵の温度計をそのまま使ってると推測します。

もう少し温度の精度がほしいです。
丁度、BME280というチップが、温度、湿度、気圧を計測でき、温度誤差は±1度なので、これを採用しました。

今回のハードウェア構成です。
-D52(Dynastream製ANTモジュール)- これでANTセンサーの無線情報を受信します。
-BME280              - これで温度、湿度、気圧を計測します

-Arduino Pro Mini          - 上記2つのモジュールからデータを受信し、文字列として、ESP-WROOMに転送します。

-ESP-WROOM            - WEBサーバとして機能し、各センサーの情報が反映されたWEBサイトをブラウザに送信します。

クライアントは、スマートフォンに限らず、WEBサイトを表示できるデバイスならば、PCでもタブレットでも、腕時計でもOKです。
専用のAppを入れる必要もなく、WiFiのアクセスポイントをESP-WROOMに変更し、ブラウザで、192.168.10.1にアクセスすれば、ブラウザで画面表示され、1秒置きにページが更新される仕組みです。

配線図




ソフトウェアは、Arduino ProMiniはもちろん、ESP-WROOMもArduinoとしてプログラムを書き込んでいます(ESP-WROOMをArduino IDEで書き込む方法はGoogle検索でたくさんでてきます)。

BME280へのアクセスは、GIT HUBのSWITCH SCIENSE製のソースコードをそのまま利用させていただきました。

つづく




2017年7月23日日曜日

nRF52モジュール比較

nRF52モジュールを複数種入手しました。
ANTに対応できないものがあることが判明しています。



左から
ーRigado製
ーsparkfun製
ーebay large version
ーebay mini version
ーDynastream製

すべてプログラムの書き込み方法は一緒です。
VCC, GND, SWDCLK, SWDIOの4線をST-LinkかnRF52-DKにつなげば書き込めます。




ただし、RigadoとDynastreamのモジュールは、あらかじめfirmwareが書き込まれ、かつプログラムが読みだせないようプロテクトがかけられています。
これを、nRFgo Studioかコマンドラインで、erase allやRecoverしたり、mbedフォルダにfirmwareを上書きすることで、消去する必要があります。

ST-Linkでは、この消去を行う機能がないため、RigadoやDynastreamのモジュールを使う際は、誰かにプロテクトを解除してもらう必要があります。

ST-Linkをj-linkに変身させるファームもリリースされていますが、なぜかST Microのチップをターゲットとしてのみ使用可で、他のチップに使うことは禁止する、絶対禁止すると表示されます。
実際は、技術的にはnRF52をターゲットとして使用可能にもかかわらず「使用するなよ、絶対するなよ」と言われるとダチョウ倶楽部を思いだいし「絶対するな=すぐにやってよい」と解釈してしまいがちですが、やはりまずいと思います。

nRF52モジュールにnRF52-DKから書き込みを行う場合、以下のように配線します。

ポイントは、ピンヘッダのVTGにVDDをGND DctにGNDを接続することです。
これにより、書き込みチップが、外付けのnRF52モジュールに書き込みを行うよう設定変更され、オンボードのチップに書き込まれなくなります。

私は、ボードの真ん中にDIPスイッチを付け、書き込み先を外付けnRF52モジュールとするか、オンボードのチップとするか、選択できるようにしています。




nRF52モジュールがnRFgo Studioに認識されると、以下のように表示されます。

この例では、Region1にSoftdeviceが書き込まれていることがわかります。
Addressが0x1f000までがSoftdeviceなので、s132(BLE用)のSoftdeviceが書き込まれてるとわかります。
Softdeviceを書き換えるには、右欄のProgram Softdeviceのタブから任意のSoftdeviceファイル(ANTの場合はS212)を選択し、ProgramボタンをせばOKです。
S212のSoftdeviceはwww.thisisant.comからダウンロードできます。



つづいて、Softdevice上で動くアプリケーションをプログラムします。
Program Applicationタブから書き込みアプリの.hexファイルを選択し、Programボタンを押せばOKです。

話を戻しますと、RigadoとSparkfunのnRF52モジュールは、ANT対応ではありません。

どうやら32khzの発振子の精度が悪いようで、BLEはなんとかOKですが、シビアなANTには対応できてませんでした。

Sparkfunのものは、32khzの発振子のパターンをカットできます。
パターンカットのうえ、秋月で買った水晶発振子に付け替えたところANTもOKとなりました。





2017年5月4日木曜日

ANT+対応サイコンの自作(ソフトウェア編)

昔、ANT+対応のサイクル・コンピュータを自作してました。

パワー、心拍、速度とケイデンスをANTセンサーから受信して表示できました。

本人的に一番の売りは、速度とケイデンスから、何枚目のギアを使ってるか算出して表示できたことでした。
10年くらい前のカンパのサイコンも同様なギア表示をしていたことがヒントでした。

こんな感じで1.8インチTFTにカラー&グラフィカル表示。

しかしこのTFT液晶は太陽光の下では視認性が悪く、
「がんばれ、もっと明るくなーれ、明るくなーれ」
と駆動電圧を上げていったところ、壊れました(汗)。
結果、上の写真のように薄暗くしか映りません。

その後、Stravaにはまってしまい、Garmin以外使わなくなっていました。

最近、お手軽パワーメータには、お手軽サイコンが欲しいな、
という妄想が湧いてきました。

以下は、キャットアイの不朽の名作(と私が勝手に思ってる)RD200。

このサイコンは有線式で、ケイデンス用の線を100回/分のペースでOn・Offすると画面に100と表示され、同様に200回/分ペースなら200と表示される。

ANTの信号を受信して、その数値に合わせて速度/ケイデンス用の線をOn/Offすれば、パワーに限らず、様々な数値を表示できる。
メリットはボタン電池で数年動作すること。
Garminは頻繁に充電が必要で、普段乗りには面倒です。

とりあえず、昔作った、Arduino Uno+nRF24(BC-ANT-Serial)用のANT対応サイコン・ソースコードを動作させてみました。
ArduinoUnoは通常5v動作ですが3.3v動作に改造しており、nRF24と接続するのにレベル・シフタは不要です。

配線は、
Arduinoの2番ピンを入力PINとして、nRF24のTXピンに接続、
Arduinoの3番ピンを出力PINとして、nRF24のRXピンに接続
nRF24の裏面のBR2をショートして、通信速度を9600bpsに設定。




PCのシリアルモニタで見ると、以下のように正常に各ANTセンサーからの情報を受信し、PCへシリアル送信しています。


「パワーが700wで心拍が70は正常でないだろ」
と思われてしまいそうですが、これはANTシミュレータ
を使っています。

このシミュレータを使うと、パワーメータ等のセンサーの出力をシミュレートして電波を送信したり、市販のANT対応センサーの電波を受信して、ログをとったりできます。
(ZWIFTで使うようなUSBのANTドングルが必要です。)

こちらのANTのサイトでフリーで入手しましたが、最新版は、あれこれ変更されてるかもしれません。
ttps://www.thisisant.com/

今回のArduino+nRF24用のANT受信サンプルのソースコードを以下のサイトに置きました(本日の日付をファイル名としています)。
(実際にアクセスする場合、末尾の000を削除して1138で終わるようURLを修正する必要があります。ロボット除けのためで、お手数をお掛けします)
ttps://sites.google.com/site/myfiles1138000

あと、このサンプルのソースコードを動作させるには、
#define NETWORKKEY {0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55}
となっている箇所を正しいNETWORKKEYに置き換える必要があります。

www.thisisant.comからANTの仕様とNETWORKKEYを入手する際、NETWORKKEYを公開しないことを約束している(させられている)ためです。
無視して、公開してる方もいるようですが・・・












2017年2月14日火曜日

AD7124-4

「チューブラーがパンクしちゃったつもり貯金」で製作するパワーメーター「TP-002」に採用したADコンバーターltc2472の読み取り値が安定しない。
とある週のゼロオフセット値(負荷ゼロでクランクを地面に垂直に向けたときの値)
火曜日:745
水曜日:746
木曜日:743
金曜日:750
土曜日:728

ADコンバーターが週末で心躍ったのか、値が大きくずれる。
これでは、週末に必ずゼロオフセット値を校正しなければならない。
原因はあれこれ考えられるが、思い切ってADコンバーターを24bitのAD7124-4に変えてみた。




早速クランクに付けたひずみゲージの値を取得。


有効ビット数は約20bitか。これは期待できる。

TP-002を仮組して、パワータップハブと比較してみた。


TP-002とパワータップハブのそれぞれについて、3回計測平均値をグラフ化。
縦軸がワット数。
上下の振れが大きい方がパワータップハブ。
24bitADコンバーターは16bitよりも安定した数値を得られ、
「今のは明らかに数値がおかしいだろ」というのがない。

グラフの後半、TP-002の値がパワータップハブより低めに出ている。
これは、ひずみゲージに電流を流しすぎた結果と推測。
ひずみゲージは電流制御をしないと、最初の数十分は数値が少しずつ、ずれてしまう。
今回も、電流制御なしの簡易セットアップだったので、その点が正確にデータに現れていると思う。

「最初の20分は安定しないパワーメーター」が某メーカーから市販されていたこともあった。


実験を繰り返すも、AD7124-4でもゼロオフセット値が日によってずれると判明。
ひずみゲージが壊れてるのか?

(2017年3月21日更新)
ひずみゲージではなく、ひずみゲージのブリッジ回路が損傷しており、ゼロオフセット値がずれる現象がでていました。