As you can see, DPS uses the Modbus RTU protocol. The Chinese firmware responds every 400ms to a Modbus request (2.5 times per second).

My alternate firmware basically uses the same Modbus registers to communicate with the DPS. Alternative firmware responds every 100ms (up to 25 times per second).

For example, U-SET can be read as holding register at address 0000H, I-SET as holding register at address 0001H, and so on.

Alternative firmware for Riden DPS and WUZHI models uses Modbus data as shown below.

In UART/USB or Bluetooth mode it works as Modbus RTU slave.

In Wi-Fi mode it works as Modbus TCP server.

You can find the communication protocol for all Riden DPS devices on the official google drive.

Link 1

Link 2

Official RD files

Modbus speed

Below in the screenshots:

  • Horizontal time base 100ms per cell
  • Yellow beam – Rx – request from the master
  • Blue beam – Tx – response from DPS/WZ device
Baudrate 9600 handles 10 requests per second
Baudrate 57600 handles 22 requests per second
Baudrate 19200 handles 14 requests per second
Baudrate 115200 handles 25 requests per second

The DPS firmware cycle is 100 milliseconds. In each cycle, the firmware first sets the output values USET, ISET -> DAC. Then it measures the output values ADC -> UOUT, IOUT and the input voltage ADC -> UIN. Then it draws the screen.

After that, in the remaining time up to 100 ms, it responds to Modbus requests. How much time, so much will answer. Depending on the speed from 1 to 3 times. Thus, sending requests to write USET / ISET or read UOUT / IOUT more than once every 100 ms does not make sense.

Features of the protocol and entries in registers

In order to simultaneously control several slave devices (slaves), you can use a broadcast write request with address zero.
Executable registers are registers, when written, the DPS performs some actions:

  • LOCK (7th) – manual or remote mode
  • ONOFF (10th) – enable/disable output
  • CMD (33rd) – see table Register CMD
  • MEM (36th) – changing the profile M0 … C9
  • CLB_CMD (41st) – execution of the calibration command

For the command to be executed, the write request must be a single one, not a group one !!! (except CLB_CMD).

Also, writing to some registers results in writing values to the EEPROM memory:

  • CMD
  • CLB_CMD
  • All profile registers M0 … C9

Since the EEPROM chip has a limited life of 1 million write cycles, the programmer should avoid using these commands frequently or cyclically. To record a profile, use the group record of the USETP … OTIM registers.

Why do we need LOCK = 1 at the beginning of the session

The firmware has the function of autosaving settings for the convenience of users, so that the changes are saved the next time the device is turned on. This function saves USET, ISET and MEM values 25 seconds after the last change. However, in case of long-term control via Modbus, this feature may be detrimental. So if LOCK = 1:

Eliminates conflict with commands from device buttons
Disable autosave feature
The function of auto-detection of a connection break is launched (it works when requests from the master are not received within 2 seconds).

After the connection is broken, the device will automatically restore its LOCK = 0 and unlock the buttons.

To correctly end the session, the master must write LOCK=0 and stop transmitting.

Communication protocol ver 4.5

Communication protocol ver 4.3-4.5

Register AddrNameRead / WriteDescriptionRangeExecutableWrite to EEPROM
0x0000 (0)USETR/Wformat 00.000...Umax
0x0001 (1)ISETR/Wformat 00.00 or 0.000 *see STATE register0...Imax
0x0002 (2)UOUTRformat 00.00
0x0003 (3)IOUTRformat 00.00 or 0.000 *see STATE register
0x0004 (4)POWERRformat 0000.0
0x0005 (5)UINRformat 00.00
0x0006 (6)LOCKWManual or remote mode. Lock-unlock keys.0 or 1YES
0x0007 (7)PROTECTR*See Register PROTECT table0...25
0x0008 (8)CVCCR0 - CV, 1- CC0 or 1
0x0009 (9)ONOFFR/W0- Power off, 1- Power On0 or 1YES
0x000A (10)BLEDR/WLCD Backlight1...6
0x000B (11)MODELRModel3003...8005
0x000C (12)VERSIONRFirmware version18....43
0x000D (13)TMPRTemperature in C
0x000E (14)STATER*See STATE register belowBitmask
0x000F (15)DEBUG_DATARInternal use
0x0010 (16)MGICRInternal use
0x0011 (17)DVIDRInternal use
0x0012 (18)COMMRInternal use
0x0013 (19)GYRORInternal use
0x0014 (20)MMAXR/WMax profile number0...19
0x0015 (21)PVERRProtocol version ID43
0x0016 (22)BCKLRInternal use
0x0017 (23)OHPR/WOverheat temperature in C0...200
0x0018 (24)TCPLRInternal use
0x0019 (25)PARAMR/W*See PARAM register belowBitmask
0x001A (26)MINSR/Wminimum source battery 0%
0x001B (27)MAXSR/Wmaximum source battery 100%
0x001C (28)CLR1R/WPowerOff ColorRGB565
0x001D (29)CLR2R/WCV colorRGB565
0x001E (30)CLR3R/WCC colorRGB565
0x001F (31)CRCRInternal use
0x0020 (32)CMDWExecute command
*See Register CMD table
YESYES
0x0021 (33)TIME_LRTime counter low word
0x0022 (34)TIME_HRTime counter high word
0x0023 (35)MEMR/WProfile number0...19YES
0x0024 (36)AHCNT_LRAmper-hour counter low word
0x0025 (37)AHCNT_HRAmper-hour counter high word
0x0026 (38)WHCNT_LRWatt-hour counter low word
0x0027 (39)WHCNT_HRWatt-hour counter high word
0x0028 (40)CLB_CMDW*See CLB_CMD tableYESYES
0x0029 (41)CLB_IDXW*See CLB_CMD table
0x002A (42)CLB_DATA_LWLow Word for CalibRecord_t.Value
0x002B (43)CLB_DATA_HWHigh Word for CalibRecord_t.Value
0x002C (44)IP_LRLow Word for local IP address
0x002D (45)IP_HRHigh Word for local IP address

Bitmask

STA_ANA_TEMP_SENSOR = 0x01 // Analog temperature sensor in the model
STA_DIG_TEMP_SENSOR = 0x02 // Digital temperature sensor LM75 found at startup
STA_GYRO_SENSOR = 0x04 // Optional MPU6050 gyro sensor found at startup
STA_CUR_DIV = 0x08 // Current divider is 10. Means ISET and IOUT has format 0.000
STA_MODEL_WUZHI = 0x10 //This is WUZHI

Bitmask
PARAM_C_OR_F = 0x01 // hex for 0000 0001
PARAM_RESET_COUNTERS = 0x02 // hex for 0000 0010
PARAM_SMART_DISPLAY = 0x04 // hex for 0000 0100
PARAM_BATTERY_SOURCE = 0x08 // hex for 0000 1000
PARAM_POWER_ON_START = 0x10 // hex for 0001 0000
PARAM_LOCK_ON_START = 0x20 // hex for 0010 0000
PARAM_SLEEP_ON_START = 0x40 // hex for 0100 0000
PARAM_TURN_OFF_FILTER  = 0x80 // hex for 1000 0000 turn off filter for Uout, Iout, Uin

Profiles M0 ... C9

Registers ADDRRegisters (Decimal)NameWrite to EEPROM
0x0050 - 0x005F80 - 95Profile M0YES
0x0060 - 0x006F96 - 111Profile M1YES
0x0070 - 0x007FProfile M2YES
0x0080 - 0x008FProfile M3YES
0x0090 - 0x009FProfile M4YES
0x00A0 - 0x00AFProfile M5YES
0x00B0 - 0x00BFProfile M6YES
0x00C0 - 0x00CFProfile M7YES
0x00D0 - 0x00DFProfile M8YES
0x00E0 - 0x00EFProfile M9YES
0x00F0 - 0x00FFProfile C0YES
0x0100 - 0x010FProfile C1YES
0x0110 - 0x011FProfile C2YES
0x0120 - 0x012FProfile C3YES
0x0130 - 0x013FProfile C4YES
0x0140 - 0x014FProfile C5YES
0x0150 - 0x015FProfile C6YES
0x0160 - 0x016FProfile C7YES
0x0170 - 0x017FProfile C8YES
0x0180 - 0x018F384 - 399Profile C9YES
*See Profile table

Profile ver. 4.5

RegisterNameRead \ WriteDescriptionRangeFirmwareWrite to EEPROM
0USETPR /WUset for profile0...UmaxAlt / ChinaYES
1ISETPR /WIset for profile0...ImaxAlt / ChinaYES
2SOVPR /WOVP0...UmaxChinaYES
3SOCPR /WOCP0...ImaxChinaYES
4SOPPR /WOPP0... Umax x ImaxAlt / ChinaYES
5BLEDR /WLCD backlight1...5ChinaYES
6PRFSR /W*See PRFS register belowAltYES
7SINIR /WChinaYES
8OTIMR /WTimer value0...5999AltYES

Bitmask

PROFILE_SOFT_FRONT = 0x01 
PROFILE_TRIGGER_OVP = 0x02 
PROFILE_TRIGGER_OCP = 0x04

PROTECT register

Error groups in the PROTECT register

  • OVP…VIN – checked by DPS firmware every 100ms when the output is on.
  • EPR – checked by DPS firmware when external power is applied, during the logo screen
  • E16…E25 – checked by DPS firmware after calibration and each time the output is turned off.

All errors are reset when the output is turned on.

PROTECT register

ValueNameDescriptionCondition
0OKNo error
1OVPOvervoltage protectionUout > Profile.OVP
2OCPOvercurrent protectionIout > Profile.OCP
3OPPOverpower protectionUout x Iout > Profile.OPP
4TIMStopped by timerTime > Profile.OTIM
5OHPOverheat protectionTMP > OHP
6BATSource battery low voltage protectionUin < MINS - 10%
7ENDCharge battery low currentIout < 50mA for 30 seconds
8EVPError voltage protectionUset > Umax
9ECPError current protectionIset > Imax
10VINLow input voltage errorUset > Uin
11EPREEPROM errorCan't read from EEPROM
12
13
14
15
16E16Calibration data errorUinL >= UinH
17E17Calibration data errorADC_UinL >= ADC_UinH
18E18Calibration data errorUoutL >= UoutH
19E19Calibration data errorADC_UoutL >= ADC_UoutH
20E20Calibration data errorDAC_UoutL >= DAC_UoutH
21E21Calibration data errorIoutL >= IoutH
22E22Calibration data errorADC_IoutL >= ADC_IoutH
23E23Calibration data errorDAC_IoutL >= DAC_IoutH
24E24Calibration data errorTempH Value <= 20C
25E25Calibration data errorTempH ADC >= Temp ADC 20C

Register CMD

ValueAction
1Stores MGIC ... CLR3 registers to EEPROM.
Stores BLED register to EEPROM
2Stores MEM to EEPROM
Stores Profile registers to EEPOM. The profile number is in MEM register.
3USET -> Profile.USETP
ISET -> Profile.ISETP
Stores MEM to EEPROM
Stores Profile registers to EEPOM. The profile number is in MEM register.
4Reset Timer and Energy counters
1234Jump to Update Mode

Registers CLB_CMD and CLB_IDX

NAME=VALUEAction/ Index
CLB_CMD = 0Show calibration screen
CLB_CMD = 1Start calibration for CLB_IDX
CLB_CMD = 2Fix the value in CLB_DATA for CLB_IDX
CLB_CMD = 3Exit and save calibration
CLB_CMD = 4Exit calibration w/o saving
CLB_IDX = 1U in L
CLB_IDX = 2U in H
CLB_IDX = 3U out L
CLB_IDX = 4U out H
CLB_IDX = 5I out L
CLB_IDX = 6I out H
CLB_IDX = 7Temp H
* Use groupped request to write CLB_CMD ... CLB_DATA_H