ZKETECH EBC-A20 Battery Tester

Table of Contents

1. Introduction

The ZKETECH EBC-A20 is a battery tester with integrated charging and discharging circuits. Its basic capabilities are:

  • voltage range when discharging 0 - 30 V
  • voltage range while charging 0 - 18 V
  • charging current range 0.1 - 5 A
  • discharge current range: 0.1 - 20 A

The device is pretty popular and there are multiple places where a manual can be downloaded with more detailed specifications. The focus of this article is the control and monitoring interface provided by the battery tester

2. Control interface

The device is equipped with a Mini USB socket on the back where a provided cable is connected. The cable contains a USB <-> serial converter as the Mini USB connector actually carries serial port signals. I have not checked what happens when an ordinary USB cable is plugged there and connected to a USB hub. I hope the designers took that possibility into account.

The control interface can be used by a vendor-provided piece of software - "EB Software(English Version)_v1.8.8.rar" (mirror). This piece of software can also be found relatively easily.

The physical layer of the control interface is a 9600 bps, 8 bit, odd parity.

2.1. Control protocol

2.1.1. Packet structure

The control protocol exchanges packets (also called "frames" in this document) between the controller PC and the battery tester. The packets are binary encoded, a typical packet is shown below in hexadecimal:

fa 0c 00 00 02 1e 00 00 00 00 00 0a 01 3c 00 0a 09 24 f8

The basic structure of the encoded packet is shown below:

  Offset 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 Notes
Value   fa 0c 00 00 02 1e 00 00 00 00 00 0a 01 3c 00 0a 09 24 f8  
Description   SOF                                 CRC EOF  

Each packet begins with a 0xfa byte and ands with 0xf8. These are marked with SOF and EOF. The payload are the bytes between offset 1 and 16 (inclusively). A packet also contains a "CRC" which is a simple checksum not an actual Cyclic redundancy check. It can be calculated by performing a XOR operation on the payload bytes:

>>> hex(0x0c ^ 0x00 ^ 0x00 ^ 0x02 ^ 0x1e ^ 0x00 ^ 0x00 ^ 0x00 ^ 0x00 ^ 0x00 ^ 0x0a ^ 0x01 ^ 0x3c ^ 0x00 ^ 0x0a ^ 0x09)
'0x24'
>>>

A number of packet types sent by the battery tester to the PC or vice-versa have been identified, an example of which is the packet sent when the controlling software requests cell charging:

Type Offset 0 1 2 3 4 5 6 7 8 9 Notes
Start charging                        
    fa 21 00 32 01 3c 00 0a 1c f8  
    SOF PT I1 I2 V1 V2 CUT1 CUT2 CRC EOF  

The first payload byte is the packet type identifier - 0x21 represents the Start charging packet. Next there are 3 16-bit fields encoding:

  • the charging current (in units of 10 mA)
  • the charging voltage (in units of 10 mV)
  • the cutoff current (in units of 10 mA)

Each of those values is encoded using the following scheme:

>>> I1 = 0x00
>>> I2 = 0x32
>>> 240 * I1 + I2
50

In effect this is a "base240" encoding and it's purpose is likely to prevent values larger than 240 (0xf0) to be present in the packet bytes. This makes sense when you consider the fact that bytes 0xfa and 0xf8 are used as "control codes" to mark start and end of packets. In summary the packet above encodes:

>>> I1 = 0x00
>>> I2 = 0x32
>>> 240 * I1 + I2
50  # charging current 50 * 10 mA = 500 mA
>>> V1 = 0x01
>>> V2 = 0x3c
>>> 240 * V1 + V2
300  # charging voltage 300 * 10 mV = 3V
>>> CUT1 = 0x00
>>> CUT2 = 0x0a
>>> 240 * CUT1 + CUT2
10  # cutoff current 10 * 10 mA = 100 mA
>>>

What follows is a table with descriptions of all of the packets that have been observed so far together with their types, encoded fields and other extra information.

2.1.2. Field reference

Fields like current or voltage have common encoding for all packet types:

Field name Description Unit Notes
PT Packet type    
DT Device type   0x09 is EBC-A20
(FW1, FW2) Firmware version   Displayed in the ZKETECH aplication, for example 302 is displayed as 'V3.02'
(T1, T2) Time min  
(I1, I2) Current 10 mA  
(V1, V2 Voltage 1 mV  
(C1, C2) Charge count 1 mAh  
(E1, E2) Unknown   Might be energy in Wh
(CC1, CC2) Charging current 10 mA Charging
(CV1, CV2) Charging voltage 10 mV  
(CUT1, CUT2) Cutoff current 10 mA  
(CC1, CC2) Charging current 10 mA Discharging
(CUTV1, CUTV2) Cutoff voltage 10 mV  

2.1.3. Packet reference

This table does not exhaust all of the packet that I have seen while sniffing the traffic between the original software and the battery tester. A bit more is documented in the Python code.

  Kind 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
Description                                        
  Status fa 02 00 00 0a 13 00 14 00 00 00 32 01 0a 00 0a 09 35 f8
Tester idle,   SOF PT I1 I2 V1 V2 C1 C2 E1 E2 CC1 CC2 CV1 CV2 CUT1 CUT2 DT CRC EOF
sent after connecting                                        
  Status fa 66 00 00 08 88 00 14 00 00 01 3e 0c 8f 09 05 09 4b f8
    SOF PT I1 I2 V1 V2 C1 C2 E1 E2 FW1 FW2 unk unk unk unk DT CRC EOF
Idle FW report,                                        
sent after connecting                                        
Maybe HW version too?                                        
unk means unknown                                        
  Status fa 0c 00 32 07 de 00 00 00 00 00 32 01 b4 00 0a 09 63 f8
    SOF PT I1 I2 V1 V2 C1 C2 E1 E2 CC1 CC2 CV1 CV2 CUT1 CUT2 DT CRC EOF
CC-CV charging in progress                                        
  Status fa 70 00 00 04 53 00 00 00 00 01 3e 0c 8f 09 05 09 63 f8
    SOF PT I1 I2 V1 V2 C1 C2 E1 E2 FW1 FW2 unk unk unk unk DT CRC EOF
CC-CV charging FW report,                                        
sent for a few                                        
seconds after                                        
charging begins                                        
  Status fa 16 00 0a 0a 64 00 14 00 00 00 32 01 0a 00 0a 09 5c f8
    SOF PT I1 I2 V1 V2 C1 C2 E1 E2 CC1 CC2 CV1 CV2 CUT1 CUT2 DT CRC EOF
CC-CV charging end                                        
sent when current cutoff                                        
threshold is reached                                        
  Status fa 00 00 00 10 49 00 00 00 00 00 32 01 3c 00 78 09 27 f8
    SOF PT I1 I2 V1 V2 C1 C2 E1 E2 CC1 CC2 CV1 CV2 CUT1 CUT2 DT CRC EOF
CC discharge idle                                        
  Status fa 0a 00 32 0f 41 00 02 00 00 00 32 01 3c 00 3c 09 4e f8
    SOF PT I1 I2 V1 V2 C1 C2 E1 E2 CC1 CC2 CV1 CV2 CUT1 CUT2 DT CRC EOF
CC discharge in progress                                        
  Status fa 14 00 32 0c 77 01 59 00 00 00 32 01 3c 00 78 09 7b f8
    SOF PT I1 I2 V1 V2 C1 C2 E1 E2 CC1 CC2 CV1 CV2 CUT1 CUT2 DT CRC EOF
CC discharge end                                        
  Command fa 05 00 00 00 00 00 00 05 f8                  
    SOF PT             CRC EOF                  
Connect                                        
After this '-PC-' appears                                        
on LCD                                        
  Command fa 06 00 00 00 00 00 00 06 f8                  
    SOF PT             CRC EOF                  
Disconnect                                        
  Command fa 02 00 00 00 00 00 00 02 f8                  
    SOF PT             CRC EOF                  
Stop                                        
Used for both charging and                                        
discharging                                        
  Command fa 21 00 32 01 3c 00 78 02 f8                  
    SOF PT CC1 CC2 CV1 CV2 CUT1 CUT2 CRC EOF                  
Start CC-CV charging                                        
  Command fa 0a 00 03 00 00 00 00 02 f8                  
    SOF PT T1 T2         CRC EOF                  
CC-CV time?                                        
sent every minute while                                        
charging                                        
  Command fa 01 00 03 00 00 00 00 02 f8                  
    SOF PT CC1 CC2 CUTV1 CUTV2 T1 T2 CRC EOF                  
Start CC discharge                                        
(CUTV1, CUTV2) is the cutoff                                        
voltage                                        
(T1, T2) is the time limit                                        

Links

Github  Sourcehut  Hackaday

  Fediring