I'm working on my digital theremin project.
Currently I'm trying to build LC phase shift based sensor suggested by dewster.
Phase shift schematic is very simple.
Assuming that MCU used for building digital theremin has following capabilities:
- generation of 2 reference frequencies (50% duty cycle), frequency change step is small enough for calibration (1-2% should be enough)
- 16bit ADC
I'm using Teensy 3.6 MCU in my project.
It's 3.3V outputs must be converted to 5V for phase shift detector.
Sensor output voltage must be in range 0..3.3V, 16bit ADC mode measures only range 0.2 .. 3.1V (value < 0.2V will give 0, and > 3.1 will give 65535).
Schematic:
Coils: air core 0.1mm wire D=32mm, winding length = 32mm, L ~= 2.1mH
Reference frequency FREF from MCU PWM pin (3.3V, ~1MHz, 50% duty cycle) is converted to 5V signal using R1, R2, C1 and U1.1 (74HC86 XOR gate).
5V ref frequency is passed to LC tank (L1, Cant, Chand, C2, C3, C4).
C3 and C4 form voltage divider to limit input signal from antenna (up to ~100V voltage swing at resonant frequency) making it suitable for U1.2 phase detector (74HC86 XOR gate). R4 and R5 move its middle point to 2.5V.
Phase shifted signal on XOR gate input, XOR gate PWM output and LP filter output:
In this simulation, Chand changes from 0 to 3pF with 0.1pF step.
When Fref equals to LC tank resonant frequency, LC tank shifts its phase by PI/2. In this case, signal on U1.2 output is PWM with duty cycle 50% and frequency 2*Fref.
If resonant frequency is higher than Fref, phase shift is decreased (up to ~0 for frequencies far from resonant, which gives 0% PWM duty cycle).
If resonant frequency is lower than Fref, phase shift is increased (up to PI for frequencies far from resonant, which gives 100% PWM duty cycle).
It's possible to select Fref so that antenna capacity change (Chand + Cant) will produce ~25% PWM duty cycle (PI/4) for hand position far from antenna, and ~90% PWM duty cycle for hand near antenna.
Phase shift PWM signal is passed to LP filter to convert PWM duty cycle value to voltage.
PWM duty cycle dependency on Chand is non-linear. It's close to TAN() function.
LP filter on two NPN transistors shifts signal down by ~1.4V.
Bigger part of ADC working range is supposed to be used Chand change range ~1pF for getting good sensitivity at far hand-to-antenna distance.
The closer hand is to antenna (and bigger Chand) the less output V is changed for the same Chand change.
It "compresses" ADC value range, getting it closer to hand distance change.
R3 can be adjusted to change LC tank Q, expanding or shrinking output range / linearity.
It makes sense to choose different LC resonant frequencies for volume and pitch antennas to avoid interference.
Sensor latency (delay between hand position change and output voltage change) depends on LP filter parameters . In this schematic it's expected to be near 0.5ms
It's better to place sensor part (producing PWM output) near antenna, and LP filter part - near MCU, connecting them using 4 pins socket (GND, VCC, FREF, PWMOUT).
MCU will convert measured ADC value (~phase shift) to linear delta Chand capacity value. It must use ATAN function to do it.
LP filter + ADC should be calibrated in order to allow calculation of delta C from ADC output.
You will need constants: ADC values for 50% PWM duty cycle ADC50 (PI/2, resonance point) and 75% duty cycle ADC75 (PI*3/4 point).
- If PWM sensor is connected to LP filter via socket, disconnect it and short FREF and PWMOUT pins on LP.
- Generate 50% duty cycle Fref and read ADC value to measure ADC50 calibration constant.
- Generate 75% duty cycle Fref and read ADC value to measure ADC75 calibration constant.
These constants may then be hardcoded in firmware. (ADC50 will be near 18000, and ADC75 - near 45000 -- for 16bit ADC).
When you have ADC50 and ADC75, you can convert ADC output value to phase shift (in radians) using formula:
phase = (x - ADC50)/(ADC75-ADC50)*PI
Where x is sensor Vout measured by ADC (in range 0..65535), phase is phase shift in radians.
Delta capacity value (Cant + Chand) - (Cresonant) may be obtained using ATAN() function
deltaC = ATAN(phase)
It's value linearly depending on Chand.
To get Chand value, you can try to scale result by choosing reasonable A and B constants:
deltaC = ATAN(phase) * A + B
But really it does not make sense to do such conversion.Calibration procedure for MCU:
Move hand far from antenna (or just go away from theremin)
Change Fref starting from expected Fresonant/2 incrementing by lowest possible step
Set new Fref
Wait for 1ms
Measure sensor output voltage with 16bit ADC
If ADC measured value (0..65535) is more than 0, stop iterating -- it's suitable Fref for sensor
Fref is set.
Move hand far from antenna.
Measure deltaC for this position.
Remember it as calibration constant CFAR.
Move hand near (~10cm) from antenna.
Measure deltaC for this position.
Remember it as calibration constant CNEAR.
Now we can try to use some formula to convert current deltaC value to distance.
Chand depends on hand to antenna distance approximately like C=1/distance
This formula may look like
dist = (CFAR - CNEAR) / (deltaC - CNEAR)
Which gives dist = 0 for hand far from antenna to dist = 1 for hand near antenna.
It can then be converted to note number for pitch antenna
note = dist * (noteMax - noteMin) + noteMin
For volume antenna, it may be used as is (volume = 0..1), or after some non-linear function (e.g. a kind of gamma correction).
Current project state:
- LTspice model - ready
- Sensor PWM module - building on PCB, work in progress
- Sensor PWM to voltage convertor - TBD
Best regards,
Vadim