MicrophoneSpectrumTFT.ino 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. /************************************************************************
  2. M5StackFire Discovery simple Spectrum example
  3. The microphone signal is sampled and a frequency analysis is performed.
  4. Please install the arduinoFFT library.
  5. You will find it in the library manager or you can get it from github:
  6. https://github.com/kosme/arduinoFFT
  7. M5StackFire September 2018, ChrisMicro
  8. ************************************************************************/
  9. #include <M5Stack.h>
  10. #include "arduinoFFT.h"
  11. //#include <WiFi.h>
  12. arduinoFFT FFT = arduinoFFT(); /* Create FFT object */
  13. #define M5STACKFIRE_MICROPHONE_PIN 34
  14. #define M5STACKFIRE_SPEAKER_PIN 25 // speaker DAC, only 8 Bit
  15. #define HORIZONTAL_RESOLUTION 320
  16. #define VERTICAL_RESOLUTION 240
  17. #define POSITION_OFFSET_Y 20
  18. #define SIGNAL_LENGTH 512
  19. double oldSignal[SIGNAL_LENGTH];
  20. double adcBuffer[SIGNAL_LENGTH];
  21. double vImag[SIGNAL_LENGTH];
  22. #define SAMPLINGFREQUENCY 40000
  23. #define SAMPLING_TIME_US (1000000UL / SAMPLINGFREQUENCY)
  24. #define ANALOG_SIGNAL_INPUT M5STACKFIRE_MICROPHONE_PIN
  25. void setup() {
  26. M5.begin();
  27. M5.Power.begin();
  28. // WiFi.mode(WIFI_OFF);
  29. // btStop();
  30. dacWrite(M5STACKFIRE_SPEAKER_PIN,
  31. 0); // make sure that the speaker is quite
  32. M5.Lcd.begin();
  33. M5.Lcd.fillScreen(BLACK);
  34. M5.Lcd.fillRect(10, 1, 150, 160, BLACK);
  35. M5.Lcd.setCursor(0, 0);
  36. M5.Lcd.setTextColor(GREEN); // M5.Lcd.setTextSize(3);
  37. M5.Lcd.setTextSize(1);
  38. M5.Lcd.println("analog input MIC");
  39. M5.Lcd.print("max. frequency: ");
  40. M5.Lcd.print(SAMPLINGFREQUENCY / 2);
  41. M5.Lcd.println(" Hz");
  42. M5.Lcd.setTextSize(2);
  43. }
  44. void showSignal() {
  45. int n;
  46. int oldx;
  47. int oldy;
  48. int oldSig;
  49. int x, y;
  50. for (n = 0; n < SIGNAL_LENGTH / 2; n++) {
  51. x = n;
  52. y = map(adcBuffer[n], 0, 512, VERTICAL_RESOLUTION, POSITION_OFFSET_Y);
  53. if (n > 0) {
  54. // delete old line element
  55. M5.Lcd.drawLine(oldx, oldSig, x, oldSignal[n], BLACK);
  56. // draw new line element
  57. if (n < SIGNAL_LENGTH - 1) // don't draw last element because it
  58. // would generate artifacts
  59. {
  60. M5.Lcd.drawLine(oldx, oldy, x, y, GREEN);
  61. }
  62. }
  63. oldx = x;
  64. oldy = y;
  65. oldSig = oldSignal[n];
  66. oldSignal[n] = y;
  67. }
  68. }
  69. double AdcMeanValue = 0;
  70. void loop(void) {
  71. int n;
  72. uint32_t nextTime = 0;
  73. // record signal
  74. for (n = 1; n < SIGNAL_LENGTH; n++) {
  75. double v = analogRead(ANALOG_SIGNAL_INPUT);
  76. AdcMeanValue += (v - AdcMeanValue) * 0.001;
  77. adcBuffer[n] = v - AdcMeanValue;
  78. // wait for next sample
  79. while (micros() < nextTime)
  80. ;
  81. nextTime = micros() + SAMPLING_TIME_US;
  82. }
  83. FFT.Windowing(adcBuffer, SIGNAL_LENGTH, FFT_WIN_TYP_HAMMING,
  84. FFT_FORWARD); /* Weigh data */
  85. FFT.Compute(adcBuffer, vImag, SIGNAL_LENGTH, FFT_FORWARD); /* Compute FFT */
  86. FFT.ComplexToMagnitude(adcBuffer, vImag,
  87. SIGNAL_LENGTH); /* Compute magnitudes */
  88. // int x = FFT.MajorPeak(adcBuffer, SIGNAL_LENGTH, 1000000UL /
  89. // SAMPLING_TIME_US);//SAMPLINGFREQUENCY
  90. int x = FFT.MajorPeak(adcBuffer, SIGNAL_LENGTH, SAMPLINGFREQUENCY);
  91. int maxAmplitudeDB = 0;
  92. for (n = 1; n < SIGNAL_LENGTH; n++) {
  93. int a = log10(adcBuffer[n]) * 20 -
  94. 54.186; // convert amplitude to dB scale, dB relative to
  95. // log10(512samples)*20=54.186dB
  96. if (a > maxAmplitudeDB) maxAmplitudeDB = a;
  97. adcBuffer[n] = (a + 30) * 5; // scale for TFT display
  98. vImag[n] = 0; // clear imaginary part
  99. }
  100. showSignal();
  101. M5.Lcd.fillRect(200, 0, 119, 40, BLUE);
  102. M5.Lcd.setCursor(210, 1);
  103. M5.Lcd.print(x);
  104. M5.Lcd.print(" Hz");
  105. M5.Lcd.setCursor(210, 21);
  106. M5.Lcd.print(maxAmplitudeDB);
  107. M5.Lcd.print(" dB");
  108. }