Metacyclopedia

Serial Protocol

The USB programming cable and Bluetooth adapter both will speak CAN bus to the Metacycle's controller and expose a serial protocol. This allows you to program the vehicle to perform differently. Limit the max RPMs, provide a power assist when you are pushing it, enable cruise control, and configuring the throttle are all done using this serial protocol.

Looking to write your own software? Bartek Banachewicz has made his notes public for a different controller, but it might speak the same protocol and could provide insight to the frames being sent. Also, another user has a packet dump and analysis that will help you decipher what's going across the wire. There's also a post decoding the serial protocol and an Android app post also has extra details.

There is a list of fault codes. In this spreadsheet, there are different tabs for different categories of data.

Serial Message Format

The following is a very low-level dive into the controller's message format. It's here to help provide a reference for what the USB to CAN bus adapter provides to the EM_V3-40 software (and all derivatives).

Each section shows a sample message in hex. All hex values are shown as code in monospace. Messages are all 24 bytes long, including the envelope. Each section talks about specific values, which will be in bold to help locate them in the sample message.

Message Envelope Structure

This applies to all messages, incoming and outgoing. Each message, both to and from the controller, is 24 bytes long. This is a sample "LDGET" request. The first two and last two bytes (both are bolded) are the envelope.

c9 14 02 4c 44 47 45 54 00 00 00 00 00 00 00 00 00 00 00 00 00 00 81 0d

c9 - The first byte is c9 if it is being sent to the controller, c0 if it is a response from the controller.

14 - The next byte is the payload size. Hex 14 is equal to decimal 20. There's 20 bytes in all payloads.

After those two bytes, the next 20 bytes is the payload.

81 - The second from the last is an XOR of all previous bytes (the payload and the first two bytes of the message envelope).

0d - The last byte is always 0d.

LDGET Request

Gets the current controller settings.

c9 14 02 4c 44 47 45 54 00 00 00 00 00 00 00 00 00 00 00 00 00 00 81 0d

The first two bytes are the envelope.

02 - Unknown.

4c 44 47 45 54 - "LDGET"

The rest of the payload are NULLs.

The last two bytes are the envelope.

LDGET Response Header

7 responses are provided to the LDGET request.

c0 14 05 52 07 3a c7 0f df 52 14 00 00 00 00 00 00 00 00 00 00 00 ef 0d

The first two bytes are the envelope.

05 - Response packet

52 - "R" Read

07 - The response number, from 1 to 7.

The middle 17 bytes are the section of configuration settings. See "Config Settings 1" through "Config Settings 7" for explanations.

The last two bytes are the envelope.

P Request

Program the controller

c9 14 02 50 01 14 02 03 5c 02 3a 0a 00 78 26 e8 02 26 05 d2 00 51 e1 0d

The first two bytes are the envelope.

02 - Request packet

50 - "P" to Program

01 - The settings page number, from 1 to 7.

The middle 17 bytes are the section of configuration settings. See "Config Settings 1" through "Config Settings 7" for explanations.

The last two bytes are the envelope.

P Response

Controller settings were updated; sent after all 7 configuration settings were sent to the controller.

c0 14 0d 50 4e 03 4d ff f8 00 00 00 00 00 00 00 41 3e 00 00 49 00 b8 0d

The first two bytes are the envelope.

0d - Response packet.

50 - "P" for Program.

The next 18 bytes are unknown.

The last two bytes are the envelope.

Init Response

Controller was initialized

c0 14 0d fe ef 55 aa 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 37 0d

The first two bytes are the envelope.

0d - Response packet.

fe - Init

The next 18 bytes are unknown.

The last two bytes are the envelope.

RESET Request

Restarts the controller. After writing configuration, the controller needs to reboot and this is one way to do that.

c9 14 02 52 45 53 45 54 00 00 00 00 00 00 00 00 00 00 00 00 00 00 8a 0d

The first two bytes are the envelope.

02 - Request packet.

52 45 53 45 54 - "RESET".

The next 14 bytes are NULL.

The last two bytes are the envelope.

CLERR Request

Resets the USB adapter, which is what the CLR DTC button does in the advanced debug panel.

c9 14 02 43 4c 45 52 52 00 00 00 00 00 00 00 00 00 00 00 00 00 00 95 0d

The first two bytes are the envelope.

02 - Request packet.

43 4c 45 52 52 - "CLERR".

The next 14 bytes are NULL.

The last two bytes are the envelope.

RESTT Request

Resets the debugging line.

c9 14 02 52 45 53 54 54 00 00 00 00 00 00 00 00 00 00 00 00 00 00 9b 0d

The first two bytes are the envelope.

02 - Request packet.

52 45 53 54 54 - "RESTT".

The next 14 bytes are NULL.

The last two bytes are the envelope.

RESTT Responses

Debug line was reset. After this is received, an AT command (AT+PIN7539) is received from the device, possibly programming a Bluetooth adapter to use the pin 7539.

c0 14 0d fe ef 55 aa 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 37 0d

41 54 2b 50 49 4e 37 35 33 39 0d 0a

The first two bytes are the envelope.

0d - Response packet.

fe ef 55 aa - Unknown.

The next 15 bytes are NULL.

The last two bytes are the envelope.

SHOW Request

c9 14 02 53 48 4f 57 00 00 00 00 00 aa 00 00 00 0a aa 05 d2 00 51 50 0d

The first two bytes are the envelope.

02 - Request packet.

53 48 4f 57 - "SHOW".

00 00 00 00 00 - Unknown, NULL.

aa - Local or remote. aa = local, 55 = remote.

00 00 - Throttle remote. Divide by 5945 (unverified through capture) to get throttle voltage.

00 - Bitmask

0a - Weak flux calibration, from Config Settings 2.

aa - Unknown.

05 d2 - Voltage calibration. 05d2 is 1490. This is the same value as what's from Config Settings 1. If this is incorrect, the controller could output the fault code for undervoltage or overvoltage in the response.

00 51 - Current calibration. 0051 is 81. This is the same value as what's from Config Settings 1.

The last two bytes are the envelope.

SHOW Response

Multiple types of responses are possible. It depends on the SHOW request send. There is no method to differentiate which type of request was sent from just the response.

c0 14 0d 59 42 03 46 ff f8 01 00 00 00 00 02 b8 5d 4b 22 d6 80 03 01 0d

The first two bytes are the envelope.

0d 59 42 - Unknown.

03 46 - First requested value. This changes based on the SHOW request.

ff f8 - Second requested value. This changes based on the SHOW request.

01 - Unknown.

00 00 00 00 - Fault code bitmask. See the tabs in this spreadsheet for fault codes for an explanation of the fault code bits.

02 b8 - RPM.

5d - Controller temp + 50. 5d = 93, minus 50 = 43° C.

4b - External temp + 50. 4b = 75, minus 50 = 25° C.

22 d6 - Temperature coefficient. 22d6 = 8918.

80 - Bitmask.

03 - Controller status. 0 = idle, 1 = init, 2 = start, 3 = run, 4 = stop, 5 = brake, 6 = wait, 7 = fault.

The last two bytes are the envelope.

Config Settings 1

Explanation of data fields in LDGET or P.

c0 14 05 52 01 14 02 03 5c 02 3a 0a 00 78 22 60 02 26 05 d2 00 51 61 0d

14 - Model type. Read-only.

02 - High nibble (0) is the brand name, low nibble (2) is the voltage.

03 5c - Overvoltage as fixed-point decimal, high byte first. 035c is 860 decimal, so 86.0 V is the overvoltage threshold.

02 3a - Soft undervoltage as a fixed-point decimal, high byte first. 023a is 570, so 57.0 V is the soft undervoltage threshold.

0a - Undervoltage variation as a fixed-point decimal. 0a is 10, so 1.0 V is the variation.

00 78 - Regen current as a decimal. 0078 is 120 A.

22 60 - Phase current. 2260 is 8800 A.

02 26 - Undervoltage as a fixed-point decimal. 0226 is 550, so 55.0 V.

05 d2 - Voltage calibration. 05d2 is 1490.

00 51 - Current calibration. 0051 is 81.

Config Settings 2

Explanation of data fields in LDGET or P.

c0 14 05 52 02 00 dc 50 4b 64 0b b8 2e e0 17 70 04 25 08 78 1e 0a 7d 0d

00 dc - Bus current limit. 00dc = 20 A.

50 - Low gear RPM %. 50 = 80%.

4b - Mid gear RPM %. 4b = 75%.

64 - High gear RPM %. 64 = 100%.

0b b8 - Flux weakening, weak magnetic value. 0bb8 = 3000.

2e e0 - High flux weakening value (KP). 2ee0 = 12000.

17 70 - Mid flux weakening value, start phase. 1770 = 6000.

04 - Bitmask. Unless otherwise specified, turning on the bit turns on the feature.

25 - Speed limit percent. 25 = 37%.

08 - Soft start grade. Values can range from 1 to 16. 08 = 8.

78 - Sport mode auto disable timer. 78 is 120 seconds.

1e - Sport mode recovery timer: 1e is 30 seconds.

0a - Maximum torque per ampere (flux-weakening compensation). 0a = 10.

Config Settings 3

Explanation of data fields in LDGET or P.

c0 14 05 52 03 00 78 8c af b4 00 69 24 54 24 d4 0a 70 10 19 e8 71 6c 0d

00 78 - Hall shift angle. Signed integer. Positive numbers are normal. Negative numbers are stored as 65536 - N. 0078 = 120°. ff88 would be -120°.

8c - Controller high temp threshold. 8c = 140° C.

af - Controller over temp (second protection phase). af = 175° C.

b4 - Max temperature limit. b4 = 180°C.

00 69 - TC1: engine phase when temp limit occurs. 0069 = 105° C.

24 54 - TC2: traction control or dampening. 2454 = 9300.

24 d4 - One-LIN speed compensate (real speed from GPS / one-LIN) * 64 * 256. 24d4 = 9428.

0a - Reverse max RPM. 0a = 10%.

70 - Bitmask. Unless otherwise specified, turning on the bit turns on the feature.

10 - Number of pole pairs. 10 = 16 pole pairs.

19 - EBS %. Enables regenerative braking and determines how much regenerative braking is applied. 19 = 25%.

e8 - Software version stored as a fixed precision integer. e8 = 232, which is version 2.32.

71 - Hardware version stored as a fixed precision integer. 71 = 113, which is version 1.13.

Config Settings 4

Explanation of data fields in LDGET or P.

c0 14 05 52 04 04 0c cc 03 e8 04 b0 51 44 14 01 2c 13 88 00 28 03 80 0d

04 - Bitmask. Unless otherwise specified, turning on the bit turns on the feature.

  • 0c cc - Moving vehicle booster amount as a percent of the motor base speed. 0ccc = 3276. Divide this by 327 to get ~10%.
  • 03 e8 - Moving vehicle booster torque. 03e8 = 1000.

    04 b0 - Hill descent control, max RPM of motor. 04b0 = 1200 RPM.

    51 - Low gear percentage of amps. 51 = 81%.

    44 - Mid gear percentage of amps. 44 = 68%.

    14 - High gear's overrating speed (KD). 14 = 20% over maximum.

    01 2c - Flux weakening value (KI). 012c = 300.

    13 88 - Max phase current limit. 1388 = 5000.

    00 28 - Max phase limit time. 0028 = 40 seconds.

    03 - Weak flux calibration. 03 = 3.

    Config Settings 5

    Explanation of data fields in LDGET or P.

    c0 14 05 52 05 c0 00 c0 00 c8 80 c0 0b c0 25 c3 11 c0 00 58 00 0a a0 0d

    c0 00 - PD0 - see Port Settings.

    c0 00 - JTCK - see Port Settings.

    c8 80 - SWD - - see Port Settings.

    c0 0b - PA11 - see Port Settings.

    c0 25 - PB3 - see Port Settings.

    c3 11 - PD1 - see Port Settings.

    c0 00 - PA12 - see Port Settings.

    58 00 - PC15 - see Port Settings.

    0a - Unknown / reserved. Suspected to be a random byte from memory.

    Config Settings 6

    Explanation of data fields in LDGET or P.

    c0 14 05 52 06 c0 00 c0 0f c0 8a c2 09 c1 10 c2 07 c0 00 cb 92 20 a6 0d

    c0 00 - PA0 - see Port Settings.

    c0 0f - PB9 - see Port Settings.

    c0 8a - PB4 - see Port Settings.

    c2 09 - PA15 - see Port Settings.

    c1 10 - PB2 - see Port Settings.

    c2 07 - PC14 - see Port Settings.

    c0 00 - PB5 - see Port Settings.

    cb 92 - PD15 - see Port Settings.

    20 - Unknown / reserved. Suspected to be a random byte from memory.

    Config Settings 7

    Explanation of data fields in LDGET or P.

    c0 14 05 52 07 3a c7 0f df 52 14 00 00 00 00 00 00 00 00 00 00 00 ef 0d

    3a - Throttle begin voltage. 3a = 58, which converts to 1.27 on screen. Due to the resolution, not all decimal values can be saved perfectly; 1.26 and 1.27 both code to 3a. To convert the saved value to voltage, add 1, multiply by 5.5, then divide by 255, and finally drop digits after the second decimal. 3a is 58, add 1 to get 59, then becomes 324.5 after multiplication, divides to 1.27155, then with digits dropped it is 1.27. To convert voltage to the saved value, multiply by 255, divide by 5.5, then drop the decimal portion. 1.26 times 255 is 321.3. Divide it by 5.5 to get ~58.42. Remove the decimal portion to get 58. Convert 58 to hex, resulting in 3a.

    c7 - Throttle end voltage. c7 = 199, which converts to 4.31. See the earlier throttle conversion explanation.

    0f - Throttle low protect. 0f = 15, which converts to 0.34. See the earlier throttle conversion explanation.

    df - Throttle high protect voltage. df = 223, which converts to 4.82. See the earlier throttle conversion explanation.

    52 - Rate of decline. 52 = 82.

    14 - Rate of acceleration. 14 = 20.

    00 00 - Starting torque.

    00 00 - Torque smoothing factor.

    00 00 00 00 00 00 00 - Unused / reserved. Sometimes has values that appear to come from other config settings. When written as INI files, these could also have random data even if the controller's settings do not change.

    Port Settings

    These are the checkboxes, radios, and drop-down lists to describe what's attached to the controller ports. This will be a two byte value from Config Settings 5 and Config Settings 6.

    c3 11

    c3 - F/U/D mode and checkboxes.

    11 - Bit flag and program.

    Contact - Files - Parts - Problems - Programming
    Send suggestions, feedback, tips, or additional files!