Skip to content

Instantly share code, notes, and snippets.

@mbullington
Created September 27, 2020 19:32
Show Gist options
  • Save mbullington/37957501a07ad065b67d4e8d39bfe012 to your computer and use it in GitHub Desktop.
Save mbullington/37957501a07ad065b67d4e8d39bfe012 to your computer and use it in GitHub Desktop.

Reverse Engineering SP110e LED Controller

Through Bluetooth sniffing, using this method I've been able to (semi reliably) control the SP110e controller via Homebridge.

You can find this controller for very cheap here: https://www.aliexpress.com/item/4000773623427.html?spm=a2g0o.productlist.0.0.4f09329cJ7C1H4&algo_pvid=542e757b-587f-4540-8652-2195883f1349&algo_expid=542e757b-587f-4540-8652-2195883f1349-0&btsid=0bb0622a16012309671478585ed4bd&ws_ab_test=searchweb0_0,searchweb201602_,searchweb201603_

This entire guide is for Bluetooth LE libraries, and uses hexidecimal.

LE configuration

Service ID can be found with ffe0. Under this is two characteristics, ffe1 and ffe2.

Important:

Upon connection, you immediately need to write data in this order to prevent the connection from closing.

I'm not honestly sure why.

ffe2: 01 00 ffe1: 01 b7 e3 d5

Controlling after Connected

All of these commands should be written to the ffe1 characteristics.

VV, RR, GG, and BB in this case are hex strings between 0-255.

Turn on:

fa 0e c7 aa

Turn off:

b0 4f c2 ab

Change color:

RR GG BB 1e

Control brightness:

VV ed 29 2a

Change to preset::

VV 09 fa 2c

Change speed of preset::

VV 10 34 03

@JonasHenkens
Copy link

JonasHenkens commented Jan 28, 2021

I've been able to get a more complete list of commands by reverse engineering the "LED Hue" app that's provided for the SP110E.
There are a total of 14 commands.

Every command consists of 4 bytes, except for the rename command that has extra bytes at the end.
The first 3 bytes contain data and the fourth is the command byte.
For the commands that require less bytes, the unused bytes can be anything.

My device's service id is 0xFFE0 and has one characteristic 0xFFE1 with a descriptor 0x2902.
For my SP110E there was no need to send specific commands immediately.

Informative

CHECK_DEVICE

Get device information and calculate checksum.

Command byte: 0xD5
Data: 3 bytes
Return: 13 bytes
Example: D7 F3 A1 D5

  1. Checksum
  2. Enable
  3. Preset
  4. Speed
  5. Brightness
  6. IC model
  7. channel
  8. Pixel count MSB
  9. Pixel count LSB
  10. Red
  11. Green
  12. Blue
  13. White led brightness

The checksum can be used to verify you are talking to the correct device.
The data bytes are used in calculation of the checksum.
It can be calculated using following function.

byte calculateChecksum(byte[] bArr) {
	return (byte) (bArr[2] | ((bArr[0] << 1) & 254 & 105) | bArr[1]);
}
GET_INFO

This command returns the same data as CHECK_DEVICE but without the checksum.

Command byte: 0x10
Data: 0 bytes
Return: 12 bytes
Example: 00 00 00 10

Configuration

SET_IC_MODEL

Update which IC the led strip uses.

Command byte: 0x1C
Data: 1 byte
Return: 0 bytes
Example: 03 00 00 1C

byte IC
0x00 SM16703
0x01 TM1804
0x02 UCS1903
0x03 WS2811
0x04 WS2801
0x05 SK6812
0x06 LPD6803
0x07 LPD8806
0x08 APA102
0x09 APA105
0x0A DMX512
0x0B TM1914
0x0C TM1913
0x0D P9813
0x0E INK1003
0x0F P943S
0x10 P9411
0x11 P9413
0x12 TX1812
0x13 TX1813
0x14 GS8206
0x15 GS8208
0x16 SK9822
0x17 TM1814
0x18 SK6812_RGBW
0x19 P9414
0x1A PG412
SET_RGB_SEQ

Set the RGB sequence.

Command byte: 0x3C
Data: 1 byte
Return: 0 bytes
Example: 04 00 00 3C

byte sequence
0x00 RGB
0x01 RBG
0x02 GRB
0x03 GBR
0x04 BRG
0x05 BGR
SET_LED_NUM

Set the amount of pixels to control (1-1024).

Command byte: 0x2D
Data: 2 bytes
Return: 0 bytes
Example: 01 6A 00 2D

First byte is the most significant.

RENAME

Rename the device.

Command byte: 0xBB
Data: 1 byte + extra byte for each character
Return: 0 bytes

The first byte contains the length of the new name.
At the end of the 4byte command you add bytes that are a hexadecimal representation of the name.

For example: change name to Upstairs
08 00 00 BB 55 70 73 74 61 69 72 73

Control

LED_ON

Turn leds on.

Command byte: 0xAA
Data: 0 bytes
Return: 0 bytes
Example: 00 00 00 AA

LED_OFF

Turn leds off.

Command byte: 0xAB
Data: 0 bytes
Return: 0 bytes
Example: 00 00 00 AB

SET_STATIC_COLOR

Set a static color.

Command byte: 0x1E
Data: 3 bytes
Return: 0 bytes

The data bytes are red, green and blue (0-255).
For example: purple
00 FF FF 1E

SET_BRIGHT

Set the brightness (0-255).

Command byte: 0x2A
Data: 1 bytes
Return: 0 bytes
Example: FF 00 00 2A

SET_WHITE

Set the brightness of the white led (If your led strip has them, 0-255).

Command byte: 0x69
Data: 1 bytes
Return: 0 bytes
Example: FF 00 00 69

SET_MODE

Change to one of the presets (1-120, 121 is static color, other values default to 1).

Command byte: 0x2C
Data: 1 bytes
Return: 0 bytes
Example: 3F 00 00 2C

SET_SPEED

Set the speed of the preset (0-255).

Command byte: 0x03
Data: 1 bytes
Return: 0 bytes
Example: C6 00 00 03

SET_MODE_AUTO

Change to auto mode.

Command byte: 0x06
Data: 0 bytes
Return: 0 bytes
Example: 00 00 00 06

@mbullington
Copy link
Author

@JonasHenkens Thanks so much for this documentation! 😄

The community since making this post has been awesome, and thanks to contributions there's now the comprehensive resource for the SP110e that I wish existed when I first bought it.

I think there's a typo in SET_STATIC_COLOR, where the example doesn't use 1E.

@JonasHenkens
Copy link

I'm glad to help!
I got mine recently and was also interested in trying to control it myself.

The typo should be fixed now. 😉

@markus-wolf
Copy link

@JonasHenkens awesome job, thank you !

@TheSilentProgrammer316
Copy link

Nice job. Did somebody managed to control the individual LEDs (maybe via a custom preset)?

@roslovets
Copy link

Thank you @mbullington and @JonasHenkens. What you have found allowed me to implement Python library to control SP110E.
https://github.com/roslovets/SP110E

@dungeon77
Copy link

Michael, what do you think about the sp107e controller? is it possible to manage it somehow?

@and7ey
Copy link

and7ey commented Nov 1, 2022

@dungeon77 I've collected some of my SP107E findings there https://gist.github.com/and7ey/c299ff2e34ac714621b2ef4f4eeb4ae3

@atchoo78
Copy link

I just wanted to chime in and say thanks to everyone (@mbullington, @roslovets, @JonasHenkens ++) for the research and dedication.
I’m currently making a humble macOS app for controlling the SP110E 😀

Screenshot (work in progress):

Screenshot-app

@chonker99
Copy link

Did anyone found out how to control individual led pixels? As an example, I have 50 pixel LEDs, I want to turn ON pixel 5, 11, 26 and set custom colors to each one. Any ideas?

@atchoo78
Copy link

Did anyone found out how to control individual led pixels? As an example, I have 50 pixel LEDs, I want to turn ON pixel 5, 11, 26 and set custom colors to each one. Any ideas?

Not possible with the SP110e as far as I know. If you don’t re-program it, that is, but it would be just as easy to use a small microcontroller with circuitpython or micropython (Raspberry Pi Pico, ESP32 etc) for the purpose.

@chonker99
Copy link

chonker99 commented May 20, 2023 via email

@ram-niwas1997
Copy link

@chonker99 @mbullington What are your thoughts on the SP105E controller? Is it possible to manage it in some way? Do you have any suggestions on how I can control a SP105e controller? And what is the format of the commands?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment