I got myself an SDL1020X-E after debating the Rigol DL3021 for a while. The siglent seemed to be much more stable with dynamic loading and generally better in hardware, so I chose that one. With the advice provided here on how to increase resolution and the power limit, and the same going for the Siglent SDS2000X+ that I also own, I think I can give something back.
I was fairly annoyed to see that both the set current and the readback values were off quite a bit. This may have to do with the hardware being X-E instead of X as someone mentioned on here, but the annoying part was that I couldn't find a way
So, I put @tv84's dump into the hex editor and looked around. There is a number of relevant commands to be found which I partly tried:
SYSTem:CALibration:MODE: Can be set to 1 by writing 1 or On. If done while the load is active, it will become inactive, but the On/Off button will stay lit. Resets to 0 after powercycle. I could not observe any changes whether active or not. Can be read with a question mark.
CALCLS:*: Deletes the calibration values. Possible subcommands are VOLTage, CURRent, RESistance, EXTV, MONItor, ALL. Effect becomes visible immediately. The reset is not written to memory though, see below.
CALibration:* Possible subcommands are DATA, EXTV, MONItor, STorage. I played around with DATA a lot to try and see if I can write calibration values, but I couldn't. I tried tuples like 1,1 ; 1,1,1; etc., I tried adding "W" for write - no luck. EXTV I didn't try. MONI crashed the unit a few times. STorage probably stores the temporarily changed calibration values, e.g. after using one of the CALCLS commands - didn't test it.
The following two commands read the calibration values back:
CALibration:CTRL?: Control calibration. In my unit, the response was 0.000668,1561,0.002856,1563,0.000084,794,0.000502,815 .
CALibration:MEAS?: Readback calibration. In my unit, the response was 0.000669,1269,0.002862,1269,0.000084,827,0.000502,786 .
CALibration:RES?: Produces no response.
I tried to interpret these and didn't fully succeed yet. What I found out:
1. A float and a 2-byte unsigned int belong together.
2. The order is as follows: Voltage Low, Voltage High, Current Low, Current High. This corresponds to the 36V/150V and 5A/30A ranges.
3. CTRL is for controlling the target voltage in CV and the load current in CC (and probably CR, CP) modes.
4. MEAS is the readback for the display. In CR and CP modes, this probably affects accuracy as the control loop will likely operate on these, so CTRL and MEAS calibrations work in tandem for those.
5. The firmware might support a hardware loop or some other form of calibration for CR mode, but doesn't expose it or it wasn't fully implemented. Therefore, RES calibration is not available.
I could not get calibration to work using these commands, so I did something else: using @atimos' post about FLASH:READ, I dumped the flash and looked for the values given by CAL:CTRL? and CAL:MEAS?. Success: The entire calibration data is within Offsets 0d-63d. I will use decimal addressing from here on as it's used for the SCPI commands.
I tried to make a memory map, but for that, I need to give those variables a name. And that's where I failed. I'm mostly through calibrating the unit, but it was at least 30% guesswork and modifying variables to observe their effect.
I assume the float is a kind of offset as it tends to shift values in both the low and high end of a range. But at some point it becomes linear. The int value could be a linear correction, but it seems that the offset is neither for all values nor does it define the maximum value. My current guess is that the offset isn't actually a data value (ADC result), but the point within the range at which a specific data value occurs. This means that the linear correction shifts with the offset. I have no mathematical proof and it sounds a bit convoluted, so I hope there is a better explanation. It's also weird that the int changes linearity and the float changes the offset, most systems I've seen and written do the opposite. To make things even more complicated, there seemed to be a squared component in the calibration: With the "right" settings, the measured values were off at the low and high end of a range, but correct in the middle.
The int and float are stored in little endian formats. I can provide a python script to decode the dump directly, I just need to finish that memory map. For those who want to take a look themselves:
CTRL V LOW starts at 0d with four bytes for the float value. At 4d two bytes for the int follow. Then there's two unknown bytes (see below).
CTRL V HIGH starts at 8d.
It seems that the calibration data is grouped by voltage/current rather than MEAS/CTRL, so there's a jump:
MEAS V LOW starts at 16d.
MEAS I LOW starts at 24d.
CTRL I LOW: 32d
CTRL I HIGH: 40d
MEAS I LOW: 48d
MEAS I HIGH: 56d
There are also oddities: between two range calibration values, there is a gap of two bytes. For most ranges those are 00 00, but for one it isn't. Modifying the bytes does not produce any noticeable change.
One big annoyance is that at least in the low current range, the set current is dependent on the Slew Rate. With 0.5 A/us, my set current is now correct to at least 1 mA. with 0.01 A/us, the current is too high by at least 20 mA across the range. I have no idea what technical reason could cause that as I would assume that CC drives the load FETs with a constant voltage generated by a DAC. Does anyone else have that issue?
One big disadvantage of directly writing the calibration values to the memory is that they only come into affect after a restart. So every time you change a value, you need to reboot, making the whole process very tedious. Maybe someone can find a way to reload the calibration data. With a three day old unit, the effect of that is:
[See attachment, I can't seem to get inline pictures to work.]
But don't worry, the startup counter can be reset too. It is a two byte int located at 236d. To reset it, all you need to do is
FLASH:WRITE 236,0
FLASH:WRITE 237,0
To set it to a reasonable value, write something to 236d and zero to 237d.