Skip to content

stc1988/moddable-m5chain

Repository files navigation

moddable-m5chain

moddable-m5chain is a Moddable SDK module for controlling M5Chain devices over UART.
It handles device enumeration, initialization, event dispatch, and polling.

Device Capability Matrix

Device Type ID HasLed HasKey CanSample Sample Event (onSample) API Guide
Encoder 0x0001 Yes Yes Yes Yes (delta value) Encoder API
Angle 0x0002 Yes No Yes Yes (normalized 0.00-1.00) Angle API
Key 0x0003 Yes Yes No No Key API
JoyStick 0x0004 Yes Yes Yes Yes ({ x, y } in -128 to 127) JoyStick API
ToF 0x0005 Yes No Yes Yes (distance in mm) ToF API

Features

  • Packet transport and matching (sendPacket / sendAndWait)
  • Automatic scan on startup
  • Automatic re-scan when ENUM_PLEASE (0xFC) is received (debounced)
  • Feature composition with mixins (LED, Key, Sample)
  • Poll loop runs only when at least one device has onSample set

Setup

1) Include this module in your manifest

In your app's manifest.json, include this module's manifest.

{
	"include": [
		{
			"git":"https://github.com/stc1988/moddable-m5chain.git"
		}
	]
}

2) Pin configuration

For M5Stack products, the default UART pins are set to the Grove port.

If you use an M5Atom series device with Atom Chain Base, automatically provides a config.m5chain pin configuration.

See Minimal Usage for the concrete usage pattern.

Minimal Usage

import M5Chain from "m5chain";
import config from "mc/config";

const m5chain = new M5Chain({
	transmit: config.m5chain.transmit,
	receive: config.m5chain.receive,
	debug: false,
	pollingInterval: 30, // ms
});

m5chain.onDeviceListChanged = (devices) => {
	for (const device of devices) {
		trace(`id=${device.id} type=0x${device.type.toString(16)} uid=${device.uuid}\n`);
	}
};

await m5chain.start();

Event Model

m5chain.onDeviceListChanged = (devices) => {}

  • Called after the initial scan completes in start()
  • Called again after re-scan when the chain sends ENUM_PLEASE
  • devices is the current connected device list

device.onPush = (status) => {}

Available on devices with HasKey (Encoder / Key / JoyStick).

  • status is a key event, not the pressed/released state
  • Use KEY_EVENT.SINGLE_CLICK, KEY_EVENT.DOUBLE_CLICK, or KEY_EVENT.LONG_PRESS
import M5Chain, { KEY_EVENT } from "m5chain";

device.onPush = async (keyEvent) => {
	if (keyEvent === KEY_EVENT.SINGLE_CLICK) {
		await device.setLedColor(255, 0, 0);
	}
};

KEY_EVENT, KEY_MODE, KEY_STATUS, and their TypeScript types are also exported from the key-capable device modules: m5chainEncoder, m5chainKey, and m5chainJoyStick.

device.onSample = function () {}

Available on devices with CanSample (Encoder / Angle / JoyStick / ToF).

If any device has onSample set, bus polling starts. It stops when all onSample handlers are null.

Use device.sample() to read the latest sample. Inside onSample, this is bound to the device:

device.onSample = function () {
	const sample = this.sample();
};

Angle, JoyStick, and ToF dispatch onSample with the latest sampled value on every poll. Encoder dispatches onSample with the delta from the previous encoder value and skips dispatch while the value is unchanged.

API

M5Chain

  • new M5Chain({ transmit, receive, debug = false, pollingInterval = 30 })
  • await m5chain.start()
  • m5chain.devices current device array

Common Device API (M5ChainDevice)

  • device.id
  • device.type
  • device.uuid (after init())
  • await device.configure(options) applies device and feature settings
  • await device.readConfiguration() reads current device and feature settings from the chain device
  • await device.getUID(uidType = 1) (uidType: 0 | 1)
  • await device.getBootloaderVersion()
  • await device.getFirmwareVersion()

LED Features (HasLed)

Available on: Encoder / Angle / Key / JoyStick / ToF

See HasLed API.

Key Features (HasKey)

Available on: Encoder / Key / JoyStick

See HasKey API.

Sample Features (CanSample)

Available on: Encoder / Angle / JoyStick / ToF

See CanSample API.

Device-specific APIs

Device-specific usage, TypeScript exports, and method details are split into focused pages:

Feature mixin details are also split into focused pages:

README intentionally keeps only the setup, event model, and shared API surface so device and feature pages can grow without making the first-read path hard to scan.

Examples

  • examples/basic: device discovery, info read, and event subscription
  • examples/led: LED control for Encoder/Angle/Key/JoyStick/ToF
  • examples/ble-hid/keyboard: BLE HID keyboard example that sends Enter from M5Chain Key events (docs)
  • examples/ble-hid/mediaControl: BLE HID media control example that sends Play/Pause, Next Track, and Previous Track from M5Chain Key events (docs)
  • examples/hotplug: re-scan verification after device reconnect, using uuid, LED blink, key events, and sampled values

BLE HID keyboard controls

examples/ble-hid/keyboard/bleKeyboard.ts exposes a small keyboard peripheral helper. It supports single keys, modifier combinations, text typing, connection state, up to six simultaneous normal keys in one HID report, manual press/release, host LED indicators such as Caps Lock, and manual BLE advertising control. See BLE HID Keyboard Example for the full API.

keyboard.notifyKey({
	keyCode: BLEKeyboard.KEY_CODE.A,
	modifiers: BLEKeyboard.MODIFIER.LEFT_SHIFT,
});

keyboard.notifyKeyCodes([BLEKeyboard.KEY_CODE.A, BLEKeyboard.KEY_CODE.B]);
keyboard.typeText("hello\n");

keyboard.pressKeyCodes([BLEKeyboard.KEY_CODE.DELETE], BLEKeyboard.MODIFIER.LEFT_CONTROL | BLEKeyboard.MODIFIER.LEFT_ALT);
keyboard.releaseAll();

keyboard.stopAdvertising();
keyboard.startAdvertising();

keyboard.onIndicatorsChanged = (indicators) => {
	trace(`caps lock=${(indicators & BLEKeyboard.INDICATOR.CAPS_LOCK) !== 0}\n`);
};

BLE HID media controls

examples/ble-hid/mediaControl/bleMediaControl.ts exposes a small media control peripheral helper. It sends HID Consumer Control usages such as Play/Pause, Next Track, Previous Track, Volume Up, Volume Down, and Mute. See BLE HID Media Control Example for the full API.

mediaControl.notifyUsage(BLEMediaControl.USAGE.PLAY_PAUSE);
mediaControl.notifyUsage(BLEMediaControl.USAGE.SCAN_NEXT_TRACK);
mediaControl.notifyUsage(BLEMediaControl.USAGE.VOLUME_UP);

Development

Format and lint:

npm run format
npm run lint

License

MIT

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors