ラベル AQM1248 の投稿を表示しています。 すべての投稿を表示
ラベル AQM1248 の投稿を表示しています。 すべての投稿を表示

2015年9月22日火曜日

スペクトルアナライザー by MSP432P401R+Energia MT

ピンぼけじゃないもん影だもん(趣味:写真)

■Energia MT=マルチタスク■

EnergiaはArduino互換の開発環境ですが、MSP432P401R版はマルチタスクに対応しています。

マルチタスクというにはあまりにも単純でセマフォとかメールとかまったくありません。でも、今までのArduinoと比べれば格段に作りやすくなりました。

使い方は単純で

  • Energia IDEでタブを開き適当な名前を付ける
  • メイン同様setupとloop関数を用意するが、setupDisplay(), loopDisplay()のようにタスク名が後に続くようにするとsetup+loopのペアを別タスクとして認識する
  • メインに置いたヘッダやメイン上のGlobal変数は別タスクでも認識される

排他などについては厳密な排他制御は無理、暫定的にGlobal上にフラグを置いて自分で制御するしかありません。また、プリエンプションやタスク優先度がどうなっているのかも不明。その辺まったく情報がありません。まぁそのうち何とかなるでしょう。

ということで、とりあえず毎度お馴染みのスペクトルアナライザーをマルチタスクで作ってみました。

■材料

MSP432P401R、アンプ付きマイクAE-MICAMP、超小型グラフィック液晶AQM1284A、ブレッドボード、ジャンパ線…すべて秋月で揃います。合計4000円ぐらい? USBシリアルなども不要なのでArduino uno正規品を買うより安いです。

マイクはアナログ出力なのでドライバ等不要です。液晶についてはAQM1284AのコントローラIC ST7565RのライブラリをAdafruitさんが公開しているので、それを少し改造して使います。

FFTは大浦先生のライブラリそのままですが、M4F対応としてdoubleをfloatに置換して使用します。

以上です。

■配線■

マイクはGND, Vcc(5vが推奨されていますが出力電圧が大きくなりすぎるので3.3vにします)を接続し、OUTをEnergiaのP5.0に接続します。

AQM1284Aは以下の通りです。


AQM1284AEnergia MSP432P401R
VDD3V3
CSP3.0 / 18
RESETP2.5 / 19
RSP5.7 / 17
SCLKP1.5 / 7
SDIP1.6 / 15
GNDGND

■使い方■

各ソースは末尾に掲載します。長くてすみません。

Energiaは最新の16を使用してください。起動する前に、ST7565という名前のフォルダを作り、その中にST7565.cppとST7565.hを入れ、Energiaのlibraryフォルダに入れます。

Enegiaを起動したら、新しいプロジェクトを作り、FFTGraph_MTをコピペします。次に、ウィンドウ右上にある下向き三角をクリックして「新規タブ」を選び、TaskLCDという名前を付けてTaskLCDをコピペします(名前は何でも良いです)。

配線の点検をすませたらMSP432をマイクロUSBで接続し、Energiaでcmd+M、ビルドとプログラムの転送が終わるとグラフィック液晶に表示が出る…はずです。

なお、この作り方は厳密にいえば正しいマルチタスクではありません。TaskLCDが表示している最中にメインスレッドが表示バッファを書き換えてしまうこともありえます。でも、表示中にスペクトルが変わったとしても人間の目で追える変化ではないので、大目に見てやってください。

■毎度お馴染みのハマり■

Adafruitのライブラリの移植は、コンパイルエラーが出る→つぶす→ビルド→エラー→潰す…を淡々と繰り返すだけですが、それで終わらないのがコントラスト設定とpagemapでした。

コントラスト設定は秋月版との液晶の違いかAdafruit版だと真っ黒になってしまうのですが、Voltage Resistor Setを指定して回避できました。

pagemapはコントローラ上のページと液晶の表示位置を対応させるための表ですが、配布されているものと秋月のでは仕様が異なるようで、こんなのが出ました。左上隅から右下隅への直線がちょっと下にずれてます。64ドットで8ページ、たぶん2ページずれているのでしょう。


何度かの途中試行錯誤を経て

逆だ

なんだこれ

最終的にちゃんと表示が出ました。ここまで約1時間。



その次はマイクからの入力が常にゼロという現象が。そんなお行儀のいいアナログ入力はありえないのでしばらく頭を抱えていたのですが、これはanalogRead対応のピンにつないだつもりがanalogWriteのピンだった、というオチ。そりゃ値ゼロだわorz

FFTライブラリはつい最近使ったものなので問題なし。マルチタスク対応に関しては、奇跡的にも一発で動きました。何も難しいことしていないので当たり前ですけども、簡単なところで引っかかるのがこの私orz

でも、「自作補聴器」に今までで一番近づいたなぁ。すごいぞM4F、偉いぞM4F。





2015年5月2日土曜日

磁束密度をFFTで処理しグラフ表示


わー、なんだか久しぶり。

以前、磁石の動きを検出するのにアナログ出力のホール素子を使ってみたのですが、かなり強力な磁石を使っても10cm程度がやっとで、あとはノイズに埋もれてしまいました。まぁアナログ技術のある人ならもうちょっとマシな結果になるかもしれませんが。

ふと思い立って、FRDM-KL46Zについている電子コンパスMAG3110を使ってみました。測定してみると何もしなくても地球磁場が600-1200ぐらいの値を返してくるのですが、すぐ近くにネオジム磁石をおいてみても200程度しか値が変わりません。ただ、地球磁場は当然ながら安定しているので、ネオジム磁石の動きは十分信号として検出できそうな気配。

ということで、ずっと部品沼で眠っていたAQM1248(秋月の超小型グラフィック液晶)、最速の誉れも高き大浦先生のFFTライブラリなどを寄せ集めて、実験してみました。

■まず予備実験■

FRDM-KL46Z内蔵のMAG3110(ライブラリ:MAG3110…ワーニング出まくるので、あとで直してpush requestしたい)を内蔵の液晶(ライブラリ:SLCD)で表示してみました。MAG3110でボード内部のI2C端子名を指定するんですが、参照した資料が間違っていて苦労しました。
MAG3110 mag(PTE25, PTE24);
これで使えます、ご参考まで。

さて、表示してみると前述の通り、値は向きによって600-1200程度の幅で変化します。そこにネオジム磁石を近づけると200ぐらい増減します。当然離すと急激に弱くなりますが、値としてはわりとはっきりしているので、たとえば自転車のホイール回転のように周波数レンジの決まっているものであれば何とか処理できそう。

ということで信号処理はFFTを使い、表示に超小型グラフィック表示液晶を使うことにしました。

■まずAQM1248■

電子工作を再開したばかりのころ、秋月の「超小型液晶」を基板にナナメにハンダ付けしてしまったのは良い思い出…今も元気に活躍しておられます、ナナメのままで。

ということで、まずフラックスを塗って置いてしばらく放置し一カ所だけハンダ付けをして向き角度などを確認してから装着。FRDM-KL46Zとの配線は以下の通り:

AQM1248FRDM-KL46Z
Vcc3.3v
CSD10
RESETD9
RSD8
SCLKD13
SDID11

mbed用のほどよいライブラリaqm1248a_lcdをリンクしサンプルをそのままコピペして動作を確認。なお、同ライブラリはプラットフォーム(mbedの機種)を識別してGPIOなどを切り替える作りになっているのですが、概ね「LPC1768とKL05、それ以外」という感じなのでLPC1768とKL05, KL46以外の方はソースの中身と配線をご確認の上、お使いになった方が良いです。

一昨日aitendoのカラー液晶に悪戦苦闘したのですが、こっちは一発動作。やっぱ私にはaitendoはハードルが高すぎます。相場?の半値ぐらいで買えたんですが、家でビニール袋から出してみたら基板に液晶が接着済(笑)。工程ミスか指示ミスか知らないけど、液晶が端子を半分覆い隠す状態になっていて普通なら納品できない品だから安かったんでしょうね。まさにジャンク。

まぁそれはともかく、これで表示はばっちり。接続ピン番号埋め込まれていてちょっと不安だったものの動作は安定しているのでグラフ描画もかなり簡素化できそうな気配。ライブラリ開発者の方に改めてお礼申し上げます。

■高速FFTライブラリ■

今回はこれを使います。
コンパクトで高速で美しい…。mbedで使うには、

  1. パッケージをダウンロード、解凍
  2. fft4g.cをブラウザ上のmbedプロジェクトにドラッグ&ドロップ
  3. ファイル名をfft4g.cppに変更
  4. あとはサンプルを参考に書くだけ
余談ですが、サンプルではfft->ifftで誤差を確認する、という処理が書かれていて、「FFT+IFFTでフィルタ作りたい」と思っている私には拍子抜けするほど簡単w

数学どころか算数レベルの私には基数って何よ?の世界なのですが、ともかくこれも一発動作。今まで使ったFFTライブラリの中で一番簡単だったかもしれません。

■ということでプログラムの構造■

  • IntervalでMAG3110を読みバッファに値を書き込んでいく
  • メインループでバッファをチェックし、一杯になったらFFTかけて液晶にグラフ表示
これだけです。

で処理の結果ですが…まず、電子機器で一杯の室内で放置した状態でのスペクトル


ごらんのように、ほぼ全域に不規則な成分が出てます。実は圧倒的に直流成分が多いのですがスケールアウトしてしまうのでカットしてます(そりゃそうだ)。そして次が、FRDM上約10cmのところでネオジム磁石をおおよそ2秒で3往復ほどの周期で振ってみたところのスペクトル


明確にでかい山が出来てます。必死に高速フリフリをすると右へ移動するし、ゆっくりにすると左へ移動するので、なんとなくできてるかなーと。さて、次は、「こういうぐあいにでっかい山ができていることを検出する処理」というのを書かないといけないのですが、パターン認識とか苦手なんす。どなたかアイディアください。

以下ソースです。

ほとんどサンプルからのコピペですが、mbedリポジトリに公開しましたのでご笑覧くださいませ。下にも貼っておきますが、何かの参考にされるのであればリポジトリの方をご覧下さい(基本的に以下のソースは更新し忘れることが多いと思うので)