Guest User

Untitled

a guest
Jan 23rd, 2019
126
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.27 KB | None | 0 0
  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. }
Add Comment
Please, Sign In to add comment