Peaks CV Values

Hi! I’m new, so please forgive me if I’ve placed this in the wrong section.

I’ve written a two-octave chromatic sequencer for Peaks. My chromatic quantization function works pretty well, but I noticed something when experimenting with the int16_t values from the native 4-step mini sequencer: The output sends 1 volt at the value +3800, and -1 volt is at -4500, with 0 volts being sent at around -350. So my questions are:

(1) Would these values be consistent if I got another Peaks and installed the same firmware?
(2) Or is there a hardware calibration option?
(3) Or is the Peaks just not designed for this sort of thing?

Like I said, I’ve got it sufficiently in tune for my own module, but I’m wondering what would happen if I installed it in another Peaks.

1/ The relationship between the 16-bit integer sent to the DAC and the output voltage depends on the value of all the resistors in the circuitry that follows the DAC, and these 5 resistors have a tolerance of 1%. There is also some variation in the voltage delivered by the -10V voltage reference (for offset) and the 2.5V reference (for the DAC). So you’ll get some variation from one module to the other and can’t trust your measurements.

2/ None of the functions performed by Peaks require accurate voltages, so the modules are not calibrated for accurate 1V/O output. The old Peaks have a trimmer at the back which is factory adjusted so that writing a value of 0 to the DAC results in a voltage of 0V. For the newer Peaks, the trimmer is gone, and the adjustment is done by adding/removing an offset in software. The modules are factory calibrated so that writing 0 + this offset results in a voltage of 0V. I had forgotten to commit the code for this in the public repo, check it again. The calibration procedure is accessed by powering the module on with the second button pressed, the first two knobs work as a coarse/fine adjustment for output 1’s zero, the last two knobs for output 2.

3/ If you want to make it work for all Peaks, you’ll have to add a second step to the calibration procedure to also calibrate for 1V output (we can assume a linear law unless you want sub mV accuracy). Up to you to decide whether asking the users of your modified firmware to stick a voltmeter at the output of their module is worth doing.

Hello, and thank you very much for the reply!

I don’t really plan on having “users” of my modified firmware, it’ll just be me, and I’m personally fine with a bit of trial and error. For now I’m going to stop tinkering with it and use it for a while, although I’m sure I won’t be able to resist trying the calibration procedure for long.

This has been an enjoyable experience, by the way. I keep thinking of new things I can do with Peaks, and you’ve made it easy to realize them. Thank you for making it.

By the way: Would 4095 send 1 volt if calibration and tolerance were both optimal?

I’m not sure what you mean by tolerances being optimal. You mean if the resistors and references all had the exact value (a tolerance of 0%)?

In this case the equation between the 16 bit unsigned integer passed to Dac::Write, and the output voltage is:

  • value / 65536 * 2.5 * 249 / 39 + 10 * 249 / 309

So it’s not exactly 4096 units / V – but who cares if you can scale this in software anyway!

Also, please note that Peaks uses an “outer resistor” output protection scheme. You’ll get a voltage drop (the VCO downstream will read only 99.1% of the expected voltage) unless you use a buffer/buffered multiple.

So your options are either:

  • Calibrating with a 100k load - assuming the VCO you’re going to use has a 100k input impedance.
  • Always using a buffer/buffered multiple.

Thanks again. I’m using Links’s 1x3 and 2x2 sections (for transposition), and both sections work well with Peaks and my oscillators.

Then you might have observed a difference in tracking, since Links’ 2x2 section has the usual 100k input impedance (9mV/V error with an 1k output protection resistor), while Links’ 1x3 section has an 1M input impedance (0.9mV/V error with an 1k output protection resistor).

Hey, if you don’t mind, what’s going on here, in mini_sequencer’s ProcessSingleSample?

return static_cast<int32_t>(steps_[step_]) * 40960 >> 16;

where this used to be

return steps_[step_];

Is this some kind of range adjustment?

> Then you might have observed a difference in tracking

I use the 2x2 over a pretty restricted range, usually to go up or down maybe a fourth, so if its error is greater than the 1x3’s for tracking, it hasn’t bothered me. It’s more important that the 1x3 tracks really well, and I’ve been pleased with it.

Yes, the original range was 0V to +8V, and this was quite large! The new range is 0V to +5V.

That calibration procedure is awesome! I no longer have to have a weird zero-offset in my code. Now it’s just a matter of tweaking some of the fixed-point arithmetic for the scale, but the octaves are dead nuts. Thank you so much!