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:
1:ad135c286d4d
Parent:
0:47be4d9de4b9
--- a/main.cpp	Fri May 01 19:26:11 2015 +0000
+++ b/main.cpp	Mon May 04 08:53:50 2015 +0000
@@ -4,12 +4,15 @@
 #include "fft4g.h"
 #include "aqm1248a_lcd.h"
 
-#define NMAX 256
+#define NMAX 64
 #define NMAXSQRT 32
 
 #define MAX(x,y) ((x) > (y) ? (x) : (y))
 
 MAG3110 mag(PTE25, PTE24);
+InterruptIn magInt(PTD1);
+PwmOut Red(PTE29);
+
 SLCD slcd;
 aqm1248a_lcd lcd;
 
@@ -20,6 +23,9 @@
 double magBuffer[NMAX+1];
 
 void readerFunction() {
+    if ((mag.dataReady() & 1) == 0) return; // XDR:X-axis new Data Available.
+    
+    Red = (float)nFilled / (float)NMAX;
     if (modeFilling) {
         float x;
         mag.getX(&x);
@@ -55,24 +61,31 @@
 
     int cnt = 0;
     
+    Red.period_ms(1);
+    
+    Red = 1;
+    
     lcd.setmode(NORMAL);
     lcd.set_contrast(25);
         
+    reader.attach(&readerFunction, 0.001);
+//    magInt.mode(PullUp);
+//    magInt.rise(readerFunction);
+    
     mag.enable();
     
-    wait(0.1);
+    wait(0.1);    
     
-    reader.attach(&readerFunction, 0.0333333);
-    
+    int n2 = n/2;
+    int height = lcd.height();
+    int width  = lcd.width();
+    int barWidth = lcd.width() / n2;
+        
     while (1) {
-        while(modeFilling == true) wait(0.1);
+        while(modeFilling == true) wait(0.01);
 
         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;
@@ -88,7 +101,7 @@
         max = height / max;
         
         for (int i = 1; i < n2; i++) {
-            lcd.line(i, height-1, i, height-1-max*magBuffer[i], 1);
+            lcd.fillrect((i-1)*barWidth, height-1, i*barWidth-1, height-1-max*magBuffer[i], 1);
         }
 
         sprintf(buf, "%4d", cnt++);