DIYstompboxes.com

DIY Stompboxes => Digital & DSP => Topic started by: niektb on October 17, 2020, 02:34:04 AM

Title: Generating LFO for PT2399 with an Arduino
Post by: niektb on October 17, 2020, 02:34:04 AM
So, I'm designing myself a PT2399 pedal (which is nothing fancy sound-wise but with a RGB and a footswitch I hope to allow for some deep-editing without the need to open it up and flick a few dip switches).

Now, I'm using a MCP41050 (50k digipot) and wired the modulation just like in the Taptation: putting a mosfet (shunted with a depth pot) between the digipot and ground

But I wondered the following: Do I need to bandlimit the LFO?

I've generated a (for now a triangle) wavetable of 1024 steps and step through it with a simple timed function that's set to a sample frequency of 250Hz, so I'm not afraid of aliasing. However, if I would switch to a square wave (which has much more harmonics), the LFO would extend into audio range... As I'm modulating delay times (and hence pitch), doesn't this cause audible FM distortion?

How do I solve it? Additive Synthesis? External RC-filter?


void wp_inc() {
  wp = wp + (1 / mod_speed);
  if (wp > 1023)
    wp = wp - 1023;
  if (wp < 0)
    wp = 0;
}

// Triggers every ~4ms
void taskMod(int id_)
{
  uint8_t _val = pgm_read_word_near(wavetable + (int)ceil(wp));
  analogWrite(pin_delay_mod, _val);

  // fade the led if in the correct mode
  if (smode == SMODE_MOD)
    analogWrite(pin_rgb_b, map(_val, 0, 255, 0, 64));

  wp_inc();
}


Also, a different (but related) question: I've read that this form of modulation can cause a tempo offset... How can this be solved?

Lastly, I've seen people on the internet (such as https://github.com/ElectricCanary/Bontempo (https://github.com/ElectricCanary/Bontempo)) that can 'calibrate' the pedal but I can't figure out how this works... Can anybody explain it to me?  :D

Thanks in advance! ;)
Title: Re: Generating LFO for PT2399 with an Arduino
Post by: ElectricDruid on October 17, 2020, 08:00:53 PM
Quote from: niektb on October 17, 2020, 02:34:04 AM
However, if I would switch to a square wave (which has much more harmonics), the LFO would extend into audio range... As I'm modulating delay times (and hence pitch), doesn't this cause audible FM distortion?
Of course. Isn't that kind-of the point?!? It's not "distortion", it's "modulation". ;)

Quote
Also, a different (but related) question: I've read that this form of modulation can cause a tempo offset... How can this be solved?
If the delay time changes, then the "tempo" of the delay changes. It doesn't change the tempo of the incoming signal. This gives a strange effect. If you modulate a PT2399's delay time / pitch with a slow sine or triangle wave, it sounds like everything is speeding up and then slowing down again, but in fact the underlying tempo doesn't change. Just the pitch and tempo of the echoes.

It's not the same as the synth "FM versus PM" case, where one can cause a pitch offset and the other doesn't. The maths is not the same.

Quote
Lastly, I've seen people on the internet (such as https://github.com/ElectricCanary/Bontempo (https://github.com/ElectricCanary/Bontempo)) that can 'calibrate' the pedal but I can't figure out how this works... Can anybody explain it to me?  :D
Anything that *doesn't* use the pin 5 "clock output" on the PT2399 (or alternatively the audio input and output) isn't "calibrated" in any meaningful sense. It's an "open loop" solution, which is to say, it sets a value and hopes the chip responds according to the datasheet or its own internal assumptions. Neither of which may be the case.
In order to "close the loop" and actually calibrate the chip, you have to set a value and then measure the result. That can be done by setting the pin 6 value and then measuring the clock at pin 5. Or you can set the pin 6 value, and then ping a signal through the delay and measure how long it takes to arrive at the output. The pin 5 output on the PT2399 is a horrid waveform and needs cleaning up, but it's still easier than the second solution. The "calibration" comes when you adjust the values you put out based on the results that you saw. Without this, there is no calibration.

The Bontempo link you posted puts *the human* in the loop, and gets you to adjust the delay until it matches the flashing tempo LED. It then stores the offset that was required for that delay value, so it can repeat it next time. It says that it does this ten times, so I would expect ten values spread across the full range of delay times it can handle. The offsets for in-between delay times can then be worked out by interpolation, which should be reasonably accurate. It's not the greatest, but if you're careful with your calibration, it should be ok. Still, it depends on *your* accuracy, not *its*, which seems like a design weakness to me.

HTH,
Tom


Title: Re: Generating LFO for PT2399 with an Arduino
Post by: Fancy Lime on October 21, 2020, 03:29:13 PM
The pitch changes of modulated delays are an electronic form of the Doppler effect. Anyway, not important, carry on.

Cheers,
Andy
Title: Re: Generating LFO for PT2399 with an Arduino
Post by: Sweetalk on October 22, 2020, 05:55:22 AM
If you already have an arduino in the project why wont' you discard the digipot and use the pwm to manipulate the time and the modulation. You can easily adjust the pwm frequency above the audible range and no audio artifacts!. There's a pwm library around (can't remember where) that I use that does this.
I've done this technique and works fine, the pwm output it's the delay time from the pot + lfo offset (you can play with additive or sustractive lfo offset). Also check the electrosmash site that has some info about arduinos and pt2399.
Title: Re: Generating LFO for PT2399 with an Arduino
Post by: niektb on October 22, 2020, 06:25:06 AM
Quote from: ElectricDruid on October 17, 2020, 08:00:53 PM
Quote from: niektb on October 17, 2020, 02:34:04 AM
However, if I would switch to a square wave (which has much more harmonics), the LFO would extend into audio range... As I'm modulating delay times (and hence pitch), doesn't this cause audible FM distortion?
Of course. Isn't that kind-of the point?!? It's not "distortion", it's "modulation". ;)

Quote
Also, a different (but related) question: I've read that this form of modulation can cause a tempo offset... How can this be solved?
If the delay time changes, then the "tempo" of the delay changes. It doesn't change the tempo of the incoming signal. This gives a strange effect. If you modulate a PT2399's delay time / pitch with a slow sine or triangle wave, it sounds like everything is speeding up and then slowing down again, but in fact the underlying tempo doesn't change. Just the pitch and tempo of the echoes.

It's not the same as the synth "FM versus PM" case, where one can cause a pitch offset and the other doesn't. The maths is not the same.

Quote
Lastly, I've seen people on the internet (such as https://github.com/ElectricCanary/Bontempo (https://github.com/ElectricCanary/Bontempo)) that can 'calibrate' the pedal but I can't figure out how this works... Can anybody explain it to me?  :D
Anything that *doesn't* use the pin 5 "clock output" on the PT2399 (or alternatively the audio input and output) isn't "calibrated" in any meaningful sense. It's an "open loop" solution, which is to say, it sets a value and hopes the chip responds according to the datasheet or its own internal assumptions. Neither of which may be the case.
In order to "close the loop" and actually calibrate the chip, you have to set a value and then measure the result. That can be done by setting the pin 6 value and then measuring the clock at pin 5. Or you can set the pin 6 value, and then ping a signal through the delay and measure how long it takes to arrive at the output. The pin 5 output on the PT2399 is a horrid waveform and needs cleaning up, but it's still easier than the second solution. The "calibration" comes when you adjust the values you put out based on the results that you saw. Without this, there is no calibration.

The Bontempo link you posted puts *the human* in the loop, and gets you to adjust the delay until it matches the flashing tempo LED. It then stores the offset that was required for that delay value, so it can repeat it next time. It says that it does this ten times, so I would expect ten values spread across the full range of delay times it can handle. The offsets for in-between delay times can then be worked out by interpolation, which should be reasonably accurate. It's not the greatest, but if you're careful with your calibration, it should be ok. Still, it depends on *your* accuracy, not *its*, which seems like a design weakness to me.

HTH,
Tom

Thanks for your response Tom!
So you're saying that it's not a problem that the LFO waveforms extend into audio range?
I had a RC-filter on the MOSFET-gate and it feels definitely cleaner than without, but maybe I'm hearing the PWM  ???

I'm still debating whether or not I should keep the digipot... (or maybe even ditch the tap tempo all together) I'm reading that the digipots are a pain because of their wide tolerances...
The ElectroSmash Time Manipulator uses a Controlled Current Sink with an opamp and a transistor, does anybody have experience with the accuracy of that approach?

P.S.: I absolutely love the rotary-like sound I can get from this chip. Put some Pitch Shift and some reverb onto it and melt away!
Title: Re: Generating LFO for PT2399 with an Arduino
Post by: ElectricDruid on October 22, 2020, 08:33:55 AM
Quote from: niektb on October 22, 2020, 06:25:06 AM
So you're saying that it's not a problem that the LFO waveforms extend into audio range?
I don't think it's a problem, no. The "LFO modulated sound" that you expect to hear will include some FM effects, but that's a part of that sound, not some kind of error.

Quote
I had a RC-filter on the MOSFET-gate and it feels definitely cleaner than without, but maybe I'm hearing the PWM  ???
Quite possibly. A single-pole RC won't reduce the PWM level much unless it's miles below the PWM frequency. What PWM frequency are you using? The standard Arduino Analogwrite PWM is only a few hundred Hertz, iirc, but you can change it.

Quote
The ElectroSmash Time Manipulator uses a Controlled Current Sink with an opamp and a transistor, does anybody have experience with the accuracy of that approach?
That's similar to what I tried. It works fine. PT2399's vary, so accuracy is mostly about getting some feedback so the processor knows what it is doing. There needs to be calibration of some type for really accurate results.
Title: Re: Controlling PT2399 with an Arduino
Post by: niektb on October 23, 2020, 02:32:47 PM
Aaah okay!

I had an RC-filter that was at a (admitted, way to low) 16Hz cutoff, whereas the PWM frequency was 490Hz. I removed the RC filter and bumped the PWM to 31kHz (which was much easier than I anticipated :))
Maybe I'll experiment later on with the the LFO sample rate or some additive synthesis (to supress aliasing) but for now that's no longer a concern :)


But would you say that the CCS gives improved results compared to the digi-pot? any measurements you did by chance?  :icon_mrgreen:

Another semi-related question! I'm using a J201 to implement a Tails bypass but I'm getting loud pops when switching the effect in and out! I used the configuration found in http://www.valvewizard.co.uk/smalltimeschem.jpg except that I'm using the Arduino to supply 5V (rather than 9v)... Anything I forgot?
Title: Re: Generating LFO for PT2399 with an Arduino
Post by: anotherjim on October 24, 2020, 05:56:08 AM
I don't think the VCO output is a all that bad  - it's just a problem to get a good look at it with normal test equipment and probes. However, the VCO can exceed 20Mhz which is probably too fast for an MCU to deal with directly - although some counter external inputs may have a prescaler but you would probably have to include some C code to set it up. An external prescaler would have to be a 74HC binary counter/divider.
I have tested the output from a 74HC counter, and I have seen a stable expected result on its slowed down outputs, so it should be workable.

I suppose you would need a Frequency/Period counter library to measure the VCO.
https://github.com/avandalen/avdweb_FreqPeriodCounter

How you line this up with actual delay is another matter. I think the PT2399 delay line has something like 44100 bits (it's a 1bit memory) but I don't know if it handles 1 bit per clock period or some binary division of that. At least you could check it out in part by first measuring the VCO to show numbers over the serial monitor while twiddling the pin6 resistor.

Title: Re: Generating LFO for PT2399 with an Arduino
Post by: ElectricDruid on October 24, 2020, 02:25:05 PM
Quote from: anotherjim on October 24, 2020, 05:56:08 AM
I don't think the VCO output is a all that bad

No, it's not *too* bad. It rounds off quite a bit at the high end, so feeding it to a Schmitt input is a good idea.

Quote
it's just a problem to get a good look at it with normal test equipment and probes. However, the VCO can exceed 20Mhz which is probably too fast for an MCU to deal with directly - although some counter external inputs may have a prescaler but you would probably have to include some C code to set it up.
Yes, I used an internal prescaler to reduce the counter rate when I tried it.

Quote
How you line this up with actual delay is another matter. I think the PT2399 delay line has something like 44100 bits (it's a 1bit memory) but I don't know if it handles 1 bit per clock period or some binary division of that. At least you could check it out in part by first measuring the VCO to show numbers over the serial monitor while twiddling the pin6 resistor.
I don't remember it being too difficult. It was a question of working out whatever the magic number is. That depends on how fast you count your tap tempo period among other things (it's rarely convenient to count in milliseconds, for example - 1000? What kind of number is that?! 1024 is *much* more like it!). The details required are up on my site:

https://electricdruid.net/useful-design-equations-for-the-pt2399/ (https://electricdruid.net/useful-design-equations-for-the-pt2399/)


Title: Re: Generating LFO for PT2399 with an Arduino
Post by: niektb on October 27, 2020, 09:05:39 AM
Quote from: ElectricDruid on October 22, 2020, 08:33:55 AM
That's similar to what I tried. It works fine. PT2399's vary, so accuracy is mostly about getting some feedback so the processor knows what it is doing. There needs to be calibration of some type for really accurate results.

I tried swapping the digipot out like in the time manipulator must I be doin something wrong... I can't get long delay times, if I set the pwm too low it simply cuts out... and it's noisy as hell... And it modulates badly... Still my PWM frequency is set at 31kHz.

(https://i.postimg.cc/NLjqq1D7/2020-10-27-14-20-27-1-Schematic-C-Users-Niek-ten-Brinke-Dropbox-Eagle-Projects-Projects-PT2399-De.png) (https://postimg.cc/NLjqq1D7)
Title: Re: Generating LFO for PT2399 with an Arduino
Post by: Digital Larry on October 27, 2020, 12:51:16 PM
I don't see any filtering on the mod PWM.  Is that intentional?
Title: Re: Generating LFO for PT2399 with an Arduino
Post by: niektb on October 27, 2020, 02:45:44 PM
Quote from: Digital Larry on October 27, 2020, 12:51:16 PM
I don't see any filtering on the mod PWM.  Is that intentional?
I tried filtering when I still had the digipot, but it didn't create a lot of difference (except for some slewing in the waveform). The PWM frequency is wel above audio range :) (could still be useful for noise suppression)
Nevertheless, it isn't the cause of my current issue as I also tried to connect R30 directly to ground (therefore omitting the whole modulation thingy)
Title: Re: Generating LFO for PT2399 with an Arduino
Post by: anotherjim on October 27, 2020, 05:44:56 PM
I don't think a TL072 is the right part for the job. It's common mode input range doesn't include the negative supply (0v in this case)

Try an LM358, or if you want to be modern, any CMOS rail to rail amp like a TLC272 etc...

Instead of combining mod and delay control to pin6, you can split them -  so basic delay controlled by pin 6 and modulation by wiggling Vref pin2, although that might mean not having Vref available for any external circuits.
Title: Re: Generating LFO for PT2399 with an Arduino
Post by: ElectricDruid on October 27, 2020, 06:36:58 PM
Quote from: anotherjim on October 27, 2020, 05:44:56 PM
I don't think a TL072 is the right part for the job. It's common mode input range doesn't include the negative supply (0v in this case)

Try an LM358, or if you want to be modern, any CMOS rail to rail amp like a TLC272 etc...

Instead of combining mod and delay control to pin6, you can split them -  so basic delay controlled by pin 6 and modulation by wiggling Vref pin2, although that might mean not having Vref available for any external circuits.

+1 agree with this. The TL072 won't cope with the input being so close to ground, and its output can't go close to ground either. It's an audio op-amp and it expects signals to float around that mid-point voltage. Push it hard to the rails and it just clips.


Title: Re: Generating LFO for PT2399 with an Arduino
Post by: niektb on October 29, 2020, 10:47:04 AM
Thanks a lot! I have a TLC2272 somewhere around so I'll try that!
Does it matter a lot whether I use a BJT or a MOSFET? Should I tried to drive the output of the op-amp blow 0.7V(ish) when using a BJT?
Title: Re: Generating LFO for PT2399 with an Arduino
Post by: anotherjim on October 29, 2020, 05:54:28 PM
Ideally, PT2399 pin6 would read about 2.5v throughout the delay range. When trying to get the shortest delay possible with a low resistance, it will be seen to pull down that voltage. Not the ideal condition but unavoidable if you want to attempt chorus. However, there should always be some resistance connected out of pin6 toward 0v so the control should not be capable of directly pulling pin6 to 0v.
Your control can go down to 0v (and it would be awkward to scale it to work otherwise), but I'll suggest you don't need a transistor there. Leave the opamp as a buffer and fit a fixed resistor to pin6 - start with 1k. This connection will either boost or reduce the influence of the modulation control. Higher voltage from the PWM will give longer delay.

Title: Re: Generating LFO for PT2399 with an Arduino
Post by: niektb on October 30, 2020, 11:35:31 AM
I'm not sure if I understand what you're saying, where do I need to connect the op-amp to? in-between the 1k resistor and the modulation mosfet? How does this work when the MOSFET is conducting?
Title: Re: Generating LFO for PT2399 with an Arduino
Post by: anotherjim on October 30, 2020, 05:57:22 PM
I was thinking of using the opamp to adjust the delay set by the lower Mosfet circuit. So the opamp would just supply another resistor to pin6 similar value to R20 providing a parallel adjustment. But thinking about it, that way of opamp connection would be better providing modulation which is the wrong way around.
Also thinking about it, I don't think the transistor in the opamp feedback loop can pull pin6 to 0v unless it goes faulty.
So as you were - apart from a more suitable opamp type!

Title: Re: Generating LFO for PT2399 with an Arduino
Post by: niektb on October 31, 2020, 04:10:08 PM
Hahaha alright then!

But would there be any functional differences between a MOSFET and a BJT?
Title: Re: Generating LFO for PT2399 with an Arduino
Post by: anotherjim on November 01, 2020, 04:59:36 AM
Well, I think most single MOSFET's have a higher gate turn-on threshold voltage compared to a BJT base-emitter, but the MOSFET has a high input impedance so doesn't need a buffer to drive it.
Title: Re: Generating LFO for PT2399 with an Arduino
Post by: niektb on November 02, 2020, 04:26:15 AM
I tried the TLC2272 but the issue largely remains :( The range of the pot at which is happens is shifted a bit but it still noisy and distorted :(
Title: Re: Generating LFO for PT2399 with an Arduino
Post by: anotherjim on November 02, 2020, 07:29:26 AM
Try simplifying. Remove MOSFET and have the 2k2 between the BJT emitter and 0v. As you vary the voltage into the opamp buffer (between 0 and 2.5v), that variation should be followed across the 2k2 resistor. The opamp output pin should follow that +0.7v to compensate for the BJT base-emitter voltage.
It's really a voltage regulator where the opamp +input pin has the required output voltage, the PT2399 pin6 is the unregulated supply voltage, the BJT emitter is the regulated output voltage and the 2k2 is the regulated load. Increasing the voltage on the resistor causes more current flow out from pin6, thru the BJT and 2k2 to 0v,  speeding up the delay VCO clock and reducing delay time.
Title: Re: Generating LFO for PT2399 with an Arduino
Post by: niektb on November 02, 2020, 03:54:30 PM
Tried it but still distorts on longer delay times... Maybe the maximum allowed delay time has shifted? Not sure though...
Also, can't get the pwm output below 0.3V?

When setting the delay pot at max (so 2.5V measured at the 2k2 resistor), something weird happens and the sound is glitching... (and doesn't sound anything like chorus)

It feels like I have a crosstalk issue as it sounds like the pulsing of the RGB LEDs is audible in pitch shift  :o (and it isnt gone when I remove the connection between the arduino and the led)
Title: Re: Generating LFO for PT2399 with an Arduino
Post by: anotherjim on November 02, 2020, 04:59:01 PM
I don't think PWM can go to absolute zero, there will be some CPU cycles between the counter reset top to bottom to give the narrowest possible pulse out and also 0.3v is good going as a minimum for logic and linear parts.
There's a limit to how long the delay can be before it gets too noisy & glitchy and the filter caps around it need increasing.
A maximum delay can be enforced by fitting a larger resistance in parallel with the control from pin6 to 0v, maybe 47k or more.
The minimum delay isn't short enough for chorus. That 2k2 value is "safe" to avoid overclocking the PT2399, but it can be made to go lower either...
1: The modulation is arranged so it can add and subtract from the pin6 current around the value flowing in the resistor. This allows the VCO to go faster as well as slower than the resistor value sets. As you have it, the 2k2 is always in series and the controls can only make it slower.
2: The minimum resistor value is less than 2k2 so the VCO can run faster anyway. This can stop the chip if it's too low a resistance, especially during power on but I've found it can safely be 1k.
3: Both 1 & 2 to have the dealy range as short as possible for chorus.
4: As 2, but modulate the chips pin2 voltage instead. See the Little Angel chorus circuits for how this is implemeted with a normal opamp based LFO. This commonly slams a very low value pin6 resistance in after a power on delay but the 47R value is too small in my experience and there are diminishing returns from it being much less than 1k.
(https://4.bp.blogspot.com/-3Rc3Hub8-gs/Ty8k_eFL2QI/AAAAAAAAA4k/q2ScJee6O80/s1600/LittleAngel-2.7.png)

Need to add, if the other half of the opamp isn't used, you need to terminate that properly so it can't oscillate and inject noise into everything!