解决ESP32板载WS2812B LED反色问题及工作状态灯的应用

news/2025/2/11 18:31:24/

本文主要介绍使用.Net nanoFramework驱动驱动 ESP32-S3-Zero 板载的 WS2812B LED的问题,以及如何设计一个灯光控制类,来方便的使用工作状态灯来显示设备的工作状态。

1. 引言

在使用Net nanoFramework驱动 ESP32-S3-Zero 的板载 WS2812B LED 时,你可能遇到一些挑战,如LED反色问题。本文将详细探讨如何解决这些问题,以及如何有效地利用工作状态灯来显示设备的工作状态。我们将使用Iot.Device.Ws28xx.Esp32库,这是一个专为ESP32板设计的库,用于驱动WS28xx系列的LED。

Ws28xx

2. 板载 LED 的使用

在硬件上的开发与纯软件不同,因为我们使用的硬件的一些特异性,往往同样的代码在不同的硬件上会有不同的表现。这就需要我们在开发的时候,对硬件的特性有一定的了解,这样才能更好的使用硬件。

一般来说通过 Iot.Device.Ws28xx.Esp32 库,我们即可方便的驱动自己的 LED。根据板子的资料我们可以查到 ESP32-S3-Zero 板载了一颗 WS2812B LED,这颗 LED 的引脚是 GPIO 21,我们可以通过以下代码来驱动这颗 LED:

int WS2812_Count = 1;
int WS2812_Pin = 21;
var leddev = new Ws2812b(WS2812_Pin, WS2812_Count);
BitmapImage img = leddev.Image;
img.SetPixel(0, 0, Color.Red);
leddev.Update();
Thread.Sleep(1000);
img.SetPixel(0, 0, Color.Green);
leddev.Update();
Thread.Sleep(1000);
img.SetPixel(0, 0, Color.Blue);
leddev.Update();

这样我们就可以通过这颗 LED 来显示不同的颜色了。但是实际情况是,灯光颜色奇奇怪怪,都趋近于白色。当我们将 Ws2812b 更换为 Ws2812c 时,可以驱动正常的颜色了,但是颜色却是反的。

3. 解决 LED 反色问题

通过官方仓库的 源码 我们可以看到,Ws2812b 类的构造函数中,使用了 BitmapImageNeo3 类来初始化 Image 属性,而 Ws2812c 类中使用的是 BitmapImageWs2808Grb。根据根据板子使用的 XL-0807RGBC-WS2812B 技术数据表来看,其颜色数据使用的是RGB顺序,这就不难发现问题所在了。

针对这种情况,我们可以通过继承 Ws28xx 类,然后自行修改,来解决这个问题。之前BitmapImageWs2808GrbBitmapImageWs2808 等这些类都是 internal,无法继承。目前最新的版本已经将这些类修改为 public,我们可以直接继承这些类,然后修改 Image 对象使用BitmapImageWs2808,来解决这个问题。

public class XlWs2812b : Ws28xx
{public XlWs2812b(int gpioPin, int width, int height = 1): base(gpioPin, new BitmapImageWs2808(width, height)){ClockDivider = 2;OnePulse = new RmtCommand(32, true, 18, false);ZeroPulse = new RmtCommand(16, true, 34, false);ResetCommand = new RmtCommand(2000, false, 2000, false);}
}

添加好这个类,我们就可以通过 XlWs2812b 类来驱动我们的 LED 了。

4. 工作状态灯的应用

为了更好的了解设备的工作状态,我们可以通过工作状态灯来显示设备的工作状态。这样,我们就可以通过灯光的颜色来了解设备的工作状态。

4.1 工作状态灯的设计

首先我们先定义一个枚举,用于表示设备的工作状态:

/// <summary>
/// 定义设备状态
/// </summary>
public enum RunStatus
{/// <summary>/// 启动中,灯蓝色常亮/// </summary>Start,/// <summary>/// 请求识别,蓝色快闪/// </summary>OnIdentify,/// <summary>/// 验证成功,灯绿色常亮/// </summary>AuthSuccess,/// <summary>  /// wifi连接中,橙色快烁/// </summary>  Connecting,/// <summary>  /// wifi 配置问题,红色闪烁  /// </summary>  ConfigFailed,/// <summary>  /// wifi 连接失败,红色常亮  /// </summary>  ConnectFailed,/// <summary>  /// 正常工作中,绿色呼吸灯  /// </summary>Working,/// <summary>/// 关闭灯光/// </summary>Close
}

然后我们定义一个 BoardLedControl 类,用于控制灯光的显示,这个类的构造函数中,我们可以设置灯光的引脚,以及灯光的检查间隔。这个类中,我们使用了一个线程来检查灯光的状态,这样我们就可以在其他线程中,通过修改灯光的状态来控制灯光的显示。

/// <summary>
/// 工作灯控制
/// </summary>
/// <param name="pin">Gpio Pin</param>
/// <param name="checkDelay">控制检查间隔</param>
public BoardLedControl(int pin = 21,int checkDelay = 500)
{WS2812_Pin = pin;leddev = new XlWs2812b(WS2812_Pin, 1, 1);image = leddev.Image;statusThread = new Thread(() => {while (true){if (autoUpdate){UpdateLedStatus();}}});statusThread.Start();
}

4.2 几种灯光模式

BoardLedControl 类中,我们定义了几种灯光模式,常亮,闪烁,呼吸灯等。

/// <summary>
/// 灯光效果-闪烁
/// </summary>
/// <param name="color">颜色</param>
/// <param name="delay">时延</param>
public void LedBlink(Color color,int delay = 500)
{image.SetPixel(0, 0, color);leddev.Update();Thread.Sleep(delay);image.SetPixel(0, 0, Color.Black);leddev.Update();Thread.Sleep(delay);
}/// <summary>
/// 灯光颜色设置
/// </summary>
/// <param name="color">颜色</param>
/// <param name="sleepDuration">等待</param>
public void LedSet(Color color, int sleepDuration = 0)
{image.SetPixel(0, 0, color);leddev.Update();if (sleepDuration > 0){Thread.Sleep(sleepDuration);}
}/// <summary>
/// 灯光效果-呼吸
/// </summary>
/// <param name="color">颜色</param>
/// <param name="duration">时长</param>
/// <param name="steps">步长</param>
public void LedBreath(Color color, int duration = 3900, int steps = 20)
{// 限制参数范围steps = steps < 10 ? 10 : steps;duration = duration < 1000 ? 1000 : duration;// 计算每一步的暂停时长 (单位:毫秒)  int sleepDuration = duration / (2 * steps);for (int i = 1; i <= steps; i++){// 计算当前明度  float brightness = (float)i / steps;// 设置颜色  Color currentColor = Color.FromArgb((int)(color.R * brightness),(int)(color.G * brightness),(int)(color.B * brightness));LedSet(currentColor, sleepDuration);}for (int i = steps; i > 0; i--){float brightness = (float)i / steps;Color currentColor = Color.FromArgb((int)(color.R * brightness),(int)(color.G * brightness),(int)(color.B * brightness));LedSet(currentColor, sleepDuration);}
}

4.3 灯光状态检查

BoardLedControl 类中,我们定义了一个 UpdateLedStatus 方法,用于检查灯光的状态,然后根据灯光的状态来控制灯光的显示。

/// <summary>
/// 更新灯光
/// </summary>
public void UpdateLedStatus()
{// 根据设备状态更新灯光switch (DeviceStatus){case RunStatus.Start:LedSet(Color.Blue);break;case RunStatus.OnIdentify:LedBlink(Color.Blue, 200);break;case RunStatus.AuthSuccess:LedSet(Color.Green);break;case RunStatus.Connecting:LedBlink(Color.Orange, 200);break;case RunStatus.ConfigFailed:LedBlink(Color.Red);break;case RunStatus.ConnectFailed:LedSet(Color.Red);break;case RunStatus.Working:LedBreath(Color.Green);break;default:LedSet(Color.Black);break;}
}

4.4 使用工作状态灯

在使用工作状态灯时,我们可以通过以下代码来使用:

// 初始化灯光控制
var _led = new BoardLedControl();
// 开启工作灯,蓝色引擎启动!
_led.StartAutoUpdate();
// ....
// 更改状态
_led.DeviceStatus = RunStatus.OnIdentify;

启动

在使用中,我们可以通过修改 DeviceStatus 属性来控制灯光的显示,这样我们就可以通过灯光的颜色来了解设备的工作状态了。当然,也可以不启用自动更新StartAutoUpdate()或在合适时候使用StopAutoUpdate方法关闭自动更新,然后通过直接调用 LedSetLedBlinkLedBreath 等方法来控制灯光的显示。

5. 最后

虽然在使用 ESP32 的板载 WS2812B LED 可能会遇到一些问题,但只要你理解了这些问题的原因,就可以找到解决方案。同时,工作状态灯是一种非常有效的工具,可以帮助你更好地了解设备的工作状态。我们希望本文能对你在使用 ESP32驱动 WS2812B LED 时提供帮助。文章中的代码已经上传到 Github ESP32_S3_Samples 项目,欢迎大家下载使用。


http://www.ppmy.cn/news/1336581.html

相关文章

通过mybatis拦截器给sql执行加一个耗时监控

代码没什么内容&#xff0c;直接贴上来吧&#xff0c;其中costTimeUtil可以看我的另一篇博文&#xff1a;java实现一个不带次数变量的加权平均值算法-CSDN博客 Slf4j Intercepts({Signature(type StatementHandler.class,method "query",args {Statement.class, …

ES6 模块化、CommonJS 模块化的区别经典面试题

语法差异: ES6 模块化 使用 import 和 export 关键字来导入和导出模块。 javascriptCopy code// 导入模块 import { someFunction } from someModule; ​ // 导出模块 export function myFunction() {// code } CommonJS 模块化 使用 require 和 module.exports 或 exports 来导…

ETCD高可用架构涉及常用功能整理

ETCD高可用架构涉及常用功能整理 1. etcd的高可用系统架构和相关组件1.1 Quorum机制1.2 Raft协议 2. etcd的核心参数2.1 常规配置2.2 特殊优化配置2.2.1 强行拉起新集群 --force-new-cluster2.2.2 兼容磁盘io性能差2.2.3 etcd存储quota 3. etcd常用命令3.1 常用基础命令3.1.1 列…

综合案例 - 商品列表

文章目录 需求说明1.my-tag组件封装&#xff08;完成初始化&#xff09;2.may-tag封装&#xff08;控制显示隐藏&#xff09;3.my-tag组件封装&#xff08;v-model处理&#xff1a;信息修改&#xff09;4.my-table组件封装&#xff08;整个表格&#xff09;①数据不能写死&…

docker swarm转移K8s 实践(-)

相关资料 Kubernetes初识_kubernetes怎么读-CSDN博客

电商新时代:小红书笔记详情API引领购物体验变革

一、引言 随着互联网的普及和电子商务的飞速发展&#xff0c;消费者的购物方式和习惯也在发生深刻变化。传统的商品详情页面已经不能满足现代消费者的需求&#xff0c;他们更希望在购物前了解更多关于产品的真实评价和详细信息。在这样的背景下&#xff0c;小红书笔记详情API应…

漏洞原理MySQL注入布尔盲注入

1 判断MySql注入点是否存在 利用盲注入的方式 http://127.0.0.1/news/show.php?id46 and 11 # 正常显示 http://127.0.0.1/news/show.php?id46 and 12 # 不显示 2 获取数据库的长度 http://127.0.0.1/news/show.php?id46 and length(database())n n的范围是从 1 开始 h…

【使用opencv、python、dlib实现人脸关键点检测、眨眼检测和嘴巴开闭检测,可简单用于疲劳检测】

使用opencv、python、dlib实现人脸关键点检测、眨眼检测和嘴巴开闭检测&#xff0c;可简单用于疲劳检测 环境准备opencvdlib 原理眨眼检测张嘴检测原理 代码示例人脸关键点检测眨眼检测张嘴检测 写在最后 环境准备 opencv 一、简单介绍 OpenCV (Open Source Computer Vision…