obsidian-notes/DIY/LED灯环.md
2024-06-20 08:45:57 +08:00

159 lines
5.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: led ring
updated: 2024-06-08
tags:
- led
- 编码器
- 源码
---
# 目的
实现一个独立的多色led灯环与电位器或编码器配合使用同步显示当前状态。
# 设计
采用WS2812B1010小封装最小连线和IO消耗下实现对每个LED的独立、多色控制。
## ~~协议1~~
动态配置HEX格式每次显示前发送显示指令`当前值,[区间下限,区间上限],[下限颜色,上限颜色]`
| 当前值 | 区间下限 | 区间上限 | 下限颜色 | 上限颜色 | |
|:-----------------------:|:----:|:----:|:----:|:----:| --- |
| 2字节 | 2字节 | 2字节 | 3字节 | 3字节 | |
| 2字节取值范围为[-32768,32768] | | | | | |
1. 参数只有`当前值`时,其它参数使用缺省值`[区间下限,区间上限]=[0,1],[下限颜色,上限颜色]=[#FF0001,#00FF7F]`
2. 参数只有`当前值`、`区间下限`、`区间上限`时,其它参数使用缺省值`[下限颜色,上限颜色]=[#FFA500,#FFA500]`
3. 缺省为静态显示,支持动态显示,如`海浪`
## ~~协议2~~
静态配置HEX格式。需初始化显示参数`索引值,[区间下限,区间上限],[下限颜色,上限颜色]`,每次显示前发送指令:`索引值,当前值`
```c
00,0000,0001,#FF0001,#00FF7F //双色显示布尔量
01,0001,0064,#FFA500,#FFA500 //单色显示0~100范围
02,FD2E,02D2,#00FF7F,#FF00FF //双色渐变显示-722~722范围
```
## 渐变色转换算法
使用色相环实现颜色渐变具有更好的显示效果
参考aardio代码实现
```javascript
rgb2hsb = function(r,g,b) {
if( 0 > r || r > 255 ) error("R值范围0~255",2)
if( 0 > g || g > 255 ) error("G值范围0~255",2)
if( 0 > b || b > 255 ) error("B值范围0~255",2)
var rgb = { r;g;b };
..table.sort(rgb);
var max = rgb[3];
var min = rgb[1];
var d = (max - min);
var s;
var v = max / 255;
if(max == 0) s = 0 else s = d / max;
var h = 0;
if(d){
if (max == r ){
h = (g - b) * 60 / d;
if (g < b) h = h + 360;
}
elseif (max == g) {
h = (b - r) * 60 / d + 120;
}
else{
h = (r - g) * 60 / d + 240;
}
}
return ..math.round(h,2)%360, ..math.round(s,2), ..math.round(v,2);
}
hsb2rgb = function(h,s,v) {
h = h % 360;
if( h <0 || h >360 ) error("h值范围0~360",2)
if( s <0 || s >1 ) error("s值范围0~1",2)
if( v <0 || v >1 ) error("v值范围0~1",2)
var r,g,b = 0,0,0;
var i = ..math.floor( (h / 60) % 6 );
var f = (h / 60) - i;
var p = v * (1 - s);
var q = v * (1 - f * s);
var t = v * (1 - (1 - f) * s);
select (i) {
case 0{
r = v;
g = t;
b = p;
}
case 1{
r = q;
g = v;
b = p;
}
case 2{
r = p;
g = v;
b = t;
}
case 3{
r = p;
g = q;
b = v;
}
case 4{
r = t;
g = p;
b = v;
}
case 5{
r = v;
g = p;
b = q;
}
}
return ..math.round(r * 255),..math.round(g * 255), ..math.round(b * 255);
}
```
在色相h、纯度s、明度l三个维度作线性差值假如共20个led其中16个led作范围显示区间划分为16等份则为渐变色
## 静态存储
静态初始化的优点是响应速度快,因为更新颜色时没有计算耗时,缺点是耗内存
三维数组uint color\[N\]\[16\]\[3\]
```c
{
{//索引0
{0x01,0x00,0xFF},//#FF0001
{0x7F,0xFF,0x00}//#00FF7F
},
{//索引1
{r0,g0,b0},
{r1,g1,b1},
{r2,g2,b2},
//...Unknown encodingUnknown encoding1024/3/16=21组。
```
## 优化后
可改用统一颜色计算uint8 colormap\[N\]\[3\]待用N为总LED个数占用N\*3字节。
### 协议为:
| [索引值] | 区间下限/当前值 | [区间上限] | [下限颜色] | [上限颜色] |
| :---: | :------: | :----: | :----: | :----: |
| 1字节 | 2字节 | 2字节 | 3字节 | 3字节 |
| 可选 | | 可选 | 可选 | 可选 |
四种模式:
1. `索引值,[区间下限,区间上限],[下限颜色,上限颜色]`总11字节
2. `索引值,[区间下限,区间上限]`总5字节
3. `索引值,当前值`总3字节
4. `当前值`总2字节
1. 0x00,0x0000,0x0000,r,g,b配置颜色。总11字节且前5字节全为0。
2. index,min,max更新索引配置。总5字节。
3. index,value动态更新颜色。总3字节。
4. 仅value则沿用上次的index。总2字节。
### 存储过程:
直接分配4\*M字节内存支持M个索引按需扩展按index进行索引存储即uint8 cfg[index]=[min,max]
> 优势是简洁高效,去重容易,直接引用,不用遍历搜索。
- ==去重==指后发送的索引配置会覆盖之前的配置
- ==直接引用==指以索引配置支持无序输入,程序以此作为数组的位置编号,取出时直接取出,无需在数组中搜索。
### 颜色值映射过程:
1. 计算渐变色并分为N个
2. 计算index=round((value-min)/((max-min)/N)),四舍五入
3. 发送colormap[0]至colormap[index]
### 主控:
华大[[MCU/华大/选型#[HC32L110C6](https //www.hdsc.com.cn/Category82-1389)|HC32L、HC32F]]系列及沁恒[[CH32V003]]系列,优选后者,便宜够用。