forked from emakefun/pxt-sensorbit
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathEMRGBLight.ts
148 lines (133 loc) · 4.58 KB
/
EMRGBLight.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
/**
* Different modes for RGB or RGB+W RGBLight LHRGBLight
*/
enum EMRGBPixelMode {
//% block="RGB (GRB format)"
RGB = 0,
//% block="RGB+W"
RGBW = 1,
//% block="RGB (RGB format)"
RGB_RGB = 2
}
/**
* RGBLight Functions
*/
namespace EMRGBLight {
//% shim=sendBufferAsm
//% parts="RGBLight"
export function sendBuffer(buf: Buffer, pin: DigitalPin) {
}
/**
* A RGBLight class
*/
export class EmakefunRGBLight {
buf: Buffer;
pin: DigitalPin;
// TODO: encode as bytes instead of 32bit
brightness: number;
start: number; // start offset in LED strip
_length: number; // number of LEDs
_mode: EMRGBPixelMode;
setBrightness(brightness: number): void {
this.brightness = brightness & 0xff;
//this.easeBrightness();
}
setPin(pin: DigitalPin): void {
this.pin = pin;
pins.digitalWritePin(this.pin, 0);
// don't yield to avoid races on initialization
}
setPixelColor(pixeloffset: number, rgb: RgbColors): void {
if (pixeloffset == this._length)//全部
{
for (let i = 0; i < this._length; i++)
{
this.setPixelRGB(i, rgb);
}
}
else
{
this.setPixelRGB(pixeloffset, rgb);
}
}
private setPixelRGB(pixeloffset: number, rgb: number): void {
if (pixeloffset < 0
|| pixeloffset >= this._length)
return;
let stride = this._mode === EMRGBPixelMode.RGBW ? 4 : 3;
pixeloffset = (pixeloffset + this.start) * stride;
let red = unpackR(rgb);
let green = unpackG(rgb);
let blue = unpackB(rgb);
let br = this.brightness;
if (br < 255) {
red = (red * br) >> 8;
green = (green * br) >> 8;
blue = (blue * br) >> 8;
}
this.setBufferRGB(pixeloffset, red, green, blue)
}
private setBufferRGB(offset: number, red: number, green: number, blue: number): void {
if (this._mode === EMRGBPixelMode.RGB_RGB) {
this.buf[offset + 0] = red;
this.buf[offset + 1] = green;
} else {
this.buf[offset + 0] = green;
this.buf[offset + 1] = red;
}
this.buf[offset + 2] = blue;
}
show() {
sendBuffer(this.buf, this.pin);
}
clear(): void {
const stride = this._mode === EMRGBPixelMode.RGBW ? 4 : 3;
this.buf.fill(0, this.start * stride, this._length * stride);
this.show();
}
easeBrightness(): void {
const stride = this._mode === EMRGBPixelMode.RGBW ? 4 : 3;
const br = this.brightness;
const buf = this.buf;
const end = this.start + this._length;
const mid = this._length / 2;
for (let i = this.start; i < end; ++i) {
const k = i - this.start;
const ledoffset = i * stride;
const br = k > mid ? 255 * (this._length - 1 - k) * (this._length - 1 - k) / (mid * mid) : 255 * k * k / (mid * mid);
const r = (buf[ledoffset + 0] * br) >> 8; buf[ledoffset + 0] = r;
const g = (buf[ledoffset + 1] * br) >> 8; buf[ledoffset + 1] = g;
const b = (buf[ledoffset + 2] * br) >> 8; buf[ledoffset + 2] = b;
if (stride == 4) {
const w = (buf[ledoffset + 3] * br) >> 8; buf[ledoffset + 3] = w;
}
}
}
}
export function create(pin: DigitalPin, numleds: number, mode: EMRGBPixelMode): EmakefunRGBLight {
let light = new EmakefunRGBLight();
let stride = mode === EMRGBPixelMode.RGBW ? 4 : 3;
light.buf = pins.createBuffer(numleds * stride);
light.start = 0;
light._length = numleds;
light._mode = mode;
light.setBrightness(128);
light.setPin(pin);
return light;
}
function packRGB(a: number, b: number, c: number): number {
return ((a & 0xFF) << 16) | ((b & 0xFF) << 8) | (c & 0xFF);
}
function unpackR(rgb: number): number {
let r = (rgb >> 16) & 0xFF;
return r;
}
function unpackG(rgb: number): number {
let g = (rgb >> 8) & 0xFF;
return g;
}
function unpackB(rgb: number): number {
let b = (rgb) & 0xFF;
return b;
}
}