First draft of neopixel
This commit is contained in:
parent
02c41b59bd
commit
8a124812b6
@ -12,6 +12,11 @@ namespace BufferMethods {
|
||||
ManagedBuffer(buf).setByte(off, v);
|
||||
}
|
||||
|
||||
//%
|
||||
uint8_t *getBytes(Buffer buf) {
|
||||
return buf->payload;
|
||||
}
|
||||
|
||||
/** Returns the length of a Buffer object. */
|
||||
//% property
|
||||
int length(Buffer s) {
|
||||
|
20
libs/neopixel/kind.json
Normal file
20
libs/neopixel/kind.json
Normal file
@ -0,0 +1,20 @@
|
||||
{
|
||||
"name": "neppixel",
|
||||
"description": "AdaFruit NeoPixel driver for micro:bit",
|
||||
"files": [
|
||||
"neopixel.ts",
|
||||
"sendbuffer.asm"
|
||||
],
|
||||
"testFiles": [
|
||||
"neotest.ts"
|
||||
],
|
||||
"microbit": {
|
||||
"config": {
|
||||
"MICROBIT_BLE_ENABLED": "0"
|
||||
}
|
||||
},
|
||||
"public": true,
|
||||
"dependencies": {
|
||||
"microbit": "file:../microbit"
|
||||
}
|
||||
}
|
88
libs/neopixel/neopixel.ts
Normal file
88
libs/neopixel/neopixel.ts
Normal file
@ -0,0 +1,88 @@
|
||||
namespace neopixel {
|
||||
|
||||
//% shim=sendBufferAsm
|
||||
function sendBuffer(buf: Buffer, pin: DigitalPin) {
|
||||
}
|
||||
|
||||
class Strip {
|
||||
buf: Buffer;
|
||||
pin: DigitalPin;
|
||||
brightness: number;
|
||||
|
||||
length() {
|
||||
return this.buf.length / 3
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the brightness of the strip, 0-255.
|
||||
*/
|
||||
setBrigthness(brightness: number): void {
|
||||
this.brightness = brightness;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the pin where the neopixel is connected, defaults to P0.
|
||||
*/
|
||||
setPin(pin: DigitalPin): void {
|
||||
this.pin = pin;
|
||||
pins.digitalWritePin(this.pin, 0)
|
||||
basic.pause(50)
|
||||
}
|
||||
|
||||
/**
|
||||
* Turn off all LEDs.
|
||||
*/
|
||||
clear(): void {
|
||||
this.buf.fill(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shift LEDs forward.
|
||||
*/
|
||||
shift(off: number): void {
|
||||
this.buf.shift(-off * 3)
|
||||
}
|
||||
|
||||
/**
|
||||
* Shift LEDs forward.
|
||||
*/
|
||||
rotate(): void {
|
||||
this.buf.rotate(-3)
|
||||
}
|
||||
|
||||
display() {
|
||||
basic.pause(1)
|
||||
sendBuffer(this.buf, this.pin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set give LED to a given color (range 0-255 for r, g, b)
|
||||
*/
|
||||
setPix(ledoff: number, r: number, g: number, b: number): void {
|
||||
ledoff = ledoff * 3;
|
||||
let br = this.brightness;
|
||||
if (br < 255) {
|
||||
r = (Math.clamp(0, 255, r) * br) >> 8;
|
||||
g = (Math.clamp(0, 255, b) * br) >> 8;
|
||||
b = (Math.clamp(0, 255, b) * br) >> 8;
|
||||
}
|
||||
let buf = this.buf;
|
||||
buf[ledoff + 0] = Math.clamp(0, 255, g);
|
||||
buf[ledoff + 1] = Math.clamp(0, 255, r);
|
||||
buf[ledoff + 2] = Math.clamp(0, 255, b);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new NeoPixel driver for `numleds` LEDs.
|
||||
* @params numleds number of leds in the strip, eg: 24,30,60,64
|
||||
*/
|
||||
export function create(numleds: number): Strip {
|
||||
let strip = new Strip();
|
||||
strip.buf = pins.createBuffer(numleds * 3);
|
||||
strip.setBrigthness(255)
|
||||
strip.setPin(DigitalPin.P0)
|
||||
return strip;
|
||||
}
|
||||
|
||||
}
|
92
libs/neopixel/neotest.ts
Normal file
92
libs/neopixel/neotest.ts
Normal file
@ -0,0 +1,92 @@
|
||||
basic.showLeds(`
|
||||
# . . . .
|
||||
. . . . .
|
||||
. . # . .
|
||||
. . . . .
|
||||
. . . . #
|
||||
`)
|
||||
console.log("Start")
|
||||
|
||||
// Create a NeoPixel driver - specify the number of LEDs:
|
||||
let strip = neopixel.create(24);
|
||||
|
||||
// If your strip is not at P0, specify the pin.
|
||||
strip.setPin(DigitalPin.P0)
|
||||
|
||||
// Brightness defaults to 255 (very bright); 0 is completely off.
|
||||
strip.setBrigthness(20)
|
||||
|
||||
// Set pixels - pixel number, followed by red, green and blue values, between 0 and 255.
|
||||
strip.setPix(0, 255, 255, 255);
|
||||
strip.setPix(1, 0, 255, 255);
|
||||
strip.setPix(2, 255, 0, 255);
|
||||
strip.setPix(3, 255, 255, 0);
|
||||
|
||||
console.log("Send!")
|
||||
|
||||
// Send the image to the strip.
|
||||
strip.display();
|
||||
basic.pause(500);
|
||||
|
||||
console.log("Sent!")
|
||||
|
||||
// Green light travelling the strip:
|
||||
for (let l = 0; l < strip.length(); l++) {
|
||||
strip.clear();
|
||||
strip.setPix(l, 0, 255, 0);
|
||||
strip.display();
|
||||
basic.pause(100);
|
||||
}
|
||||
|
||||
let special = false;
|
||||
let numcol = 0;
|
||||
input.onButtonPressed(Button.A, () => {
|
||||
special = true;
|
||||
let r = 0;
|
||||
let g = 0;
|
||||
let b = 0;
|
||||
if (numcol == 0) {
|
||||
r = 255;
|
||||
g = 255;
|
||||
b = 255;
|
||||
} else if (numcol == 1) {
|
||||
r = 255;
|
||||
} else if (numcol == 2) {
|
||||
b = 255;
|
||||
} else if (numcol == 3) {
|
||||
r = 255;
|
||||
g = 255;
|
||||
} else if (numcol == 4) {
|
||||
r = 10;
|
||||
g = 10;
|
||||
b = 10;
|
||||
}
|
||||
numcol = (numcol + 1) % 5;
|
||||
for (let k = 0; k < 7; k++) {
|
||||
strip.setPix(k, r, g, b);
|
||||
}
|
||||
strip.display();
|
||||
});
|
||||
|
||||
control.inBackground(() => {
|
||||
for (let j = 0; j < 2000000; j++) {
|
||||
if (special) {
|
||||
basic.pause(100);
|
||||
continue;
|
||||
}
|
||||
let r1 = (0 + j * 2) & 63;
|
||||
let g1 = (20 + j * 1) & 63;
|
||||
let b1 = (30 + j * 3) & 63;
|
||||
for (let i = 0; i < strip.length(); i++) {
|
||||
strip.setPix(i, (r1 - i) * 20, (g1 - i) * 20, (b1 - i) * 20);
|
||||
}
|
||||
strip.display()
|
||||
basic.pause(60);
|
||||
}
|
||||
});
|
||||
|
||||
control.inBackground(() => {
|
||||
while (true) {
|
||||
basic.showString("XMAS!", 150);
|
||||
}
|
||||
});
|
62
libs/neopixel/sendbuffer.asm
Normal file
62
libs/neopixel/sendbuffer.asm
Normal file
@ -0,0 +1,62 @@
|
||||
push {r4,r5,r6,r7,lr}
|
||||
|
||||
mov r4, r0 ; save buff
|
||||
mov r6, r1 ; save pin
|
||||
|
||||
mov r0, r4
|
||||
bl buffer::count
|
||||
mov r5, r0
|
||||
|
||||
mov r0, r4
|
||||
bl buffer::cptr
|
||||
mov r4, r0
|
||||
|
||||
; setup pin as digital
|
||||
mov r0, r6
|
||||
movs r1, #0
|
||||
bl micro_bit::digitalWritePin
|
||||
|
||||
; load pin address
|
||||
mov r0, r6
|
||||
|
||||
ldr r0, [r0, #8] ; get mbed DigitalOut from MicroBitPin
|
||||
ldr r1, [r0, #4] ; r1-mask for this pin
|
||||
ldr r2, [r0, #16] ; r2-clraddr
|
||||
ldr r3, [r0, #12] ; r3-setaddr
|
||||
|
||||
cpsid i ; disable irq
|
||||
|
||||
b .start
|
||||
|
||||
.nextbit: ; C0
|
||||
str r1, [r3, #0] ; pin := hi C2
|
||||
tst r6, r0 ; C3
|
||||
bne .islate ; C4
|
||||
str r1, [r2, #0] ; pin := lo C6
|
||||
.islate:
|
||||
lsrs r6, r6, #1 ; r6 >>= 1 C7
|
||||
bne .justbit ; C8
|
||||
|
||||
; not just a bit - need new byte
|
||||
adds r4, #1 ; r4++ C9
|
||||
subs r5, #1 ; r5-- C10
|
||||
bcc .stop ; if (r5<0) goto .stop C11
|
||||
.start:
|
||||
movs r6, #0x80 ; reset mask C12
|
||||
nop ; C13
|
||||
|
||||
.common: ; C13
|
||||
str r1, [r2, #0] ; pin := lo C15
|
||||
; always re-load byte - it just fits with the cycles better this way
|
||||
ldrb r0, [r4, #0] ; r0 := *r4 C17
|
||||
b .nextbit ; C20
|
||||
|
||||
.justbit: ; C10
|
||||
; no nops, branch taken is already 3 cycles
|
||||
b .common ; C13
|
||||
|
||||
.stop:
|
||||
str r1, [r2, #0] ; pin := lo
|
||||
cpsie i ; enable irq
|
||||
|
||||
pop {r4,r5,r6,r7,pc}
|
Loading…
Reference in New Issue
Block a user