PlatformIO+ESP32S3学习:驱动WS2812矩阵彩灯显示FFT音律拾音灯

本文继承自之前的彩灯驱动文章:https://blog.csdn.net/qq_51930953/article/details/140736628

本文完成的效果:

在这里插入图片描述

1. 硬件准备


1.1. WS2812矩阵彩灯

在这里插入图片描述
购买地址:WS2812B全彩软像素屏8X8 8X32 16X16幻彩5V显示可编程像素软屏

1.2. 麦克风模块

在这里插入图片描述

购买地址:GY-MAX4466 声音传感器模块 MAX4466麦克风前置放大器 提供程序

1.3. ESP32S3开发板

在这里插入图片描述

购买地址:立创·ESP32S3R8N8 开发板

2. 工程创建


在VSCode中打开PlatformIO扩展创建工程。

在这里插入图片描述

设置工程向导

在这里插入图片描述
在这里插入图片描述
等待创建完成。

在这里插入图片描述

3. 安装驱动库


创建完成之后,我们在VSCode中打开我们刚才创建的工程文件夹。

在这里插入图片描述
在VSCode中回到PlatformIO的主页,准备给工程安装驱动库。

在这里插入图片描述
在这里插入图片描述
最底层的驱动,需要分别安装三个库:

  1. 搜索Adafruit NeoMatrix,安装来自AdafruitAdafruit NeoMatrix库。
    在这里插入图片描述
  2. 搜索Adafruit GFX Library,安装来自AdafruitAdafruit GFX Library库。
    在这里插入图片描述
  3. 搜索arduinoFFT,安装来自Enrique CondesarduinoFFT库。

在这里插入图片描述

将它们都安装到我们的工程当中。安装步骤以下以Adafruit GFX Library库为例:

在这里插入图片描述
在这里插入图片描述

都安装完成之后,打开platformio.ini文件,可以看到已经安装上了三个驱动库。

在这里插入图片描述

4. 编辑代码


在工程下的include文件夹下新建一个 musicfft.h文件。

在这里插入图片描述
接下来往 musicfft.h 文件写入代码:

#include <Adafruit_NeoMatrix.h>
#include <arduinoFFT.h>#define CHANNEL 1  //音频输入引脚
#define xres 32   
#define yres 8            const uint16_t samples = 64; //采样点数,必须为2的整数次幂
const double samplingFrequency = 4000; //Hz, 声音采样频率unsigned int sampling_period_us;
unsigned long microseconds;
unsigned long lastTime = 0;
unsigned long fallingTime = 0;double vReal[samples]; //FFT采样输入样本数组
double vImag[samples]; //FFT运算输出数组
int freq_gain2[xres] = {30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30};
int Intensity[xres] = {}; // initialize Frequency Intensity to zero
int FallingPoint[xres] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int Displacement = 1;          // Create LED Object//ArduinoFFT FFT = ArduinoFFT(); //创建FFT对象
ArduinoFFT<double> FFT = ArduinoFFT<double>(vReal, vImag, samples, samplingFrequency);void getSamples(){microseconds = micros();for(int i = 0; i < samples; i++){vReal[i] = analogRead(CHANNEL);vImag[i] = 0;microseconds += sampling_period_us;}bool reduce = false;if ((millis() - lastTime) > 16) {lastTime = millis();reduce = true;}//FFTFFT.windowing(vReal, 1, FFT_WIN_TYP_HAMMING, FFT_FORWARD);FFT.compute(vReal, vImag, samples, FFT_FORWARD);FFT.complexToMagnitude(vReal, vImag, samples);//Update Intensity Array  int t = 16;for(int i = t; i < (xres*Displacement)+t; i+=Displacement){vReal[i] = constrain(vReal[i], 0 ,3596);            // set max value for input datavReal[i] = map(vReal[i], freq_gain2[(i-t)/Displacement], 1548, 0, yres);        // map data to fit our displayif(reduce){Intensity[(i-t)/Displacement] --;                      // Decrease displayed value}if (vReal[i] > Intensity[(i-t)/Displacement])          // Match displayed value to measured valueIntensity[(i-t)/Displacement] = vReal[i];}
}void drawYLine(Adafruit_NeoMatrix *matrix, int16_t x, int16_t y, int16_t h, int16_t c){for(int i=y;i<y+h;i++){matrix->drawPixel(x,7 - i,c);}
}uint16_t hsv2rgb2(Adafruit_NeoMatrix *matrix, uint16_t hue, uint8_t saturation, uint8_t value)
{uint8_t red = 0;uint8_t green = 0;uint8_t blue = 0;uint16_t hi = (hue / 60) % 6;uint16_t F = 100 * hue / 60 - 100 * hi;uint16_t P = value * (100 - saturation) / 100;uint16_t Q = value * (10000 - F * saturation) / 10000;uint16_t T = value * (10000 - saturation * (100 - F)) / 10000;switch (hi){case 0:red = value;green = T;blue = P;break;case 1:red = Q;green = value;blue = P;break;case 2:red = P;green = value;blue = T;break;case 3:red = P;green = Q;blue = value;break;case 4:red = T;green = P;blue = value;break;case 5:red = value;green = P;blue = Q;break;default:return matrix->Color(255, 0, 0);}red = red * 255 / 100;green = green * 255 / 100;blue = blue * 255 / 100;return matrix->Color(red, green, blue);
}void displayUpdate(Adafruit_NeoMatrix *matrix, int displayPattern){int color = 0;switch(displayPattern){case 0:for(int i = 0; i < xres; i++){drawYLine(matrix,i,yres-Intensity[i],Intensity[i],hsv2rgb2(matrix, color, 80, 80 ));drawYLine(matrix,i,0,yres-1-Intensity[i],hsv2rgb2(matrix, color, 80, 80 ));color += 360/xres;}break;case 1:if ((millis() - fallingTime) > 130) {for(int i = 0; i < xres; i++){if(FallingPoint[i]>0){FallingPoint[i]--;}}fallingTime = millis();}for(int i = 0; i < xres; i++){drawYLine(matrix,i,0,yres-1,matrix->Color(0,0,0));if(FallingPoint[i]<Intensity[i]){FallingPoint[i] = Intensity[i];}drawYLine(matrix,i,yres-Intensity[i]+1,Intensity[i]-1,hsv2rgb2(matrix, color, 80, 80 ));if(FallingPoint[i]>0){matrix->drawPixel(i,yres-FallingPoint[i],matrix->Color(255,255,255));}color += 360/xres;}break;case 2:for(int i = 0; i < xres; i++){drawYLine(matrix,i,0,yres,matrix->Color(0,0,0));drawYLine(matrix,i,0,Intensity[i]+1,hsv2rgb2(matrix, color, 80, 80 ));color += 360/xres;}break;}
}

接下来在 main.cpp中编写以下代码:

#include <Arduino.h>
#include <Adafruit_NeoMatrix.h> //点亮LED矩阵需要的库
#include "musicfft.h" //音乐频谱库//像素阵列定义
#define kMatrixWidth   32             //宽度
#define kMatrixHeight  8              //高度
#define BRIGHTNESS     10            //默认亮度 0-255
#define BRIGHTNESS_INTERVAL 30        //亮度调节间隔
#define LED_PIN        8              //像素阵列引脚Adafruit_NeoMatrix *matrix;     //LED矩阵类指针//像素矩阵初始化
void InitLED_Matrix(void)
{//设置像素矩阵的方向以及排列方式matrix = new Adafruit_NeoMatrix(32, 8, LED_PIN, NEO_MATRIX_TOP + NEO_MATRIX_LEFT+NEO_MATRIX_COLUMNS +  NEO_MATRIX_ZIGZAG,NEO_GRB + NEO_KHZ800);matrix->setTextWrap(false);       //设置文字是否自动换行matrix->clear();                  //清除当前显示内容matrix->setBrightness(BRIGHTNESS);//设置亮度
}void showFFT(void)
{//进行采样getSamples();//更新频谱柱displayUpdate(matrix, 2);
}void setup() 
{//初始化LED矩阵显示InitLED_Matrix();    
}void loop() 
{matrix->clear();showFFT();matrix->show();delay(50);
}

5. 硬件连接


在这里插入图片描述

6. 代码验证


代码编写完成并且接好线之后,将ESP32S3开发板接入电脑。我当前的开发板上是CH340K的驱动,故我这里选择COM3端口。

在这里插入图片描述
编译并下载到开发板中。

在这里插入图片描述

实物显示如下:

使用黑色亚克力面板+白纸格挡光线显示

叠层从上到下是这样的:黑色亚克力面板 -> 白纸 -> LED矩阵

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/50083.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Ip2region - 基于xdb离线库的Java IP查询工具提供给脚本调用

文章目录 Pre效果实现git clone编译测试程序将ip2region.xdb放到指定目录使用改进最终效果 Pre OpenSource - Ip2region 离线IP地址定位库和IP定位数据管理框架 Ip2region - xdb java 查询客户端实现 效果 最终效果 实现 git clone git clone https://github.com/lionsou…

YOLOV8源码解读-C2f模块-以及总结c2模块、Bottleneck

c2f模块是对c2模块的改进 c2模块图解解读 先给出YOLOV8中卷积的定义模块一键三连-卷积-BN-激活函数 def autopad(k, pNone, d1): # kernel, padding, dilation"""Pad to same shape outputs."""if d > 1:k d * (k - 1) 1 if isinstance…

Linux:进程信号(二.信号的保存与处理、递达、volatile关键字、SIGCHLD信号)

上次介绍了&#xff1a;(Linux&#xff1a;进程信号&#xff08;一.认识信号、信号的产生及深层理解、Term与Core&#xff09;)[https://blog.csdn.net/qq_74415153/article/details/140624810] 文章目录 1.信号保存1.1递达、未决、阻塞等概念1.2再次理解信号产生与保存1.3信号…

Pytorch深度学习实践(9)卷积神经网络

卷积神经网络 全连接神经网络 神经网络中全部是线性模型&#xff0c;是由线性模型串联起来的 全连接网络又叫全连接层 卷积神经网络 在全连接神经网络中&#xff0c;由于输入必须是一维向量&#xff0c;因此在处理图像时必须要对图像矩阵进行拉伸成一维的形式&#xff0c;…

【算法】布隆过滤器

一、引言 在现实世界的计算机科学问题中&#xff0c;我们经常需要判断一个元素是否属于一个集合。传统的做法是使用哈希表或者直接遍历集合&#xff0c;但这些方法在数据量较大时效率低下。布隆过滤器&#xff08;Bloom Filter&#xff09;是一种空间效率极高的概率型数据结构&…

【NPU 系列专栏 2.8 -- 特斯拉 FDS NPU 详细介绍 】

请阅读【嵌入式及芯片开发学必备专栏】 文章目录 特斯拉 NPU 芯片介绍FSD(Full Self-Driving)芯片 简介FSD主要特点FSD 详细参数FSD 应用场景特斯拉 Hardware 3.0 芯片 简介Hardware 3.0主要特点Hardware 3.0 详细参数Hardware 3.0应用场景特斯拉自研 NPU 的优势优化设计高度…

【数学建模】——matplotlib简单应用

目录 1.绘制带有中文标签和图例的正弦和余弦曲线 2. 绘制散点图 1.修改散点符号与大小 2.修改颜色 3.绘制饼状图 4.在图例中显示公式 5.多个图形单独显示 6.绘制有描边和填充效果的柱状图 7.使用雷达图展示学生成绩 8.绘制三维曲面 9.绘制三维曲线 10.设置…

定制化即时通讯企业级移动门户解决方案,WorkPlus IM系统让工作事半功倍

随着移动设备的普及和移动办公的兴起&#xff0c;企业越来越需要一种定制化的即时通讯企业级移动门户解决方案来提高工作效率和团队协作效果。WorkPlus IM系统作为一种创新的解决方案&#xff0c;为企业提供了一个个性化定制、高度安全和高效便捷的移动门户平台。本文将对定制化…

BFF:优化前后端协作设计模式

BFF&#xff1a;优化前后端协作设计模式 BFF是什么 BFF即 Backends For Frontends (服务于前端的后端)。是一种介于前端和后端之间一种重要的通信设计模式。它旨在解决前端与后端协作中的复杂性问题。 背景 行业背景&#xff1a;传统前端应用&#xff08;如Web应用、移动应…

微服务-MybatisPlus下

微服务-MybatisPlus下 文章目录 微服务-MybatisPlus下1 MybatisPlus扩展功能1.1 代码生成1.2 静态工具1.3 逻辑删除1.4 枚举处理器1.5 JSON处理器**1.5.1.定义实体****1.5.2.使用类型处理器** **1.6 配置加密&#xff08;选学&#xff09;**1.6.1.生成秘钥**1.6.2.修改配置****…

网络安全防御【IPsec VPN搭建】

目录 一、实验拓扑图 二、实验要求 三、实验思路 四、实验步骤&#xff1a; 修改双机热备的为主备模式&#xff1a; 2、配置交换机LSW6新增的配置&#xff1a; 3、防火墙&#xff08;FW4&#xff09;做相关的基础配置&#xff1a; 4、搭建IPsec VPN通道 &#xff08;1…

Java代码基础算法练习-求杨辉三角第n行的值-2024.07.27

任务描述&#xff1a; 给定一个非负整数n&#xff0c;生成「杨辉三角」的第n行。&#xff08;1<n<10&#xff09;在「杨辉三角」中&#xff0c;每 个数是它左上方和右上方的数的和。 &#xff08;提示&#xff0c;第一列数值为1&#xff0c;如数组下标用i,j表示&#xf…

独占电脑资源来执行一个应用

1. 背景 在人工智能时代&#xff0c;随着神经网络的发展&#xff0c;训练人工智能模型需要越来越多的硬件资源&#xff0c;例如&#xff0c;利用10万条棋局数据、使用一台PC电脑、完整地训练一次确定性神经网络五子棋模型&#xff0c;需要花费一年半的时间。随着训练数据的增长…

APP逆向 day23司小宝逆向

一.前言 今天也是讲最后一个基础知识点了&#xff0c;ptrace占坑&#xff0c;这个也算是一个坑&#xff0c;今天通过这个案例和大家讲一下&#xff0c;今天这个案例我们来整验证码登录&#xff0c;版本选择4.7.8 二.抓包分析 抓包发现&#xff0c;请求头里的东西通过改包发现…

Spring Boot:图书管理系统(一)

1.编写用户登录接口 代码&#xff1a; package com.example.demo;import jakarta.servlet.http.HttpSession; import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotatio…

技术成神之路:设计模式(九)备忘录模式

介绍 备忘录模式&#xff08;Memento Pattern&#xff09;是一种行为设计模式&#xff0c;它允许在不破坏封装性的前提下捕获和恢复对象的内部状态。通过备忘录模式&#xff0c;可以在程序运行过程中保存和恢复对象的某个状态&#xff0c;从而实现“撤销”等功能。 1.定义 备忘…

【BUG】已解决:UnicodeDecodeError: ‘utf-8’ codec can’t decode bytes in position 10

UnicodeDecodeError: ‘utf-8’ codec can’t decode bytes in position 10 目录 UnicodeDecodeError: ‘utf-8’ codec can’t decode bytes in position 10 【常见模块错误】 【解决方案】 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 欢迎来到我的主页&#x…

使用python内置的虚拟环境

在一台机器上安装了太多的第三方python库&#xff0c;它们依赖相同的库可能版本不同&#xff0c;就会造成某些第三方库崩溃&#xff0c;之前可以使用的库可能就会坏掉不能用了&#xff0c;所以可以使用虚拟环境运行不同的程序&#xff0c;python有内置的虚拟环境&#xff1b; …

前端八股文 promise async await 的理解

promise是什么 Promise 是异步编程的一种解决方案&#xff0c;比传统的解决方案——回调函数和事件——更合理和更强大。 目的 解析 吴优编程 &#xff08;解决异步编程中的嵌套问题的&#xff0c;将嵌套的格式 用peomise 写成同步&#xff09; promise.then() 是成功后继…

Cocos Creator2D游戏开发(4)-飞机大战(2)-编辑器界面

编辑器几个重要板块 参考: https://docs.cocos.com/creator/3.8/manual/zh/editor/ (1) 场景编辑器: 仅看2D视图: 按钮作用依次是: 平移, 旋转,缩放,矩形变换,增量吸附工具,最后三个,前俩是变换工具,最后一个是布局组件 矩形变换: 中心点和锚点切换 以后用到慢慢整吧! (2)层…