BLE Protocol Analysis#

This page documents the BLE (Bluetooth Low Energy) protocol used by SkyRC MC3000 battery chargers.

It is based on analyzing sniffed Bluetooth traffic and decompilation of the official SkyRC MC3000 Android app.

Device Identification#

Local Name#

According to the Android app, the device announces itself using one of the following names:

  • SimpleBLEPeripheral

  • Charger

  • HitecCharger

My device with hardware version 2.2 and firmware version 1.15 uses the name Charger.

MAC Address#

My device uses a MAC address starting with a Texas Instruments OUI (d8:a9:8b:xx:xx:xx). Other hardware revisions might use different chipset manufacturers.

Service Description#

The device offers a BLE service with the 16-bit UUID 0xffe0 (corresponding 128-bit UUID: 0000ffe0-0000-1000-8000-00805f9b34fb). The 16-bit UUID is in the reserved range, but has not been officially registered with the Bluetooth SIG.

The service contains a single characteristic with 16-bit UUID 0xffe1 (128-bit UUID: 0000ffe1-0000-1000-8000-00805f9b34fb).

This characteristic is used to communicate with the device by writing correctly formatted commands to it. The device will respond by sending a value change notification from the characteristic with the results of the command. It is therefore important to enable notifications for this characteristic after connecting to the device.

The device will never send notifications on its own - all data must be polled from the device!

Protocol#

General Packet Layout#

All packets follow the same layout:

Byte Index

Description

0

Packet start byte, always 0x0F

1

Command

2-19

Payload

20

Checksum
Sum of previous bytes (modulo 256)

Get Version Info#

Example packets#

> 0F-57-00-BE-56-7B-8B-A9-D8-00-00-00-00-00-00-00-00-00-00-01  getVerInfo()
< 0F-57-00-31-30-30-30-38-33-01-00-00-00-00-01-0F-16-00-AD-E7
> 0F-57-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-66  getVerInfo()
< 0F-57-00-31-30-30-30-38-33-01-00-00-00-00-01-0F-16-00-AD-B2

Request#

Byte Index

Example packet (hex)

Description

0

0F

Packet start byte, always 0x0F

1

57

Command (0x57 = 87)

2

00

Empty

3-8

BE-56-7B-8B-A9-D8

MAC address of device. Can be left empty.

9-19

00-00-00-00-00-00-00-00-00-00

Empty

20

01

Checksum (sum of previous bytes)

Response#

Note

Version response packets seem to have no valid checksum. This might be due to a firmware bug.

Byte Index

Example packet (hex)

Description

0

0F

Packet start byte, always 0x0F

1

57

Command (0x57 = 87)

2-13

00-31-30-30-30-38-33-01-00-00-00-00

Unknown

14-15

01-0F

Firmware version
0x01 = 1, 0x0F = 15 –> “1.15”
16

16

Hardware version
0x16 = 22 –> “2.2”

17-18

00-AD-E7

Unknown

20

E7

Invalid Checksum?

Get Basic Data#

Example packets#

> 0F-61-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-70  getBasicData()
< 0F-61-00-00-01-01-00-2A-F8-00-00-00-00-00-00-00-00-00-00-94

Request#

Byte Index

Example packet (hex)

Description

0

0F

Packet start byte, always 0x0F

1

61

Command (0x61 = 97)

2-19

00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00

Empty

20

70

Checksum (sum of previous bytes)

Response#

Byte Index

Example packet (hex)

Description

0

0F

Packet start byte, always 0x0F

1

61

Command (0x61 = 97)

2


00


Temperature unit
0 = Celsius
1 = Fahrenheit
3


00


System beep
0 = Off
1 = On
4






01






Display
0 = Off
1 = Auto
2 = 1 minute
3 = 3 minutes
4 = 5 minutes
5 = Always on
5


01


Screensaver
0 = Off
1 = On
6










00










Cooling fan
0 = Auto
1 = Off
2 = On
3 = 20 °C / 68 °F
4 = 25 °C / 77 °F
5 = 30 °C / 86 °F
6 = 35 °C / 95 °F
7 = 40 °C / 104 °F
8 = 45 °C / 113 °F
9 = 50 °C / 122 °F
7-8

2A-F8

Input voltage (mV)
0x2AF8 = 11000 mV = 11.000 V

9-19

00-00-00-00-00-00-00-00-00-00

Empty

20

94

Checksum (sum of previous bytes)

Get Channel Data#

Example packets#

> 0F-55-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-64  getChannel(0)
< 0F-55-00-00-00-00-04-14-56-10-51-00-00-04-F9-1B-00-1D-70-D8
> 0F-55-01-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-65  getChannel(1)
< 0F-55-01-00-00-00-04-09-86-10-4D-00-00-02-95-1B-00-21-00-28
> 0F-55-02-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-66  getChannel(2)
< 0F-55-02-00-00-00-04-0B-5A-10-47-00-00-02-8D-1B-00-7D-00-4D
> 0F-55-03-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-67  getChannel(3)
< 0F-55-03-00-00-00-00-00-00-00-00-00-00-00-00-1B-00-00-00-82

Request#

Byte Index

Example packet (hex)

Description

0

0F

Packet start byte, always 0x0F

1

55

Command (0x55 = 85)

2

00

Channel (between 0 and 3)

3-19

00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00

Empty

20

64

Checksum (sum of previous bytes)

Response#

Byte Index

Example packet (hex)

Description

0

0F

Packet start byte, always 0x0F

1

55

Command (0x55 = 85)

2

00

Channel (between 0 and 3)

3









00









Battery type
0 = LiIon
1 = LiFe
2 = LiIon 4.35V
3 = NiMH
4 = NiCd
5 = NiZn
6 = Eneloop
7 = RAM
8 = LTO
4





00





Mode
0 = Charge
1 = Refresh
2 = Storage (for LiIon/LiFe/LiIo4_35) or Break-in
3 = Discharge
4 = Cycle

5

00

Cycle count

6

















04

















Status
0 = Stand-by
1 = Charge
2 = Discharge
3 = Pause
4 = Done (completed)
128 = Input voltage too low
129 = Input voltage too high
130 = MCP3424-1 Err
131 = MCP3424-2 Err
132 = Connection break
133 = Check Voltage
134 = Capacity protection
135 = Time protection
136 = Temp. is too high!
137 = Battery’s temp is too high!
138 = Battery short circuit
139 = Reverse polarity
7-8

14-56

Time (s)
0x1456 = 5206 s = 01:26:46
9-10

10-51

Voltage (mV)
0x1051 = 4177 mV = 4.177 V
11-12

00-00

Current (mA)
0x0000 = 0 mA = 0.000 A
13-14

04-F9

Capacity (mAh)
0x04F9 = 1273 mAh
15

1B

Temperature (°C)
0x1B = 27 °C
16-17

00-1D

Internal resistance (mΩ)
0x001D = 29 mΩ
18










70










LEDs (Bitmask of all channels)
0x70 = Green, Green, Green, Off
Bitmask:
0x01 = Channel 1 Red
0x02 = Channel 2 Red
0x04 = Channel 3 Red
0x08 = Channel 4 Red
0x10 = Channel 1 Green
0x20 = Channel 2 Green
0x40 = Channel 3 Green
0x80 = Channel 4 Green

20

D8

Checksum (sum of previous bytes)

Get Voltage Curve#

Example packets#

> 0F-56-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-65  getVoltageCurve(0)
< 0F-56-00-00-20-0F-4E-0F-81-0F-8A-0F-90-0F-95-0F-9B-0F-A0-0F
< A6-0F-AB-0F-AF-0F-B4-0F-B9-0F-BF-0F-C4-0F-C9-0F-CE-0F-D2-0F
< D8-0F-DD-0F-E2-0F-E8-0F-ED-0F-F2-0F-F7-0F-FD-10-02-10-07-10
< 0B-10-10-10-15-10-18-10-1D-10-20-10-25-10-28-10-2D-10-30-10
< 35-10-39-10-3D-10-41-10-46-10-4B-10-50-10-56-10-5C-10-62-10
< 68-10-68-10-68-10-68-10-68-10-68-10-68-10-68-10-68-10-68-10
< 68-10-68-10-68-10-68-10-68-10-68-10-68-10-68-10-68-10-68-10
< 68-10-68-10-68-10-68-10-68-10-68-10-68-10-68-10-68-00-00-00
< 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
< 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
< 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
< 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
< 00-00-00-00-00-71

Request#

Byte Index

Example packet (hex)

Description

0

0F

Packet start byte, always 0x0F

1

56

Command (0x56 = 86)

2

00

Channel (between 0 and 3)

3-19

00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00

Empty

20

65

Checksum (sum of previous bytes)

Response#

Note

This is the only known command with a multi-packet response messages. The response will always be 246 bytes long.

Byte Index

Example packet (hex)

Description

0

0F

Packet start byte, always 0x0F

1

56

Command (0x56 = 86)

2

00

Channel (between 0 and 3)

3-4

00-20

Time?

5-244



10-5C-10-62-10-68



120 measurements (mV)
0x105C = 4188 mV = 4.188 V
0x1062 = 4194 mV = 4.194 V
0x1068 = 4200 mV = 4.200 V

245

71

Checksum (sum of previous bytes)

Start Charging#

Example packets#

> 0F-05-01-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-15 startCharge(0)
< 0F-05-01-F0-FF-FF-00-00-00-00-00-00-00-00-00-00-00-00-00-03
> 0F-05-02-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-16 startCharge(1)
< 0F-05-02-F0-FF-FF-00-00-00-00-00-00-00-00-00-00-00-00-00-04
> 0F-05-04-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-18 startCharge(2)
< 0F-05-04-F0-FF-FF-00-00-00-00-00-00-00-00-00-00-00-00-00-06
> 0F-05-08-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-1C startCharge(3)
< 0F-05-08-F0-FF-FF-00-00-00-00-00-00-00-00-00-00-00-00-00-0A

Request#

Byte Index

Example packet (hex)

Description

0

0F

Packet start byte, always 0x0F

1

05

Command (0x05 = 5)

2

01

Channels (4 bits, one per channel)

3-19

00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00

Empty

20

15

Checksum (sum of previous bytes)

Response#

Byte Index

Example packet (hex)

Description

0

0F

Packet start byte, always 0x0F

1

05

Command (0x05 = 5)

2

01

Channels (4 bits, one per channel)

3-5

F0-FF-FF

Unknown

6-19

00-00-00-00-00-00-00-00-00-00-00-00-00

Empty

20

03

Checksum (sum of previous bytes)

Stop Charging#

Example packets#

> 0F-FE-01-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-0E stopCharge(0)
< 0F-FE-01-F0-FF-FF-00-00-00-00-00-00-00-00-00-00-00-00-00-FC
> 0F-FE-02-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-0F stopCharge(1)
< 0F-FE-02-F0-FF-FF-00-00-00-00-00-00-00-00-00-00-00-00-00-FD
> 0F-FE-04-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-11 stopCharge(2)
< 0F-FE-04-F0-FF-FF-00-00-00-00-00-00-00-00-00-00-00-00-00-FF
> 0F-FE-08-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-15 stopCharge(3)
< 0F-FE-08-F0-FF-FF-00-00-00-00-00-00-00-00-00-00-00-00-00-03

Request#

Byte Index

Example packet (hex)

Description

0

0F

Packet start byte, always 0x0F

1

FE

Command (0xFE = 254)

2

01

Channels (4 bits, one per channel)

3-19

00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00

Empty

20

0E

Checksum (sum of previous bytes)

Response#

Byte Index

Example packet (hex)

Description

0

0F

Packet start byte, always 0x0F

1

FE

Command (0x05 = 5)

2

01

Channels (4 bits, one per channel)

3-5

F0-FF-FF

Unknown

6-19

00-00-00-00-00-00-00-00-00-00-00-00-00

Empty

20

FC

Checksum (sum of previous bytes)