Originally posted by moodz
View Post
Announcement
Collapse
No announcement yet.
Announcement
Collapse
No announcement yet.
Android Phone Based Metal Detector - FCMD
Collapse
X
-
Couple of items...
Running so many frequencies so close together doesn't buy anything and will cost you depth. A 3:1 ratio is about the minimum useful spacing so I would do 3 frequencies at, say, Tones 1, 5, and 8.
I never saw a phase reference stated anywhere so I don't know where the target phases are coming from. Ferinstance, the examples in 9.2.1 make no sense to me. You absolutely have to have a reference or you won't know where ground is at.
Comment
-
Originally posted by Carl-NC View PostCouple of items...
Running so many frequencies so close together doesn't buy anything and will cost you depth. A 3:1 ratio is about the minimum useful spacing so I would do 3 frequencies at, say, Tones 1, 5, and 8.
I never saw a phase reference stated anywhere so I don't know where the target phases are coming from. Ferinstance, the examples in 9.2.1 make no sense to me. You absolutely have to have a reference or you won't know where ground is at.
A mindreader!
Yesterday I wrote something similar to Paul via Whatsapp:
Comment
-
Yep .. regarding the tones : I did allow for 2 to 24 tones ... user selectable ... the default is 8.Originally posted by Carl-NC View PostCouple of items...
Running so many frequencies so close together doesn't buy anything and will cost you depth. A 3:1 ratio is about the minimum useful spacing so I would do 3 frequencies at, say, Tones 1, 5, and 8.
I never saw a phase reference stated anywhere so I don't know where the target phases are coming from. Ferinstance, the examples in 9.2.1 make no sense to me. You absolutely have to have a reference or you won't know where ground is at.
1. Target Discrimination (Primary Benefit)
Different metals respond differently across the frequency spectrum. The VDI Calculator uses this to identify target types:
Phase Slope Analysis (VDICalculator.kt:85-96):
// Calculate phase slope across frequencies
val phaseDiff = highest.phaseDegrees() - lowest.phaseDegrees()
val freqDiff = highest.frequency - lowest.frequency
return phaseDiff / (freqDiff / 1000.0) // degrees per kHz
- Ferrous metals (iron, steel): Steep negative phase slope (< -3°/kHz) → VDI 0-30
- Non-ferrous metals (copper, gold, aluminum): Flat or positive slope → VDI 30-99
This is impossible with a single frequency - you need at least two frequencies to measure a slope.
2. Conductivity Index (VDICalculator.kt:102-117)
High conductivity metals maintain amplitude better at high frequencies due to skin effect:
val lowFreqAmp = analysis.take(analysis.size / 3).map { it.amplitude }.average()
val highFreqAmp = analysis.takeLast(analysis.size / 3).map { it.amplitude }.average()
val ratio = highFreqAmp / lowFreqAmp
- High conductors (copper, silver): Ratio > 1.0 → Strong high-freq response
- Low conductors (foil, aluminum): Ratio < 1.0 → Weak high-freq response
This helps distinguish copper (VDI 70-99) from aluminum (VDI 40-50).
3. Depth Estimation (DepthEstimator.kt:120-134)
Deep targets preferentially attenuate high frequencies:
val freqRatio = lowFreqAmp / highFreqAmp
// ratio > 1.5 indicates deep target (high freqs absorbed more)
This helps disambiguate "large shallow" vs "small deep" targets, though it's still challenging.
4. Confidence Scoring (VDICalculator.kt:123-136)
Multiple frequencies enable phase consistency checks:
val phases = analysis.map { it.phaseDegrees() }
val stdDev = calculateStandardDeviation(phases)
val consistency = 1.0 - (stdDev / 90.0) // 0-1 score
If phase varies wildly across frequencies → Low confidence (noisy/unstable target)
If phase is consistent → High confidence (solid target)
5. Reduced False Positives
A single frequency might miss targets or give false alarms. With 8-24 frequencies:
- Ferrous rejection is more reliable (need steep slope across ALL frequencies)
- Gold vs aluminum separation improves (though still challenging)
- Ground mineralization affects frequencies differently, so multi-freq helps cancel it
Trade-offs
More frequencies = Better discrimination BUT:
- Higher CPU usage (24 IQ demodulators running)
- More transmit power spread across frequencies
- Longer processing time
The app defaults to 8 logarithmically-spaced tones (1-20 kHz) as a good balance between discrimination power and performance.
Bottom line: Single frequency = "There's metal here"
Multi-frequency = "That's a copper penny at 4 inches with 85% confidence"
------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------
Regarding phase reference :
Looking at the IQDemodulator.kt implementation, I can explain why a reference phase recovery system isn't needed in this design:
Key Reasons:
1. Coherent Monostatic System
This is a coherent system where the same device both transmits AND receives. The app generates the transmit signal using MultiToneGenerator, so it has perfect knowledge of the transmitted
frequencies and phases.
2. Direct Phase Knowledge
In SingleToneDemodulator (line 68-69), the local oscillator phase is directly tracked:
private var phase = 0.0
private val phaseIncrement = 2.0 * PI * frequency / sampleRate
Since the demodulator runs in the same process as the transmitter, using the same sample rate and clock source, it's inherently synchronized - no PLL or carrier recovery needed.
3. Relative Phase is What Matters
For metal detection, what's important is the phase shift caused by metal targets, not absolute phase. The demodulator measures phase relative to the transmitted signal. When metal distorts the
electromagnetic field, it creates a phase lag that shows up in the I/Q components (lines 81-82, 96):
val i = sample * cos(phase)
val q = -sample * sin(phase)
val phaseAngle = atan2(qFiltered, iFiltered)
4. Contrast with Traditional Radio Systems
In a typical radio receiver:
- Remote transmitter with unknown frequency drift
- Unknown carrier phase
- Requires PLL/Costas loop/carrier recovery
But here, the transmitter and receiver share the same clock and are perfectly synchronized by design.
The ground balance system (GroundBalanceManager.kt) captures baseline I/Q vectors to cancel soil
effects, but that's different from phase synchronization - it's removing unwanted target-like responses from mineralized ground.
The AI "dev team" answered your questions here.
I would have basically said the same but less words and maybe no references.
I had a very good discussion with the AI in the early stages of this project .... it seemed to have a very clear idea of how a Minelab multi IQ detector works and showed me code to match ... so one would infer it has seen / been trained on code from that source
Comment
-
The code use "phase slope" or degrees per Khz .... so more points plotted on a graph is better than less points in most cases to determine the phase slope.Originally posted by ivconic View Post

A mindreader!
Yesterday I wrote something similar to Paul via Whatsapp:
Multi-Frequency Detectors That Likely Use Similar Techniques:
Minelab FBS/BBS Technology:
- FBS (Full Band Spectrum) - 28 frequencies simultaneously
- BBS (Broad Band Spectrum) - 17 frequencies
- Multi-IQ (newer) - 5-40+ frequencies depending on model
These definitely analyze phase response across multiple frequencies for discrimination. Minelab patents mention phase analysis, though the exact algorithm isn't published.
XP Deus Series:
- Multi-frequency capable (4-40+ kHz range)
- Uses phase information for target ID
- Allows frequency offset analysis
Whites Electronics (now defunct, acquired):
- V3i had three-frequency correlation
- Showed separate VDI readings per frequency
- Users could observe phase/response differences
What I Know For Sure:
1. VDI scales (0-99) are industry standard - used by Garrett, Whites, Fisher, etc.
2. Phase discrimination is well-established physics:
- Referenced in academic papers on induction metal detection
- Ferrous vs non-ferrous discrimination via phase lag is documented
3. Multi-frequency discrimination is proven superior to single-frequency for target ID
What's Uncertain:
- Whether they calculate explicit "degrees per kHz slope" like this code
- They may use lookup tables, neural networks, or other proprietary methods
- Exact algorithms are trade secrets worth millions in R&D
Comment
-
You could be right .. .the AI formulated all this ... the AI tends to be very confident ....maybe over confident in its designs.Originally posted by Altra View PostStudying the ebook some more. I believe that the VDI chart (9.1.1) the gold range should be above the mid conductor range targets?
Ferrous
Low conductors
Gold - included in low to mid conductors
Mid conductors
High conductors
To be fair the AI does mention calibrating targets though .... and there is or was code in there to do this. ( for future implementation )
Comment
-
LOL ... good job !
I asked the AI to draw a diagram of the hardware and it added a new section to the eBook with writeup and diagrams ...
https://haxidermist.github.io/FCMD/A...ion_Ebook.html
The small powered USB hub is so we can power everything and maybe add other stuff :-)
Comment
-
In ground-balanced VLF detectors (including MF) ground is canceled by creating a "ground channel" where the demod is rotated such that the ground produces no response. In non-viscous ground this about the same phase as the R (resistive) channel so you can think of the R-channel as being the targeting channel, that is, it is the signal that causes the detector to beep. For high conductors, although the magnitude of the signal does increase with frequency, the R-channel signal increases until a phase of 135°, then it decreases. As an example, a US silver dollar (0.94 troy ounce) has a 135° frequency of ~510Hz; beyond that, as the frequency increases the R-channel signal drops and the coin gets harder to detect.Originally posted by moodz View PostHigh conductivity metals maintain amplitude better at high frequencies due to skin effect:
- High conductors (copper, silver): Ratio > 1.0 → Strong high-freq response
- Low conductors (foil, aluminum): Ratio < 1.0 → Weak high-freq response
This is true for all IB detector designs. But what, exactly, is being used as the phase reference? The TX voltage? The TX current? Something else? It has to be something, somewhere, or the whole scheme won't work.Looking at the IQDemodulator.kt implementation, I can explain why a reference phase recovery system isn't needed in this design:
Key Reasons:
1. Coherent Monostatic System
This is a coherent system where the same device both transmits AND receives. The app generates the transmit signal using MultiToneGenerator, so it has perfect knowledge of the transmitted frequencies and phases.
Tell AI that wasn't the question.Since the demodulator runs in the same process as the transmitter, using the same sample rate and clock source, it's inherently synchronized - no PLL or carrier recovery needed.
Yes, it's a phase relative to the TX "signal". In ITMD3, I consistently use the TX magnetic field as the reference phase because, physically speaking, it's an absolute reference that does not rely on any circuit characteristics, such as coil reactance. It is 100% consistent no matter how you design the detector. And with this reference, ground is always close to 0°, magnetic targets are always 0-90°, and eddy targets are always 90-180°. Makes everything conceptually simple. If you read patents (and I'm sure AI does this) you will find that different people have used different phase systems so there is little consistency. This is bound to confuse an AI analysis of those patents.3. Relative Phase is What Matters
For metal detection, what's important is the phase shift caused by metal targets, not absolute phase. The demodulator measures phase relative to the transmitted signal. When metal distorts the electromagnetic field, it creates a phase lag that shows up in the I/Q components (lines 81-82, 96):
Not necessarily... if all the points fall on the same line, then you could have described that line with only 2 points. And more frequencies will take away from raw depth.Originally posted by moodz View PostThe code use "phase slope" or degrees per Khz .... so more points plotted on a graph is better than less points in most cases to determine the phase slope.
None of these, nor any of the other MF detectors on the market, have ever used more than 3 frequencies in any given mode.Multi-Frequency Detectors That Likely Use Similar Techniques:
Minelab FBS/BBS Technology:
- FBS (Full Band Spectrum) - 28 frequencies simultaneously
- BBS (Broad Band Spectrum) - 17 frequencies
- Multi-IQ (newer) - 5-40+ frequencies depending on model
These definitely analyze phase response across multiple frequencies for discrimination. Minelab patents mention phase analysis, though the exact algorithm isn't published.
I can tell you with certainty that "degrees per kHz slope" or something very equivalent is used.What's Uncertain:
- Whether they calculate explicit "degrees per kHz slope" like this code
- They may use lookup tables, neural networks, or other proprietary methods
- Exact algorithms are trade secrets worth millions in R&D
I think this is a very interesting project. But beware AI, I've used it and gotten a lot of wrong answers. It's important to know enough about the subject to keep it in check.
- Likes 1
Comment
-
Truth be told, the first thing I thought of was how the ESP32 would cope in performing those tasks and that's how I came up with the objective 3 frequency.
The second thing that immediately came to mind is almost 1 year of off-road experience with the Vanquish and Equinox models.
Vanquish as a (then) cheap model delighted me with its sensitivity to very small objects, grains... later Eqinox too.
But it was rather disappointing (like all other models and brands ever made without exception) on the problem of various aluminum foils and lead chunks vs thin silver and especially gold coins.
We have skipped an unforgivable amount of gold coins to this day because of that problem, and this is proven to me more and more every day.
With this in mind, on most ancient terrains you have to be prepared to dig low VDI numbers as well.
And that pretty much makes the whole story pointless, doesn't it?
Maybe not in the vast deserts of Australia, where you have a clash of ferro vs gold.
But on my grounds we have a fundamental problem here with pieces of aluminum foil and lead vs the most expensive finds.
I will digress, but this has a bit of an analogy with covid vaccines. RNA vaccines have proven superior in laboratories.
But in practice...?
...
The reason I played around with Python code is quite practical. I can't figure out a way to do that on the Android devices I have; keep the system audio but also provide an output for TX.
This is a pretty big problem to solve. A smart phone dongle is a solution, but not available to everyone.
And then there are the mental images in the head; me on the field carrying a phone with an added dongle from which the cable goes to the coil! lol
But for "laboratory" conditions, experiments and further learning; the project is really fantastic, my hat off!
One thing led to another and then I remembered that there are small USB audio card dongles that register as a separate and independent device to the Windows system.
The price is a couple of dollars and anyone can get them everywhere.
I don't know how easy it is to do this under Android, but it's easy under Windows.
Comment
-
The reason that phase references are not needed is because time does not exist in software code. Its just code ... it has no time dimension. However time does exist once it comes outside the CPU where a real time TX and RX signal is generated. Just because you tell the Codec to produce 20 KHZ .. does not mean that the RX will sample at the same rate. So testing the hardware showed phase rotations occurring due to this problem.
So now we ( me and the AI
) use this scheme and it actually works because it compensates for the real world loop timing errors. See section 8 in the eBook its been updated.
We just use the real TX signal as the demodulation Local oscillator signal. This compensates for the problem with the phase rotations due to CODEC clocking differences between TX and RX.
I tested it with real hardware it works !
Comment
-
You'll think I'm joking this time too, but no, this is the truth. Ever since the first AI's came out, I've tried many methods to get the AI to not spout gibberish every other sentence.Originally posted by Carl-NC View Post...But beware AI, I've used it and gotten a lot of wrong answers. It's important to know enough about the subject to keep it in check...
And after many unsuccessful attempts... I think I found the method! (it's similar to forum methods, lol).
After every mistake the AI makes, and it makes fairly banal mistakes very often; I burst into violent swearing and name-calling!
The first reaction of all AIs so far is a sudden withdrawal and warnings that this is not a correct method of addressing.
But if I persist in such behavior; The AI "gets used" to me and after a few days accepts such behavior and considers it an indisputable part of my character.
And then, miraculously; make fewer mistakes!
...
What annoys me the most is when the AI starts inventing pins and functions on the ESP32 that don't exist! Then a flood of swear words comes out of me!
Comment
-
Yep .. FCMD project is just an experiment in AI usage. I never wrote even one line of code, wrote one document or drew a diagram. The AI generated it all. Not only all the code but it also set up an populated the Github site. Every time it generates a new feature. I load the app in the phone ... have a look then tell the AI to "update the eBook" and it just does everything. I only had to tell it my username on github. Its never failed a single compile ... the code quality is almost magical.Originally posted by ivconic View PostTruth be told, the first thing I thought of was how the ESP32 would cope in performing those tasks and that's how I came up with the objective 3 frequency.
The second thing that immediately came to mind is almost 1 year of off-road experience with the Vanquish and Equinox models.
Vanquish as a (then) cheap model delighted me with its sensitivity to very small objects, grains... later Eqinox too.
But it was rather disappointing (like all other models and brands ever made without exception) on the problem of various aluminum foils and lead chunks vs thin silver and especially gold coins.
We have skipped an unforgivable amount of gold coins to this day because of that problem, and this is proven to me more and more every day.
With this in mind, on most ancient terrains you have to be prepared to dig low VDI numbers as well.
And that pretty much makes the whole story pointless, doesn't it?
Maybe not in the vast deserts of Australia, where you have a clash of ferro vs gold.
But on my grounds we have a fundamental problem here with pieces of aluminum foil and lead vs the most expensive finds.
I will digress, but this has a bit of an analogy with covid vaccines. RNA vaccines have proven superior in laboratories.
But in practice...?
...
The reason I played around with Python code is quite practical. I can't figure out a way to do that on the Android devices I have; keep the system audio but also provide an output for TX.
This is a pretty big problem to solve. A smart phone dongle is a solution, but not available to everyone.
And then there are the mental images in the head; me on the field carrying a phone with an added dongle from which the cable goes to the coil! lol
But for "laboratory" conditions, experiments and further learning; the project is really fantastic, my hat off!
One thing led to another and then I remembered that there are small USB audio card dongles that register as a separate and independent device to the Windows system.
The price is a couple of dollars and anyone can get them everywhere.
I don't know how easy it is to do this under Android, but it's easy under Windows.
I did make suggestions to it to solve some problems ... like fixing the phase rotation instability by injecting the TX signal from Lout to Rin and using it as the LO. But that is literally what I told it and it went off and generated the code and updated the documentation and pushed it to Github. Productivity just went up by 1000 X.
The FCMD actually works .... it needs more finessing ( this can be human or AI ) but the point is to generate so much progress in such a short time would be impossible using previous manual coding.
Some people have suggested that LLMs ( AIs ) are just big look up machines ... this is wrong ... they are massive probability vector fields with feed back ( See the sentinal paper in the subject "Attention is all you need " ) Nothing is stored verbatim in these probability vectors ... information is generated on probabilities and context. The feedback path feeds the output back into the input and it affects future output probabilities ... very simplified answer ... more complex than that. but anyway.
The bottom line is if you know how to ask the right questions ... you dont have to write code any more / or compile it / debug it / document it.
- Likes 1
Comment

Comment