Lerne, wie man einen Metalldetektor mit einem Colpitts-Oszillator und einem Arduino baut.
Wie funktionieren Metalldetektoren?
Die Tankschaltung
In der obigen Schaltung bilden der Reihenkondensator und die Spule eine Tankschaltung. In einer Tankschaltung wird wiederholt Energie zwischen einem Kondensator und einer Induktivität übertragen, wodurch eine Schwingung entsteht. Der vom Kondensator entladene Strom fließt durch den Induktor; wenn der Kondensator vollständig entladen ist, hält das abnehmende Magnetfeld des Induktors den Stromfluss aufrecht. Der Kondensator lädt sich dann mit der entgegengesetzten Polarität auf, und wenn das Magnetfeld vollständig zusammengebrochen ist, entlädt sich der Kondensator, was zu einem Stromfluss in der dem ursprünglichen Strom entgegengesetzten Richtung führt. Dieser Zyklus setzt sich fort.
Die Spule des obigen Tankkreises bildet den Detektor des Metalldetektors (eine große Drahtspule). Nähert sich ein metallisches Material dem Zentrum des Induktors (der Detektorspule), tritt es in das vom Induktor erzeugte Magnetfeld ein. Dadurch ändert sich die magnetische Permeabilität des Kerns der Spule, was zu einer Änderung der Induktivität führt. Die Änderung der Induktivität verändert wiederum die Schwingungsfrequenz des Tankkreises.
Wären die Bauteile ideal, würde der Tankkreis ohne externe Stromquelle unbegrenzt schwingen. Aber in der Praxis sind die Bauteile nicht ideal. Der unerwünschte Widerstand der Bauteile führt zu Energieverlusten, so dass der oszillierende Strom zum Erliegen kommt. Um dem entgegenzuwirken, wird ein einstufiger invertierender BJT-Verstärker verwendet, um die Tankschaltung kontinuierlich zu verstärken.
Der Colpitts-Oszillator
Da die Oszillation an den Knoten vor und nach der Spule um 180° zueinander phasenverschoben ist, liefert einer der Knoten die Oszillation an die Transistorbasis, verstärkt und invertiert das Signal am Kollektor und gibt es dann phasengleich an den anderen Knoten der Tankschaltung zurück. Diese gesamte Schaltung wird als Colpitts-Oszillator bezeichnet.
Der obige Colpitts-Oszillator liefert eine gleichmäßige Schwingung mit einer Frequenz im Bereich von 100 kHz. Metalle aus Haushaltsgegenständen, die die Permeabilität des Spulenkerns verändern, lassen diese Frequenz um 10kHz schwanken. Da dieser Frequenzbereich außerhalb des menschlichen Hörspektrums (20 Hz bis 20 kHz) liegt, müssen wir die Schwingung in einen hörbaren Ton umwandeln.
Traditionelle BFO-Metalldetektoren (Beat-Frequency Oscillator) umgehen dieses Problem, indem sie einen weiteren Tankkreis mit einer festen Frequenz einbauen, die der Frequenz des Detektortankkreises ohne den Einfluss von Metallen entspricht. Die Differenz zwischen den beiden Frequenzen isoliert dann die schwankenden Frequenzen des Detektorkreises und bringt sie auf einen hörbaren Bereich.
Für dieses Metalldetektorprojekt werden wir einen Arduino verwenden, um das Schwingungssignal zu verarbeiten, anstatt die Schwingung mit einem zweiten Tankkreis zu kompensieren. Der Arduino speichert die festgelegte Frequenz und vergleicht kontinuierlich die eingehende Frequenz des Detektorschaltkreises mit der gespeicherten Frequenz (mehr zum Arduino-Programm weiter unten).
Materialien für deinen DIY-Metalldetektor
Für dieses Projekt wurde ein Spielzeug-Unkrautstecher gewählt, um alle Komponenten unterzubringen. Er verfügt über die folgenden Funktionen:
- einen Auslöseknopf, den wir zum Auslösen des Lautsprechers umfunktionieren werden
- einen seitlichen Knopf, mit dem wir die Festfrequenz einstellen werden
- ein Batteriefach (3xAA-Batterien) mit einem Ein-/Ausschalter
- einen Lautsprecher, über den wir den Ton abspielen werden
- einen Motor mit angebrachten LEDs, die aktiviert werden, wenn der Frequenzunterschied einen bestimmten Schwellenwert überschreitet
- einen runden Kopf, in den wir eine Drahtspule für die Spule der Tankschaltung einbauen werden
Wir werden auch ein Potentiometer (Silber) hinzufügen, um die Empfindlichkeit der Tonänderungen einstellbar zu machen.
Die Induktionsspule wird aus etwa 50 Windungen 26 AWG Draht um eine Spule von 5,5 Zoll Durchmesser hergestellt.
Im Inneren des Gehäuses werden wir die Originalplatine durch unsere eigene Schaltung ersetzen und alle Peripheriegeräte mit Stiftleisten an die Schaltung anschließen.
Schaltpläne für die Metallerkennung
Ich habe einen Arduino UNO verwendet, um einen DIP ATMega328 zu programmieren. Den ATMega328 habe ich dann von der Entwicklungsplatine entfernt und zusammen mit dem Rest der Schaltung in eine Lochrasterplatine eingebaut.
Der Colpitts-Oszillator, unten links im Diagramm, speist die Schwingung in den Zähler 1 (Pin T1) des Chips (auf dem Arduino UNO als Digitalpin 5 gekennzeichnet), wo er ständig die Schwingungsfrequenz zählt.
Auf der oberen Ebene des Diagramms wird eine Stromversorgung von 4.5V (3xAA-Batterien, mit Bypass-Kondensatoren) verwendet, um den ATmega328, den Oszillator, den Lautsprecher und den Motor (mit LEDs) zu versorgen.
Um die Stromaufnahme der digitalen Pins des Mikrocontrollers auf einem sicheren Niveau zu halten (maximal 40 mA pro Pin für den ATmega328), wird ein NPN-Transistor (C2878) verwendet, um den Lautsprecher zu betreiben, und ein N-Kanal-MOSFET (SUB45N03), um den Motor zu betreiben.
Sowohl der Trigger- als auch der Reset-Schalter (stellt die Festfrequenz ein) sind mit digitalen Pins verdrahtet, die eine interne Pull-up-Konfiguration verwenden. Kleine Kondensatoren werden parallel hinzugefügt, um die Schalter zu entprellen.
Das Empfindlichkeitspotentiometer ist als Spannungsteiler aufgebaut, und die Teilung wird über einen analogen Pin ausgelesen.
Code Walkthrough
Der vollständige Quellcode für dieses Projekt kann hier gefunden werden:
- https://github.com/evankale/ArduinoMetalDetector
Nachfolgend finden Sie einen detaillierten Walkthrough des Codes.
Setup-Funktion
Um die Oszillationsfrequenz des Detektors über den Timer-Zähler 1 zu verfolgen, müssen wir zunächst die Timer/Counter-Controller-Register (TCCR) konfigurieren. Der Zugriff auf diese TCCRs erfolgt über die drei Ganzzahlen: TTCR1A, TTCR1B und TTCR1C.
TCCR1A = 0b00000000;TCCR1B = 0b00000111;
Wir müssen die Wellenformerzeugung auf den normalen Modus einstellen, indem wir die WGM-Flags von TCCR1A und TCCR1B auf 0 setzen, und den Modus zur Auswahl der Taktgeschwindigkeit auf eine externe Taktquelle einstellen, indem wir die CS-Flags von TCCR1B auf Modus 3 (externer Takt bei steigender Flanke) setzen. In dieser Konfiguration wird das Register OCR1A jedes Mal um 1 dekrementiert, wenn eine steigende Flanke der Oszillation erkannt wird.
TIMSK1 |= (1 << OCIE1A);
Als nächstes müssen wir den Timer/Count-Interrupt A aktivieren, indem wir das OCIE1A-Flag im TIMSK1-Register setzen. Dadurch wird die Unterbrechungsfunktion SIGNAL(TIMER1_COMPA_vect) immer dann aufgerufen, wenn das Register OCR1A den Wert 0 erreicht.
OCR1A = 1;
Initialisieren Sie nun OCR1A auf 1, damit die Unterbrechungsfunktion aufgerufen wird, sobald die erste steigende Flanke erkannt wird.
Unterbrechungsfunktion
Dies ist die Funktion SIGNAL(TIMER1_COMPA_vect). Sie wird aufgerufen, wenn das OCR1A-Register 0 erreicht. In dieser Funktion wollen wir die Anzahl der Mikrosekunden verfolgen, die seit dem letzten Aufruf der Funktion vergangen sind. Dieses Zeitdelta wird als signalTimeDelta gespeichert.
storedTimeDelta ist das „Festfrequenz“-Zeitdelta, mit dem signalTimeDelta in der Hauptschleife verglichen wird. storedTimeDelta wird auf signalTimeDelta gesetzt, wenn storedTimeDelta auf Null gesetzt wird (beim Hochfahren und wenn der Reset-Schalter gedrückt wird).
OCR1A += CYCLES_PER_SIGNAL;
Nach der Durchführung von Interrupt-Operationen muss OCR1A zurückgesetzt werden, indem es mit unserer vordefinierten Konstante CYCLES_PER_SIGNAL (Anzahl der Zyklen, bevor der nächste Interrupt auftritt) inkrementiert wird.
Schleifenfunktion
In der Schleifenfunktion wird geprüft, ob der Trigger gedrückt ist. Wenn ja, wird der analoge Wert des Empfindlichkeitspotentiometers gelesen und der analoge Wert (0 bis 1023) linear auf eine leichter zu handhabende Skala (0,5 bis 10,0) interpoliert.
int storedTimeDeltaDifference = (storedTimeDelta - signalTimeDelta) * sensitivity;
Die Differenz zwischen der Festfrequenz (storedTimeDelta) und der gemessenen Frequenz (signalTimeDelta) wird berechnet und mit dem Empfindlichkeitswert multipliziert.
tone(SPEAKER_PIN, BASE_TONE_FREQUENCY + storedTimeDeltaDifference);
Dieser Wert wird dann mit einer hörbaren Basistonfrequenz, BASE_TONE_FREQUENCY, summiert und mit der Arduino tone()-Funktion über den Lautsprecher ausgegeben.
Wenn die Differenz den durch SPINNER_THRESHOLD definierten Schwellenwert überschreitet, wird der Motor aktiviert.
Wenn der Auslöser losgelassen wird, wird der Lautsprecherton gestoppt (durch Aufruf der Funktion noTone()) und der Motor wird deaktiviert.
Wenn der Reset-Knopf gedrückt wurde, wird das gespeicherteTimeDelta auf Null gesetzt, so dass der nächste Interrupt-Aufruf einen neuen Wert setzen kann.
Wie funktionsfähig ist unser Arduino-basierter Metalldetektor?
Mit der niedrigsten Empfindlichkeitseinstellung kann der Metalldetektor große Gegenstände wie Getränkedosen, Handys und Eisenwerkzeuge innerhalb weniger Zentimeter von der Spule entfernt aufspüren. Mit der höchsten Empfindlichkeitseinstellung können auch kleinere Gegenstände wie Stahlringe, Schrauben und Münzen in der gleichen Entfernung erkannt werden. Eine Demonstration finden Sie im Video am Anfang des Artikels!
Um die Reichweite des Detektors zu erhöhen, können wir die von der Spule erzeugte Magnetfeldfläche vergrößern. Dies kann erreicht werden, indem man den Stromfluss durch die Spule erhöht (indem man die Eingangsspannung des Oszillators erhöht, was eine größere Verstärkung im Verstärker ermöglicht), oder indem man die Anzahl der Drahtwicklungen in der Spule erhöht.
Mit einem Arduino-basierten Metalldetektor können wir andere interessante Dinge tun, die mit herkömmlichen BFO-Metalldetektoren nicht möglich sind. Bleiben Sie dran für zukünftige Projekte, wie wir diesen Metalldetektor-Mechanismus für andere Zwecke nutzen können!
ArduinoMetalDetector-master.zip
Testen Sie dieses Projekt selbst! Holen Sie sich die Stückliste.