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との接続は以下の通りです:

AQM1248KL46
Vcc3.3v
CSD10
RESETD9
RSD8
SCLKD13
SDID11
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;
+    }
+}
+
+