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

main.cpp

Committer:
TareObjects
Date:
2015-05-04
Revision:
1:ad135c286d4d
Parent:
0:47be4d9de4b9

File content as of revision 1:ad135c286d4d:

#include "mbed.h"
#include "SLCD.h"
#include "MAG3110.h"
#include "fft4g.h"
#include "aqm1248a_lcd.h"

#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;

Ticker reader;

bool modeFilling = true;
int  nFilled = 0;
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);
        
        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;
    
    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);    
    
    int n2 = n/2;
    int height = lcd.height();
    int width  = lcd.width();
    int barWidth = lcd.width() / n2;
        
    while (1) {
        while(modeFilling == true) wait(0.01);

        rdft(n, 1, magBuffer, ip, w);

        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.fillrect((i-1)*barWidth, height-1, i*barWidth-1, height-1-max*magBuffer[i], 1);
        }

        sprintf(buf, "%4d", cnt++);           
        slcd.printf(buf);
        if (cnt > 9999) cnt = 0;
        
        nFilled = 0;
        modeFilling = true;
    }
}