esp32cmini SK6812 2个方式
1
#include <SPI.h>
// ESP32-C系列的SPI引脚
#define MOSI_PIN 7 // ESP32-C3/C6的SPI MOSI引脚
#define NUM_LEDS 30 // LED灯带实际LED数量 - 确保与实际数量匹配!
#define SPI_CLOCK 10000000 // SPI时钟频率
// 颜色结构体
struct CRGB {
uint8_t r;
uint8_t g;
uint8_t b;
};
// 定义常用颜色
namespace Colors {
const CRGB Black = {0, 0, 0};
const CRGB White = {255, 255, 255};
const CRGB Red = {255, 0, 0};
const CRGB Green = {0, 255, 0};
const CRGB Blue = {0, 0, 255};
}
CRGB leds[NUM_LEDS];
uint8_t brightness = 20; // 亮度 (0-255)
// SK6812协议需要精确的时序
// T0H: 0码高电平时间 ~0.3us
// T0L: 0码低电平时间 ~0.9us
// T1H: 1码高电平时间 ~0.6us
// T1L: 1码低电平时间 ~0.6us
// RES: 重置时间 >80us
// 根据SPI时钟调整字节模式
// 每个位需要至少3个字节来正确表示时序
#define BYTES_PER_BIT 3
#define BYTES_PER_LED (3 * 8 * BYTES_PER_BIT) // 3颜色 * 8位/颜色 * 字节/位
uint8_t spiBuffer[NUM_LEDS * BYTES_PER_LED + 100]; // 添加一些额外的缓冲空间
// 在ESP32上初始化SPI
SPIClass * vspi = NULL;
void setup() {
// 初始化串口调试
Serial.begin(115200);
Serial.println("ESP32-C SPI SK6812控制初始化开始");
// 初始化SPI
vspi = new SPIClass(SPI);
vspi->begin(MOSI_PIN);
// 设置SPI属性
vspi->beginTransaction(SPISettings(SPI_CLOCK, MSBFIRST, SPI_MODE0));
// 测试模式 - 打印灯带配置
Serial.print("控制 ");
Serial.print(NUM_LEDS);
Serial.println(" 个LED");
// 初始化LED为关闭状态
clearAll();
delay(500);
// 测试所有LED - 确认连接
testAllLeds();
}
void loop() {
// 从头到尾逐个点亮
sequentialLightUp();
// 从尾到头逐个熄灭
sequentialLightDown();
}
// 测试所有LED - 确认连接和灯带长度
void testAllLeds() {
// 全部设为红色
for(int i = 0; i < NUM_LEDS; i++) {
leds[i] = Colors::Red;
}
show();
delay(500);
// 全部设为绿色
for(int i = 0; i < NUM_LEDS; i++) {
leds[i] = Colors::Green;
}
show();
delay(500);
// 全部设为蓝色
for(int i = 0; i < NUM_LEDS; i++) {
leds[i] = Colors::Blue;
}
show();
delay(500);
// 全部熄灭
clearAll();
delay(500);
}
// 将HSV颜色转换为RGB
CRGB hsv2rgb(uint8_t h, uint8_t s, uint8_t v) {
CRGB rgb;
// 实现HSV到RGB的转换
uint8_t region, remainder, p, q, t;
if (s == 0) {
rgb.r = v;
rgb.g = v;
rgb.b = v;
return rgb;
}
region = h / 43;
remainder = (h - (region * 43)) * 6;
p = (v * (255 - s)) >> 8;
q = (v * (255 - ((s * remainder) >> 8))) >> 8;
t = (v * (255 - ((s * (255 - remainder)) >> 8))) >> 8;
switch (region) {
case 0:
rgb.r = v; rgb.g = t; rgb.b = p;
break;
case 1:
rgb.r = q; rgb.g = v; rgb.b = p;
break;
case 2:
rgb.r = p; rgb.g = v; rgb.b = t;
break;
case 3:
rgb.r = p; rgb.g = q; rgb.b = v;
break;
case 4:
rgb.r = t; rgb.g = p; rgb.b = v;
break;
default:
rgb.r = v; rgb.g = p; rgb.b = q;
break;
}
return rgb;
}
void sequentialLightUp() {
// 清除所有LED
clearAll();
// 从第一个LED开始逐个点亮
for(int i = 0; i < NUM_LEDS; i++) {
// 选择不同的颜色效果
leds[i] = hsv2rgb(i * 10, 255, 255); // 渐变色相
// 更新灯带显示
show();
delay(50); // 控制点亮速度
}
}
void sequentialLightDown() {
// 从最后一个LED开始逐个熄灭
for(int i = NUM_LEDS - 1; i >= 0; i--) {
leds[i] = Colors::Black; // 熄灭
// 更新灯带显示
show();
delay(50); // 控制熄灭速度
}
}
// 清除所有LED
void clearAll() {
for(int i = 0; i < NUM_LEDS; i++) {
leds[i] = Colors::Black;
}
show();
}
// 重新优化的代码,确保正确的位时序
void show() {
// 准备SPI数据缓冲区
memset(spiBuffer, 0, sizeof(spiBuffer)); // 先清空缓冲区
prepareSPIBuffer();
// 发送数据前输出调试信息
Serial.println("发送LED数据...");
// 通过SPI发送数据
//vspi->transferBytes(spiBuffer, nullptr, NUM_LEDS * BYTES_PER_LED);
vspi->transferBytes(spiBuffer, nullptr, NUM_LEDS * 3 * 8);
// vspi->transferBytes(spiBuffer, nullptr, NUM_LEDS);
// 添加重置时间
delayMicroseconds(300); // >280μs的LED重置时间
}
// 更精确的SPI缓冲区准备
void prepareSPIBuffer() {
int bufferPos = 0;
// 处理每个LED的数据
for(int i = 0; i < NUM_LEDS; i++) {
// 应用亮度
uint8_t r = (leds[i].r * brightness) / 255;
uint8_t g = (leds[i].g * brightness) / 255;
uint8_t b = (leds[i].b * brightness) / 255;
// SK6812使用GRB顺序
// 转换每个颜色分量为SPI数据
convertByte(bufferPos, g); // 绿色
bufferPos += 8 * BYTES_PER_BIT;
convertByte(bufferPos, r); // 红色
bufferPos += 8 * BYTES_PER_BIT;
convertByte(bufferPos, b); // 蓝色
bufferPos += 8 * BYTES_PER_BIT;
}
}
// 优化的位编码 - 使用更少的字节
void convertByte(int offset, uint8_t byte) {
for(int i = 0; i < 8; i++) { // 每个字节8位
// 获取最高位
bool bit = byte & 0x80;
byte <<= 1;
// 根据SK6812的协议,为SPI准备数据
// 调整以下值以匹配您的SPI时钟和SK6812的时序需求
if(bit) {
// 1码 (T1H ~ 0.6us, T1L ~ 0.6us)
spiBuffer[offset + 0] = 0xF8; // 11111000
spiBuffer[offset + 1] = 0x00; // 00000000
spiBuffer[offset + 2] = 0x00; // 00000000
} else {
// 0码 (T0H ~ 0.3us, T0L ~ 0.9us)
spiBuffer[offset + 0] = 0xC0; // 11000000
spiBuffer[offset + 1] = 0x00; // 00000000
spiBuffer[offset + 2] = 0x00; // 00000000
}
offset += BYTES_PER_BIT; // 每位使用BYTES_PER_BIT个字节表示
}
}
2
#include <FastLED.h>
#define LED_PIN 6 // 数据引脚
#define NUM_LEDS 30 // LED数量
#define LED_TYPE SK6812 // LED类型
#define COLOR_ORDER GRB // 颜色顺序
CRGB leds[NUM_LEDS];
void setup() {
FastLED.addLeds<LED_TYPE, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS);
FastLED.setBrightness(50); // 设置亮度
}
void loop() {
// 从头到尾逐个点亮
sequentialLightUp();
// 从尾到头逐个熄灭
sequentialLightDown();
}
void sequentialLightUp() {
// 清除所有LED
FastLED.clear();
// 从第一个LED开始逐个点亮
for(int i = 0; i < NUM_LEDS; i++) {
// 选择不同的颜色效果
leds[i] = CHSV(i * 10, 255, 255); // 渐变色相
FastLED.show();
delay(50); // 控制点亮速度
}
}
void sequentialLightDown() {
// 从最后一个LED开始逐个熄灭
for(int i = NUM_LEDS - 1; i >= 0; i--) {
leds[i] = CRGB::Black; // 熄灭
FastLED.show();
delay(50); // 控制熄灭速度
}
}
// 可选:添加更多炫酷效果
void rainbowEffect() {
static uint8_t hue = 0;
for(int i = 0; i < NUM_LEDS; i++) {
leds[i] = CHSV(hue + (i * 10), 255, 255);
}
EVERY_N_MILLISECONDS(100) {
hue++;
}
FastLED.show();
}
相关文章:
esp32cmini SK6812 2个方式
1 #include <SPI.h> // ESP32-C系列的SPI引脚 #define MOSI_PIN 7 // ESP32-C3/C6的SPI MOSI引脚 #define NUM_LEDS 30 // LED灯带实际LED数量 - 确保与实际数量匹配! #define SPI_CLOCK 10000000 // SPI时钟频率 // 颜色结构体 st…...

【数据集】30 m地表温度LST数据集
目录 数据概述🔧研究目标与意义🧠 算法核心组成1. 地表比辐射率(LSE)估算2. 大气校正(Atmospheric Correction)LST反演流程图📊 精度验证与评估结果参考《Generating the 30-m land surface temperature product over continental China and USA from Landsat 5/7/8 …...

【CATIA的二次开发07】草图编辑器对象结构及应用
【CATIA的二次开发07】草图编辑器对象结构及应用 草图编辑器(SketchEditor)是用于创建和编辑2D草图的核心对象。其对象结构遵循CATIA的层级关系,以下是详细说明及代码示例: 一、核心对象结构图 Application │ └─ Documents│└─ Document (.CATPart)│└─ Part│└─…...

IT | 词汇科普手册Ⅱ
目录 1.报文(Message) 2.Token(令牌) Token vs. Cookie Token vs. Key "碰一碰"支付 3.NFC 4.Nginx 5.JSON 6.前置机 前置机vs.Nginx反向代理 以PDA、WMS举例前置机场景 7.RabbitMQ 核心功能 1.报文(Message) 报文(Message)是系统或组件之…...

【 java 基础问题 第一篇 】
目录 1.概念 1.1.java的特定有哪些? 1.2.java有哪些优势哪些劣势? 1.3.java为什么可以跨平台? 1.4JVM,JDK,JRE它们有什么区别? 1.5.编译型语言与解释型语言的区别? 2.数据类型 2.1.long与int类型可以互转吗&…...
以前端的角度理解 Kubernetes(K8s)
作为一名前端开发者,我们每天都在与 React、Vue、Webpack 等工具打交道,而 Kubernetes(K8s)听起来更像是后端或运维的“专属领域”。但实际上,K8s 的核心思想和前端开发中的某些模式高度相似。那么咱们用熟悉的类比帮助…...

自用git记录
像重复做自己在网上找的练习题,这种类型的git仓库管理,一般会用到以下命令: git revert a1b2c3 很复杂的git历史变成简单git历史 能用git rebase -i HEAD~5^这种命令解决,就最好(IDEA还带GUI,很方便&…...
pyhton基础【2】基本语法
一. 注释 单行注释 以#开头,#右边的所有的内容当做说明,起辅助说明作用 # 我是一个单行注释 print(Hello) 多行注释 """ 在三引号中的注释被称之为多行注释 可以写很多行的功能说明 """ 二. 交互模式 终端输入代码…...
python数据结构-列表详解
Python中的列表(List)是一种序列类型的数据结构,它支持元素的动态添加和删除,可以容纳任意类型的数据,包括数字、字符串、甚至是其他列表或其他复杂数据结构。列表因其灵活性和广泛的应用场景,成为Python中最常用的数据结构之一。…...

本地环境下 前端突然端口占用问题 针对vscode
1.问题背景 本地运行前端代码,虚拟机中使用nginx反向代理。两者都使用vscode进行开发。后端使用vscode远程连接。在前端发起一次接口请求后,后端会产生新的监听端口,出现如下图的提示情况。随后前端刷新,甚至无法正常显示界面。 …...
flutter 项目调试、flutter run --debug调试模式 devtools界面说明
Flutter DevTools 网页界面说明 1. 顶部导航栏 Inspector:查看和调试 Widget 树,实时定位 UI 问题。Performance-- 性能分析面板,查看帧率、CPU 和 GPU 使用情况,识别卡顿和性能瓶颈。Memory-- 内存使用和对象分配分析ÿ…...
在局域网(LAN)中查看设备的 IP 地址
在局域网(LAN)中查看设备的 IP 地址,可以使用以下几种方法: 方法 1:使用 ipconfig(Windows) 1. 打开 CMD: 按 Win R,输入 cmd,回车。 2. 输入命令&#…...
Axure 基本用法学习笔记
一、元件操作基础 1. 可见性控制 隐藏/显示:可以设置元件的可见性,使元件在特定条件下隐藏或可见 应用场景:创建动态交互效果,如点击按钮显示隐藏内容 2. 层级管理 层级概念:元件有上下层关系,上层元件…...
使用 Hyperlane 实现 WebSocket广播
使用 Hyperlane 实现 WebSocket广播 hyperlane 框架原生支持 WebSocket 协议,开发者无需关心协议升级过程,即可通过统一接口处理 WebSocket 请求。本文将介绍如何使用 hyperlane 实现服务端的单点发送与广播发送功能,以及如何配套实现一个简…...
SQL每日一题(5)
前言:五更!五更琉璃!不对!是,五更佩可! 原始数据: new_hires reasonother_column1other_column2校园招聘信息 11社会招聘信息 22内部推荐信息 33猎头推荐信息 44校园招聘信息 55社会招聘信息…...
git提交通用规范
提交类型 类型说明feat新增功能或特性fix修复Bugdocs文档更新(README、CHANGELOG、注释等)style代码样式调整(空格、分号、格式等,不改变逻辑)refactor代码重构(既非新增功能,也非修复Bug的代码…...

C++ - 仿 RabbitMQ 实现消息队列(3)(详解使用muduo库)
C - 仿 RabbitMQ 实现消息队列(3)(详解使用muduo库) muduo库的基层原理核心概念总结:通俗例子:餐厅模型优势体现典型场景 muduo库中的主要类EventloopMuduo 的 EventLoop 核心解析1. 核心机制:事…...

docker部署XTdrone
目录 一、前置准备 二、依赖安装 三、ros安装 四、gazebo安装 五、mavros安装 六、PX4的配置 七、Xtdrone源码下载 八、xtdrone与gazebo(实际上应该是第四步之后做这件事) 九、键盘控制 参考链接:仿真平台基础配置 语雀 一、前置准…...

图解 | 大模型智能体LLM Agents
文章目录 正文1. 存储 Memory1.1 短期记忆 Short-Term Memory1.1.1 模型的上下文窗口1.1.2 对话历史1.1.3 总结对话历史 1.2 长期记忆Long-term Memory 2. 工具Tools2.1 工具的类型2.2 function calling2.3 Toolformer2.3.1 大模型调研工具的过程2.3.2 生成工具调用数据集 2.4 …...
Lambda表达式的方法引用详解
Lambda表达式的方法引用详解 1. 方法引用的概念与作用 定义:方法引用(Method Reference)是Lambda表达式的一种简化写法,允许直接通过方法名引用已有的方法。核心目的:减少冗余代码,提升可读性,尤其在Lambda仅调用一个现有方法时。语法符号:双冒号 ::。2. 方法引用的四种…...

echarts设置标线和最大值最小值
echarts设置标线和最大值最小值 基本ECharts图表初始化配置 设置动态的y轴范围(min/max值) 通过markPoint标记最大值和最小值点 使用markLine添加水平参考线 配置双y轴图表 自定义标记点和线的样式(颜色、符号等) 响应式调整图表大…...
gcc编译构建流程
0. 项目结构 /home/pi/test/ ├── src/ │ ├── add/ │ │ ├── add.cpp │ │ ├── add.h │ └── log/ │ ├── log.cpp │ ├── log.h │ ├── data.h ├── main.cppmain.cpp代码 // main.cpp #include "log.h&quo…...

Maven 中央仓库操作指南
Maven 中央仓库操作指南 登录注册 在 Maven Central 登录(注册)账号。 添加命名空间 注册 通过右上角用户菜单跳转到命名空间管理页面: 注册命名空间: 填入你拥有的域名并注册: 刚提交的命名空间状态是Unverified…...

BUUCTF——RCE ME
BUUCTF——RCE ME 进入靶场 <?php error_reporting(0); if(isset($_GET[code])){$code$_GET[code];if(strlen($code)>40){die("This is too Long.");}if(preg_match("/[A-Za-z0-9]/",$code)){die("NO.");}eval($code); } else{highlight…...
clickhouse-1-特性及docker化安装
clickhouse-1-特性及docker化安装 1.核心特性1.1.列式存储与高效压缩1.2.向量化执行引擎1.3.分布式架构与高可用性1.4.多样化的表引擎1.5.实时处理能力2.安装2.1 拉取镜像2.2 创建容器3.连接4.使用4.1.创建数据库5.其他5.1 primary key5.2 ENG…...
Docker核心笔记
一、概述 1、架构 Docker容器基于镜像运行,容器共享宿主机的内核,不会加载额外内核,通过Namespaces(环境隔离)和Cgroups(资源控制)实现隔离,Cgroups会限容器使用资源并控制优先级和统计数据。隔离后的容器仅包含应用所需的用户态依赖 2、安装 安装先卸载再安装,使用的yum…...
log日志最佳实践
log日志最佳实践 1、占位符的使用2、延迟计算 1、占位符的使用 在进行日志打印的时候,推荐使用占位符进行字符串打印,而不是直接使用字符串拼接。原因: 这样可以避免不必要的字符串拼接。使用占位符时,实际字符串拼接由日志框架…...

FreeRTOS--消息队列
一、简介 消息队列是FreeRTOS中用于任务与任务或任务与中断之间数据交换的一种机制,采用FIFO(先进先出)方式管理数据,也可以采用LIFO(后进先出)方式。有点类似全局变量。 1.1 那为什么不直接使用全局变量&a…...

三步快速部署一个本地Windows/Linux大语言模型ChatGLM(环境配置+权重下载+运行)
前言: 最近刚拿到实验室一个装了3张3090显卡的服务器账号,感觉不用来霍霍有点浪费,于是有了部署一个大语言模型的想法,除去下载权重和传文件到服务器上可能也就用了十分钟不到(这下看懂为啥python受众现在这么广了&…...
深入解析Spring Boot与Redis的缓存集成实践
深入解析Spring Boot与Redis的缓存集成实践 引言 在现代Web应用开发中,缓存技术是提升系统性能的重要手段之一。Redis作为一种高性能的内存数据库,广泛应用于缓存场景。本文将详细介绍如何在Spring Boot项目中集成Redis,并探讨其在实际开发…...