TheHWcave / OWON-XDM1041

Files and information for the OWON XDM1041 Bench Multimeter
MIT License
45 stars 10 forks source link

Calibration Data Dump #4

Open sigxcpu76 opened 2 years ago

sigxcpu76 commented 2 years ago

Can someone post their calibration data? I've managed to destroy mine with the updater in this repository and now I'm running with the data from XDM2041. It is okish, but I cannot be sure.

Calibration data can be dumped using this Python script.

Thank you.

https://github.com/PetteriAimonen/owon-xdm2041-info/blob/main/bootloader/backup_calibration.py

Maybe @TheHWcave ?

TheHWcave commented 2 years ago
On Thursday, 23 June 2022 at 17:08:41 BST, Alexandru Pirvulescu ***@***.***> wrote:  

Can someone post their calibration data? I've managed to destroy mine with the updater in this repository and now I'm running with the data from XDM2041. It is okish, but I cannot be sure.

Calibration data can be dumped using this Python script.

Thank you.

https://github.com/PetteriAimonen/owon-xdm2041-info/blob/main/bootloader/backup_calibration.py

Maybe @TheHWcave ?

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you were mentioned.Message ID: @.***>

TheHWcave commented 2 years ago

calibration.bin.zip

TheHWcave commented 2 years ago

Hope that works for you. Please let me know. BTW, I take it from the "accident" that the bootloader prog. still needs to be treated with caution ;)

sigxcpu76 commented 2 years ago

Thank you. Uploaded. Now I bet I've "cloned" yours (in terms of serial number & stuff). image

sigxcpu76 commented 2 years ago

It is still ~20-50mV lower on the DC measurements. It is compared with a OWON HDS272S and a RIDEN RD6018 (which mostly agree between them).

TheHWcave commented 2 years ago

I just checked using my 5V reference:  The XDM1041 is reading just 2.2 mV lower than my Agilent 34401A. If yours are so different, it means cal values are really specific for individual meters (which is what you would expect). Sadly the HY3131 chip datasheet is silent how the cal values are encoded, if that is even done there and not in the processor.

On Thursday, 23 June 2022 at 21:33:47 BST, Alexandru Pirvulescu ***@***.***> wrote:  

It is still ~20-50mV lower on the DC measurements. It is compared with a OWON HDS272S and a RIDEN RD6018 (which mostly agree between them).

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you were mentioned.Message ID: @.***>

sigxcpu76 commented 2 years ago

I guess that that calibration based adjustments are done in the software itself. Strings in the firmware show a bit about calibration, so it may be a combination of keys that allows you to adjust stuff. The small scales are reading a bit higher, so I guess there is a correction value per each individual scale.

LE: all the offsets are here: https://github.com/PetteriAimonen/owon-xdm2041-info/tree/main/orig_firmware

Now I need a way to recompute & rewrite them.

TheHWcave commented 2 years ago

An update... Someone posted on EEVblog some secret key sequences that get you into a cal menu. There is a manual and automatic cal apparently. Sadly the auto cal starts without any way of stopping and proceeds relentlessly for all ranges and hence I have lost all my cal!  Tonight I will try to upload the dump I made for you ... . In the mean time, I tried manual cal on the 5V DC range (nothing to lose ...:) and it worked fine. 5V DC is now the only range that works on my XDM1041... The take away, if you have a good reference you can do a manual recalibration. I will mail more about how to do it later.

On Thursday, 23 June 2022 at 22:55:45 BST, Alexandru Pirvulescu ***@***.***> wrote:  

I guess that that calibration based adjustments are done in the software itself. Strings in the firmware show a bit about calibration, so it may be a combination of keys that allows you to adjust stuff. The small scales are reading a bit higher, so I guess there is a correction value per each individual scale.

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you were mentioned.Message ID: @.***>

sigxcpu76 commented 2 years ago

Thank you. I already got a 2041, but managed to calibrate most of the DC voltage ranges and few cap ranges using software. I have a small Go app that reads the 2KB calibration file, adjusts the values and writes it back. I check the value with my "good" ( :) ) DMM then with 1041, compute factor and adjust the value. Write the new cal file, upload it, rinse and repeat.

TheHWcave commented 2 years ago

Nice. Can you reveal what the formulae are to adjust the values? It appears there are 2 per range, called "zero" and "coef" in the hidden debug menu By the way, I managed to reload the cal data from the dump I made for you.

The hidden menus can be reached with these sequences UTILITY-MATH-UP-RANGE-DOWN:   gets a menu on my system which offers DEBUG, Keyboard test and LCD test. DEBUG is the manual cal menu. MATH seems to exit the menu. RECORD to move the cursor between zero and coef and the arrows to change digits.

UTILITY-DUAL-UP-RANGE-DOWN:  starts autocal immediately which will destroy your existing cal on all modes and ranges.

On Friday, 1 July 2022 at 14:26:34 BST, Alexandru Pirvulescu ***@***.***> wrote:  

Thank you. I already got a 2041, but managed to calibrate most of the DC voltage ranges and few cap ranges using software. I have a small Go app that reads the 2KB calibration file, adjusts the values and writes it back. I check the value with my "good" ( :) ) DMM then with 1041, compute factor and adjust the value. Write the new cal file, upload it, rinse and repeat.

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you were mentioned.Message ID: @.***>

sigxcpu76 commented 2 years ago

There is no magic formula. I adjust just the "coef" I guess. Its "default" value is 1000000 (or whatever is already stored in the calibration). I try to measure in the middle of the scale (as much as I can) with a "good" DMM. Let's say I get value A. The "bad" DMM shows value B. Then new_coef = old_coef * A/B.

The coef is second value in the data structure in the "app" below, which I am using to do what I described above.

The offsets for calibration values I've taken from here: https://github.com/PetteriAimonen/owon-xdm2041-info/tree/main/orig_firmware

That is the calibration information for 2041, but it matched my 1041 until now, at least for the top part of the table. I think the calibration table structure is identical between them, after checking your dump (thank you again for that).

package main

import (
    "fmt"
    "io/ioutil"
    "os"
)

type CalibrationValue struct {
    Address     int
    Value       int32
    Scalar      float64
    Description string
}

var calibrationValues = []CalibrationValue{
    {0x0001F9F8, 1023991, 0.068321, "Scale for 50 mVDC"},
    {0x0001F9FC, 1024787, 0.683336, "Scale for 500 mVDC"},
    {0x0001FA00, 1029923, 7.516670, "Scale for 5 VDC, tested"}, /* 1028925 */
    {0x0001FA04, 1041205, 68.333600, "Scale for 50 VDC, tested"},
    {0x0001FA08, 1029563, 683.331000, "Scale for 500 VDC, tested"},
    {0x0001FA0C, 1029286, 1366.680000, "Scale for 1000 VDC"},
    {0x0001FA20, 1026853, 78.720800, "Scale for 500 mVAC, tested, relative to sqrt(RMS_DATA)"},
    {0x0001FA24, 1031555, 865.928000, "Scale for 5 VAC, tested"},
    {0x0001FA28, 1042351, 7872.030000, "Scale for 50 VAC, tested"},
    {0x0001FA2C, 1025702, 78720.900000, "Scale for 500 VAC, tested"},
    {0x0001FA48, 1011027, 0.000684, "Scale for 500uADC"},
    {0x0001FA4C, 1012140, 0.006833, "Scale for 5mADC"},
    {0x0001FA50, 1019301, 0.068333, "Scale for 50mADC, tested"},
    {0x0001FA54, 1020369, 0.683336, "Scale for 500mADC, tested"},
    {0x0001FA58, 1028499, 6.833350, "Scale for 5ADC"},
    {0x0001FA5C, 1028501, 13.666700, "Scale for 10ADC"},
    {0x0001FA74, 1017592, 0.000000, "Unknown"},
    {0x0001FA78, 1023615, 0.000000, "Unknown"},
    {0x0001FA7C, 1025093, 0.000000, "Scale for AC current measurements, on top of DC"},
    {0x0001FAA4, 914813, 1112800.000000, "Scale for 500kohm, tested"},
    {0x0001FAA8, 1019972, 6676250.000000, "Scale for 5Mohm, tested"},
    {0x0001FAAC, 1023225, 67351000.000000, "Scale for 50Mohm, tested"},
    {0x0001FAC0, 1007702, 1112.130000, "Scale for 500ohm, tested"},
    {0x0001FAC4, 1007131, 11198.800000, "Scale for 5kohm, tested"},
    {0x0001FAC8, 997716, 112494.000000, "Scale for 50kohm, tested"},
    {0x0001FB38, 955828, 0.000000, "Scale for 50nF, tested"},
    {0x0001FB3C, 979000, 0.000000, "Scale for 500nF, tested"},
    {0x0001FB40, 999917, 0.000000, "Scale for 5uF"},
    {0x0001FB44, 991883, 0.000000, "Scale for 50uF, tested"},
    {0x0001FB48, 689933, 0.000000, "Scale for 500uF"},
    {0x0001FB4C, 714670, 0.000000, "Scale for 5mF"},
    {0x0001FB50, 990931, 0.000000, "Scale for 50mF"},
    {0x0001FBB0, -10774, 0.000000, "Offset for 50 mVDC range in nanovolts"},
    {0x0001FBB4, 27369, 0.000000, "Offset for 500 mVDC range in nanovolts"},
}

func main() {
    f, err := os.Open("calibration_xdm1041.bin")
    if err != nil {
        panic(err)
    }

    data, err := ioutil.ReadAll(f)
    f.Close()

    fmt.Printf("read %d byte(s)\n", len(data))

    var buf int32

    for _, x := range calibrationValues {
        offset := x.Address - 0x0001f800
        buf = int32(data[offset]) + int32(data[offset+1])<<8 + int32(data[offset+2])<<16 + int32(data[offset+3])<<24
        //fmt.Printf("%7d %7d (%08X %08X %s)\n", buf, int32(x.Value), x.Address, offset, x.Description)
        fmt.Printf("    {0x%08X, %d, %f, \"%s\"},\n", x.Address, buf, x.Scalar, x.Description)
        // write the new value
        data[offset] = byte(x.Value & 0xFF)
        data[offset+1] = byte((x.Value >> 8) & 0xFF)
        data[offset+2] = byte((x.Value >> 16) & 0xFF)
        data[offset+3] = byte((x.Value >> 24) & 0xFF)
    }

    err = ioutil.WriteFile("calibration_xdm1041.bin", data, 0644)
    if err != nil {
        panic(err)
    }
}
TheHWcave commented 2 years ago

Thanks Alexandru, this is great stuff. I will try that on my XDM1041.

As  I said, the first of the hidden menus with the DEBUG command seems to expose the individual ZERO and COEF values and allows changing them online so to say. With a known reference value fed into the meter, you can tweak ZERO or COEF until the reading on the display is correct. However, I am not sure if you can just examine and quit. Probably there is a button that does that but it seems extremely easy to accidentally change and save even when you don't want it.

By the way, there is this 2nd value (in the DEBUG menu) called ZERO which I think was usually zero. Is this an offset to correct deviation from zero? Last question: After I restored my CAL, I put a 5V ref voltage on and manually changed range (to see if the upper ranges had been restored). The DC volts worked as expected, even at 1000V range I can see a readout of 5.0 The AC volts is different. My AC ref is slightly below 5V. I can see 4.99xx in the 5V and 50V range but it is zero for 500V or 750V ranges. Experimenting a bit, it seems that if an AC volt value is less that 1% of the range it is simply shown as zero. For example  you need more that 5VAC to get a non-zero reading in the 500V range and more than 7VAC for the 750V range. I must admit that I never noticed that behaviour before. It makes sense from an accuracy point of view as the TRMS conversion needs a minimum input to work but usually that is simply a note in the specs on AC accuracy. Indeed the XDM1041 specifies a min value of  >5% of range for stated accuracy and from 1% to 5% an additional error of 0.1% is added. That is common with other multimeters  but none of my other meters simply turn the readout off if the value drops below 1%. I'd much prefer if it showed "something" rather than nothing, because it really let me on chase to find out why my 500VAC range apparently was no longer working... Oh well, yet another OWON quirk I guess.

Does your meter does the same?

On Friday, 1 July 2022 at 16:00:46 BST, Alexandru Pirvulescu ***@***.***> wrote:  

There is no magic formula. I adjust just the "coef" I guess. Its "default" value is 1000000 (or whatever is already stored in the calibration). I try to measure in the middle of the scale (as much as I can) with a "good" DMM. Let's say I get value A. The "bad" DMM shows value B. Then new_coef = old_coef * A/B.

The coef is second value in the data structure in the "app" below, which I am using to do what I described above.

The offsets for calibration values I've taken from here: https://github.com/PetteriAimonen/owon-xdm2041-info/tree/main/orig_firmware

That is the calibration information for 2041, but it matched my 1041 until now, at least for the top part of the table. I think the calibration table structure is identical between them, after checking your dump (thank you again for that). package main

import ( "fmt" "io/ioutil" "os" )

type CalibrationValue struct { Address int Value int32 Scalar float64 Description string }

var calibrationValues = []CalibrationValue{ {0x0001F9F8, 1023991, 0.068321, "Scale for 50 mVDC"}, {0x0001F9FC, 1024787, 0.683336, "Scale for 500 mVDC"}, {0x0001FA00, 1029923, 7.516670, "Scale for 5 VDC, tested"}, / 1028925 / {0x0001FA04, 1041205, 68.333600, "Scale for 50 VDC, tested"}, {0x0001FA08, 1029563, 683.331000, "Scale for 500 VDC, tested"}, {0x0001FA0C, 1029286, 1366.680000, "Scale for 1000 VDC"}, {0x0001FA20, 1026853, 78.720800, "Scale for 500 mVAC, tested, relative to sqrt(RMS_DATA)"}, {0x0001FA24, 1031555, 865.928000, "Scale for 5 VAC, tested"}, {0x0001FA28, 1042351, 7872.030000, "Scale for 50 VAC, tested"}, {0x0001FA2C, 1025702, 78720.900000, "Scale for 500 VAC, tested"}, {0x0001FA48, 1011027, 0.000684, "Scale for 500uADC"}, {0x0001FA4C, 1012140, 0.006833, "Scale for 5mADC"}, {0x0001FA50, 1019301, 0.068333, "Scale for 50mADC, tested"}, {0x0001FA54, 1020369, 0.683336, "Scale for 500mADC, tested"}, {0x0001FA58, 1028499, 6.833350, "Scale for 5ADC"}, {0x0001FA5C, 1028501, 13.666700, "Scale for 10ADC"}, {0x0001FA74, 1017592, 0.000000, "Unknown"}, {0x0001FA78, 1023615, 0.000000, "Unknown"}, {0x0001FA7C, 1025093, 0.000000, "Scale for AC current measurements, on top of DC"}, {0x0001FAA4, 914813, 1112800.000000, "Scale for 500kohm, tested"}, {0x0001FAA8, 1019972, 6676250.000000, "Scale for 5Mohm, tested"}, {0x0001FAAC, 1023225, 67351000.000000, "Scale for 50Mohm, tested"}, {0x0001FAC0, 1007702, 1112.130000, "Scale for 500ohm, tested"}, {0x0001FAC4, 1007131, 11198.800000, "Scale for 5kohm, tested"}, {0x0001FAC8, 997716, 112494.000000, "Scale for 50kohm, tested"}, {0x0001FB38, 955828, 0.000000, "Scale for 50nF, tested"}, {0x0001FB3C, 979000, 0.000000, "Scale for 500nF, tested"}, {0x0001FB40, 999917, 0.000000, "Scale for 5uF"}, {0x0001FB44, 991883, 0.000000, "Scale for 50uF, tested"}, {0x0001FB48, 689933, 0.000000, "Scale for 500uF"}, {0x0001FB4C, 714670, 0.000000, "Scale for 5mF"}, {0x0001FB50, 990931, 0.000000, "Scale for 50mF"}, {0x0001FBB0, -10774, 0.000000, "Offset for 50 mVDC range in nanovolts"}, {0x0001FBB4, 27369, 0.000000, "Offset for 500 mVDC range in nanovolts"}, }

func main() { f, err := os.Open("calibration_xdm1041.bin") if err != nil { panic(err) }

data, err := ioutil.ReadAll(f)
f.Close()

fmt.Printf("read %d byte(s)\n", len(data))

var buf int32

for _, x := range calibrationValues {
    offset := x.Address - 0x0001f800
    buf = int32(data[offset]) + int32(data[offset+1])<<8 + int32(data[offset+2])<<16 + int32(data[offset+3])<<24
    //fmt.Printf("%7d %7d (%08X %08X %s)\n", buf, int32(x.Value), x.Address, offset, x.Description)
    fmt.Printf("    {0x%08X, %d, %f, \"%s\"},\n", x.Address, buf, x.Scalar, x.Description)
    // write the new value
    data[offset] = byte(x.Value & 0xFF)
    data[offset+1] = byte((x.Value >> 8) & 0xFF)
    data[offset+2] = byte((x.Value >> 16) & 0xFF)
    data[offset+3] = byte((x.Value >> 24) & 0xFF)
}

err = ioutil.WriteFile("calibration_xdm1041.bin", data, 0644)
if err != nil {
    panic(err)
}

}

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you were mentioned.Message ID: @.***>

sigxcpu76 commented 2 years ago

I don't have voltage references to check. I can only check against another multimeter, that is not broken by me :) I do have a signal generator, I could try with that and compare multiple multimeters (I do have the 2041 now, the "old" 1041 and a HDS272S).

TheHWcave commented 2 years ago

The HDS272S signal gen should be able to do it. Generate an AC voltage of just under 5V and see if it shows in the 500V range.

On Saturday, 2 July 2022 at 10:50:20 BST, Alexandru Pirvulescu ***@***.***> wrote:  

I don't have voltage references to check. I can only check against another multimeter, that is not broken by me :) I do have a signal generator, I could try with that and compare multiple multimeters (I do have the 2041 now, the "old" 1041 and a HDS272S).

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you were mentioned.Message ID: @.***>

TheHWcave commented 1 year ago

Nice to have a clone. Yes, that looks exactly like what I have, serial number and all.  Is your meter showing the correct values, i.e. how well does my cal data match your meter?

On Thursday, 23 June 2022 at 21:26:45 BST, Alexandru Pirvulescu ***@***.***> wrote:  

Thank you. Uploaded. Now I bet I've "cloned" yours (in terms of serial number & stuff).

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you were mentioned.Message ID: @.***>

sigxcpu76 commented 1 year ago

I didn't move past few initial recalibrations. It was given to my son and I've got a 2041 for myself. It is good enough (TM) for his playing around/learning stuff.