diff --git a/README.md b/README.md index 468bd83..8e390ed 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,8 @@ Migration work has already started on the [`copilot/restructure-repo-for-api-sup [Spell Caster — Gyro Demo](https://shimmerresearch.github.io/webBLEDemos/spell-gyro/) +[DJ Gyro — 3D Turntable Scratch Demo](https://shimmerresearch.github.io/webBLEDemos/dj-gyro/) + [Shimmer Capture](https://shimmerresearch.github.io/webBLEDemos/ShimmerCapture/) [Shimmer3R Chrome Extension](https://github.com/ShimmerEngineering/webBLEDemos/tree/main/shimmer-extension) source code only, will require loading this locally via Chrome diff --git a/ShimmerAPI/shimmer3r.js b/ShimmerAPI/shimmer3r.js index a83c3fc..84fcd85 100644 --- a/ShimmerAPI/shimmer3r.js +++ b/ShimmerAPI/shimmer3r.js @@ -3,7 +3,7 @@ // Your note: "timestamp is u24, so layout is: 0x00 [u24 timestamp] " // This build defaults to u24, and you can also pass { timestampFmt: 'u24' } in the constructor. -const OPCODES = { DATA: 0x00, INQUIRY_CMD: 0x01, INQUIRY_RSP: 0x02, START_STREAM: 0x07, STOP_STREAM: 0x20, ACK: 0xFF, SAMPLING_RATE: 0x05, SET_SENSORS_CMD: 0x08, SET_GSR_RANGE: 0x21, SET_INTERNAL_EXP_POWER_ENABLE_CMD: 0x5E, START_BT_STEAM_SD_Logging: 0x70, STOP_BT_STEAM_SD_Logging: 0x97}; +const OPCODES = { DATA: 0x00, INQUIRY_CMD: 0x01, INQUIRY_RSP: 0x02, START_STREAM: 0x07, STOP_STREAM: 0x20, ACK: 0xFF, SAMPLING_RATE: 0x05, SET_SENSORS_CMD: 0x08, SET_GSR_RANGE: 0x21, SET_GYRO_RANGE: 0x49, SET_INTERNAL_EXP_POWER_ENABLE_CMD: 0x5E, START_BT_STEAM_SD_Logging: 0x70, STOP_BT_STEAM_SD_Logging: 0x97}; const DEFAULTS = { SERVICE_UUID: '65333333-a115-11e2-9e9a-0800200ca100', @@ -292,6 +292,39 @@ export class Shimmer3RClient { return { gsrRange, ackRemainder }; } + /** + * Set the gyro range (SET_MPU9150_GYRO_RANGE_COMMAND, 0x49). + * Shimmer3R: 0 = ±125dps, 1 = ±250dps, 2 = ±500dps, 3 = ±1000dps, 4 = ±2000dps, 5 = ±4000dps. + * (Shimmer3 only supports 0–3: ±250/500/1000/2000dps.) + */ + async setGyroRange(gyroRange) { + if (!Number.isInteger(gyroRange) || gyroRange < 0 || gyroRange > 5) { + throw new Error('gyro range must be a 0-5 value'); + } + if (!this.rx) throw new Error('Not connected (RX missing)'); + + const cmd = new Uint8Array([ + OPCODES.SET_GYRO_RANGE, + gyroRange & 0xFF, + ]); + + this._emitStatus( + `SET_GYRO_RANGE → waiting for ACK…` + ); + + const ackRemainder = await this._writeExpectingAck(cmd, 1500); + + this._emitStatus( + `SET_GYRO_RANGE (ACK received).` + ); + this.gyroRangeSetting = gyroRange; + return { gyroRange, ackRemainder }; + } + + getGyroRange() { + return this.gyroRangeSetting; + } + getInternalExpPower(){ return this.ExpPower; } diff --git a/dj-gyro/index.html b/dj-gyro/index.html new file mode 100644 index 0000000..ffa2bca --- /dev/null +++ b/dj-gyro/index.html @@ -0,0 +1,1818 @@ + + + + + + + + + + DJ Gyro — Shimmer3R Turntable + + + +
+ + +
+
+

🎧 DJ GYRO

+
A 3D turntable driven by your Shimmer3R's Z-axis gyroscope
+
    +
  • Connect: pick a gyro range, then hit 🔍 Scan & Play — it connects, configures and starts streaming in one go.
  • +
  • Hold the Shimmer3R flat (like a record) and twist it around its Z-axis — the vinyl follows your hand 1:1. Twist fast to scratch, hold still to stop the record.
  • +
  • Motor: 🎚️ Motor 33⅓ keeps the record grooving at 33⅓ RPM whenever your hand is off it.
  • +
  • No device? Drag the record with your mouse/finger, or hit 🤖 Auto-DJ to watch it scratch itself.
  • +
  • The crate: three original tracks — funk, boom bap and house — all synthesized in your browser, 100% royalty-free. Swap records with the 💿 selector.
  • +
  • Record your set: ⏺ Record captures everything you hear and saves it as a WAV when you stop.
  • +
+
+ Requirements: Shimmer3R · Firmware ≥ v1.0.22 · Chrome/Edge (Web Bluetooth) +
+
+ + +
+ +
+
+ + +
+ + + + + + + + +

No device selected

+
+ + +
+
Deck A · Shimmer Funk Break
+
Platter0.0RPM
+
Pitch%
+
Gyro Z0°/s
+
+ +
+ + +
+
+ + +
+
+ + +
+
+ + +
+ +
+ +

+  
🖱️ Drag the record to scratch · Click the deck's START/STOP button · Space = motor · Drag empty space to orbit
+
+ + + + + +