電池が持たない最大の要因は、一回あたりのWakeUp時間が52msと長いせいだと考えられます。その大半が、IO状態の読み取りと送信待ちである事もわかりました。IO状態の読み取りは、電池残量を知る必要があるのでなくす訳には行かないのですが、頻度はある程度減らしてもいいはずです。
IO状態の読み取りを60秒毎に1回のペースまで落とし、2秒に1回のWakeUp時間を減らしたところ、計測できる下限の4msになりました。これは、起きた直後にスリープするような感じです。しかし、ここまで短くしてしまうと、親機からのパケットを取りこぼしてばかりで、肝心のビーコンとしての動作が開始できなくなりました。
タイミングのイメージとしては、 この図のようになります。青が子機のWakeUp時間、ピンクが親機のパケット送信時間を表しています。
WakeUp部分を切り出しすと、下の図になります。1/32秒間隔で再送1回を伴う送信を行う場合、4msのWakeUp時間では親機のパケットの隙間に埋もれてしまい、すれ違いがちになります。
WakeUp時間があまりに短いと、受信処理に支障が出ることが分かったので、スリープ前にウェイト入れてWakeUp時間を20msに延長してみました。
かなりマシになりましたが、まだ時々取りこぼします。タイミングによっては、WakeUpが親機のパケットの隙間を縫ってしまうようです。
ウエイトを長くしてWakeUp時間をたっぷり確保すれば確実に受信できますが、それでは電池持ちが改善されません。
電池持ちのために受信間隔を長くするとWakeUpを長くしても電池は持ちますが、応答が悪くなってしまいます。 また、たまに取りこぼしたときのペナルティが大きくなってしまう問題もあります。
この問題を解決するために、子機のWakeUp時間を20msにしたまま、親機のパケット送信ペースを毎秒64回に倍増することにしました。
今度は、子機のWakeUp時間の間に、親機のパケットを確実に受信できるようになりました。
パケット密度が高すぎて輻輳がちょっと心配になりますが、親機の電源は一日に2-3秒しかONにしませんので、この方法で行く事にします。
0 件のコメント:
コメントを投稿