2014年9月14日日曜日

メロディーと光で置き場所を知らせる自転車ビーコン製作中

回路とソフトの試作ができました。
昨日は、使用するチャンネルを変えると、親子のチャンネルが揃っていても応答しないという落とし穴で一日無駄にしましたが、今日は快調です。自機または対抗機(親機)の電池残量が少なくなったときに、LEDの点滅周期を速くして警告する機能も付けました。



TWE--Lite子機間欠モードで受信が行えるチャンネル

 TWE-Liteのチャンネルをデフォルトの18から16に変えたら、子機間欠モードの受信動作が機能しなくなった。すべてのチャンネルを調べたわけではないが、どうも、使用するチャンネルによって、間欠モードの受信動作が動いたり動かなかったりするらしい。これに気がつくまで、ほぼ1日かかった。今のところ、16,18,19と3種類試してみて、成功したのは18だけ。

TWE-Liteの子機間欠モードで受信動作した場合の消費電流

 子機間欠モードの受信動作は、sToCoNet_AppContext.bRxOnIdle を有効にするまで成功しなかった。このフラグの説明には、
  • 無線回路アイドル時も受信回路を動作させます。
  • 受信時は常に受信電流を消費します。
と書かれている。これだけ読むと、スリープさせても受信回路が起きていて電流を消費しまくるように受け取れる。受信動作中のTWE-Liteの消費電流は約17mAなので、こんなんでは間欠モードの受信動作は使えないと思えるが、やってみたら、実はそうではなかった。
 テスターで図ったところ、bRxOnIdleをTRUEに変えても、スリープ中に大きな電流を消費することは無かった。ブレッドボード上に回路を組んだ状態での実測値は1.9μAと、とても小さかった。どうやら、bRxOnIdleを有効にしても常時動作をするわけではなく、結局、スリープが解除されている間しか受信は行わないようだ。これは、スリープ中に親機からパケットを送っても反応しない事実とも矛盾しない。

2014年9月10日水曜日

子機間欠モードで待ち受ける自転車ビーコン

 TOCOS TWE-Liteで動作する、自転車ビーコンアプリケーションのソースコードをgithubに置きました。親機/子機のどちらでも機能します。
    https://github.com/true-nature/App_BicycleFinder

 アピールポイントは、ズバリ「子機間欠モードでの受信動作」です。検索しても実装例が見つけられなかったので、TWE-Liteの応用例としては珍しいのでないかと思います。
 心配される電池持ちは、自転車に取り付ける実物ができてから計測します。

2014年9月9日火曜日

TWE-Liteで子機を間欠モードにした場合の親機側の設定

 子機間欠モードで受信をする場合は、親機側の動作も変更しないと実用にならない。連続動作モードで連続なのは受信の方で、送信動作はスイッチやタイマーなどのイベントを契機に発信する間欠的動作だからだ。スイッチを押すなどの操作した場合、または、約1秒周期でIO状態が送信されるが、これでは、子機の間欠受信に滅多にミートしないので、送信間隔を短くする必要がある。
 現行のApp_Tweiteであれば、オプションビットの設定で毎秒32回の連続送信が設定できる。ところが、何故かApp_Melodyにはオプションビットの機能が無い。しょうがないので、親機にApp_Tweliteを、子機には改造したApp_Melodyを書き込んで、親機のApplication IDを子機と揃えることで対応した。

TWE-Liteで子機間欠受信を有効にする方法

最初は無理かと思ったけど、だんだんわかってきた気がする。
「超簡単!TWE標準アプリ」を子機間欠モードで受信に対応させるには、若干のソース変更が必要。

無線回路アイドル時に受信回路を有効化する


 cbAppColdStart()で子機間欠モードの場合に
sToCoNet_AppContext.bRxOnIdle = FALSE;
としている部分を、
sToCoNet_AppContext.bRxOnIdle = TRUE;
に変える。

 SDKマニュアル中のbRxOnIdle の説明には「受信時は常に受信電流を消費します。」という恐ろしいことが書いてあるが、テスターで測った感じだと、間欠動作の場合はbRxOnIdle =TRUE にしてもスリープ時に17mAも電流を消費するようなことは無い。デジタルテスターの20mAレンジでは、スリープ時の電流消費は0mAとしか表示されず、連続動作に比べたら誤差の範囲。スリープ解除のタイミングだけ、連続動作並みに消費電流が増える。

受信イベントのコールバック関数で受信処理をスキップさせない

cbToCoNet_vRxEvent()に、子機間欠モードの受信処理を抑制するif文が存在する。これをコメントアウトする。
例えば、1秒間欠モードの受信を有効にするなら、 こんな感じ。
--- a/Master/Source/Master.c
+++ b/Master/Source/Master.c
@@ -989,7 +989,9 @@ void cbToCoNet_vRxEvent(tsRxDataApp *psRx) {
             psRx->u32SrcAddr, psRx->u32DstAddr);

     if (IS_APPCONF_ROLE_SILENT_MODE()
+#ifndef USE_RX_ON_SLP_1SEC
             || sAppData.u8Mode == E_IO_MODE_CHILD_SLP_1SEC
+#endif
             || sAppData.u8Mode == E_IO_MODE_CHILD_SLP_10SEC) {
         // SILENT, 1秒スリープ, 10秒スリープでは受信処理はしない。
         return;

 手元の改造ソースでは、vProcessEvCoreSlp()を変更して、状態遷移を数TICK遅らせてスリープまでの時間稼ぎをしているけど、これが必須か否かは未確認。まあ、受信したからには何か処理をするだろうから、必須でなくともイベント追加したりすると思う。

2014年9月8日月曜日

TWE-Liteの子機間欠モードでは受信できない?

駅前駐輪場で、自転車の置き場所をよく忘れる。
忘れても大丈夫なように、携帯のToDoメモに置き場所をメモるようにしているのだが、急いでいるとメモるのを忘れてしまう。先週も、メモを忘れた上に置き場所を憶えてなくて、5分くらい駐輪場をさまよった。

で、ふと思った。
これってもしかして、TWE-Lite使ったら、解決するんじゃね?

早速、家にあったTWE-Liteで試作を開始したのだが、どうもだめっぽい。
自転車に装着する予定の子機は、大半の時間は用無しなので、電池節約のため間欠モードでなくてはならない。さもないと、数日で電池がなくなってしまう。
 東京コスモス電機の説明では、
間欠1秒モードは休止状態(スリープモード)になり、1秒毎に送受信を行うモードです。休止状態では送受信は行わず内蔵タイマーだけを動作させ節電を行います。
休止中は親機からの信号を受けることができません。
 と書いてあって、休止が解除されたタイミングでは受信できそうに書いてある。ところが、超簡単!TWE標準アプリで子機を間欠1秒モードにしてみると、親機の操作にまったく反応しない。
 ソースを見てみると、間欠モードでは受信処理を抑止している事がわかった。受信処理のコールバック関数 cbToCoNet_vRxEvent() では、間欠モードでは素通りで戻るようになっている。
void cbToCoNet_vRxEvent(tsRxDataApp *psRx) {
    //uint8 *p = pRx->auData;

    DBGOUT(3, "Rx packet (cm:%02x, fr:%08x, to:%08x)"LB, psRx->u8Cmd,
            psRx->u32SrcAddr, psRx->u32DstAddr);

    if (IS_APPCONF_ROLE_SILENT_MODE()
            || sAppData.u8Mode == E_IO_MODE_CHILD_SLP_1SEC
            || sAppData.u8Mode == E_IO_MODE_CHILD_SLP_10SEC) {
        // SILENT, 1秒スリープ, 10秒スリープでは受信処理はしない。
        return;
    }
 試しに、間欠1秒モードでも受信処理へ進むようにif分の条件を変えてみたが、結果は変わらず。そもそも、このコールバックさえ呼ばれていなかった。道は険しそうだ。
とりあえず、TWE-Lite標準アプリの子機間欠モードは送信専用で、受信処理ができないらしい。

可能か否かはまだ不明だが、目標としているのは、こんなアプリ。
  • 音と光で知らせる自転車発見器にする予定なので、ベースにはApp_Melodyを使う。
  • 子機は間欠モード。数秒おきに動作する。
  • タイマーで起動したら、数msの間だけ受信動作する。
  • 親機の信号を受信したらメロディーを鳴らしてLEDを光らせる。
  • メロディーが鳴っている間はスリープしない。
  • 親機は連続動作。ただし、必要な時だけ電源を入れる。