Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions build/devices/pico/targets/ws_round/host/provider.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import PulseCount from "embedded:io/pulsecount";
import PWM from "embedded:io/pwm";
import SMBus from "embedded:io/smbus";
import SPI from "embedded:io/spi";
import QMI8658 from "embedded:sensor/Accelerometer-Gyroscope/QMI8658";

class Backlight {
#io;
Expand Down Expand Up @@ -92,6 +93,27 @@ const device = {
return new Backlight({pin: device.pin.backlight });
}
}
},
sensor: {
IMU: class extends QMI8658 {
constructor(options) {
super({
...options,
sensor: {
...device.I2C.default,
io: device.io.SMBus
}
});
}
sample() {
const sample = super.sample();
[sample.accelerometer.x, sample.accelerometer.y] = [sample.accelerometer.y, sample.accelerometer.x];
sample.accelerometer.z *= -1;
[sample.gyroscope.x, sample.gyroscope.y] = [sample.gyroscope.y, sample.gyroscope.x];
sample.gyroscope.z *= -1;
return sample;
}
}
}
};

Expand Down
9 changes: 1 addition & 8 deletions build/devices/pico/targets/ws_round/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@
"include": [
"$(MODDABLE)/modules/io/manifest.json",
"$(MODDABLE)/modules/drivers/gc9a01/manifest.json",
"$(MODULES)/drivers/led/manifest.json",
"$(MODULES)/drivers/button/manifest.json",
"$(MODULES)/pins/pwm/manifest.json"
"$(MODDABLE)/modules/drivers/sensors/qmi8658/manifest.json"
],
"modules": {
"setup/target": "./setup-target"
Expand All @@ -19,11 +17,6 @@
"lcd_cs_pin": 9
},
"defines": {
"i2c": {
"sda_pin": 6,
"scl_pin": 7,
"port": 1
},
"spi": {
"mosi_pin": 11,
"sck_pin": 10
Expand Down
43 changes: 9 additions & 34 deletions build/devices/pico/targets/ws_round/setup-target.js
Original file line number Diff line number Diff line change
@@ -1,45 +1,20 @@
import Digital from "pins/digital";
import config from "mc/config";
import Timer from "timer";
import PWM from "pins/pwm";

class Backlight extends PWM {
constructor(brightness = 100) {
super({pin: config.backlight});
this.write(brightness);
}
write(value) {
if (value <= 0)
value = 0;
else if (value >= 100)
value = 1023;
else
value = (value / 100) * 1023;
super.write(value);
}
}

globalThis.Host = Object.freeze({
Backlight
}, true);

export default function (done) {
if ((undefined == config.brightness) || ("none" === config.brightness))
Digital.write(config.backlight, 0);
else if ("off" === config.backlight)
Digital.write(config.backlight, 1);
else {
globalThis.backlight = new device.peripheral.Backlight;
backlight.brightness = parseInt(config.brigtness) / 100;
}
const Digital = device.io.Digital;

const displayResetPin = new Digital({ pin: config.lcd_rst_pin, mode: Digital.Output });
const displayCSPin = new Digital({ pin: config.lcd_cs_pin, mode: Digital.Output });

Digital.write(config.lcd_rst_pin, 1);
displayResetPin.write(1);
Timer.delay(100);
Digital.write(config.lcd_rst_pin, 0);
displayResetPin.write(0);
Timer.delay(100);
Digital.write(config.lcd_rst_pin, 0);
Digital.write(config.lcd_cs_pin, 0);
displayCSPin.write(0);
Timer.delay(100);
displayResetPin.close();
displayCSPin.close();

done();
}
22 changes: 21 additions & 1 deletion build/devices/pico/targets/ws_round_touch/host/provider.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2022-2025 Moddable Tech, Inc.
* Copyright (c) 2022-2026 Moddable Tech, Inc.
*
* This file is part of the Moddable SDK Runtime.
*
Expand Down Expand Up @@ -27,6 +27,7 @@ import PWM from "embedded:io/pwm";
import SMBus from "embedded:io/smbus";
import SPI from "embedded:io/spi";
import Touch from "embedded:sensor/Touch/CST816";
import QMI8658 from "embedded:sensor/Accelerometer-Gyroscope/QMI8658";

class Backlight {
#io;
Expand Down Expand Up @@ -117,6 +118,25 @@ const device = {
result.configure({ });
return result;
}
},
IMU: class extends QMI8658 {
constructor(options) {
super({
...options,
sensor: {
...device.I2C.default,
io: device.io.SMBus
}
});
}
sample() {
const sample = super.sample();
[sample.accelerometer.x, sample.accelerometer.y] = [sample.accelerometer.y, sample.accelerometer.x];
sample.accelerometer.z *= -1;
[sample.gyroscope.x, sample.gyroscope.y] = [sample.gyroscope.y, sample.gyroscope.x];
sample.gyroscope.z *= -1;
return sample;
}
}
}
};
Expand Down
11 changes: 2 additions & 9 deletions build/devices/pico/targets/ws_round_touch/manifest.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
{
"include": [
"$(MODDABLE)/modules/io/manifest.json",
"$(MODDABLE)/modules/drivers/gc9a01/manifest.json",
"$(MODULES)/drivers/led/manifest.json",
"$(MODULES)/drivers/button/manifest.json",
"$(MODULES)/pins/pwm/manifest.json",
"$(MODULES)/drivers/gc9a01/manifest.json",
"$(MODULES)/drivers/sensors/qmi8658/manifest.json",
"$(MODULES)/drivers/sensors/cst816/manifest.json"
],
"modules": {
Expand All @@ -20,11 +18,6 @@
"lcd_cs_pin": 9
},
"defines": {
"i2c": {
"sda_pin": 26,
"scl_pin": 27,
"port": 1
},
"spi": {
"mosi_pin": 11,
"sck_pin": 10
Expand Down
2 changes: 1 addition & 1 deletion documentation/devices/pico.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ The Moddable SDK supports devices built with the Pico. The following table lists
| <img src="../assets/devices/pico-adafruit-qt-py-rp2040.png" width=150></a><br>Adafruit<br>QT Py | `pico/qtpy` | STEMMA/Qwiic connector, Neopixel, 1 button | <li>[Adafruit product page](https://www.adafruit.com/product/4900)</li> |
| <img src="../assets/devices/pico-adafruit-qt-trinkey.png" width=150></a><br>Adafruit<br>Trinkey QT2040 | `pico/qt_trinkey` | STEMMA/Qwiic connector, Neopixel, 1 button | <li>[Adafruit product page](https://www.adafruit.com/product/5056)</li> |
| <img src="../assets/devices/pico-pimoroni-tiny-2040.png" width=150></a><br>Pimoroni<br>Tiny 2040 | `pico/tiny2040` | RGB LED, 1 button| <li>[Pimoroni product page](https://shop.pimoroni.com/products/tiny-2040?variant=39560012234835)</li> |
| <img src="../assets/devices/ws_round.png" width=150></a><br>WAVESHARE<br>1.28inch Round LCD | `pico/ws_round`<BR>`pico/ws_round_touch` | 1.28" IPS 240×240 Round Display| <li>[WAVESHARE product page](https://www.waveshare.com/rp2040-lcd-1.28.htm)</li><li>[touch LCD version](https://www.waveshare.com/product/rp2040-touch-lcd-1.28.htm)</li> |
| <img src="../assets/devices/ws_round.png" width=150></a><br>WAVESHARE<br>1.28inch Round LCD | `pico/ws_round`<BR>`pico/ws_round_touch` | 1.28" IPS 240×240 Round Display<BR>IMU| <li>[WAVESHARE product page](https://www.waveshare.com/rp2040-lcd-1.28.htm)</li><li>[touch LCD version](https://www.waveshare.com/product/rp2040-touch-lcd-1.28.htm)</li> |
| <img src="../assets/devices/pico-seeed-studio-xiao-rf2040.png" width=150></a><br>Seeed Studio<br>XIAO RP2040 | `pico/xiao_rp2040` | Neopixel | <li>[Seeed Studio product page](https://www.seeedstudio.com/XIAO-RP2040-v1-0-p-5026.html)</li> |
| <img src="../assets/devices/pico-xiao-ili9341.png" width=140></a><BR>ili9341 | `pico/xiao_ili9341` | ili9341 QVGA display<BR>320 x 240<BR>16-bit color | <li>[Wiring Guide - Pico](../displays/images/xiao-qtpy-ili9341-wiring.png)</li> |
| <img src="../assets/devices/pico-ili9341.png" width=140></a><BR>ili9341 | `pico/ili9341` | ili9341 QVGA display<BR>320 x 240<BR>16-bit color | <li>[Generic 2.4" & 2.8" Displays (Resistive Touch) Wiring Guide - Pico](../displays/wiring-guide-generic-2.4-spi-pico.md)</li> |
Expand Down
Binary file added examples/drivers/sensors/qmi8658/bounce/ball.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
132 changes: 132 additions & 0 deletions examples/drivers/sensors/qmi8658/bounce/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
/*
* Copyright (c) 2016-2017 Moddable Tech, Inc.
*
* This file is part of the Moddable SDK.
*
* This work is licensed under the
* Creative Commons Attribution 4.0 International License.
* To view a copy of this license, visit
* <http://creativecommons.org/licenses/by/4.0>.
* or send a letter to Creative Commons, PO Box 1866,
* Mountain View, CA 94042, USA.
*
*/

import config from "mc/config";
import Timer from "timer";
import parseBMF from "commodetto/parseBMF";
import parseBMP from "commodetto/parseBMP";
import Poco from "commodetto/Poco";
import Resource from "Resource";
import ILI9341 from "ili9341";
import device from "embedded:provider/builtin";
import Accelerometer from "embedded:sensor/Accelerometer-Gyroscope/MPU6050";

let pixelsOut = new ILI9341({});
const width = pixelsOut.width;
const height = pixelsOut.height;

let render = new Poco(pixelsOut);
let font = parseBMF(new Resource("OpenSans-Semibold-18.bf4"));

let ball = parseBMP(new Resource("ball-color.bmp"));
ball.alpha = parseBMP(new Resource("ball-alpha.bmp"));
ball.x = width >> 1;
ball.y = height >> 1;
ball.vx = 0;
ball.vy = 0;
ball.yMin = font.height * 3;
ball.backGroundColor = render.makeColor(0, 0, 0);

const textColor = render.makeColor(255, 255, 255);
const backgroundColor = render.makeColor(64, 64, 64);
const barColor = render.makeColor(128, 128, 128);

render.begin();
render.fillRectangle(backgroundColor, 0, 0, width, ball.yMin);
render.fillRectangle(ball.backgroundColor, 0, ball.yMin, width, height);
render.end();

let sensor = new Accelerometer({
sensor: {
...device.I2C.default,
io: device.io.SMBus
}
});

Timer.repeat(() => {
let values = sensor.sample();

if (180 === parseInt(config.orientation)) {
values.accelerometer.x = -values.accelerometer.x;
}

render.begin(0, 0, width, ball.yMin);
render.fillRectangle(backgroundColor, 0, 0, width, height);

drawBar("X", values.accelerometer.x, 0, 0, width, font.height);
drawBar("Y", values.accelerometer.y, 0, font.height, width, font.height);
drawBar("Z", values.accelerometer.z, 0, font.height * 2, width, font.height);
render.end();

ball.vx = (ball.vx + values.accelerometer.y) * 0.98;
ball.vy = (ball.vy + values.accelerometer.x) * 0.98;
let x = ball.x + ball.vx;
let y = ball.y + ball.vy;
if (x < 0) {
x = -x;
ball.vx = -ball.vx;
}
else if (x > (width - ball.width)) {
x = width - ball.width;
ball.vx = -ball.vx;
}
if (y < ball.yMin) {
y = ball.yMin;
ball.vy = -ball.vy;
}
else if (y > (height - ball.height)) {
y = height - ball.height;
ball.vy = -ball.vy;
}
moveBallTo(x, y)
}, 17);

function formatValue(value) {
if (!value)
return value;
if (value < 0)
return value.toFixed(3);
return "+" + value.toFixed(3);
}

function drawBar(label, value, x, y, width, height) {
const halfWidth = width >> 1;
const barWidth = (value * halfWidth) | 0;

if (value > 0)
render.fillRectangle(barColor, x + halfWidth, y, barWidth, height);
else
render.fillRectangle(barColor, x + halfWidth + barWidth, y, -barWidth, height);

render.drawText(label + " " + formatValue(value), font, textColor, x + 50, y);
}

function moveBallTo(x, y) {
const w = ball.width, h = ball.height;

if ((Math.abs(ball.x - x) <= w) && (Math.abs(ball.y - y) <= h))
render.begin(Math.min(ball.x, x), Math.min(ball.y, y), w << 1, h << 1); // often overdrawing
else {
render.begin(ball.x, ball.y, w, h);
render.fillRectangle(ball.backgroundColor, 0, 0, width, height);
render.continue(x, y, w, h);
}

render.fillRectangle(ball.backgroundColor, 0, 0, width, height);
render.drawMasked(ball, x, y, 0, 0, w, h, ball.alpha, 0, 0);
render.end();

ball.x = x;
ball.y = y;
}
24 changes: 24 additions & 0 deletions examples/drivers/sensors/qmi8658/bounce/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"include": [
"$(MODDABLE)/examples/manifest_base.json",
"$(MODDABLE)/examples/manifest_commodetto.json",
"$(MODDABLE)/modules/drivers/ili9341/manifest.json",
"$(MODDABLE)/modules/drivers/sensors/mpu6050/manifest.json",
"$(MODDABLE)/modules/io/manifest.json"
],
"modules": {
"*": [
"./main"
]
},
"config": {
"orientation": "180"
},
"preload": [
"pins/*"
],
"resources": {
"*": "./ball",
"*-mask": "$(MODDABLE)/examples/assets/fonts/OpenSans-Semibold-18"
}
}
35 changes: 35 additions & 0 deletions examples/drivers/sensors/qmi8658/poll/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Copyright (c) 2026 Moddable Tech, Inc. ,Satoshi Tanaka
*
* This file is part of the Moddable SDK.
*
* This work is licensed under the
* Creative Commons Attribution 4.0 International License.
* To view a copy of this license, visit
* <http://creativecommons.org/licenses/by/4.0>.
* or send a letter to Creative Commons, PO Box 1866,
* Mountain View, CA 94042, USA.
*
*/

import QMI8658 from "embedded:sensor/Accelerometer-Gyroscope/QMI8658";
import Timer from "timer";

const sensor = new QMI8658({
sensor: {
...device.I2C.default,
io: device.io.SMBus
}
});

sensor.configure({
ACCEL_SCALE: 8.0 / 32768.0, // AFS_8G
GYRO_SCALE: 1024.0 / 32768.0 // GFS_1024DPS
});

Timer.repeat(() => {
const sample = sensor.sample();
trace(`Accel: [${sample.accelerometer.x?.toFixed(2)}, ${sample.accelerometer.y?.toFixed(2)}, ${sample.accelerometer.z?.toFixed(2)}] - `);
trace(`Gyro: [${sample.gyroscope.x?.toFixed(2)}, ${sample.gyroscope.y?.toFixed(2)}, ${sample.gyroscope.z?.toFixed(2)}]\n`);
}, 2000);

9 changes: 9 additions & 0 deletions examples/drivers/sensors/qmi8658/poll/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"include": [
"$(MODDABLE)/examples/manifest_base.json",
"$(MODDABLE)/modules/drivers/sensors/qmi8658/manifest.json"
],
"modules": {
"*": "./main"
}
}