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.
- Fault Codes: First tab lists all fault codes as bitmasks.
- Error Codes: Second tab details the error codes that are expressed as blinking lights.
- Program Values: Third tab shows the 127 program values for the port settings.
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.
-
Two-byte numbers are stored with the most significant byte first.
00 24is 36 in decimal. -
All decimals are transmitted as fixed position, so 1.2 is
transmitted as the decimal value 12, which is
0c. -
Negative numbers are saved as two's complement.
ffis -1,feis -2,fdis -3. To convert to a two-byte negative number, take the first overflow value (256 for one byte, 65536 for two bytes) and add the negative number. 65535 + (-2) is 65534, which isff fe. Convert back from hex by checking if the high bit is set. If so, take the number and subtract the overflow value;ff feis is 65534, then 65534 - 65536 is -2.
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".
-
4findicates using CAN ID3ff(channel A). This value changes when using different CAN IDs. The controller is 3fe. If you forget to reset the channel back, it is unfortunately saved to the registry in Windows and will need to be reset manually. Search for keys named "EM_V3" and delete them.-
50is CAN ID3fd(channel B) -
51is3fb(channel C) -
52is3f9(channel D) -
53is3f7(channel E) -
54is3f5(channel F) -
55is3f3(channel G) -
56is3f1(channel H)
-
-
57changes to59when the "CAN" advanced debug checkbox is enabled. It allows switching to different CAN IDs.
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
-
Bits 01 and 02: Set gear for remote mode.
- 0 = Low gear
- 1 = Mid gear
- 2 = High gear
- 3 = Sport mode.
- Bit 04: Unknown.
- Bit 08: Show D-axis and Q-axis amperage instead of battery voltage and battery amperage.
- Bit 10: Show D-axis and Q-axis voltage instead of battery voltage and battery amperage.
- Bit 20: Indicate "lock" in remote mode.
- Bit 40: Indicates reverse gear in remote mode.
- Bit 80: Indicate the brake is engaged in remote mode.
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.
-
When requesting battery info, this is fixed-point battery voltage.
0346= 838, which is 83.8 V. -
When requesting axis voltage, this is fixed-point Q-axis voltage.
0004= 4, which is 0.4 V. -
When requesting axis amperage, this is fixed-point Q-axis amperage.
ffff= -1, which is -0.1 A.
ff f8 - Second requested value. This changes based on the SHOW
request.
-
When requesting battery info, this is fixed-point battery current.
fff8is -8, which is -0.8 A. -
When requesting axis voltage, this is fixed-point D-axis voltage.
fff1is -15, which is -1.5 V. -
When requesting axis amperage, this is fixed-point D-axis amperage.
fff8is -8, which is -0.8 A.
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.
-
Bits
01,02: Current gear.0is low,1is medium,2is high,3is sport. - Bit
04: Reverse. - Bit
08: Parked. - Bit
10: Brake - Bit
20: Lock (anti-theft) - Bit
40: Side stand - Bit
80: Regen
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.
05= EM-30S0A= EM50S14= EM-100S1E= EM150S28= EM-200S
02 - High nibble (0) is the brand name, low
nibble (2) is the voltage.
-
High nibble: brand name
0*= common1*= lvyuan2*= lima3*= lvjia4*= lvjia-15*= guangyang6*throughf*= reserved
-
Low nibble: voltage
*0= 48 V*1= 60 V*2= 72 V*3= 84 V*4= 96 V*5through*f= reserved
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.
- Bit
01: Speed limiter. -
Bit
02,04,08: Default gear.02= high,04= mid,08= low. -
Bit
10: Motor type.00= surface,10= v-type. -
Bit
20: Gear changing.00= button,20= switch. - Bit
40: Noise reduction (low brake). - Bit
80: Soft start.
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.
-
Bits
01,02,04: Unknown. - Bit
08: Hill hold control. - Bit
10: Exchange phase wire blue-green. - Bit
20: Exchange hall wire yellow-blue. - Bit
40: Sport mode auto disable. -
Bit
80: Motor rotation changing.00= forward,80= reverse.
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.
- Bit
01: Moving vehicle booster (MBC). -
Bit
02: Hill descent control (HDC), maximum RPM limiter. -
Bit
04: Speedometer output.00= hall speedometer,04= one-LIN. - Bit
08: Enable cruise control. - Bit
10: Double voltage detection. -
Bit
20: Double voltage low/high.00= low,20= high. - Bit
40: Secure boot. - Bit
80: Unknown / reserved.
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.
- Bit
01if SW checked. -
Bit
02if U mode, bit04if D mode, neither bit is F mode. - Bit
08if LA checked. -
Bits
10,20,40,80are unknown. Typically this value iscin hex, meaning40and80are set. For one port it is5in hex, meaning10and40are set.
11 - Bit flag and program.
- Bit
80if IO is checked. -
Program values are from
00to7f(1 to 128). They are detailed in a tab within this spreadsheet.