Documentation and code for the ISDT CM1620 charging module
The ISDT CM1620 is a charging module, intended for industrial use. In contrast to the "hobby-grade" chargers it does not have buttons to use the device, instead you are expected to remote control it, (either with a display/controller that can be bought separately or via a PC) which makes sense for industrial use.
It can also be controlled via a smartphone app for a more stand-alone usage.
Official specifications:
Despite its drawbacks (see Reverse Engineering Discoveries), the cheap price might still make this device a useful tool for battery charging.
There is at least one scenario where the CM1620 dies (ask me how I know).
So I would suggest when using multiple of them in parallel to always keep the power inputs parallel, especially when a battery is hooked up! IIRC powering up both units at the same time even with the battery hooked up was fine (though I'm not 100% certain).
Powering up a single unit with or without a battery hooked up seems to both be fine as well.
There is some official documentation and C# example code on the ISDT website: https://www.isdt.co/down/openSource/CM1620.zip
While the documentation and code are very helpful, they still aren't great. The documentation is incomplete and the code quality isn't great. For example, the code breaks depending on the system language/culture, the request/response messages in the code comments often don't match what the device actually sends, etc.
In addition to the chemistries defined in the spec, there seems to be an extra chemistry called ULiHv
.
Also, there is an artificial cell voltage limitation, which makes this device unsuitable to charge LiIon batteries (with the stock firmware), as 4.1V is just outside the LiPo voltage range.
LiFe
: 3.555V to 3.755VLiPo
: 4.105V to 4.305VLiHv
: 4.255V to 4.455VULiHv
(undocumented): 4.350V to 4.550VPossibly, the LiFe
mode could be used to storage+balance charge LiIon/LiPo batteries, even if it's not intended to be used like that.
In theory, that limit could easily be patched out by modifying two bytes in the firmware, but this hasn't been tested.
#hello SL1
to find the next charger in the chainIn addition to the documented default password null
used in the serial communication, there seem to be additional passwords like tdsi
(ISDT backwards) and _monitor_
likely used by the communication between chargers and between charger+display.
Additional, less relevant, reverse-engineering notes can be found in the README inside the RevEng/ folder.
The serial protocol is based on simple request-response communication.
It uses #
as a sign for the controller and @
as a sign for the responder. Commands and their responses may span multiple lines, each (including the last one) ending in \n
. The end of the command/response is always marked with \r
.
For most commands, the user has to be "logged in" (otherwise the device will respond with @confused
). Logging in just means the #login
command has to be sent with a password. The password (under normal circumstances) always seems to be "null", however there are some internal passwords (see Reverse Engineering Discoveries).
The login times out after ~3 seconds after the last command has been sent, so either commands have to be sent continuously, or the @confused
message should be handled to relogin on the device.
In most commands, the response of all devices in the chain is returned. The first line usually contains the number of responses, followed by one line per device.
Example:
(>
is controller->device, <
is device->controller, \n
is shown as a line break):
> #login null
> \r
< @login 2
< SL0 ok
< SL1 ok
< \r
SL0
and SL1
refer to the two connected chargers ("slaves").
Based on the serial protocol documentation, the example code and some reverse engineering, I've written some example code in C# that implements most of the protocol commands as straight-forward as I could (arguably, RegEx might not be the most readable way to parse these messages, but it's one of the easier ways to do it).
It can be found under code/
.
Some pictures of the insides can be found in the RevEng/ folder.