Let's Design and Build a (mostly) Digital Theremin!

Posted: 12/3/2024 10:57:22 AM
dewster

From: Northern NJ, USA

Joined: 2/17/2012

"Another possible method I can think of is to wind the coil using two (or more) wires in parallel. One makes up the coil, and the other spaces the windings out. The second wire can be made of any material. It can be removed after the winding is finished, or left there if it's not magnetic or conductive. This is probably more difficult than using a single wire, but should still be easier than basket/honeycomb winding. One potential problem is that the friction between the wire and the former is normally quite low, if we remove the second wire, there will be space for the first wire to slide. We may need to use some adhesive to stick it to the former (which also has a higher dielectric constant than air / vacuum, though)."  - Zhuoran

One could perhaps use thread to space things out?  If it's porous then it would provide a path to the coil former for varnish / dope, likely increasing physical stability and therefore potentially decreasing thermal drift.  It's something of a challenge winding anything finer than say 32 AWG with my crude winder, the prospect of adding thread to even finer gauges isn't super appealing.  It's not clear what the ideal spacing might be for a given mH and aspect ratio, so it would likely require some (painful) experimentation.  And it would make the coils physically larger, though I personally am OK with that.

Lately I'm worrying less about the dielectric constants of the former & dope.  There seems to be a ceiling of 200 or so beyond which Q can't be practically increased.  Not sure how much of a Q factor the intrinsic (self) capacitance of the antenna plays into this either.  Q is a direct multiplier of drive=>antenna voltage, frequency selectivity, and oscillator stability, so it's a triple-whammy type spec.

Posted: 12/3/2024 2:45:08 PM
Zhuoran

Joined: 11/29/2024

90 degrees phase shift in feedback current is a kind of surprise for me.
...
Trying to replace BJTs with current feedback opamp IC.
...
Simulation with LT1395 and LT6210 instead of discrete opamp shows that a trick with getting drive signal shifted by 90 degrees from negative input current will not work because these ICs are tuned to have minumum feedback current during operation.
Small current (10-40uA) is too hard to sense. So, to use normal opamp with small feedback current instead of discrete one (which is tuned to have high feedback current), different solution for 90 degrees shift should be found.
...
Ideas for getting of 90 degrees shift at resonance.
* get drive feedback without shift; advantages: we can get rid of feedback comparator, and use something like self-biasing unbuffered inverter buffer instead.
* current sensing cirquit has to be reworked to provide additional 90 degrees shift (e.g. via additional integrator); possible advantage - integrated signal is naturally LP filtered and has less noise.

It seems that the phase shift is provided by the delay of the amplifier, which is mainly the delay of the "I-to-V converter" (Q93, Q94, Q98, Q103, C9). The "I-to-V converter" is basically an integrator that integrates the current (mirrored) from IN-. Since integrators shift the phase by 90°, it's not very surprising to see a 90° phase shift in this circuit. The problem is that the result depends on the speed/gain/bandwidth of the integrator, which, when using ICs, we don't always have much control of, and are likely too high for this purpose.

I think this is effectively using the CFOA as an integrator (to provide feedback in order to "solve for" I(IN-) such that ∫I(IN-)dt (+ C) = DRV_SINE and eventually creating a differentiator: I(IN-) = d/dt(DRV_SINE), the current at IN- is the derivative of the drive signal, and R30 converts it to voltage).
If we don't need to use the CFOA to provide the phase shift, we can simply replace it with a buffer.

Maybe instead of using CFOA, use an actual integrator/differentiator to provide the shift, or use a phase detector that does not require the 90° shift is more sensible?

Posted: 12/3/2024 4:46:42 PM
Buggins

From: Porto, Portugal

Joined: 3/16/2017


It seems that the phase shift is provided by the delay of the amplifier, which is mainly the delay of the "I-to-V converter" (Q93, Q94, Q98, Q103, C9). The "I-to-V converter" is basically an integrator that integrates the current (mirrored) from IN-. Since integrators shift the phase by 90°, it's not very surprising to see a 90° phase shift in this circuit. The problem is that the result depends on the speed/gain/bandwidth of the integrator, which, when using ICs, we don't always have much control of, and are likely too high for this purpose.

I think this is effectively using the CFOA as an integrator (to provide feedback in order to "solve for" I(IN-) such that ∫I(IN-)dt (+ C) = DRV_SINE and eventually creating a differentiator: I(IN-) = d/dt(DRV_SINE), the current at IN- is the derivative of the drive signal, and R30 converts it to voltage).
If we don't need to use the CFOA to provide the phase shift, we can simply replace it with a buffer.

Maybe instead of using CFOA, use an actual integrator/differentiator to provide the shift, or use a phase detector that does not require the 90° shift is more sensible?


Updated model, with integrating OTA current sensor. (Available under the same link)

Here, phase shift is not a property of amplifier, it's a result of integration.
 
CFOA is not a requirement anymore. Any unity buffer should be ok.

Feedback output does not have phase shift anymore, implemented on two inverters.

 Only single comparator is now required.


Posted: 12/4/2024 10:39:07 AM
dewster

From: Northern NJ, USA

Joined: 2/17/2012

"Maybe instead of using CFOA, use an actual integrator/differentiator to provide the shift, or use a phase detector that does not require the 90° shift is more sensible?"  - Zhuoran

The 90 degree shift allows for the use of a quadrature multiplying (XOR) phase detector, which rejects noise but is sensitive to harmonic locking and duty cycle variation.  Staggering the edges in the XOR case also helps to isolate edge related disturbances in the AFE circuitry.  In-phase detectors compare edges rather than entire waveforms, and so are susceptible to edge noise, but they aren't harmonic or duty cycle sensitive. 

It should be noted too that the phase detector in this case is just that, whereas in true PLL situations it must function as a phase & frequency detector.  This is because the I/O phase difference of an LC filter can only vary by 180 degrees - the LC can't change the frequency.  So a DLL (delay locked loop) would in theory also work as stimulus, but a precision NCO (numerically controlled oscillator) is trival to construct, provides constant stimulus (the starting / stalling issue), and naturally integrates the phase error over a long period.

In the FPGA one could generate a quadrature output from the DPLL and use this as the reference, but it wouldn't travel the same route as the other signals, and so would be sensitive to timing variations due to voltage and temperature.  Unfortunately, when measuring femto-Farads every sensor becomes a thermometer.

Posted: 12/4/2024 3:24:05 PM
Buggins

From: Porto, Portugal

Joined: 3/16/2017


"Maybe instead of using CFOA, use an actual integrator/differentiator to provide the shift, or use a phase detector that does not require the 90° shift is more sensible?"  - Zhuoran


Zero degrees lock phase detector only causes the problems if implemented in hardware (e.g. with DFF).
For FPGA the simple and accurate implementation is possible, probably even with better performance than XOR.
A see the only problem with using it in D-Lev is incompatibility with existing AFE - either separate FPGA firmware is needed for two cases, or both implementations
with some software switch between them.

BTW, zero phase measurement algorithm implemented in FPGA is simple enough, and does not consume a lot of resources.
I believe it's at least not worse than XOR algorithm.


Code:
// accepts input bits in deserialized 4 bit slices
// output value correction: 0 - no correction, >0 need to increase NCO frequency, 0 need to increase NCO frequency, 0 need to increase NCO frequency, <0 need to decrease NCO frequency
module xor_phase_detector(
    wire [3:0] in ref_in,
    wire [3:0] in sense_in,
 wire in clk,
 wire in reset,
 // possible correction output: -4..+4
 reg signed [3:0] correction
);

wire [3:0] xor_bits;
assign xor_bits = ref_in ^ sense_in;

// I'm not sure about correction polarity, probably should have opposite sign
always @(posedge CLK)
    if (reset)
     correction = 0;
    else
        correction = (xor_bits[0] ? +1 : -1) + (xor_bits[1] ? +1 : -1) + (xor_bits[2] ? +1 : -1) + (xor_bits[3] ? +1 : -1);

"Manual" simulation:


Code:
ref is slightly delayed comparing to sense, duty cycle=50%, corr = +10,-12 = -2/22

ref        00001111111111100000000000111111111110000000000011111111
sense      00000000011111111111000000000001111111111100000000000111
xor        00001111100000011111000000111110000001111100000011111000
correction [-4][+4][+2][+2][+4][-4][ 0][+2][-4][+2][ 0][-4][+4][-2]

ref is slightly earlier than sense, duty cycle=50%, corr = +2/22

ref        00001111111111100000000000111111111110000000000011111111
sense      00000000001111111111100000000000111111111110000000000011
xor        00001111110000011111100000111111000001111110000011111100

duty cycle of ref is 9:13, corr = +10,-12 = -2/22

ref        00000111111111000000000000011111111100000000000001111111
sense      00000000011111111111000000000001111111111100000000000111
xor        00000111100000111111000000011110000011111100000001111000

It looks like XOR is immune to bad duty cycle, but only if phase error is far enough from +/-90 degrees.
Close to +/-90 degrees phase error, bad duty cycle (probably) reduces normally supported range.

* Each 4 source points give only 4 possible outputs: -4, -2, 0, +2, +4
* Harder to filter correction: correction is usually -4 or +4 for almost 1/4 of cycle, only 4 times pre cycle it can be 0, -2, or +2

I think, 90-degrees lock signals processing may be improved by replacing of XOR with different function.
If you handle only result of XOR, you actually loss half of information you have.
Instead of filtering of XOR, let's utilize both inputs and use another function, like average or diff.


Code:
a  b  xor  avg  diff
0  0  -1    -1    0
0  1  +1     0   -1
1  0  +1     0   +1
1  1  -1    +1    0

Changing of phase detector to one utilizing both would give more information per input sample (+1, 0, -1), and more smoother output values (-4, -3, -2, .... +4)
Averaging of such output should be easier amplitude of surce data is twice smaller - in half of cases there is 0 on output.
As well, as I believe (not sure 100%), this approach allows to get rid of issues appearing close to +/-90 degrees phase error range bounds, and allows exceeding them.

Anyway, probably simple change to utilize both inputs instead of resulting XOR may give some advantages for FPGA based 90-degrees DPLL phase error detector.

UPD: it looks like stateless solution will not work. But it could be possible to adapt my zero-phase detector core to work on 90 degrees phase.


90 degrees lock phase detector is easy to implement in hardware - XOR or analog multiplier.
E.g. such frontend could be used for analog PLL in this case.
The main advantage of 90 degrees AFE is a compatibility with D-Lev firmware.
New AFE may be used as a drop-in replacement in existing devices.


The 90 degree shift allows for the use of a quadrature multiplying (XOR) phase detector,
which rejects noise but is sensitive to harmonic locking and duty cycle variation. 
Staggering the edges in the XOR case also helps to isolate edge related disturbances in the AFE circuitry. 
In-phase detectors compare edges rather than entire waveforms, and so are susceptible to edge noise, but they aren't harmonic or duty cycle sensitive.

I would agree that in-phase detectors, like DFF based ones, are sensitive to edge noise.

But I believe in-phase detector I proposed above is not sensitive for edge noise (not more than XOR one), and in general it is not worse than XOR.


It should be noted too that the phase detector in this case is just that, whereas in true PLL situations it must function as a phase & frequency detector. 
This is because the I/O phase difference of an LC filter can only vary by 180 degrees - the LC can't change the frequency. 
So a DLL (delay locked loop) would in theory also work as stimulus, but a precision NCO (numerically controlled oscillator) is trival to construct,
provides constant stimulus (the starting / stalling issue), and naturally integrates the phase error over a long period.

In the FPGA one could generate a quadrature output from the DPLL and use this as the reference, but it wouldn't travel the same route as the other signals,
and so would be sensitive to timing variations due to voltage and temperature.  Unfortunately, when measuring femto-Farads every sensor becomes a thermometer.

Unless tuning gone too far due to temperature drift, player would not notice the changes. 


 

Posted: 12/4/2024 5:30:02 PM
Zhuoran

Joined: 11/29/2024

Quote from: dewster on 12/4/2024
The 90 degree shift allows for the use of a quadrature multiplying (XOR) phase detector, which rejects noise but is sensitive to harmonic locking and duty cycle variation. Staggering the edges in the XOR case also helps to isolate edge related disturbances in the AFE circuitry.

This is what I got when I tried to use the DPLL of D-Lev: when it starts, it locks to 1/3 of the resonance frequency, and drives the LC circuit with the 3rd harmonic. It moves to the fundamental if I touch the antenna or set dither left shift to 7. Not sure if I made a mistake somewhere or if this is a compatibility issue. (I'm using a different FPGA and AFE)

Quote from: dewster on 12/4/2024
In-phase detectors compare edges rather than entire waveforms, and so are susceptible to edge noise, but they aren't harmonic or duty cycle sensitive.

By edge noise, you mean something similar to the bouncing of mechanical switches or buttons, right? This, in my experience, mainly happens when the amplitude of the sense signal is too low, otherwise it's generally fine, and it may be filtered out using analog or digital filters, similar to debouncing.
For XOR, as long as we keep the duty cycle of one of the waveforms to ≈1/2, the duty cycle of the other waveform shouldn't matter much. If A have 2/1 duty cycle, XOR will detect 0 phase error when the center of each pulses in B is aligned with edges in A, regardless the duty cycle of B.

Quote from: dewster on 12/4/2024
It should be noted too that the phase detector in this case is just that, whereas in true PLL situations it must function as a phase & frequency detector.  This is because the I/O phase difference of an LC filter can only vary by 180 degrees - the LC can't change the frequency.  So a DLL (delay locked loop) would in theory also work as stimulus, but a precision NCO (numerically controlled oscillator) is trival to construct, provides constant stimulus (the starting / stalling issue), and naturally integrates the phase error over a long period.

One limitation of DLL is that it doesn't directly provide a high precision measurement of the frequency. We may need additional circuit for frequency measurement, similar to when using standalone oscillators. One advantage of it over using standalone oscillator is it may be able to provide better phase alignment.
In my experience, the oscillation generally start more easily when using a delay, and it does not need a relatively accurate estimation of the resonance frequency, and will not lock to harmonics. So I'm thinking about using a delay (locked, constant, or sweep) to start the oscillation, and then switch to PLL.

Quote from: dewster on 12/4/2024
In the FPGA one could generate a quadrature output from the DPLL and use this as the reference, but it wouldn't travel the same route as the other signals, and so would be sensitive to timing variations due to voltage and temperature. Unfortunately, when measuring femto-Farads every sensor becomes a thermometer.

Another method Buggins and I mentioned and is used in his latest circuit is to use an integrator to provide the phase shift. This also has the problem that the signals don't travel the same route. (And so does the original CFOA based circuit that uses the amplifier to provide the shift!) Though I guess phase drift is somewhat less problematic than frequency drift?

Alternatively, we can digitally delay one of the inputs by 1/4 period. This shouldn't introduce additional drift, but the resolution of the delay is limited. This may be mitigated by dithering, and considering that the input is already temporally quantized, it shouldn't be too much of an issue.

Yet another way is to use some sort of "signed xor" like what buggins described here.

In your reply to that post:

Quote from: dewster on 1/9/2022
Consider the scenario where a glitching B is centered on A (without error averaging):

A=0, B=0 : state=0, error=0
A=1, B=1 : state=1, error=0
A=1, B=0 : state=1, error=-1
A=1, B=1 : state=1, error=0
A=1, B=1 : state=1, error=0
A=1, B=0 : state=1, error=-1
A=1, B=1 : state=1, error=0
A=0, B=0 : state=0, error=0

The phase error is -2 but it should be zero.

If B also glitches when A=0, the error should cancel out. It's unlikely that it will only glitch in half of the cycle and not the other half. Otherwise, B effectively has non 1/2 duty cycle.

The most simple way, of course, is not using current sensing with DPLL. The ≈0°/180° phase shift of it is desirable for standalone oscillators, but doesn't seems to be beneficial to DPLL, and the 1pF capacitor (or the lack thereof) is likely not going to make a huge difference.

By the way, is there documentations about porting D-Lev to another FPGA and different external circuit? The FPGA I'm currently using is ZYNQ 7020.
I know that D-Lev doesn't contain a lot of manufacturer specific things, the few things I'm currently aware of are input and output DDR, PLL, ram init files, and, of course, project files. Is there something else?
Currently I extracted the lc_dpll and timing module, connected the DPLL to APB then to AXI through a bridge, connected sq_48k_o to an interrupt source, then read the frequency using the built-in ARM cores. As I mentioned before, it's not working correctly and locks to 1/3 of the resonance frequency, but if I make it lock to the fundamental, apply a 20ms averaging, then I get a result with about 1-2ppm noise/uncertainty (absolute), which is about the same as when using MCU with a standalone oscillator. I wonder what's the absolute precision of the original D-Lev.

Posted: 12/4/2024 5:56:10 PM
Zhuoran

Joined: 11/29/2024

Quote from: Buggins on 12/4/2024

Instead of filtering of XOR, let's utilize both inputs and use another function, like average or diff.

Code:
a  b  xor  avg  diff
0  0  -1    -1    0
0  1  +1     0   -1
1  0  +1     0   +1
1  1  -1    +1    0

I also thought about this, but then I realized that if we replace XOR with one of these and filter the output, what we get will be the same as the average or difference of the two inputs filtered separately. If the duty cycle of the inputs is 1/2, then the output will always be 0. Looks like a phase detector for 0°/180° phase needs to be stateful, like your previous one.

Posted: 12/4/2024 6:03:47 PM
Buggins

From: Porto, Portugal

Joined: 3/16/2017

Yet another version of 90-degree output current sensing AFE.

Main drive buffer was simplified, now it's not a current feedback opamp.

Added separate emitter followers to feed LP filter and REF output. It should reduce noise from input square signal, and from output inverters.

As well, now Drive cascade only feeds LC tank, and if we can measure its current.

Current sensor changed from OTA to a pair of current mirrors. Current output from sensor is being integrated.
This approach gives double filtering for possible noise from the antenna. First stage - inductor, second - integrator.


As usual, you can download LTSpice model to play with from github

You must be logged in to post a reply. Please log in or register for a new account.