diff --git a/braille-display/client.ts b/braille-display/client.ts new file mode 100644 index 000000000..5935285e4 --- /dev/null +++ b/braille-display/client.ts @@ -0,0 +1,139 @@ +namespace modules { + /** + * Converts a string from unicode Braille or Braille ASCII to unicode braille + */ + export function brailify(s: string) { + if (!s) return "" + // space char -> unicode character + const braille_ascii = + "⠀⠮⠐⠼⠫⠩⠯⠄⠷⠾⠡⠬⠠⠤⠨⠌⠴⠂⠆⠒⠲⠢⠖⠶⠦⠔⠱⠰⠣⠿⠜⠹⠈⠁⠃⠉⠙⠑⠋⠛⠓⠊⠚⠅⠇⠍⠝⠕⠏⠟⠗⠎⠞⠥⠧⠺⠭⠽⠵⠪⠳⠻⠘⠸" + const a0 = " ".charCodeAt(0) + const an = braille_ascii.length + + let r = "" + const su = s.toUpperCase() + for (let i = 0; i < su.length; ++i) { + const c = su.charCodeAt(i) + const ai = c - a0 + if (c >= 0x2800 && c <= 0x28ff) r += String.fromCharCode(c) + else if (ai < an) r += braille_ascii.charAt(ai) + else r += "" + } + return r + } + + /** + * A Braille pattern display module. This module display [unicode braille patterns](https://www.unicode.org/charts/PDF/U2800.pdf), country specific encoding have to be implemented by the clients. + **/ + //% fixedInstances blockGap=8 + export class BrailleDisplayClient extends jacdac.Client { + private readonly _enabled: jacdac.RegisterClient<[boolean]> + private readonly _patterns: jacdac.RegisterClient<[string]> + private readonly _length: jacdac.RegisterClient<[number]> + + constructor(role: string) { + super(jacdac.SRV_BRAILLE_DISPLAY, role) + + this._enabled = this.addRegister<[boolean]>( + jacdac.BrailleDisplayReg.Enabled, + jacdac.BrailleDisplayRegPack.Enabled + ) + this._patterns = this.addRegister<[string]>( + jacdac.BrailleDisplayReg.Patterns, + jacdac.BrailleDisplayRegPack.Patterns + ) + this._length = this.addRegister<[number]>( + jacdac.BrailleDisplayReg.Length, + jacdac.BrailleDisplayRegPack.Length, + jacdac.RegisterClientFlags.Const + ) + } + + /** + * Sets the patterns displayed as Braille ASCII or Unicode Braille characters. + * Enables the display if needed. + * @param text Braille ASCII or Unicode Braille characters to display + */ + //% blockId=jacdac_brailledisplay_set_patterns_text block="set %brailledisplay text to %text" + //% group="Display" + //% weight=100 + setText(text: string) { + const length = this.length() + let brailled = brailify(text) + if (length > 0) brailled = brailled.slice(0, length) + this.setPatterns(brailled) + if (text) this.setEnabled(true) + } + + /** + * Determines if the braille display is active. + */ + //% callInDebugger + //% group="Display" + //% block="%brailledisplay enabled" + //% blockId=jacdac_brailledisplay_enabled___get + //% weight=99 + enabled(): boolean { + this.start() + const values = this._enabled.pauseUntilValues() as any[] + return !!values[0] + } + + /** + * Determines if the braille display is active. + */ + //% group="Display" + //% blockId=jacdac_brailledisplay_enabled___set + //% block="set %brailledisplay %value=toggleOnOff" + //% weight=98 + setEnabled(value: boolean) { + this.start() + const values = this._enabled.values as any[] + values[0] = value ? 1 : 0 + this._enabled.values = values as [boolean] + } + + /** + * Braille patterns to show. Must be unicode characters between `0x2800` and `0x28ff`. + */ + //% callInDebugger + //% group="Display" + //% weight=98 + patterns(): string { + this.start() + const values = this._patterns.pauseUntilValues() as any[] + return values[0] + } + + /** + * Braille patterns to show. Must be unicode characters between `0x2800` and `0x28ff`. + */ + //% group="Display" + //% weight=97 + setPatterns(value: string) { + this.start() + this.setEnabled(true) + const values = this._patterns.values as any[] + values[0] = value + this._patterns.values = values as [string] + } + + /** + * Gets the number of patterns that can be displayed. + */ + //% callInDebugger + //% group="Display" + //% weight=96 + length(): number { + this.start() + const values = this._length.pauseUntilValues() as any[] + return values[0] + } + } + + //% fixedInstance whenUsed weight=1 block="braille display1" + export const brailleDisplay1 = new BrailleDisplayClient("braille Display1") + + //% fixedInstance whenUsed weight=2 block="braille display2" + export const brailleDisplay2 = new BrailleDisplayClient("braille Display2") +} diff --git a/braille-display/pxt.g.json b/braille-display/pxt.json similarity index 96% rename from braille-display/pxt.g.json rename to braille-display/pxt.json index 93e73a712..690050012 100644 --- a/braille-display/pxt.g.json +++ b/braille-display/pxt.json @@ -4,7 +4,7 @@ "description": "A Braille pattern display module. This module display [unicode braille patterns](https://www.unicode.org/charts/PDF/U2800.pdf), country specific encoding have to be implemented by the clients.", "files": [ "constants.ts", - "client.g.ts" + "client.ts" ], "testFiles": [ "test.ts" diff --git a/braille-display/test.ts b/braille-display/test.ts new file mode 100644 index 000000000..58ec191a1 --- /dev/null +++ b/braille-display/test.ts @@ -0,0 +1,6 @@ +let i = 0 +forever(() => { + modules.brailleDisplay1.setText(i + "") + pause(1000) + i++ +}) diff --git a/sound-level/client.g.ts b/sound-level/client.g.ts index 8da8c5f27..0c837117b 100644 --- a/sound-level/client.g.ts +++ b/sound-level/client.g.ts @@ -5,6 +5,8 @@ namespace modules { //% fixedInstances blockGap=8 export class SoundLevelClient extends jacdac.SimpleSensorClient { private readonly _enabled: jacdac.RegisterClient<[boolean]> + private readonly _loudThreshold: jacdac.RegisterClient<[number]> + private readonly _quietThreshold: jacdac.RegisterClient<[number]> constructor(role: string) { super( @@ -17,6 +19,14 @@ namespace modules { jacdac.SoundLevelReg.Enabled, jacdac.SoundLevelRegPack.Enabled ) + this._loudThreshold = this.addRegister<[number]>( + jacdac.SoundLevelReg.LoudThreshold, + jacdac.SoundLevelRegPack.LoudThreshold + ) + this._quietThreshold = this.addRegister<[number]>( + jacdac.SoundLevelReg.QuietThreshold, + jacdac.SoundLevelRegPack.QuietThreshold + ) } /** @@ -59,19 +69,101 @@ namespace modules { this._enabled.values = values as [boolean] } + /** + * Set level at which the `loud` event is generated. + */ + //% callInDebugger + //% group="Sound" + //% weight=97 + loudThreshold(): number { + this.start() + const values = this._loudThreshold.pauseUntilValues() as any[] + return values[0] * 100 + } + + /** + * Set level at which the `loud` event is generated. + */ + //% group="Sound" + //% weight=96 + //% value.min=0 + //% value.max=100 + //% value.defl=100 + setLoudThreshold(value: number) { + this.start() + const values = this._loudThreshold.values as any[] + values[0] = value / 100 + this._loudThreshold.values = values as [number] + } + + /** + * Set level at which the `quiet` event is generated. + */ + //% callInDebugger + //% group="Sound" + //% weight=95 + quietThreshold(): number { + this.start() + const values = this._quietThreshold.pauseUntilValues() as any[] + return values[0] * 100 + } + + /** + * Set level at which the `quiet` event is generated. + */ + //% group="Sound" + //% weight=94 + //% value.min=0 + //% value.max=100 + //% value.defl=100 + setQuietThreshold(value: number) { + this.start() + const values = this._quietThreshold.values as any[] + values[0] = value / 100 + this._quietThreshold.values = values as [number] + } + /** * Run code when the sound level changes by the given threshold value. */ //% group="Sound" //% blockId=jacdac_soundlevel_on_sound_level_change //% block="on %soundlevel sound level changed by %threshold (\\%)" - //% weight=97 + //% weight=93 //% threshold.min=0 //% threshold.max=100 //% threshold.defl=5 onSoundLevelChangedBy(threshold: number, handler: () => void): void { this.onReadingChangedBy(threshold / 100, handler) } + + /** + * Register code to run when an event is raised + */ + //% group="Sound" + //% blockId=jacdac_on_soundlevel_event + //% block="on %soundlevel %event" + //% weight=92 + onEvent(ev: jacdac.SoundLevelEvent, handler: () => void): void { + this.registerEvent(ev, handler) + } + + /** + * Generated when a loud sound is detected. + */ + //% group="Sound" + //% weight=91 + onLoud(handler: () => void): void { + this.registerEvent(jacdac.SoundLevelEvent.Loud, handler) + } + /** + * Generated low level of sound is detected. + */ + //% group="Sound" + //% weight=90 + onQuiet(handler: () => void): void { + this.registerEvent(jacdac.SoundLevelEvent.Quiet, handler) + } } //% fixedInstance whenUsed weight=1 block="sound level1" diff --git a/sound-level/constants.ts b/sound-level/constants.ts index bf9aa4e41..0fffbfebc 100644 --- a/sound-level/constants.ts +++ b/sound-level/constants.ts @@ -19,6 +19,24 @@ namespace jacdac { * ``` */ Enabled = 0x1, + + /** + * Read-write ratio u0.16 (uint16_t). Set level at which the `loud` event is generated. + * + * ``` + * const [loudThreshold] = jdunpack<[number]>(buf, "u0.16") + * ``` + */ + LoudThreshold = 0x6, + + /** + * Read-write ratio u0.16 (uint16_t). Set level at which the `quiet` event is generated. + * + * ``` + * const [quietThreshold] = jdunpack<[number]>(buf, "u0.16") + * ``` + */ + QuietThreshold = 0x5, } export namespace SoundLevelRegPack { @@ -31,5 +49,29 @@ namespace jacdac { * Pack format for 'enabled' register data. */ export const Enabled = "u8" + + /** + * Pack format for 'loud_threshold' register data. + */ + export const LoudThreshold = "u0.16" + + /** + * Pack format for 'quiet_threshold' register data. + */ + export const QuietThreshold = "u0.16" + } + + export const enum SoundLevelEvent { + /** + * Generated when a loud sound is detected. + */ + //% block="loud" + Loud = 0x1, + + /** + * Generated low level of sound is detected. + */ + //% block="quiet" + Quiet = 0x2, } }