daily pastebin goal
3%
SHARE
TWEET

Untitled

a guest Jan 23rd, 2019 62 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2.  * M5StackでSAMPLING_FREQUENCYでマイクを測定し、FFTして周波数成分をLCDにグラフ表示。
  3.  */
  4. #include <M5Stack.h>
  5. #include "arduinoFFT.h"
  6.  
  7. #define MIC 36
  8.  
  9. #define SAMPLING_FREQUENCY 40000
  10. const uint16_t FFTsamples = 256;  // サンプル数は2のべき乗
  11.  
  12. double vReal[FFTsamples];  // vReal[]にサンプリングしたデーターを入れる
  13. double vImag[FFTsamples];
  14. arduinoFFT FFT = arduinoFFT(vReal, vImag, FFTsamples, SAMPLING_FREQUENCY);  // FFTオブジェクトを作る
  15.  
  16. unsigned int sampling_period_us;
  17.  
  18. void sample(int nsamples) {
  19.     for (int i = 0; i < nsamples; i++) {
  20.         unsigned long t = micros();
  21.         vReal[i] = (double)analogRead(MIC) / 4095.0 * 3.6 + 0.1132; // ESP32のADCの特性を補正
  22.         vImag[i] = 0;
  23.         while ((micros() - t) < sampling_period_us) ;
  24.     }
  25. }
  26.  
  27. int X0 = 30;
  28. int Y0 = 20;
  29. int _height = 240 - Y0;
  30. int _width = 320;
  31. float dmax = 5.0;
  32.  
  33. void drawChart(int nsamples) {
  34.     int band_width = floor(_width / nsamples);
  35.     int band_pad = band_width - 1;
  36.  
  37.     for (int band = 0; band < nsamples; band++) {
  38.         int hpos = band * band_width + X0;
  39.         float d = vReal[band];
  40.         if (d > dmax) d = dmax;
  41.         int h = (int)((d / dmax) * (_height));
  42.         M5.Lcd.fillRect(hpos, _height - h, band_pad, h, WHITE);
  43.         if ((band % (nsamples / 4)) == 0) {
  44.             M5.Lcd.setCursor(hpos, _height + Y0 - 10);
  45.             M5.Lcd.printf("%.1fkHz", ((band * 1.0 * SAMPLING_FREQUENCY) / FFTsamples / 1000));
  46.         }
  47.     }
  48. }
  49.  
  50. void setup() {
  51.     M5.begin();
  52.     M5.Speaker.write(0); // スピーカーをオフする
  53.     Serial.begin(115200);
  54.     while (!Serial) ;
  55.  
  56.     pinMode(MIC, INPUT);
  57.  
  58.     sampling_period_us = round(1000000 * (1.0 / SAMPLING_FREQUENCY));
  59. }
  60.  
  61. void DCRemoval(double *vData, uint16_t samples) {
  62.     double mean = 0;
  63.     for (uint16_t i = 1; i < samples; i++) {
  64.         mean += vData[i];
  65.     }
  66.     mean /= samples;
  67.     for (uint16_t i = 1; i < samples; i++) {
  68.         vData[i] -= mean;
  69.     }
  70. }
  71.  
  72. void loop() {
  73.     sample(FFTsamples);
  74.  
  75.     DCRemoval(vReal, FFTsamples);
  76.     FFT.Windowing(FFT_WIN_TYP_HAMMING, FFT_FORWARD);  // 窓関数
  77.     FFT.Compute(FFT_FORWARD); // FFT処理(複素数で計算)
  78.     FFT.ComplexToMagnitude(); // 複素数を実数に変換
  79.     M5.Lcd.fillScreen(BLACK);
  80.     drawChart(FFTsamples / 2);
  81. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top