mirror of
https://github.com/KevinMidboe/linguist.git
synced 2025-10-29 01:30:22 +00:00
221 lines
10 KiB
Plaintext
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. │
|
|
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
|
|
}} |