加速度データをSDカードに記録できるようになっているので、実際にバイクに乗せてデータを取ってみました。
名前を付けておく
呼び方がないと不便なので、今回作っている工作物の名前は「RXタコメータ」にします。
いきなり結果
こんな感じでデータが取れました。
- 家の近所を一周してきました。
- RXタコメータで取得した加速度時系列データ(加速度ログ)を時間ごとにFFTしたものです。
- 縦の軸が周波数、横の軸が時間
- 縦軸 : 3.125Hz / 1刻み
- 横軸 : 0.32秒 / 1刻み
- ピークの周波数位置がそれらしく動いているように見えます。
- 最初は1速で発進します。(ギア比最低)
- 発進した後、ある程度スピードが出たら1段ずつギアシフトしていきます。このとき、アクセルを一旦緩めます。
- ピーク周波数が急激に落ちているところはおそらくそのときのものです。
- 色が全体的に薄くなっている箇所は、停止しているときのものと思われます。
何をやったか
Octaveを使って、加速度時系列データから先ほどのグラフを作成しました。
MATLAB互換のフリーのツールです。
他にもpython + numpy + matplotlibでも同じようなことができそうです。
具体的にやったこと
先ほどのグラフ作成の手順は以下の通りです。
- SDカードをPCに差して、RXタコメータで取得した加速度ログをコピー
- Octaveで、加速度ログ(バイナリデータ)を読み込む
- 加速度ログを適当な長さ(今回は512にしました)に区切って、それぞれFFTを実施
- 「スペクトル強度(周波数, 時刻)」の形のデータができる
- 周波数点数 : 512、ただし元が実数データなので半分は意味のないデータ
- 時刻点数 : 時系列データ点数/512
- Octaveの2次元プロット機能でグラフ表示
Octaveコード
加速度データ取り込み
以下のファイルを作って、read_adxl345_log_bin_2byte()
関数で加速度データを取り込めるようにしました。
function [dat_g dat_ovrn] = read_adxl345_log_bin_2byte(fname) fid = fopen(fname, "r"); dat_g = fread(fid, Inf, "int16", 2); fseek(fid, 2, SEEK_SET); dat_ovrn = fread(fid, Inf, "int16", 2); fclose(fid); endfunction
加速度ログファイルには、以下のようにデータが並んでいます。
G[0] FLG[0] G[1] FLG[1] G[2] FLG[2] ... G[i] : i番目の加速度データ(16bit) FLG[i] : i番目データの関連フラグ等(16bit)
Octaveコードのfread()
では、バイナリデータを繰り返し読んで行列変数に格納する、ということが可能です。
上記で使ったfread()
のフォーマット :
val = fread(fid, size, precision, skip); # fid : ファイルID # size : 読み出しデータ数、Inf -> 読めるだけ読む # precision : 読み出しデータの型(uint8, ushortなど) # skip : 繰り返し読み出しの際の読み飛ばし数(バイト単位)
"関連フラグ等"としては、現状"オーバランフラグ"を入れています。
今回使っている加速度センサは、決まったレートで勝手に測定を行い、これを割り込みピンでCPUに通知します。
CPUでは、SDカードの1セクタ分データがたまったら実際にSDカードへの書き込みを行いますが、これがそれなりに時間がかかってしまうので、この間に入ってくる加速度データを取りこぼしてしまうことがあります。
"オーバランフラグ"は、この取りこぼしが発生したことを示すものです。
FFT
以下のファイルを用意して、所定のデータ数ごとにFFTを行いました。
窓関数もかけています。
function ffts = fft_slice(d, u) # d : data for FFT # u : unit size for FFT n_ffts = cast(floor(size(d)/u), "uint32"); for i = 1:n_ffts # ffts(:,i) = fft(d(1+(i-1)*u : i*u)); ffts(:,i) = fft(d(1+(i-1)*u : i*u) .* hamming(u)); endfor endfunction
グラフ表示
今回のような2変数のデータを可視化するのに、いくつかのグラフが用意されています。
- contour (contourf)
- surf
- pcolor
全部試してみたのですが、pcolorが一番わかりやすく表示されました。これが記事先頭のグラフです。
グラフ表示した際のコードは以下の通りです。
[gData ovrn] = read_adxl345_log_bin_2byte("adxl345_log_002.bin"); gFFT = fft_slice(gData, 512); pcolor(abs(gFFT(3:128,:))); colorbar caxis([0 4000])
グラフ表示参考 :
Yapso, Yet Another Plotting System for Octave
改善項目
- 軸の目盛りを秒単位、Hz単位にしたい
- 加速度値もきちんとしたい
- 今は16bitのAD変換値をそのまま使っています。加速度センサ(ADXL345)は、今回使った設定だと4mg/LSBのAD変換になっています。
- いずれもできそうなので、次回やってみます。
困ったこと
いくつか困ったことはありました。
- 取得した加速度ログデータを見ると、最大レートの3200Hzではオーバランが発生していました。1600Hzでもやはり発生していました。
- SDカードの接続が怪しいのか、ファイルオープンや書き込みに失敗することがありました。RXタコメータの上部をちょっと開けるとちゃんと動いたりしました…
ハードを作り直したい…
その他
はてなブログではコードブロックでのファイル名表示ができなかったのですが、以下のサイトのデザインCSSを使わせていただいて、表示できるようにしました。
はてなブログでソースコード表示時にタイトルを付ける - 酔いどれ技術者の備忘録
次回
もうちょっと長距離走って測定を行ったので、その結果を見てみたいと思います。