Files
linguist/samples/Propeller Spin/Inductor.spin

221 lines
10 KiB
Plaintext

{{
*****************************************
* Inductive Sensor Demo v1.0 *
* Author: Beau Schwabe *
* Copyright (c) 2007 Parallax *
* See end of file for terms of use. *
*****************************************
Test Circuit:
10pF 100K 1M
FPin ───┳──┳── SDF(sigma-delta feedback)
│ ┣──── SDI(sigma-delta input)
L  100K
 
GND GND
Test Coils:
Wire used was the "Radio Shack Special" GREEN (about 27 gauge)
25T (Coke Can form) = 2.1MHz
15T (Coke Can form) = 3.9MHz
5T (Coke Can form) = 5.3MHz
50T (BIC pen form) = 3.2MHz
How does it work?
Note: The reported resonate frequency is NOT the actual resonate LC frequency. Instead it is where the voltage produced from
the LC circuit was clipped.
In the example circuit below:
C L
A ────┳──── GND
B
When you apply a small voltage at a specific frequency to an LC circuit (at point "A") that is at or near the resonate
frequency of LC, it is not uncommon to measure 10's or 100's of times the amount of voltage (at point "B") that you are
applying to the LC circuit. (at point "A")
In the "Test Circuit" above, point "B" passes through a diode which then basically feeds a divide by 2 voltage divider:
100K 100K
B ───┳── GND
C
...So in order see the sigma-delta ADC "clip" the frequency sweep result, the output from the LC circuit only needs
to generate about 6.6 Volts above ground. (0.6V drop across the diode, and since the ADC is only sensitive to about
3V, it works out to be about 6.6V after the voltage divider.)
A typical magnitude plot of a frequency sweep applied to an LC circuit might look something like this:
*
*
*
*
* *
* *
* *
* *
* *
***** *****
...With 'clipping' the pattern looks more like this:
X****
* *
* *
* *
***** *****
...The 'X' denotes the location of the reported resonate frequency. The reason this is slightly off is for
two reasons really. 1) lazy - I didn't want to fiddle with the voltage divider combo... adjusting so that the
"peak" was also where the ADC happened to "clip". 2) some benefit - When you apply a frequency to a tuned LC
circuit that's resonate frequency is the same as the applied frequency, the LC acts like a dead short. A
situation not exactly great for Propeller I/O's
Now that we have that out of the way, what happens next? How can we use this so called "coil" as a sensor?
If a frequency sweep is initially preformed to determine the resonate frequency clip point, then it just so
happens that adding additional "metal" (<- Does not need to be ferrous) causes the resonate frequency to shift
to a HIGHER frequency.
Once you determine the "clip" frequency and you use one of the available counters to constantly feed that
particular frequency back to the LC circuit, the resulting ADC output is proportional and somewhat linear when
metal objects are introduced to the coil.
Assume frequency increases from Left to Right. With a slight resonate shift to the right, the ADC reports a
lower "de-tuned" value because the voltage magnitude no longer "clips" at the reported resonate frequency.
Typical ranges are full scale between 65535 (no metal) and 0 (metal saturation)
X *****
* *
ADC reports value here --> * *
* *
***** *****
Slight shift to the right
I also made mention that the response is somewhat linear. As the LC resonance shifts and the ADC value begins
to lower, the slope is steepest near the "clip" point. Therefore, the slightest shift results in larger value
changes. Since the coil is actually the least sensitive to metal the further away it is (Law of squares) and
most sensitive to metal the closer it is, the resulting combination acts to linearize the output. I need to
point out that some LC combinations will exhibit plateaus and other anomalies caused by varying parasitic circuit
conditions that will affect the overall output, so a little bit of trial and error is necessary to get things
the way you want them.
}}
OBJ
Freq : "Synth"
ADC : "ADC"
gr : "graphics"
Num : "Numbers"
CON
FPin = 0
UpperFrequency = 6_000_000
LowerFrequency = 2_000_000
bitmap_base = $2000
display_base = $5000
VAR
long FMax, FTemp, FValue, Frequency
PUB demo
'start and setup graphics
gr.start
gr.setup(16, 12, 128, 96, bitmap_base)
FindResonateFrequency
DisplayInductorValue
PUB DisplayInductorValue | X
Freq.Synth("A", FPin, FValue)
repeat
ADC.SigmaDelta(@FTemp)
'**************************************** Graphics Option Start *********************************************
'clear bitmap
gr.clear
'draw text
gr.textmode(1,1,7,5)
gr.colorwidth(1,0)
gr.text(0,90,string("Inductive Propeller Sensor"))
gr.colorwidth(1,5)
X := (65535 - FTemp )*200/65535
gr.plot(-100+X,15)
gr.textmode(1,1,7,%0000)
gr.colorwidth(1,0)
gr.text(-100,-20,string("Resonate Frequency ="))
gr.text(35,-20,Num.ToStr(FValue,10))
gr.text(-100,-36,string("ADC Frequency Response ="))
gr.text(65,-36,Num.ToStr(FTemp,10))
'copy bitmap to display
gr.copy(display_base)
'**************************************** Graphics Option Finish *********************************************
PUB FindResonateFrequency | P
dira[FPin] := 1
FMax := 0
repeat Frequency from LowerFrequency to UpperFrequency step 1000
Freq.Synth("A", FPin, Frequency)
ADC.SigmaDelta(@FTemp)
if FTemp > FMax
FMax := FTemp
FValue := Frequency
'**************************************** Graphics Option Start *********************************************
P := (Frequency - LowerFrequency)*100/(UpperFrequency - LowerFrequency)
gr.colorwidth(1,5)
gr.plot(0,0)
gr.line(P,0)
gr.colorwidth(3,5)
gr.line(100,0)
gr.colorwidth(2,0)
gr.plot(P,(FTemp/1024)+10)
gr.colorwidth(0,1)
gr.plot(P+1,5)
gr.line(P+1,50)
gr.copy(display_base)
'**************************************** Graphics Option Finish *********************************************
DAT
{{
┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ TERMS OF USE: MIT License │
├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │
│files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │
│modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│
│is furnished to do so, subject to the following conditions: │
│ │
│The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│
│ │
│THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │
│WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │
│COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │
│ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
}}