こんにちは、macnicaでAnalog Devices社(以下ADI社)製品のエンジニア(FAE)をしているHirokiです。
今回は、コイン電池1つで動作する衝撃検知デモの、構想から完成までの過程を紹介します。
通常業務の合間を縫って、約5ヶ月。途中、動作確認がうまくできず泣いた夜もありましたが、完成したデモは多くの方に興味を持ってもらいました。
衝撃検知デモのイメージはこちらもご参照ください。
[加速度センサADXL372] 輸送中の衝撃・振動を検出する
長文ですが、IoT技術には欠かせないキーワードも出くるので、ぜひ最後までお付き合いください!
- 衝撃検知デモの検討
- 衝撃検知デモの構築を開始
- [フェーズ1] まずはADXL362を使って検証
- [フェーズ2] 本番用センサADXL372を使って検証
- ADXL372の内蔵FIFOの有効活用
- [フェーズ3] 本番デモ機で動作確認とさらなる改善
- [フェーズ4] 時間との勝負!完成へ向けた最終調整
- 衝撃検知デモの全貌
- アナログ技術セミナー 当日は大盛況
衝撃検知デモの検討
衝撃検知デモを構築したきっかけは、毎年9月頃に開催されているADI社主催の "アナログ技術セミナー" に出展するためでした。
2017年のテーマは、巷で話題の "IoT"。
このIoTを支える "センシング技術" を紹介する!ということで、検討を開始しました。
通常のサポート業務と並行して、ADI社の公認サードベンダの金子システム社のADuCM3029のボードとADXL362の評価ボード(EVAL-ADXL362Z)使って、ADuCM3029とADXL362の動作検証をしていました。このとき、テストボード(図1)を作成して、"遊んで" いました。結果的に、これが初期試作ボードになりました。
初期試作ボードをベースに、「ADXL372 を使って、衝撃検知デモを構築しよう」とチーム内でまとまったのが、2017年5月のことでした。しかし、ADuCM3029の基本的な動作確認(LED点滅や外部割り込み、UART通信など)が終わったものの、通常業務が多忙となり、手が付けられない日々が続きました。
衝撃検知デモの構築を開始
2017年のアナログ技術セミナーは、9月28日から開催されます。これに合わせデモの準備に取り掛かりました。
デモの構築にアサインされたのが、先輩社員Sさんと私です。
H/W開発および、デモ時のGUI開発 ⇒ Sさん
ADuCM3029のアプリ開発 ⇒ 私
この時点で決定している内容は以下の通りです。それ以外は都度相談しながら、ということでスタート!
デモの構成
※構成は図1と大きく変わりません。ただし、これを47x72mmのユニバーサル基板で実現
- 電源:コイン電池1つ(CR2032)
- ADXL372 動作モード
※この2つをS/Wで切り替えて使えるようにする
- データ出力:USBブリッジ経由のCOMポート
- 使用開発ツール:ADI社 CCES 2.6.0 と エミュレータ ICE-1000
ここからは、それぞれの開発フェーズでの状況を紹介します。
[フェーズ1] まずはADXL362を使って検証
フェーズ1で使用したボードは、図1の初期試作ボードです。
ADuCM3029の開発環境は、ADI社のDSP/Processor製品の標準の開発環境となるCCESを使用しました。
なお、CCESを用いる場合、必ずVersion 2.6.0以降(最新2.7.0:2018年1月現在)を使用してください。
CCESは、Eclipseベースの統合開発環境でコンパイラ関連はGCCを使用しています。もちろんCCESではなく、IAR、Keilもサポートしているので、使い慣れた環境で利用できます。
また、CCESには、Keil環境でお馴染みの "CMSIS Pack Manager" が、インストールされているので、これを使用して、BSP(ドライバ、サンプルコード類)の管理などを行います。
フェーズ1の目標
フェーズ1では、以下の内容を目標に開発を進めました。
- DIPスイッチの状態を判断し、LEDを点滅させるルーティンとADXL362を動作するルーティンを切り分けて動作させる。
- ADXL362の設定は、閾値(4g)を越えたら、ADXL362内蔵のFIFOにサンプリングデータを格納し、INT1の割り込みを生成する。
- ADuCM3029は、初期設定(GPIO、SPI、UART、割り込み、ADXL362)を行った後、Waitさせる。
- ADXL362からの割り込みがあった場合、SPI経由でFIFO Readを行う。
- ボタンスイッチを割り込み要因とし、この割り込みが発生したら、UART経由でPCにデータ出力させる。
ADuCM3029のアプリを開発
早速、アプリ開発に着手しました。
ADuCM3029の評価ボード(UCM3029EZLITE)には、ADXL363が搭載されています。CMSIS Pack Managerを確認したところ、ADXL363向けのドライバおよび、サンプルコードが準備されていることを発見。これをベースに開発をすることにしました。
ADuCM3029の詳細はこちら
超低消費電力が最大の魅力 Arm® Cortex® -M3マイコン ADuCM3029
まず、ADXL362 と 363 の違いをチェックしたところ、レジスタの配置が全然違うことが判明。データシートをもとに、ADXL362 用のレジスタマップを地道に作成。今後、ADXL372へ変更することも考慮して、ADXL363用ドライバのソースコードをベースに各命令をADXL362用に移植しました。
コーディング/Build作業は、特に問題も発生せず、動作チェックへ進みました。
割り込みが動かない・・・
DIPスイッチでのアプリの切り替えはうまくいき、Lチカも問題なく動作。
さて、いよいよADXL362の動作チェックです。
ん?動かない・・・。
すんなり行かないとは思っていましたが・・・
Step実行および、Console Windowにデバック情報を表示させながら進めると、SPI 経由のADXL362へのR/Wは問題なく、レジスタの設定も正しいことは確認できました。オシロを使いADXL362からの割り込み信号も出ていることを確認。
さらに調査を進めると、割り込み処理内で問題が起こっていることが判明。
ドライバから移植したコード内でエラーが発生していました。このドライバかなり階層が深く、コードを追っかけて行くのが大変。。。
何かの設定が足りないのは分かるのですが、どこから影響されているのか分からず、時間だけが過ぎていきます。(汗)さらに他の業務も立て込んで、この時すでに7月・・・。
そんな時、Sさんが衝撃を与えやすいようにADXL372評価ボードを細工してくれました。
これを機会にADXL362ベースでの動作確認を一旦あきらめて、ADXL372ベースへ進むことにしました。
敗北ではありません。今まで未確認だったSPIでのアクセスは確認できました。悔しい。(涙)
しかし、この判断が吉と出ました。
[フェーズ2] 本番用センサADXL372を使って検証
さて、いよいよADXL372を使った開発へフェーズを移しました。
ADXL372の詳細はこちら
コイン電池で動作する加速度センサ「ADXL372」とは?
フェーズ2で使用したボードは、初期試作ボードに、Sさんが加工してくれたADXL372の評価ボードを接続したものです。ADXL372は、大きなg(Max:200g) も検出でき、さらにSさんの加工で、今までよりも衝撃が与えやすくなりました。
フェーズ2の目標
フェーズ2での目標はこちらの3点です。
- ADXL372の動作確認(2つのモードの動作確認:DIPスイッチで切り替え)
- インスタント・オン・モード
- ピーク検出モード
- ADuCM3029は、各初期化後、Hibernateモードに遷移。ボタンスイッチをトリガにActiveモードへ復帰
- 復帰後、ADXL372のFIFO Readを行い、UART(COMポート)経由でデータ出力。再度、Hibernateモードへ遷移
ドライバを活用してアプリ開発
フェーズ2では、デモで実現する基本動作の確認を行います。フェーズ1の割り込み処理で問題を起こしていたので、最初に悩んだのが、「アプリの構築をどうするか?」 でした。
フェーズ1で使用したADXL363用ドライバベースのアプリを継承するか?スクラッチで作り変えるか?
残された時間も考慮する必要性もあります。
結果的には、フェーズ1で使用したADXL363用ドライバベースではなく、各ペリフェラル向けに準備されているドライバを活用することにしました。
今回使用したのは、SPI / UART / Interrupt / Power / DMA / GPIOの各ドライバです。
フェーズ1で使用したADXL362とADXL372のレジスタマップを比べたところ、かなり似ていました。もちろん拡張されている箇所もあり、変更は必要でしたが、この作業は比較的楽にすんなりと終了。(フェーズ1の作業が役に立ちました!)
コーディング自体は、各ドライバを使用したサンプルコードを参照して、各ドライバのドキュメントを片手に作業を進めました。これも特に問題は発生しませんでした。
いよいよ実機検証です。
今回は、あっさり割り込みが動いた
まずは、フェーズ1で失敗(涙)した、割り込み動作からチェック。
フェーズ1ではADXL362からの割り込み信号を使いましたが、今回はボタンスイッチにて割り込み信号を生成するように変更。理由はUARTのデータ出力を、任意のタイミングにするためです。
割り込みルーティンの先頭にブレークポイントを設定し、恐る恐るボタンスイッチを押したところ、あっさり動作確認が出来ました。
あれ?フェーズ1の失敗は一体なんだったのか?
はじめからこの方法でやれば・・・。
いいえ、失敗から多くのものを学べばよし!と自分に言い聞かせ、先に進みます。
ADXL372の動作確認 – インスタント・オン・モード
いよいよADXL372の動作チェックへ。
まずはインスタント・オン・モードから動作確認を始めました。ADXL372の設定は、以下の通りです。
- FIFOの設定(ADXL372の内蔵FIFOの有効活用 参照)
- X、Y、Z軸の加速度データを保存
- FIFO数:120段(3軸x 40Set分)
- モード:オールデスト・セーブ・モード
- パワー制御の設定
- 閾値レベル:Low(10g ~ 15g)
- フィルタ・セトリング時間:370ms
- インスタント・オン・モード
- 測定制御の設定
- Auto Sleep モード/ ループ・モード(データシート 参照)
- 4極ローパスフィルタの帯域幅:200Hz
- ODR : 400Hz
インスタント・オン・モードのテスト結果
今回のデモでは、通信用にSilicon Labs社のCP2102N(UART-USB ブリッジIC)を搭載していますので、COMポート(Tera Termを使用)に結果を出力させます。出力させた結果はこちらです。
出力結果を見る限り、動いていることが分かります。
ADXL372のスケール・ファクタは、100mg/LSBなので、Z軸に-108gの加速度が計測されたことが分かります。このデータは、ADXL372のボードを1回強く弾いてみた結果です。衝撃を検知した後、徐々に終息していくことも分かるかと思います。
さらに、ベクトル演算をしてみました。結果(図4)を見る限り、データが "荒い" ので、FIFO数を増やす、ODRを高速へ、などの調整が必要だと考えました。
ADXL372の動作確認 – ピーク検知モード
さらに、ピーク検知も以下のように設定して動作確認しました。
- FIFOの設定:インスタント・オン・モードと同一
- 各閾値の設定
- ACT閾値(X、Y、Z):4G
- ACT時間:6.6ms(Min値)
- INACT閾値(X、Y、Z):2G
- INACT時間:130ms(26ms x 5)
- パワー制御の設定
- フィルタ・セトリング時間:370ms
- フル・計測・モード
ピーク検知モードのテスト結果
テストでは、ADXL372のモジュールを4回弾いた後に、一旦データを出力。その後2回弾いた後に、再度データを出力してみました。結果は、以下のように出力されました。
Peak Maxには、FIFO内の最大値が格納されています。
それぞれベクトル演算してみました。
インスタント・オン・モード、ピーク検知・モードの基本的な動作確認はできました。
フェーズ2では大きな問題もなく、すんなりと進みました。少し先が見えてきたようで、ホッとしましたが、これから調整が必要となってきます。フェーズ3へ進みます!
ADXL372の内蔵FIFOの有効活用
ここでは、ADXL372に内蔵されているFIFOについて紹介します。
FIFOを有効に使うことで、ADXL372を自律的に動作させることができます。これにより、マイコンの関与を最小限に抑え、システムレベルでの低消費電力化への貢献を高める効果があります。
柔軟な設定が可能!512段のFIFO
FIFOは512段準備されていて、以下のように任意に割り当てることができます。
- 3軸データの最大170サンプルセット
- 2軸データ(ユーザ選択可能)の最大256サンプルセット
- 1軸データの最大512サンプルセット
- 衝突イベント・ピークの最大170セット(X、Y、Z)
さらにデータを保存するモードとして、以下のモードが準備されています。
オールデスト・セーブ・モード
FIFOがフルになるまでデータを蓄積し、データを読み出すまで保持(今回のデモで使用したモードです。)
ストリーム・モード
FIFOには常に新しいデータを格納、新しいデータが来ると最も古いデータを削除
トリガ・モード
FIFOはアクティブな検出イベントが発生するまでストリーム・モードと同様に動作し、イベント検出後はイベント前後のサンプルを保存
このようにユーザアプリケーションに合わせて柔軟に使用することが可能です。
ADXL372内蔵FIFOを使用するときの注意点
ここで1点、FIFOの使い方で注意があります。
フェーズ2のインスタント・オン・モードの設定にて、FIFOの設定数を "40Set" としました。しかし、図6では、FIFOエントリー数として "39" となっていて、実際に出力しているデータも "39" となっています。これは、意図して行っています。データシートには、FIFOのReadの際の注意点として以下の記述があり、これに従って処理したからです。
「FIFOから複数軸のデータを読み出すときは、データが上書きされたり誤った順番で保存されたりしないように、それぞれの読出し後に、少なくとも1つのサンプルセットをFIFO上に残しておく必要があります(したがって、3 軸データ・セットのサンプル数は最大でも169 としなければなりません)」
[フェーズ3] 本番デモ機で動作確認とさらなる改善
いよいよ、デモ機での検証作業です。
このとき、すでに8月。一緒に作業を進めているSさんは、非常に忙しいなか、こちらから指定したピン配を基に、デモ機を組み立ててくれました。
残り1ヶ月、デモ機を組み立て
図6にはボタンスイッチが付いています。しかし、図7の最終的なブロック図にはありません。
実は当初、このボタンスイッチを1つの割り込み要因として使っていたのですが、途中で変更し、完成したデモ機にはどこにも配線されていません。これは、後程、少し触れてみたいと思います。
また、DIPスイッチを付けました。理由は2つあります。
- PORの際、ADXL372の初期の動作モードを決定するため
- ADuCM3029のBootモードを決定するため
Bootモードには、UART downloadモードと、Flash bootモードの2つのモードが準備されています。
デバックの際、Flashに予期しない動作を行うアプリを書き込んでも、UART Bootが出来る環境であれば、外部から専用のツールでFlashのErase/Writeが可能になります。Bootモードを切り替える仕組みは、準備しておいた方が良いと思います。
フェーズ3では、電池駆動ではなく、Silicon Labs社のUSB ブリッジIC CP2102Nの機能を使い、USB Busパワーを使い動作させました。CP2102Nは、レギュレータを内蔵しているので、Busパワー(5V)から3.3Vを生成し、外部供給ができるので活用しました。
押しても触ってもチャタリングが発生!
フェーズ2で作成したコードを基に動作確認を始めました。基本的な動作確認は出来ていたので、サクサク進みます。ただ、気になる点が出てきました。ボタンスイッチです。
このボタンスイッチには、UART出力のタイミングを決める重要な役割があります。これによって、ADuCM3029がWake Upし、UART出力を開始します。
確認するとボタンを押す際に、"チャタリング" が頻繁に発生していました。とりあえず、ソフト的に回避しようとTimerなどを使いチャタ防止策を取りましたが防ぎきれません。
この際、気づいた点が。ボタンに触れただけで信号がチャタリングしてしまう現象が発生。(ボタンの側面を触れてもチャタリング) そこで、抵抗/キャパシタの追加や絶縁テープなどを使い防止策を実施してもらいましたが、100%回避することはできませんでした。
ボタンスイッチをやめることで解決
そこで、思い切ってボタンスイッチをやめることにしました。
では、ADuCM3029のWake Upするタイミングはどうするか?Hibernateモードからの復帰要因としては、以下のものが準備されています。
- 外部割り込み
- UART RX 割り込み
- RTC割り込み
- Power on Reset
この中から、UART RX 割り込み(UART RXラインが遷移するとWake Up割り込みが生成)を活用することにして、ボタンスイッチは廃止としました。
4つの改善でさらに完成度を高める
ここで、作成したテストコードを仮リリースして、Sさんと並行して動作チェックを実施しました。これにより、4つの改善点を洗い出し、さらに完成品に向けフェーズ合わせを行いました。
改善点1:GNDの強化
まれに、動作が不安定になるケースが発生したので、GND面の強化を図り問題を解消。
改善点2:バッテリ動作への変更
これは当初から想定していた内容です。Sさんが電池ホルダを取り付けてくれました。
改善点3:ADuCM3029のWake Up割り込みの変更
Hibernateモードからの復帰の際、UART RX信号によってWake Upを行うように変更。
ドライバ内にHibernateモードを設定する命令も、もちろん準備されているのですが、これを使いこなすことができず・・・。結局この部分のみドライバは使用せず、C言語を自分で記述し、動作確認が取れました。(これは今後の要確認ポイントです。)
改善点4:ボードの制御自体をUART経由のコマンド・インタプリタに変更
GUIから制御を行うために、コマンド・インタプリタに対応。さらに、ADXL372の動作確認を行いやすいように、いくつかのレジスタ設定値もGUIから変更できるように対応。
他のマイコンで実績のあるコードを移植。これも、すんなり動作確認ができました。これにより、今までADXL372のレジスタ値を変更するたびに行っていた、コード修正 / ReBuild / Downloadの工程が不要となり、UART(COMポート)経由でADXL372のレジスタの修正が可能に。さらに、このコマンドをベースにSさんが今回のデモのGUIを作成してくれました。
[フェーズ4] 時間との勝負!完成へ向けた最終調整
いよいよ、最終フェーズに入ります。
通常業務と並行しながらの作業となり、このとき、すでに9月に入り、時間との勝負なってきました。ここからは、セミナー来場者に対する "見せ方" を意識した最終調整となります。
デモの見せ方を意識して、ギリギリまで最終調整
ここでいったんデモの "見せ方" について、関係者で協議して、最終調整を行いました。
最終調整1:FIFO数の拡大
現状テストで使用しているFIFOの設定数は、40set分。これをMaxの170分setへ拡大。
最終調整2:インスタント・オン・モード時の衝撃データの扱い
インスタント・オン・モードは、閾値を越えた衝撃を検知すると、FIFOがフルになるまで、自動計測を行います。FIFOはRead、もしくは、初期化を行うまでデータを保持し、新しいデータの取得はできない設定にしています。
そのため、1回のデータ出力で、1つの衝撃データしか、計測できませんでした。これを最大3つの衝撃データを計測できるように修正しました。
最大3つのデータを計測するために、ADXL372のINT1ピンを用いて、FIFOがフルになったとき、割り込みを発生させました。この割り込みによりADuCM3029はHibernateモードからWakeUpし、SPI経由で衝撃データをReadし、内蔵RAMに保存。その後、ADXL372 ⇒ インスタント・オン・モード、ADuCM3029 ⇒ Hibernateモードに、それぞれ遷移して、超低消費電力モードで待機するように修正しました。
最終調整3:Time Stamp データの付加
より実アプリケーションに近くイメージしてもらうために、衝撃事象が発生したTime Stampを付けることにしました。
ADuCM3029には、Real Time Clock(RTC)が2つ内蔵されていて、Hibernateモードに遷移しても、指定したRTCは動作を継続(カウントを継続)します。
今回は、内部オシレータ(LFOSC)をRTCのクロック源とし、1Hzの時間をカウントさせました。それぞれのモード、タイミングでRTCのカウント値を内部RAMに保持して衝撃データ出力の際、一緒に出力を行うよう修正しました。
<インスタント・オン・モード>
- FIFOがフルになったとき、INT1割り込みが生成(最終調整2 のタイミング)
- FIFO Readの前に、RTCカウント値を内蔵RAMに保持(最大3つ)
<ピーク検出モード>
- ACTからINACTへ遷移した時(INACTを検知したとき)INT1割り込みを生成
- RTCカウント値を内蔵RAMに保持(最大170)
このRTCは、初期化ルーティン内で設定を行い、RTCカウントを開始。今回のデモでは、RTCカウント値をホスト(PC)に渡して、このカウント値から衝撃事象が発生した時刻を算出しました。
衝撃検知デモの全貌
紆余曲折いろいろありましたが、何とかお披露目できる程度まで、デモの構築ができました。(まだ課題はありますが・・・)ここでは、デモの様子を紹介します。
荷物をイメージしたデモ
今回の衝撃検知デモでは、Sさんが荷物をイメージして "特別な箱" を手作りしてくれました。この中にモジュールを入れて、箱ごと衝撃を与えます。
まずはGUIでデモ機のモード設定
まず、ホストPCとモジュールをUSB接続し、モードの設定をしていきます。モジュールがポート接続されていることを確認し、GUIの立ち上げを行います。
"モード確認"ボタンをクリックすると設定されているモードを表示します。なお、接続の確認もかねています。
インスタント・オン・モードでデモ
最初に、インスタント・オン・モードでテストしてみます。
下記のような設定をして、デモ機を梱包箱に設置します。
いよいよ衝撃を与えてみます。
約1mの高さから落下させてみました。これを3回繰り返します。
梱包箱からモジュールを取り出し、先程のGUIに再度接続して、"データ読み取り" ボタンをクリックします。
データ読み取り画面を表示させ、"読み取り開始" ボタンをクリックすると、図18のようなデータが取得できました。
ピーク検知モードでデモ
次は、ピーク検知モードに設定して、同じようにテストしました。
今回はランダムな高さから5回落下させました。結果は以下のようになりました。
アナログ技術セミナー 当日は大盛況
ADI社のADXL372 + ADuCM3029を活用した、衝撃検知デモができあがるまでの工程を紹介しました。いかがでしたでしょうか?
2017年のアナログ技術セミナー(ADI社 主催)に無事にデモ展示したので、来場された方の中には、「そういえば見たな・・・」と思った方もいるかと思います。(ちなみに、ET2017展のマクニカブースでも展示しました。)
当日は、苦労した甲斐あって、多くのお客様に興味を持っていただきました!
当初は、お客様に梱包箱を投げてもらい、そのデータを出力する予定でいましたが、幸いにも多くのお客様に声を掛けていただいた関係(スペース、時間の問題)で、誠に残念ながら、実際にデモを体験していただくことはできませんでした。この場をお借りしてお詫び申し上げます。
今回作成したデモ機、使用した加速度センサ、マイコン、他のアプリケーション例などについて詳しい情報をご希望でしたら、ぜひお問い合わせください。
おすすめ記事/資料はこちら
[加速度センサADXL372] 輸送中の衝撃・振動を検出する
コイン電池で動作する加速度センサ「ADXL372」とは?
超低消費電力が最大の魅力 Arm® Cortex® -M3マイコン ADuCM3029
商品の購入はこちら
ADXL372BCCZ-RL7
EVAL-ADXL372Z(開発ツール)
ADUCM3029BCBZ-R7
ADUCM3029BCPZ-R7
ADZS-UCM3029EZLITE(開発ツール)
メーカーサイト/その他関連リンクはこちら
ADXL372評価ボード EVAL-ADXL372Z
ADXL372 データシート Rev.0(PDF)
ADuCM3029ボード
ADuCM3029 データシート Rev.0(PDF)
UCB-ADUCM3029-B ユーザーズ・マニュアル/回路図(PDF)
ADuCM302x Hardware Reference Manual Rev1.0(PDF)
Silicon Labs社 CP2102N-MINIEK