Fortunately, this can be compensated for by increasing the capacitor charging current at the low end. Using an oscilloscope, I've measured what increase in DAC output voltage is required to get the correct amplitude. The plot of frequency vs dac increase (in dac steps, each step is 76.3 uV, which when placed across a 56k resistor equals a current of 76.3uV/56kOhm = 1.36nA per step) is like this:
It shows that as the frequency drops, a higher and higher correction is needed to reach the correct amplitude in the available time. It also shows that the correction necessary is negligible for frequencies above 300Hz.
This plot shows the expected charge current vs the required one for the same range, blue being the expected and orange the required:
I am trying to find a function that fits what I see, to make it easy to add the necessary charge voltage to the precalculated dac lookup table. I've had some success with exponential regression but it doesn't quite fit.
But what is the effect I'm seeing? Why is a larger current than expected required at low frequencies, and why does it change?
The only thing I can think of is that we have a leak somewhere - some of the charge in the cap leaks out, or some of the current goes somewhere else or is turned to heat etc. As this effect goes on for a longer time the lower the frequency, it is a reasonable assumption which fits what I see.
There are very few parts involved in the integrator. A capacitor, a transistor and a 2.2Ohm resistor which I suspect is there to limit the current during capacitor discharging.
I tried removing the resistor, nothing changed. This leaves the transistor and cap.
A BJT like the one used in the DCO has a maximum leakage current of 15nA at 30V. It will be less at lower voltages, but not necessary propotionally less, according to this post. While I haven't tried to do any calculations, this is in the same range as the currents required to correct the error.
The Yusynth VCO, which also has an integrator core, uses a n-channel JFET instead of a BJT, and specifies a high quality capacitor - styroflex or silver mica, 1%. A JFET has a much lower channel-to-gate leakage current than a BJT, so this may improve things. I will try this, but it requires a slight redesign of the circuit.