Newer
Older
M5StickCPlus_FactoryTest2022 / SampleSrc / accel02.ino
@Your Name Your Name on 9 Apr 2024 2 KB run script
/** 
 * FFTで周波数特性
 * https://101010.fun/iot/m5stickc-plus-accel.html
 * を改変
 */

#include <M5StickCPlus.h>
#include <arduinoFFT.h>

#define SAMPLE_PERIOD 10    // サンプリング間隔(mS)

const uint16_t FFTsamples = 64; //This value MUST ALWAYS be a power of 2
double vReal[FFTsamples];
double vImag[FFTsamples];
const double samplingFrequency = 1000.0 / (double)SAMPLE_PERIOD;
ArduinoFFT<double> FFT = ArduinoFFT<double>(vReal, vImag, FFTsamples, samplingFrequency);

int Y0 = 15;
int _height = 135 - Y0;
int _width = 240;
float dmax = 1000.0; // Sensitive

void drawChart(int nsamples) {
    int band_width = floor(_width / nsamples);
    int band_pad = band_width - 1;

    for (int band = 0; band < nsamples; band++) {
        int hpos = band * band_width;
        float d = vReal[band];
        if (d > dmax) d = dmax;
        int h = (int)((d / dmax) * (_height) * 0.9);
        M5.Lcd.fillRect(hpos, _height - h, band_pad, h, BLACK);
        if ((band % 16) == 0) {
            M5.Lcd.setCursor(hpos, _height);
            M5.Lcd.printf("%dHz", (int)((band * 1.0 * samplingFrequency) / FFTsamples));
        }
    }
}

void setup() {
  M5.begin();
//   M5.Axp.ScreenBreath(24);
  M5.Lcd.setRotation(3);
  M5.Lcd.fillScreen(WHITE);
  M5.Lcd.setTextColor(BLACK);
  M5.Lcd.setTextSize(2);
  M5.IMU.Init();
  M5.IMU.SetAccelFsr(M5.IMU.AFS_4G);
}

void DCRemoval(double *vData, uint16_t samples) {
    double mean = 0;
    for (uint16_t i = 0; i < samples; i++) {
        mean += vData[i];
    }
    mean /= samples;
    for (uint16_t i = 0; i < samples; i++) {
        vData[i] -= mean;
    }
}

void loop() {
  for (int i = 0; i < FFTsamples; i++) {
    float ax, ay, az; // 画面短軸方向がx 長軸方向がy 画面に対して垂直がz
    long t = micros();
    M5.IMU.getAccelData(&ax,&ay,&az);  // MPU6886から加速度を取得
    vReal[i] = az * 1000;  // mGに変換
    vImag[i] = 0;
    delayMicroseconds(SAMPLE_PERIOD * 1000 - (micros() - t));
  }

  DCRemoval(vReal, FFTsamples);  // 直流分を除去
  FFT.windowing(FFT_WIN_TYP_HAMMING, FFT_FORWARD);  // 窓関数
  FFT.compute(FFT_FORWARD); // FFT処理(複素数で計算)
  FFT.complexToMagnitude(); // 複素数を実数に変換
  double x = FFT.majorPeak();

  M5.Lcd.fillScreen(WHITE);  // 画面をクリア
  drawChart(FFTsamples / 2);
  M5.Lcd.setCursor(40, 0);
  M5.Lcd.printf("Peak: %3.1fHz", x);
}