Coming soon
last updated: 2025-05-20
The DP100 is a tiny power supply and fits very well on your desk without taking space. It has 2 USB connectors. The USB-C connector is the power input up to 32 V, 5 A with an USB-PD power supply (or another DC alimentation up to 32 V). It has a tiny OLED display, three buttons and an adjustment wheel. The second USB-A connector can also be used to provide power (5 V/1 A) but is primarily needed to connect the device to a PC and to use the PC Windows software.
I love Linux, but mostly software is only written for Windows and Mac. Unfortunately the USB data transfer protocols of products are often proprietary and so it's hard to write software for Linux. To do so we need to understand the proprietary protocol used on USB. Her my new Cynthion helped to sniff the traffic. For more information : https://www.weigu.lu/other_projects/usb/cynthion/index.html.
I wrote a Python software for Linux to manipulate the DP100. It can surely also be used on Mac and Windows, but I will not cover that here. My software covers the basics needed but can surely be enhanced e.g. to load batteries. So feel free to use and enhance it.
The DP100 uses HID to avoid a driver. We have a vendor designed usage. No HID class is used. The exchange of data is done with a field of 64 byte (8 bit). The meanings are normally only known to the vendor.
I will use the python hidapi library to communicate with the device. I was not able to run the software without being root (sudo
). So the writing of udev rules is not not absolutely necessary. But let's do it anyway. The vendor ID is 0x2E3C
and the product ID is 0xAF01
.
cd /etc/udev/rules.d
sudo nano 55-ATK-MDP100.rules
Copy the following lines in the editor and save (Ctrl+o, Ctrl+x) and reload the rules.
# DP100
SUBSYSTEM=="hidraw", ATTRS{idVendor}=="2e3c", ATTRS{idProduct}=="af01", MODE="0660", GROUP="plugdev"
sudo udevadm control --reload
sudo udevadm trigger
We can test test the udev rules with:
udevadm test /sys/class/hidraw/hidraw0
ls -l /dev/hidraw0
The IN and OUT transactions (we have only 2 endpoints) use 64 byte. So we will always send and receive 64 byte (0-63). The host PC sends always 0xFB
as first byte (OUT) and get's an 0xFA
(IN) from the device. The second byte is a command. The third byte is always 0x00
.
I will use 3 commands: 0x10
(device info), 0x30
basic info and 0x35
(switch on/off, manipulate profiles).
Byte | 0 | 1 | 2 | 3 | 4–3+n | 4+n | 5+n |
---|---|---|---|---|---|---|---|
Meaning | 0xfb/0xfa | command | 0x00 | len data n | ... | crcL | crcH |
The fourth byte is the length of the following data. Then comes the data and the two last bytes are a checksum called CRC-16-Modbus. The data values with two bytes (16 bit) and the checksum are send with the lowest byte coming first also called as little endian!
From host (PC):
Byte | 0 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|---|
Basic Set | 0xfb | 0x10 | 0x00 | 0x00 | crc 0x30 | crc 0xc5 |
From device (DP100):
Byte | 0 | 1 | 2 | 3 | 4–19 | 20–21 | 22–3 | 24–35 | 36–39 | 40–43 | 44–45 |
---|---|---|---|---|---|---|---|---|---|---|---|
Device Info | 0xfa | 0x10 | 0x00 | 0x28 | name | hver | sver | ... | serial nr | ... | crc |
The first 9 data byte give us the name "ATP-DP100" (ASCII code, bytes). We also see the hardware and software version of the device (2 bytes) and the serial number (bytes).
The hardware and software versions are coded as 16 bit. 0x0E00
gives in the right order 0x000E
= 14. The version is 1.4.
The 0x30
command returns basic information. Most interesting are the output voltage and current (vout and iout).
From host (PC):
Byte | 0 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|---|
Basic Set | 0xfb | 0x30 | 0x00 | 0x00 | crc 0x31 | crc 0x0f |
From device (DP100):
Byte | 0 | 1 | 2 | 3 | 4–5 | 6–7 | 8–9 | 10–19 | 20–21 |
---|---|---|---|---|---|---|---|---|---|
Basic Info | 0xfa | 0x30 | 0x00 | 0x10 | vin | vout | iout | ... | crc |
As an example:
If we get the following data bytes for vout, iout: 0x8D
, 0x13
, 0x17
, 0x00
, we obtain 0x138D
= 5005 and 0x0017
= 23.
The voltage is 5005 mV and the current is 23 mA.
First we must understand, that the DP100 only works with 10 profiles containing the set voltage and the set current. There is no other way to manipulate the voltage and the current. If we switch the device on or off the voltage and current of the activated profile is used. And even more complications. To change a profile, activate it or switch on and off we need to first get the data from the profile, change one byte or more and send it back!
So first to be able to switch on and off we need to get the activated profile:
If we send the command 0x35
with the data byte 0x80
we get the data for the active profile.
From host (PC):
Byte | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
---|---|---|---|---|---|---|---|
Basic Set | 0xfb | 0x35 | 0x00 | 0x01 | 0x80 | crc 0xce | crc 0x28 |
From device (DP100):
Byte | 0 | 1 | 2 | 3 | 4 | 5 | 6–7 | 8–9 | 10–11 | 12–13 | 14–15 |
---|---|---|---|---|---|---|---|---|---|---|---|
Basic Set | 0xfa | 0x35 | 0x00 | 0xa | index | state | vo_set | io_set | OVP | OCP | crc |
Index gives us this information. The second data byte state informs us if the output is on or off!
If we replace 0x80
with 0x00
–0x09
we can read voset and ioset for all profiles.
To change a profile, we need to read the profile and save the data. Then we change the first data byte (byte 4) and the values for voltage and current.
We recalculate the CRC and send the data back.
The upper nibble of byte 4 must be 0x4 and the lower nibble is the profile number (e.g. to change third profile (number 2) we send 0x42
).
If we want to change voltage or/and current we need to activate the profile with the wanted values or even first set the values to a profile and than activate it.
To do so we need to read the profile and save the data. Then we change the first data byte (byte 4), recalculate the CRC and send the data back.
The upper nibble of byte 4 must be 0xA and the lower nibble is the profile number (e.g. to activate the forth profile (number 3) we send 0x83
).
To switch on/off we have to look which profile is activated. Then we read this profile, save the data and change the first and the second data byte (Byte 4 and 5), recalculate the CRC and send the data back.
The upper nibble of byte 4 must be 0x2 and the lower nibble is the profile number (e.g. to switch on/off the active profile number 5 we send 0x25
).
Byte 5 is 0x01
to switch on and 0x00
to switch off.
With this information I was able to write a first version of a Python program doing the most important things needed.
It uses hidapi
under Linux and Python Tkinter GUI. Unfortunately it must be run as root. Even with udev rules and all rights set it was not possible
to use it without sudo
.
https://github.com/trezor/cython-hidapi
sudo apt-get install libusb-1.0-0-dev libudev-dev .venv/bin/pip3 install --upgrade setuptool .venv/bin/pip3 install hidapi