The PT2399 is a single chip audio delay circuit. This chip is very popular among DIY guitar effect and modular synthesizer builders. The PT2399 has one flaw though: the delay time can only be set by a simple variable resistor. This makes it impractical to control accurately with MIDI or CV since the delay time to resistance ratio changes with temperature, supply voltage and other parameters.
The PT2399 does however have a frequency output that allows for monitoring the actual delay time.
By using an Arduino to monitor this signal and constantly adjusting the delay it is possible to lock the PT2399 to accurate delay times.
This guide discribes the hardware and Arduino firmware needed to control the delay time using MIDI sync.
How it works
The PT2399 datasheet suggest the circuit on the right. Audio enters the input terminal and is delayed for some time before appearing at the output terminal. Some of the output signal can be fed back to the input creating the echo effect.
In this circuit the delay time is controlled by the potentiometer and resistor.
The only change we make for this project is replacing the resistor and potentometer with a circuit that controls the delay using an Arduino.
Circuit for controlling the internal oscillator
Pin 5 of the PT2399 chip is an output from an internal clock generator. The frequency of this oscillator is directly proportional to the delay time. Normally the frequency is set by the combined resistance connected to pin 6.
For our purpose we need to be able to control the frequency with a voltage rather than a resistance.
It turns out that it is possible to control the frequency using the circuit on the right but the voltage to frequency is very non linear so we can’t just apply a voltage that corresponds to a certain delay. Instead an Arduino continuously measures the clock signal from the PT2399 and compares it to a desired frequency. If the frequency is too high it makes pin 8 output a short positive (5V) pulse and if it’s too low a short negative (0V) pulse. In this way the frequency is constantly nudged towards the desired frequency.
How Arduino locks the PT2399’s clock frequency
This project uses an Arduino UNO equipped with a ATMEGA328P chip. Other compatible ATMEGA chips will also work.
The ATMEGA328P has three timers, one 16-bit and two 8-bit. One 8-bit timer is reserved by the Arduino system for time keeping but one 8-bit and one 16-bit are available for applications.
In this example the 8-bit timer is set up to generate 500 timer events per second and the 16-bit timer for counting the clock pulses from the PT2399. 500 times a second the number of clock pulses are read and stored in a variable. This variable is compared to a pre-set value, representing the desired frequency (keep in mind not in Hertz but 1/500 Hertz).
A capacitor is connected to pin 8 of the Arduino. This pin is set as INPUT most of the time and thus does not change the charge of the capacitor.
If the frequency is found to be too low, pin 8 is set as OUTPUT and LOW for a small ammount of time, causing the capacitor to discharge a small ammount. Likewise if the frequency is found to be too high pin 8 is set as OUTPUT and HIGH for a short timer charging the capacitor a small ammount.
Eventually a voltage is reached on the capacitor that causes the desired clock frequency to be generated in the PT2399.
This technique is called a frequency locked loop.
Controlling it with MIDI
When using the echo effect with MIDI it is useful to synchronize the delay time with the speed of the sequencer. This is done by receiving MIDI clock signal from the sequencer and calculating the desired delay from this.
Normal MIDI clock is transmitted at 25 clocks per quarter note. The example code measures the time it takes for 96 of these clocks (one note) and calculates a clock frequency for the PT2399 that corresponds to a 3/16 note delay (nice groove).
The 3/16 note may be changed in the code by changing the “GROOVE” value
Audio example where the echo synchronizes to MIDI
From the PT2399 datasheet:
342 mS delay equals 2MHz clock frequency
This gives us:
delay = x / clock => x = 0.342s * 2000000 = 684000 =>