It was easier than I thought. Inspired by LTC1043, and app. note from LT.
Here is the setup. Since I don't have good quality equipment to test linearity over 12 bits, my multimeter has only 1 mV resolution below 4V at the best, I use ADS1232 board from aliex. I also install MAX5717A DAC (16-bits, 1 LSB INL) in parallel as a verification/ reference path. Arduino Mega is running pwm driver, reading ADC, updates both DACs and switching multiplexer in front of ADC, plus searching linear regression and print an error over serial monitor.
Everything on a breadboard, a lot of noise, but results is quite good for start.
Linear: y = 1.000762 * x -249761.562500
Linear: y = 1.004887 * x -249921.296875
bin_C uVolt 5717a error er_uV pwmD error er_uV
16384 128000 -233375 -9 -70 -233456 +1 +7
32768 256000 -216973 -4 -31 -216989 +4 +31
49152 384000 -200576 -3 -23 -200524 +5 +39
65536 512000 -184176 +0 +0 -184058 +7 +54
81920 640000 -167779 +0 +0 -167594 +6 +46
98304 768000 -151381 +1 +7 -151132 +4 +31
114688 896000 -134982 +4 +31 -134674 -1 -7
131072 1024000 -118585 +4 +31 -118210 -1 -7
147456 1152000 -102187 +6 +46 -101747 -2 -15
163840 1280000 -85791 +5 +39 -85284 -3 -23
180224 1408000 -69394 +6 +46 -68815 +1 +7
196608 1536000 -52998 +5 +39 -52347 +5 +39
212992 1664000 -36601 +6 +46 -35885 +3 +23
229376 1792000 -20206 +4 +31 -19422 +2 +15
245760 1920000 -3811 +3 +23 -2959 +1 +7
262144 2048000 +12586 +3 +23 +13504 +0 +0
278528 2176000 +28979 +0 +0 +29965 -2 -15
294912 2304000 +45373 -2 -15 +46428 -4 -31
311296 2432000 +61771 +0 +0 +62892 -4 -31
327680 2560000 +78166 -2 -15 +79356 -4 -31
344064 2688000 +94563 -1 -7 +95820 -4 -31
360448 2816000 +110959 -2 -15 +112284 -4 -31
376832 2944000 +127354 -3 -23 +128747 -5 -39
393216 3072000 +143752 -2 -15 +145212 -4 -31
409600 3200000 +160148 -2 -15 +161677 -3 -23
425984 3328000 +176545 -2 -15 +178144 +0 +0
442368 3456000 +192942 -1 -7 +194610 +1 +7
458752 3584000 +209341 +0 +0 +211077 +4 +31
475136 3712000 +225736 +0 +0 +227544 +7 +54
491520 3840000 +242130 -3 -23 +244009 +8 +62
507904 3968000 +258524 -5 -39 +260471 +5 +39
Columns:
1. bin_C- binary code, scaled to 19-bits, same as ADC, I don't need 24-noisy bits, 19-more than enough.
2. uVolt - microvolts associated with 4096mV reference
3. raw ADC data from 5717a
4. error in 19-bits scale
5. error in microVolts er_uV
6. raw ADC data from pwmDAC
error
er_uV
PWM set to 3.9 kHz, based on 16 MHz / 4096 (12-bits). MAX5717A getting 16-bits, pwmDAC - 12, to keep settling time low. I will check more on this tomorrow probably.