Skip to content

Integration basics

Common rules for all DzenTech devices. Device-specific details live on each device’s page.

Typical sequence:

  1. start a BLE scan;
  2. pick the device by name and a stable identifier;
  3. establish a GATT connection;
  4. locate the required service and characteristic;
  5. enable notifications if the device replies asynchronously;
  6. send a liveness/status query;
  7. consider the device ready only after a valid protocol-level reply;
  8. serialize all write operations to a single device;
  9. on disconnect, stop issuing commands, cancel pending waits and close the GATT objects.

All controllers use:

  • service UUID: 0000FFE0-0000-1000-8000-00805F9B34FB;
  • characteristic UUID: 0000FFE1-0000-1000-8000-00805F9B34FB.

Common serial-port parameters:

  • 8 data bits;
  • no parity;
  • 1 stop bit;
  • flow control disabled.

Baud rate depends on the device:

  • GlamBot: 115200;
  • Spinner360: 9600.

ASCII commands end with the byte 0D (\r). No LF is appended.

An open BLE or COM transport does not yet mean the device is ready. Distinguish:

  • transportConnected — the channel is open;
  • protocolReady — a valid device reply has been received;
  • desiredState — the requested state;
  • actualState — the state confirmed by a reply.

A successful GATT/COM write confirms delivery to the transport, not execution of the command by the device.

This gap is not theoretical — it is the most common cause of commands that “were sent but did nothing”. Two shapes of it show up on hardware:

  • Right after subscribing. Queries fired immediately after enabling notifications, or as a tight burst, can be dropped before the parser is running. Pace the opening queries — roughly 400–500 ms apart on Spinner360 — and repeat the one whose reply never arrived.
  • Between repeated commands. Relative step commands need real spacing: MixUp Pixel v1 loses steps below 120 ms between writes, even though every write was acknowledged.

Per-device figures are on each device page. When in doubt, gate the next command on a reply rather than on the write acknowledgement.

Recommended baseline policy:

  1. at most three attempts for an idempotent command;
  2. a 300–500 ms interval;
  3. after the attempts are exhausted, close the transport;
  4. reconnect;
  5. re-read the status;
  6. do not retry non-idempotent commands without checking the actual state.
  • don’t filter the scan by service UUID — advertised and GATT UUIDs differ (see BLE);
  • match every known name alias, not just the primary mask: MixUp Backlight v2 also appears as SPStellar;
  • a silent V? on Spinner360 doesn’t mean the controller is incompatible — only that its version and acceleration support are unconfirmed. Probe the basic commands separately.

Check:

  1. the right device identifier is selected;
  2. the service and characteristic UUIDs match;
  3. service discovery has completed;
  4. the GATT object hasn’t been closed by a parallel operation;
  5. a stale GATT cache isn’t in use;
  6. notifications are enabled before any command with a fast reply.
  • check the characteristic write mode (with/without response);
  • serialize writes;
  • space repeated commands — an acknowledged write is not an applied one;
  • read the status after the command;
  • MixUp Pixel v1: always read power before a toggle; keep ≥ 120 ms between speed steps; expect an unsolicited status after a toggle, and a duplicate if you then query;
  • MixUp Backlight v2: re-select the RGB/white mode before sending a value; effect speed is a 0…10 scale and the firmware clamps above 0A;
  • Spinner360: check the decimal/hex interpretation — set commands take decimal, replies come back hexadecimal with a P (speed) or C (acceleration) prefix;
  • MixUp White: check the percent → 0..255 conversion.

Check:

  • the right COM port;
  • the baud rate;
  • 8N1;
  • flow control disabled;
  • the 0D terminator;
  • no other process holding the port.

On disconnect:

  1. block new commands;
  2. cancel pending waits;
  3. end the notification subscription;
  4. close the characteristic, service and device;
  5. do not reuse old GATT objects after a reconnect.

Close/unsubscribe operations must not run as a synchronous blocking wait on a UI/STA thread.