Python coding

Alientek DP100 power supply manipulator

Coming soon

last updated: 2025-05-20

DP100_manipulator
click for a better view

Intro

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.

Data exchange over USB with hidapi

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

Protocol

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!

Command 0x10: Device Info

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.

Command 0x30: Basic Info

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.

The complicated command 0x35

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:

Get active 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!

Get all profiles

If we replace 0x80 with 0x000x09 we can read voset and ioset for all profiles.

Change a profile

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).

Activate a profile

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).

Switch ON and OFF

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

Downloads

Interesting links