FFT power Spectrum on AQM1248 LCD. - FRDM-KL46Z - inner LCD - inner MAG3110 Magnetometer - AQM1248 micro graphical LCD - Dr.Ooura's very fast FFT library thanks.
Dependencies: MAG3110 SLCD aqm1248a_lcd mbed
FRDM-KL46Zに内蔵されているMAG3110で磁力を測定し、FFTでパワースペクトルを求めてグラフ表示しています。と言っても自分ではほとんどコードは書いておらず、すべては
- 内蔵LCD
- 内蔵MAG3110
- AQM1248
- 大浦先生のFFTライブラリ
以上のライブラリのおかげです。ありがとうございます。
プログラムとしては:
- Intervalを使ってバッファにMAG3110からのデータを詰め込む
- メインループではバッファを監視し、バッファが一杯になったらFFTかけてスペクトル表示
を繰り返しているだけです。せめてRTOSを使ってFFT〜スペクトル表示も別タスクにしないと…。
関連ブログ:http://jiwashin.blogspot.com/2015/05/fft.html
なお、AQM1248ライブラリのソースを拝見するとサポートしているのは「LPC1768とKL05」という感じです。KL46では動作確認しましたが、その他のプラットフォーム上で使用する場合には、ピンアサインなどを十分確認してください。その点に気をつければとても使い勝手の良いライブラリです。開発者の方に改めてお礼申し上げます。
なお、AQM1248とKL46との接続は以下の通りです:
AQM1248 | KL46 |
Vcc | 3.3v |
CS | D10 |
RESET | D9 |
RS | D8 |
SCLK | D13 |
SDI | D11 |
Diff: main.cpp
- Revision:
- 0:47be4d9de4b9
- Child:
- 1:ad135c286d4d
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Fri May 01 19:26:11 2015 +0000 @@ -0,0 +1,103 @@ +#include "mbed.h" +#include "SLCD.h" +#include "MAG3110.h" +#include "fft4g.h" +#include "aqm1248a_lcd.h" + +#define NMAX 256 +#define NMAXSQRT 32 + +#define MAX(x,y) ((x) > (y) ? (x) : (y)) + +MAG3110 mag(PTE25, PTE24); +SLCD slcd; +aqm1248a_lcd lcd; + +Ticker reader; + +bool modeFilling = true; +int nFilled = 0; +double magBuffer[NMAX+1]; + +void readerFunction() { + if (modeFilling) { + float x; + mag.getX(&x); + + if (nFilled < NMAX) { + magBuffer[nFilled++] = x; + if (nFilled >= NMAX) { + modeFilling = false; + } + } + } +} + + +void putdata(int n, double *a) +{ + int j; + + double pi2 = 3.14159265*2 / n; + for (j = 0; j <n; j++) { + a[j] = sin(j*pi2*10)*10 + sin(j*pi2*15)*5 + sin(j*pi2*20)*10; + } +} + + +int main() +{ + char buf[80]; + int n, ip[NMAXSQRT + 2]; + double w[NMAX * 5 / 4]; + ip[0] = 0; + n = NMAX; + + int cnt = 0; + + lcd.setmode(NORMAL); + lcd.set_contrast(25); + + mag.enable(); + + wait(0.1); + + reader.attach(&readerFunction, 0.0333333); + + while (1) { + while(modeFilling == true) wait(0.1); + + rdft(n, 1, magBuffer, ip, w); + + int n2 = n/2; + int height = lcd.height(); + int width = lcd.width(); + + double max = 0; + for (int i = 0; i < n2; i++) { + int i2 = i*2; + magBuffer[i] = magBuffer[i2]*magBuffer[i2] + magBuffer[i2+1]*magBuffer[i2+1]; + if (i > 0 && magBuffer[i] > max) max = magBuffer[i]; + } + + lcd.cls(); + + lcd.locate(0,0); + lcd.printf("%lf", max); + + max = height / max; + + for (int i = 1; i < n2; i++) { + lcd.line(i, height-1, i, height-1-max*magBuffer[i], 1); + } + + sprintf(buf, "%4d", cnt++); + slcd.printf(buf); + if (cnt > 9999) cnt = 0; + + nFilled = 0; + modeFilling = true; + } +} + +