diff --git a/libs/i2c-fram/README.md b/libs/i2c-fram/README.md new file mode 100644 index 00000000..8107643b --- /dev/null +++ b/libs/i2c-fram/README.md @@ -0,0 +1,30 @@ +# I2C FRAM driver + +This library provides a driver for this FRAM part: https://www.adafruit.com/products/1895 + +The memory is accessed one byte at a time. The library provides a utility functions +to write an entire buffer. + +## Reading/writing byte + +``` +let addr = 100 +i2c_fram.writeByte(addr, 42) +let val = i2c_fram.readByte(addr) +console.log(`${addr}: ${val}`) +``` + +## Reading/writing a buffer + +This code will log current time and acceleration in X axis every second. + +``` +let bufSz = 8 +for (let addr = 0; addr < 0x8000; addr += bufSz) { + let buf = pins.createBuffer(bufSz) + buf.setNumber(NumberFormat.Int32LE, 0, input.runningTime()) + buf.setNumber(NumberFormat.Int32LE, 4, input.acceleration(Dimension.X)) + i2c_fram.writeBuffer(addr, buf) + basic.pause(1000) +} +``` diff --git a/libs/i2c-fram/fram.ts b/libs/i2c-fram/fram.ts new file mode 100644 index 00000000..525cdb18 --- /dev/null +++ b/libs/i2c-fram/fram.ts @@ -0,0 +1,55 @@ +namespace i2c_fram { + const devaddr = 0x50; + const memend = 0x7fff; + + //% shim=ksrt::panic + function panic(code: number) { } + + function die() { panic(142) } + + export function readByte(addr: number) { + if (addr < 0 || addr > memend) + die(); + + let buf = pins.createBuffer(2) + buf[0] = (addr >> 8) & 0xff; + buf[1] = addr & 0xff; + + pins.i2cWriteBuffer(devaddr, buf); + buf = pins.i2cReadBuffer(devaddr, 1); + + return buf[0]; + } + + export function writeByte(addr: number, val: number) { + if (addr < 0 || addr > memend) + die(); + + if (val < 0 || val > 0xff) + die(); + + let buf = pins.createBuffer(3) + + buf[0] = (addr >> 8) & 0xff; + buf[1] = addr & 0xff; + buf[2] = val; + + pins.i2cWriteBuffer(devaddr, buf) + } + + export function readBuffer(addr: number, length: number) { + if (addr < 0 || length < 0 || (addr + length) > memend) + die(); + let buf = pins.createBuffer(length) + for (let i = 0; i < length; ++i) + buf[i] = readByte(addr + i) + return buf + } + + export function writeBuffer(addr:number, buf: Buffer) { + if (addr < 0 || (addr + buf.length) > memend) + die(); + for (let i = 0; i < buf.length; ++i) + writeByte(addr + i, buf[i]) + } +} diff --git a/libs/i2c-fram/ftest.ts b/libs/i2c-fram/ftest.ts new file mode 100644 index 00000000..0f24cfea --- /dev/null +++ b/libs/i2c-fram/ftest.ts @@ -0,0 +1,16 @@ +i2c_fram.writeByte(100, 42) +i2c_fram.writeByte(101, 108) + +function toBuf(arr: number[]) { + let buf = pins.createBuffer(arr.length) + for (let i = 0; i < arr.length; ++i) + buf[i] = arr[i] + return buf +} + +i2c_fram.writeBuffer(98, toBuf([1, 2, 3, 4, 5, 6, 7])) + +console.log("100:" + i2c_fram.readByte(100)) +console.log("101:" + i2c_fram.readByte(101)) + + diff --git a/libs/i2c-fram/kind.json b/libs/i2c-fram/kind.json new file mode 100644 index 00000000..49dd3a6f --- /dev/null +++ b/libs/i2c-fram/kind.json @@ -0,0 +1,16 @@ +{ + "name": "i2c-fram", + "description": "AdaFruit I2C FRAM driver for micro:bit", + "files": [ + "README.md", + "fram.ts" + ], + "testFiles": [ + "ftest.ts" + ], + "public": true, + "dependencies": { + "microbit": "file:../microbit" + }, + "installedVersion": "hhneqa" +} diff --git a/libs/neopixel/README.md b/libs/neopixel/README.md new file mode 100644 index 00000000..a091dfa1 --- /dev/null +++ b/libs/neopixel/README.md @@ -0,0 +1,47 @@ +# NeoPixel driver + +This library provides a driver for various Neo Pixel LED strips, +see https://www.adafruit.com/category/168 + +NeoPixels consist of a number of RGB LEDs, every one of them controlled +separately. + +## Basic usage + +``` +// Create a NeoPixel driver - specify the number of LEDs: +let strip = neopixel.create(24) + +// set pixel colors +strip.setPix(0, 255, 255, 255) // white +strip.setPix(1, 255, 0, 0) // red +strip.setPix(2, 0, 255, 0) // green +strip.setPix(3, 0, 0, 255) // blue + +// send the data to the strip +strip.display() +``` + +Use `strip.setPin()` if your strip is not at `P0`. + +Use `strip.setBrigthness()` to lower the brightness (it's maxed out by default). + +Use `strip.shift()` or `strip.rotate()` to shift the lights around. + +## Example: Using accelerometer to control colors + +This little program will let the position of the microbit control the color of the first LED. +This first LED will then get shifted further away every 100ms. + +``` +let strip = neopixel.create(24) +while (true) { + let x = input.acceleration(Dimension.X) / 2 + let y = input.acceleration(Dimension.Y) / 2 + let z = input.acceleration(Dimension.Z) / 2 + strip.setPix(0, x, y, -z); + strip.shift(1); + strip.display(); + basic.pause(100); +} +``` diff --git a/libs/neopixel/kind.json b/libs/neopixel/kind.json index 1192d770..e19ceda7 100644 --- a/libs/neopixel/kind.json +++ b/libs/neopixel/kind.json @@ -1,7 +1,8 @@ { - "name": "neppixel", + "name": "neopixel", "description": "AdaFruit NeoPixel driver for micro:bit", "files": [ + "README.md", "neopixel.ts", "sendbuffer.asm" ], @@ -16,5 +17,6 @@ "public": true, "dependencies": { "microbit": "file:../microbit" - } + }, + "installedVersion": "zbhlje" } diff --git a/libs/neopixel/neopixel.ts b/libs/neopixel/neopixel.ts index 96118f36..4d1b497d 100644 --- a/libs/neopixel/neopixel.ts +++ b/libs/neopixel/neopixel.ts @@ -39,7 +39,7 @@ namespace neopixel { /** * Shift LEDs forward. */ - shift(off: number): void { + shift(off: number = 1): void { this.buf.shift(-off * 3) } diff --git a/libs/neopixel/neotest.ts b/libs/neopixel/neotest.ts index bf3de988..96ac9307 100644 --- a/libs/neopixel/neotest.ts +++ b/libs/neopixel/neotest.ts @@ -1,92 +1,47 @@ -basic.showLeds(` - # . . . . - . . . . . - . . # . . - . . . . . - . . . . # - `) -console.log("Start") +let strip = neopixel.create(24); +let br = 100; +strip.setBrigthness(100); +input.onButtonPressed(Button.B, () => { + br = br + 20; + if (br > 255) { + br = 5; + } + strip.setBrigthness(br); +}); -// Create a NeoPixel driver - specify the number of LEDs: -let strip = neopixel.create(7); +let rotationMode = false; +input.onButtonPressed(Button.A, () => { + rotationMode = !rotationMode; + if (rotationMode) { + basic.showLeds(` + . # # # . + # . . . # + # . . . # + # . . . # + . # # # . + `); + } else { + basic.showLeds(` + . . # . . + . . . # . + # # # # # + . . . # . + . . # . . + `); -// 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); +while (true) { + let x = input.acceleration(Dimension.X) / 2 + let y = input.acceleration(Dimension.Y) / 2 + let z = input.acceleration(Dimension.Z) / 2 + if (rotationMode) { + strip.rotate(); + } else { + strip.setPix(0, x, y, -z); + strip.shift(1); + } 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); - } -});