13浏览
查看: 13|回复: 2

[项目] 【Arduino 动手做】ESP32 带有 INMP441 的 WS2812B 矩阵

[复制链接]
ESP32-INMP441-Matrix-VU
重要提示:目前,该代码仅适用于 ESP32 核心 1.0.6,在 2.0.0 上不可靠。我认为这是一个 FastLED 问题,但我可能错了!使用 Boards Manager 恢复到 1.0.6 以便编译和上传。

这是 3D 打印的(可选)电池供电的 WS2812B LED 矩阵的存储库,它使用来自 INMP441 数字麦克风的音频输入产生漂亮的图案,并在 ESP32 上运行。在下面的 YouTube 链接中观看解释视频:

硬件
您至少需要:
可以使用用于生产外壳的 3D 打印机,STL。
ESP32 开发板,确切的类型并不重要。
一个 8x8 (80x80 mm) 或 16x16 (160x160 mm) WS2812B LED 矩阵。
我的代码应该适用于宽度为 8 或 16 的倍数的任何矩阵。高度并不重要。如果您使用的是 WLED,您可以拥有任何您喜欢的尺寸!
我的矩阵的数据输入位于左下角,并以水平之字形模式连接。
INMP441 I2S 麦克风。
电源开关
DC 输入插座和 5V 电源(如果您不是由电池供电)。
建造它的常用电子设备和设备。
无电池原理图

如果您想为您的创作提供电池,您还需要:
LiPo / LiIon 电池 - 确切规格取决于您需要的运行时间以及您用于充电/升压电路的解决方案。
一个充电/升压板,用于连接您的电池并为 LED 输出 5V。
或者,您可以为这些函数使用单独的模块,这对于更高功率的 16x16 矩阵来说可能是一个好主意。
电池原理图

软件
关于软件,您有两个主要选择,此存储库中给出的软件或 WLED Sound Reactive fork。任一选项的硬件连接都是相同的。与该软件相比,使用 WLED 有很多优点,它是一个更完整的解决方案,可以更好地支持同步多个控制器、设置模式播放列表和自定义现有的模式。我的软件唯一真正的优势是我想编写自己的模式,并且能够完全自定义事情的运作方式。您可以自由选择。如果您想使用我的软件,请继续阅读...

软件设置
下载代码,并确保已安装所有必需的库。它们列在 .ino 文件的顶部。
确保在软件中正确设置了矩阵的输入位置和接线样式。有关更多详细信息,请参阅 .ino 文件顶部的注释。
将 和 更改为矩阵的正确 LED 数量。M_WIDTHM_HEIGHT
进入 web_server.h 并将 、 、 和 更改为您的主网络凭证和备用网络凭证。ssidpasswordssid2password2
将代码上传到您的 ESP32 并希望一切顺利!

使用矩阵
每次您为矩阵供电时,它都会尝试连接到主 WiFi 网络 5 秒钟。如果失败,它将尝试辅助凭证 5 秒钟。如果此作也失败,它将回退到之前的设置,但您将无法进行任何更改。我已将辅助凭证设置为手机上的热点,因此我可以在家庭网络之外使用该设备。 如果成功连接到网络,ESP 的本地 IP 将在屏幕上滚动。在任何浏览器中转到此地址以更改设置。可以更改的设置包括:

下一个模式 - 不言自明。
Auto-change pattern (自动更改模式) - 将每隔几秒循环一次模式,定义如下...
在 auto 上显示每个模式的秒数 - 接受 1 到 65535 秒之间的值
亮度 - 在这里要小心,在最大亮度下,较大的面板可能会消耗许多安培。确保您的电源能够胜任工作!
增益 - 提高麦克风的灵敏度,以适应更响亮或更安静的环境。
静噪 - 增加此值会限制将拾取的最安静的声音。如果您有一些背景噪音要消除,则很有用。 这些设置保存在 EEPROM 中,因此它们在重启后应保持不变。

【Arduino 动手做】ESP32 带有 INMP441 的 WS2812B 矩阵图1

【Arduino 动手做】ESP32 带有 INMP441 的 WS2812B 矩阵图2

【Arduino 动手做】ESP32 带有 INMP441 的 WS2812B 矩阵图3

【Arduino 动手做】ESP32 带有 INMP441 的 WS2812B 矩阵图4

【Arduino 动手做】ESP32 带有 INMP441 的 WS2812B 矩阵图5

【Arduino 动手做】ESP32 带有 INMP441 的 WS2812B 矩阵图6

驴友花雕  中级技神
 楼主|

发表于 4 小时前

【Arduino 动手做】ESP32 带有 INMP441 的 WS2812B 矩阵

项目代码

  1. /*
  2. * Web enabled FFT VU meter for a matrix, ESP32 and INMP441 digital mic.
  3. * The matrix width MUST be either 8 or a multiple of 16 but the height can
  4. * be any value. E.g. 8x8, 16x16, 8x10, 32x9 etc.
  5. *
  6. * We are using the LEDMatrx library for easy setup of a matrix with various
  7. * wiring options. Options are:
  8. *  HORIZONTAL_ZIGZAG_MATRIX
  9. *  HORIZONTAL_MATRIX
  10. *  VERTICAL_ZIGZAG_MATRIX
  11. *  VERTICAL_MATRIX
  12. * If your matrix has the first pixel somewhere other than the bottom left
  13. * (default) then you can reverse the X or Y axis by writing -M_WIDTH and /
  14. * or -M_HEIGHT in the cLEDMatrix initialisation.
  15. *
  16. * REQUIRED LIBRARIES
  17. * FastLED            Arduino libraries manager
  18. * ArduinoFFT         Arduino libraries manager
  19. * EEPROM             Built in
  20. * WiFi               Built in
  21. * AsyncTCP           https://github.com/me-no-dev/ESPAsyncWebServer
  22. * ESPAsyncWebServer  https://github.com/me-no-dev/AsyncTCP
  23. * LEDMatrix          https://github.com/AaronLiddiment/LEDMatrix
  24. * LEDText            https://github.com/AaronLiddiment/LEDText
  25. *
  26. * WIRING
  27. * LED data     D2 via 470R resistor
  28. * GND          GND
  29. * Vin          5V
  30. *
  31. * INMP441
  32. * VDD          3V3
  33. * GND          GND
  34. * L/R          GND
  35. * WS           D15
  36. * SCK          D14     
  37. * SD           D32
  38. *
  39. * REFERENCES
  40. * Main code      Scott Marley            https://www.youtube.com/c/ScottMarley
  41. * Web server     Random Nerd Tutorials   https://randomnerdtutorials.com/esp32-web-server-slider-pwm/
  42. *                                  and   https://randomnerdtutorials.com/esp32-websocket-server-arduino/
  43. * Audio and mic  Andrew Tuline et al     https://github.com/atuline/WLED
  44. */
  45. #include "audio_reactive.h"
  46. #include <FastLED.h>
  47. #include <LEDMatrix.h>
  48. #include <LEDText.h>
  49. #include <FontMatrise.h>
  50. #include <EEPROM.h>
  51. #define EEPROM_SIZE 5
  52. #define LED_PIN     2
  53. #define M_WIDTH     16
  54. #define M_HEIGHT    16
  55. #define NUM_LEDS    (M_WIDTH * M_HEIGHT)
  56. #define EEPROM_BRIGHTNESS   0
  57. #define EEPROM_GAIN         1
  58. #define EEPROM_SQUELCH      2
  59. #define EEPROM_PATTERN      3
  60. #define EEPROM_DISPLAY_TIME 4
  61. uint8_t numBands;
  62. uint8_t barWidth;
  63. uint8_t pattern;
  64. uint8_t brightness;
  65. uint16_t displayTime;
  66. bool autoChangePatterns = false;
  67. #include "web_server.h"
  68. cLEDMatrix<M_WIDTH, M_HEIGHT, HORIZONTAL_ZIGZAG_MATRIX> leds;
  69. cLEDText ScrollingMsg;
  70. uint8_t peak[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
  71. uint8_t prevFFTValue[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
  72. uint8_t barHeights[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
  73. // Colors and palettes
  74. DEFINE_GRADIENT_PALETTE( purple_gp ) {
  75.   0,   0, 212, 255,   //blue
  76. 255, 179,   0, 255 }; //purple
  77. DEFINE_GRADIENT_PALETTE( outrun_gp ) {
  78.   0, 141,   0, 100,   //purple
  79. 127, 255, 192,   0,   //yellow
  80. 255,   0,   5, 255 };  //blue
  81. DEFINE_GRADIENT_PALETTE( greenblue_gp ) {
  82.   0,   0, 255,  60,   //green
  83. 64,   0, 236, 255,   //cyan
  84. 128,   0,   5, 255,   //blue
  85. 192,   0, 236, 255,   //cyan
  86. 255,   0, 255,  60 }; //green
  87. DEFINE_GRADIENT_PALETTE( redyellow_gp ) {
  88.   0,   200, 200,  200,   //white
  89. 64,   255, 218,    0,   //yellow
  90. 128,   231,   0,    0,   //red
  91. 192,   255, 218,    0,   //yellow
  92. 255,   200, 200,  200 }; //white
  93. CRGBPalette16 purplePal = purple_gp;
  94. CRGBPalette16 outrunPal = outrun_gp;
  95. CRGBPalette16 greenbluePal = greenblue_gp;
  96. CRGBPalette16 heatPal = redyellow_gp;
  97. uint8_t colorTimer = 0;
  98. void setup() {
  99.   FastLED.addLeds<WS2812B, LED_PIN, GRB>(leds[0], NUM_LEDS);
  100.   Serial.begin(57600);
  101.   setupWebServer();
  102.   setupAudio();
  103.   if (M_WIDTH == 8) numBands = 8;
  104.   else numBands = 16;
  105.   barWidth = M_WIDTH / numBands;
  106.   
  107.   EEPROM.begin(EEPROM_SIZE);
  108.   
  109.   // It should not normally be possible to set the gain to 255
  110.   // If this has happened, the EEPROM has probably never been written to
  111.   // (new board?) so reset the values to something sane.
  112.   if (EEPROM.read(EEPROM_GAIN) == 255) {
  113.     EEPROM.write(EEPROM_BRIGHTNESS, 50);
  114.     EEPROM.write(EEPROM_GAIN, 0);
  115.     EEPROM.write(EEPROM_SQUELCH, 0);
  116.     EEPROM.write(EEPROM_PATTERN, 0);
  117.     EEPROM.write(EEPROM_DISPLAY_TIME, 10);
  118.     EEPROM.commit();
  119.   }
  120.   // Read saved values from EEPROM
  121.   FastLED.setBrightness( EEPROM.read(EEPROM_BRIGHTNESS));
  122.   brightness = FastLED.getBrightness();
  123.   gain = EEPROM.read(EEPROM_GAIN);
  124.   squelch = EEPROM.read(EEPROM_SQUELCH);
  125.   pattern = EEPROM.read(EEPROM_PATTERN);
  126.   displayTime = EEPROM.read(EEPROM_DISPLAY_TIME);
  127.   if (WiFi.status() == WL_CONNECTED) showIP();
  128. }  
  129. void loop() {
  130.   if (pattern != 5) FastLED.clear();
  131.   
  132.   uint8_t divisor = 1;                                                    // If 8 bands, we need to divide things by 2
  133.   if (numBands == 8) divisor = 2;                                         // and average each pair of bands together
  134.   
  135.   for (int i = 0; i < 16; i += divisor) {
  136.     uint8_t fftValue;
  137.    
  138.     if (numBands == 8) fftValue = (fftResult[i] + fftResult[i+1]) / 2;    // Average every two bands if numBands = 8
  139.     else fftValue = fftResult[i];
  140.     fftValue = ((prevFFTValue[i/divisor] * 3) + fftValue) / 4;            // Dirty rolling average between frames to reduce flicker
  141.     barHeights[i/divisor] = fftValue / (255 / M_HEIGHT);                  // Scale bar height
  142.    
  143.     if (barHeights[i/divisor] > peak[i/divisor])                          // Move peak up
  144.       peak[i/divisor] = min(M_HEIGHT, (int)barHeights[i/divisor]);
  145.       
  146.     prevFFTValue[i/divisor] = fftValue;                                   // Save prevFFTValue for averaging later
  147.    
  148.   }
  149.   // Draw the patterns
  150.   for (int band = 0; band < numBands; band++) {
  151.     drawPatterns(band);
  152.   }
  153.   // Decay peak
  154.   EVERY_N_MILLISECONDS(60) {
  155.     for (uint8_t band = 0; band < numBands; band++)
  156.       if (peak[band] > 0) peak[band] -= 1;
  157.   }
  158.   EVERY_N_SECONDS(30) {
  159.     // Save values in EEPROM. Will only be commited if values have changed.
  160.     EEPROM.write(EEPROM_BRIGHTNESS, brightness);
  161.     EEPROM.write(EEPROM_GAIN, gain);
  162.     EEPROM.write(EEPROM_SQUELCH, squelch);
  163.     EEPROM.write(EEPROM_PATTERN, pattern);
  164.     EEPROM.write(EEPROM_DISPLAY_TIME, displayTime);
  165.     EEPROM.commit();
  166.   }
  167.   
  168.   EVERY_N_SECONDS_I(timingObj, displayTime) {
  169.     timingObj.setPeriod(displayTime);
  170.     if (autoChangePatterns) pattern = (pattern + 1) % 6;
  171.   }
  172.   
  173.   FastLED.setBrightness(brightness);
  174.   FastLED.show();
  175.   ws.cleanupClients();
  176. }
  177. void drawPatterns(uint8_t band) {
  178.   
  179.   uint8_t barHeight = barHeights[band];
  180.   
  181.   // Draw bars
  182.   switch (pattern) {
  183.     case 0:
  184.       rainbowBars(band, barHeight);
  185.       break;
  186.     case 1:
  187.       // No bars on this one
  188.       break;
  189.     case 2:
  190.       purpleBars(band, barHeight);
  191.       break;
  192.     case 3:
  193.       centerBars(band, barHeight);
  194.       break;
  195.     case 4:
  196.       changingBars(band, barHeight);
  197.       EVERY_N_MILLISECONDS(10) { colorTimer++; }
  198.       break;
  199.     case 5:
  200.       createWaterfall(band);
  201.       EVERY_N_MILLISECONDS(30) { moveWaterfall(); }
  202.       break;
  203.   }
  204.   // Draw peaks
  205.   switch (pattern) {
  206.     case 0:
  207.       whitePeak(band);
  208.       break;
  209.     case 1:
  210.       outrunPeak(band);
  211.       break;
  212.     case 2:
  213.       whitePeak(band);
  214.       break;
  215.     case 3:
  216.       // No peaks
  217.       break;
  218.     case 4:
  219.       // No peaks
  220.       break;
  221.     case 5:
  222.       // No peaks
  223.       break;
  224.   }
  225. }
  226. void showIP(){
  227.   char strIP[16] = "               ";
  228.   IPAddress ip = WiFi.localIP();
  229.   ip.toString().toCharArray(strIP, 16);
  230.   Serial.println(strIP);
  231.   ScrollingMsg.SetFont(MatriseFontData);
  232.   ScrollingMsg.Init(&leds, leds.Width(), ScrollingMsg.FontHeight() + 1, 0, 0);
  233.   ScrollingMsg.SetText((unsigned char *)strIP, sizeof(strIP) - 1);
  234.   ScrollingMsg.SetTextColrOptions(COLR_RGB | COLR_SINGLE, 0xff, 0xff, 0xff);
  235.   ScrollingMsg.SetScrollDirection(SCROLL_LEFT);
  236.   ScrollingMsg.SetFrameRate(160 / M_WIDTH);       // Faster for larger matrices
  237.   while(ScrollingMsg.UpdateText() == 0) {
  238.     FastLED.show();  
  239.   }
  240. }
  241. //////////// Patterns ////////////
  242. void rainbowBars(uint8_t band, uint8_t barHeight) {
  243.   int xStart = barWidth * band;
  244.   for (int x = xStart; x < xStart + barWidth; x++) {
  245.     for (int y = 0; y <= barHeight; y++) {
  246.       leds(x,y) = CHSV((x / barWidth) * (255 / numBands), 255, 255);
  247.     }
  248.   }
  249. }
  250. void purpleBars(int band, int barHeight) {
  251.   int xStart = barWidth * band;
  252.   for (int x = xStart; x < xStart + barWidth; x++) {
  253.     for (int y = 0; y < barHeight; y++) {
  254.       leds(x,y) = ColorFromPalette(purplePal, y * (255 / barHeight));
  255.     }
  256.   }
  257. }
  258. void changingBars(int band, int barHeight) {
  259.   int xStart = barWidth * band;
  260.   for (int x = xStart; x < xStart + barWidth; x++) {
  261.     for (int y = 0; y < barHeight; y++) {
  262.       leds(x,y) = CHSV(y * (255 / M_HEIGHT) + colorTimer, 255, 255);
  263.     }
  264.   }
  265. }
  266. void centerBars(int band, int barHeight) {
  267.   int xStart = barWidth * band;
  268.   for (int x = xStart; x < xStart + barWidth; x++) {
  269.     if (barHeight % 2 == 0) barHeight--;
  270.     int yStart = ((M_HEIGHT - barHeight) / 2 );
  271.     for (int y = yStart; y <= (yStart + barHeight); y++) {
  272.       int colorIndex = constrain((y - yStart) * (255 / barHeight), 0, 255);
  273.       leds(x,y) = ColorFromPalette(heatPal, colorIndex);
  274.     }
  275.   }
  276. }
  277. void whitePeak(int band) {
  278.   int xStart = barWidth * band;
  279.   int peakHeight = peak[band];
  280.   for (int x = xStart; x < xStart + barWidth; x++) {
  281.     leds(x,peakHeight) = CRGB::White;
  282.   }
  283. }
  284. void outrunPeak(int band) {
  285.   int xStart = barWidth * band;
  286.   int peakHeight = peak[band];
  287.   for (int x = xStart; x < xStart + barWidth; x++) {
  288.     leds(x,peakHeight) = ColorFromPalette(outrunPal, peakHeight * (255 / M_HEIGHT));
  289.   }
  290. }
  291. void createWaterfall(int band) {
  292.   int xStart = barWidth * band;
  293.   // Draw bottom line
  294.   for (int x = xStart; x < xStart + barWidth; x++) {
  295.     leds(x,0) = CHSV(constrain(map(fftResult[band],0,254,160,0),0,160), 255, 255);
  296.   }
  297. }
  298. void moveWaterfall() {
  299.   // Move screen up starting at 2nd row from top
  300.   for (int y = M_HEIGHT - 2; y >= 0; y--) {
  301.     for (int x = 0; x < M_WIDTH; x++) {
  302.       leds(x,y+1) = leds(x,y);
  303.     }
  304.   }
  305. }
复制代码


回复

使用道具 举报

驴友花雕  中级技神
 楼主|

发表于 4 小时前

【Arduino 动手做】ESP32 带有 INMP441 的 WS2812B 矩阵

【Arduino 动手做】可 3D 打印的 ESP32 供电 VU 显示屏,带有 INMP441 数字麦克风和 WS2812B 矩阵
项目链接:https://github.com/s-marley/ESP32-INMP441-Matrix-VU
项目作者:S-马利

项目视频 :https://www.youtube.com/watch?v=9PEjvFkdpIE&t=14s
项目代码:https://github.com/s-marley/ESP3 ... /main/INMP441Matrix
3D 文件:https://github.com/s-marley/ESP3 ... ee/main/3D%20Models
WLED Sound Reactive:https://github.com/atuline
【Arduino 动手做】ESP32 带有 INMP441 的 WS2812B 矩阵图1

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
[[wsData.name]]

硬件清单

  • [[d.name]]
btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4 备案 沪公网安备31011502402448

© 2013-2025 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail