# CLUE Metal Detector in CircuitPython

## Overview

https://www.youtube.com/watch?v=_sYRRU4IB3c

This project creates a metal detector using an Adafruit CLUE with a few common components and an easy-to-make coil.

The program is written in CircuitPython for version 5.1.0 or later. The code also runs on the Circuit Playground Bluefruit (CPB) with the TFT Gizmo screen. The program can be used without a screen on the CPB in audio/light mode only.

Alligator clips to male jumpers can be used with or without the Adafruit Dragontail to connect the CLUE and the coil to the breadboard. The pictures feature alternate products.

This project was inspired by an old Ray Marston book featuring a metal detector project and the [Detectorists](https://www.imdb.com/title/tt4082744/ "IMDB: Detectorists") BBC TV series.

![](https://cdn-learn.adafruit.com/assets/assets/000/090/814/medium800/sensors_clue-metal-detector-unstacked-1-2000x1500.jpg?1588515880 An Adafruit CLUE with a simple circuit on a breadboard detecting a metallised sticker with a coil.)

## Parts
### CLUE version
### Part: Adafruit CLUE
quantity: 1
Adafruit CLUE - nRF52840 Express with Bluetooth LE
[Adafruit CLUE](https://www.adafruit.com/product/4500)

### Part: Adafruit DragonTail
quantity: 1
Adafruit DragonTail for micro:bit - Fully Assembled (or use 3 Alligator Clip to Male Jumper Wires)
[Adafruit DragonTail](https://www.adafruit.com/product/3695)

### Part: 1k Resistor
quantity: 1
Through-Hole Resistors - 1.0K ohm 5% 1/4W - Pack of 25 (1 needed)
[1k Resistor](https://www.adafruit.com/product/4294)

### Circuit Playground Bluefruit with TFT Gizmo version
### Part: Circuit Playground Bluefruit (CPB)
quantity: 1
Circuit Playground Bluefruit - Bluetooth Low Energy
[Circuit Playground Bluefruit (CPB)](https://www.adafruit.com/product/4333)

### Part: Circuit Playground TFT Gizmo (LCD Screen)
quantity: 1
Circuit Playground TFT Gizmo - Bolt-on Display + Audio Amplifier
[Circuit Playground TFT Gizmo (LCD Screen)](https://www.adafruit.com/product/4367)

### Part: STEMMA 3-Pin to Male Header Cable
quantity: 2
STEMMA JST PH 3-Pin to Male Header Cable - 200mm
[STEMMA 3-Pin to Male Header Cable](https://www.adafruit.com/product/3893)

### Circuit Playground Bluefruit only version
### Part: Circuit Playground Bluefruit (CPB)
quantity: 1
Circuit Playground Bluefruit - Bluetooth Low Energy
[Circuit Playground Bluefruit (CPB)](https://www.adafruit.com/product/4333)

### Part: 1k Resistor
quantity: 1
Through-Hole Resistors - 1.0K ohm 5% 1/4W - Pack of 25 (1 needed)
[1k Resistor](https://www.adafruit.com/product/4294)

### Common
### Part: USB 1m cable - A to Micro-B
quantity: 1
USB cable - USB A to Micro-B - 3 foot long
[USB 1m cable - A to Micro-B](https://www.adafruit.com/product/592)

### Part: Half-size breadboard
quantity: 1
Half-size breadboard
[Half-size breadboard](https://www.adafruit.com/product/64)

### Part: Alligator Clip to Male Jumper Wires
quantity: 1
Small Alligator Clip to Male Jumper Wire Bundle - 6 Pieces (2 needed for coil)
[Alligator Clip to Male Jumper Wires](https://www.adafruit.com/product/3448)

### Part: Male/Male Jumper Wires
quantity: 1
Premium Male/Male Jumper Wires - 40 x 3" (75mm)
[Male/Male Jumper Wires](https://www.adafruit.com/product/759)

### Part: Signal Diode
quantity: 1
1N4148 Signal Diode - 10 pack (1 needed)
[Signal Diode](https://www.adafruit.com/product/1641)

### Part: 0.1uF Capacitor
quantity: 1
0.1uF ceramic capacitors - 10 pack (1 needed)
[0.1uF Capacitor](https://www.adafruit.com/product/753)

### Part: 36ft (11m) Wire
quantity: 1
Enameled Copper Magnet Wire – 11 meters / 0.1mm diameter (5-8m of most insulated wire will work fine)
[36ft (11m) Wire](https://www.adafruit.com/product/3522)

### Part: 3 x AAA Switched Battery Holder
quantity: 1
3 x AAA Battery Holder with On/Off Switch and 2-Pin JST (if you want to be mobile!)
[3 x AAA Switched Battery Holder](https://www.adafruit.com/product/727)

### Part: AAA Batteries
quantity: 1
Pack of 3
[AAA Batteries](https://www.adafruit.com/product/3520)

# CLUE Metal Detector in CircuitPython

## Design

![](https://cdn-learn.adafruit.com/assets/assets/000/090/605/medium800/sensors_Induction_experiment.png?1587661043 Michael Faraday's experiment to demonstrate inductance in 1831, engraving from Magnetism and Electricity by Arthur Poyser (1892). Primary coil (A) attached to battery (on right), secondary coil (B) attached to galvanometer (C).)

Inductance is a key part of many technologies in daily life, for example:

- charging - electric toothbrushes, the latest smartphones and some wireless, in-ear headphones;
- heating - [induction cooking](https://en.wikipedia.org/wiki/Induction_cooking "Wikipedia: Induction cooking") with metal cookware;
- communication - contactless smartcards using [NFC](https://en.wikipedia.org/wiki/Near-field_communication "Wikipedia: Near field\_communication"), [RFID](https://en.wikipedia.org/wiki/Radio-frequency_identification "Wikipedia: radio-frequency identification") tags and traditional tuning circuits for radios;
- power supplies - [transformers](https://en.wikipedia.org/wiki/Transformer "Wikipedia: Transformer") reduce the mains AC voltage to a more practical level;
- metal detection - airport security, automatic car park exit gates, pipe/cable finders and hunting for treasure.

Leon Theremin's [The Thing](https://en.wikipedia.org/wiki/The_Thing_%28listening_device%29 "Wikipedia: The Thing (listening\_device)") is an interesting, minimalist example of a resonant cavity microphone, the equivalent of using an inductor for [L](https://en.wikipedia.org/wiki/Inductor "Wikipedia: inductor")[C](https://en.wikipedia.org/wiki/Capacitor "Wikipedia: capacitor") tuning, an application of [band-pass filtering](https://en.wikipedia.org/wiki/Band-pass_filter "Wikipedia: Band-pass filter").

## Inductance and Permeability

A current flowing produces a magnetic field around it. Inductors are electrical components designed to store energy in that magnetic field. These are typically coils and often wrapped around a core. The magnetic field can be affected by:

- the material it passes through, this property is referred to as [magnetic permeability;](https://en.wikipedia.org/wiki/Permeability_(electromagnetism) "Wikipedia: Permeability (electromagnetism)")
- the presence of a conductor nearby changing the effective inductance of the coil from the induced [eddy currents](https://en.wikipedia.org/wiki/Eddy_current "Wikipedia: Eddy current") in that conductor creating their own magnetic field;
- other magnetic fields.

These first two properties make the inductor useful for detecting conductive objects.

[MAKE Presents: The Inductor](https://www.youtube.com/watch?v=STDlCdZnIsw "YouTube: MAKE presents: The Inductor") is an excellent video introduction to inductors by [Collin Cunningham](https://learn.adafruit.com/users/collinmel "Adafruit Learn: Collin Cunningham").

https://www.youtube.com/watch?v=STDlCdZnIsw

## Metal Detection

The effect of nearby conductors on an inductor makes them a useful component for detecting metal. A classic implementation of this in electronics uses [heterodyning](https://en.wikipedia.org/wiki/Heterodyne "Wikipedia: heterodyne") where the beat frequency from mixing an inductor-based search oscillator with a reference oscillator is output to headphones.

### Beat Frequency From An Oscillator Pair
The schematic on the left from R.M. Marston's _20 Solid State Projects For The Home (1969)_ shows a transitor-based detector with two [colpitts oscillators](https://en.wikipedia.org/wiki/Colpitts_oscillator "Wikipedia: Colpitts oscillator"). One oscillator uses the search coil and the other a tuneable reference coil which the users adjust to reduce the beat frequency audio output to near 0Hz away from the target material.

![sensors_marston-sspfth-project20-metal-detector-schematic-left-2000x1500.png](https://cdn-learn.adafruit.com/assets/assets/000/090/674/medium640/sensors_marston-sspfth-project20-metal-detector-schematic-left-2000x1500.png?1587837218)

![sensors_marston-sspfth-project20-metal-detector-schematic-right-2000x1500.png](https://cdn-learn.adafruit.com/assets/assets/000/090/675/medium640/sensors_marston-sspfth-project20-metal-detector-schematic-right-2000x1500.png?1587837225)

### RLC Filters

Filters can easily be created with a resistor (R), an inductor (L) and a capacitor (C). There are a variety of configurations of [RLC filters](https://en.wikipedia.org/wiki/RLC_circuit#Applications "Wikipedia: RLC circuit#Applications") and many of them could be used to filter the square wave output from a microcontroller which could then be sampled to check the attenuation of the filter which would vary with the inductance.

An initial test of this approach with an Adafruit CLUE and a low-pass filter didn't yield promising results. The plots below show theoretical plots for a band-stop (notch) filter made with a resistor and a parallel LC circuit which might be worth exploring.

![](https://cdn-learn.adafruit.com/assets/assets/000/090/737/medium800thumb/sensors_frames-rlc-bandstop-filter-response-magnitude-phase-log.jpg?1588097216 Bode plot for a band-stop (notch) passive R-LC filter. The different lines are for various resistor values. The animation varies the inductance to show the frequency shift.)

The lower resistor values might not be practical as they put a higher current demand on the GPIO port.

The annotated linear plot below is better for seeing how this attenuation could potentially be used to detect small variations in inductance.

![](https://cdn-learn.adafruit.com/assets/assets/000/090/738/medium800thumb/sensors_frames-rlc-bandstop-filter-response-magnitude.jpg?1588097233 A linear plot with an example measurement of signal magnitude at a specific frequency as the inductance varies.)

This would require sampling the 989Hz signal to determine the attenuation by the filter. A high inductance is attractive here as it will lower the frequency making the determination of the attenuation more accurate.

A frequency sweeping approach is an alternative for finding the frequency of the filter. This is likely to be slower but it would be less ambiguous. A simple measurement approach at one frequency, say 2.741V, corresponds to _two_ frequencies and therefore two different inductance values.

### Charging a Capacitor with RLD

An [Arduino-based project on Instructables](https://www.instructables.com/id/Simple-Arduino-Metal-Detector/ "Instructables: Simple Arduino Metal Detector ") uses an [RL circuit](https://en.wikipedia.org/wiki/RL_circuit "Wikipedia: RL circuit") with the output rectified with a diode which then charges a capacitor. The steps in the measurement of the inductance are:

1. A few pulses are output through the circuit to charge the capacitor. A higher inductance will result in a higher final voltage across the capacitor.
2. An analogue input then measures the capacitor's voltage with over-sampling aiming to improve the accuracy.
3. The analogue input is changed momentarily to _output mode_ to empty ([sink](https://knowledge.ni.com/KnowledgeArticleDetails?id=kA00Z0000019LBbSAM "National Instruments: What is the Difference Between Sinking and Sourcing Digital I/O?")) the charge from the capacitor.

A C++ program (sketch) on the Arduino Uno offers precise timing. This is essential for this approach to give accurate results for the inductance.

In CircuitPython, the [pulseio library](https://circuitpython.readthedocs.io/en/latest/shared-bindings/pulseio/ __init__.html "CircuitPython Docs: pulseio library") can be used for creating PWM signals and pulse trains with microsecond precision. In general, as an interpreted language with garbage collection, it does not offer precise timing. The unpredictable delay between step 1 and step 2 is likely to affect the final accuracy of the measurement causing sporadic, spurious indications.

### Continuous Charge/Discharge with RLD

The previous approach can be used in a continuous fashion where a constant series of pulses flow through the RLD. A circuit diagram from the [Falstad Circuit Simulator](http://www.falstad.com/circuit/circuitjs.html?cct=%24+1+7.8125e-8+15.472767971186109+53+5+50%0Ar+304+160+400+160+0+1000%0Al+400+160+400+288+0+0.00011999999999999999+0.0032993409398656055%0Ad+400+160+480+160+2+1N4148%0Ac+480+160+480+288+0+1.0000000000000001e-7+1.9792242576134755%0Aw+480+160+544+160+0%0Ar+544+160+544+288+0+1000000%0Ar+400+288+400+336+0+0.2%0Ag+480+288+480+304+0%0Ag+544+288+544+304+0%0Ag+400+336+400+352+0%0Aw+544+160+608+160+0%0Ar+608+160+608+288+0+400000%0Ag+608+288+608+304+0%0AO+608+160+640+160+0%0AR+304+160+272+160+0+2+400000+1.65+1.65+0+0.84%0Ao+13+1+0+21250+5+0.1+0+1%0A38+0+0+1+1000+Resistance%0A38+1+0+0.000001+0.001+Inductance%0A38+5+0+1+1000000+Resistance%0A38+6+0+1+10+Coil%5CsResistance%0A38+3+0+0.00001+0.0022+Capacitance%0A "Falstad Circuit Simulator") is shown below.

![](https://cdn-learn.adafruit.com/assets/assets/000/090/676/medium800thumb/sensors_circuit-sim-running-high-speed-current-onecycle.jpg?1587855600 Circuit simulation of the continuous charging approach. The 200 milliohm resistor represents the parasitic resistance of the coil. The 400k is an estimate of the input impedance of the GPIO in analogue input mode. (This is a short animated loop hence the incorrect current flow on the right side of the diode.))

This design could be considered as an RL filter with an [envelope detector](https://en.wikipedia.org/wiki/Envelope_detector "Wikipedia: Envelope detector").

The value of the capacitor affects how quickly it discharges. A tiny capacitance will cause a rapid discharge causing a ripple which may reduce the accuracy or complicate the voltage measurement. A large capacitor value will take time to charge and discharge and this could make the sensing unresponsive.

A value of 0.1uF (which can be written as 100nF) was chosen from experimental testing. For comparison, a simulation with 100pF (top left) shows a very undesirable 197mV of ripple whereas 0.1uF only has ~1mV ripple.

![sensors_circuit-tinycaptoshowripple-chopped.png](https://cdn-learn.adafruit.com/assets/assets/000/090/679/medium640/sensors_circuit-tinycaptoshowripple-chopped.png?1587855994)

![sensors_circuit-actualcapminimalripple-chopped.png](https://cdn-learn.adafruit.com/assets/assets/000/090/680/medium640/sensors_circuit-actualcapminimalripple-chopped.png?1587856021)

A small amount of steady voltage drop around 1mV is actually useful here to ensure over-sampling is an effective technique to improve the resolution. In the (unlikely) absence of noise or variation, a _theoretically perfect_ [analogue to digital converter (ADC)](https://en.wikipedia.org/wiki/Analog-to-digital_converter "Wikipedia: Analog-to-digital converter") would output the same value repeatedly for a constant voltage. The [ADC Analysis](https://learn.adafruit.com/clue-metal-detector-circuitpython/adc-analysis "Adafruit Learn: CLUE Metal Detector in CircuitPython: ADC Analysis") page takes a closer look at this.

### Two Coil Systems

Modern metal detectors using the induction balanced approach use two, often partially overlapping search coils. One is used for transmitting and one for receiving. A relatively small overlap will create a section with increased sensitivity. These detectors can discriminate to some extent between metals by reporting on the [phase difference](https://en.wikipedia.org/wiki/Phase_(waves)#Phase_shift "Wikipedia: Phase (waves)") between the transmitted and received signal. This is typically presented to the user as a numerical value with different ranges giving an approximate identification. Garrett's chart for their AT Pro metal detector is shown below.

![](https://cdn-learn.adafruit.com/assets/assets/000/090/874/medium800/sensors_garrett-target-id-chart-intl-43.jpg?1588692486 Garrett AT Pro metal detector numeric target identifier chart.)

## CLUE Metal Detector

Some initial testing of the **Continuous Charge/Discharge with RLD** approach worked well so this was selected for the project.

The CLUE has an onboard LIS3MDL, a triple-axis magnetometer. This is a useful addition for finding magnets and magnetised items.

# CLUE Metal Detector in CircuitPython

## Microcontrollers vs Inductors

![](https://cdn-learn.adafruit.com/assets/assets/000/090/626/medium800thumb/sensors_electroboom-inductor-3leds.jpg?1587684427 Three LEDs with a combined forward voltage of approximately 9V lit by a 1.5V battery with an inductor in series shown at 0.5x speed from Magic of Magnetism and Inductors by ElectroBOOM.)

## Microcontrollers vs Inductors

Inductors can generate high voltages which may exceed the desired levels in a circuit. The video above shows a single-cell battery connected to an inductor (top right) in series with three white LEDs. The white LEDs require over 9V to illuminate but a mere 1.5V battery is able to briefly illuminate them due to the inductor's effect.

In this case the red wire is being used to briefly short across the non-conducting LEDs to allow current to flow from the battery through the inductor. The inductor is storing energy in its magnetic field and this field products the momentary higher voltage as the red wire is removed from the circuit. This demonstration of voltage spikes suggests care is required when using inductors in circuits to keep voltage levels at normal levels to avoid damaging sensitive components.

[TDK](https://www.tdk.com/corp/en/about_tdk/our_history/index.htm "TDK Corporation: History"), a company founded on the invention of [ferrite](https://en.wikipedia.org/wiki/Ferrite_(magnet) "Wikipedia: ferrite (magnet)"), offers an explanation of this below with a parallel version of the circuit lighting a 70V [neon lamp](https://en.wikipedia.org/wiki/Neon_lamp "Wikipedia: neon lamp") from a 4.5V battery. This is from [TDK's The Wonders of Electromagnetism: Power Inductors in Mobile Phones](https://www.tdk.com/tech-mag/inductive/005 "TDK Corporation: The Wonders of electromagnetism: vol.5 Power Inductors in Mobile Phones").

![](https://cdn-learn.adafruit.com/assets/assets/000/090/805/medium800/sensors_tdk-wonders-of-electromagnetism-self-inductance-diagrams-trimmed.png?1588337691 Explanation of self induction and generating voltage spikes with an inductor in parallel. Copyright TDK Corporation.)

## GPIO Protection

The [general-purpose input/output (GPIO)](https://en.wikipedia.org/wiki/General-purpose_input/output "Wikipedia: General purpose input/output") pins on microcontrollers typically have some limited protection built-in for adverse voltages often to deal with static electricity ([ESD](https://en.wikipedia.org/wiki/Electrostatic_discharge#Damage_prevention_in_electronics "Wikipedia: electrostatic discharge")). The CLUE board uses an [nRF52 series chip and this has two internal diodes](https://devzone.nordicsemi.com/f/nordic-q-a/26897/esd-protection-for-external-button-human-touch-activated "Nordic SemiConductors: DevZone: ESD protection for external button(human touch activated)?") on each GPIO pin. The partial schematic below shows an example of how these these two diodes are used for one pin.

![](https://cdn-learn.adafruit.com/assets/assets/000/090/645/medium800/sensors_clue-nrf52840-gpio-pad-protection-v1.png?1587754850 Partial schematic showing one example of a reverse-biased diode pair inside the nRF52840 microcontroller protecting input and output against over/under voltage. The CLUE board's 1M resistor to facilitate touch input is also shown.)

The schematic shows the CLUE board's 1 Megaohm resistor. There's one resistor per large pad used for the [capacitive touch](https://en.wikipedia.org/wiki/Capacitive_sensing "Wikipedia: capacitive sensing") implementation. The schematic also shows an _external_ resistor. This is another precaution that's typically used to limit output current but it will also reduce any current flowing through these _very small_, protective diodes in the microcontroller.

The metal detector circuit on the next page uses a resistor primarily to limit the current from the **P1** _output_ but it will also reduce any adverse currents from under or over voltages caused by the inductor.

The square wave (3.3V [pk-pk](https://en.wikipedia.org/wiki/Amplitude#Peak-to-peak_amplitude "Wikipedia: peak-to-peak amplitude"), 84% [duty cycle](https://learn.adafruit.com/arduino-to-circuitpython/analog-pwm-output#disscussion-8-2 "Adafruit Learn: Arduino to CircuitPython: Analog and PWM Output")) can be seen with and without the inductor in the circuit here. The inductor does cause a small _negative_ voltage which briefly "peaks" at -0.6V on the **P1** pin/pad. The magnitude and brevity of this spike and the current protection from the external 1k resistor mean the microcontroller is not at risk.

![sensors_final-circuit-post-R1-inductor-disconnected.jpg](https://cdn-learn.adafruit.com/assets/assets/000/090/624/medium640/sensors_final-circuit-post-R1-inductor-disconnected.jpg?1587683024)

![sensors_final-circuit-post-R1-inductor-effect.jpg](https://cdn-learn.adafruit.com/assets/assets/000/090/661/medium640/sensors_final-circuit-post-R1-inductor-effect.jpg?1587772870)

## Larger Coil Currents

If more current was being used through the coil then an external protection diode capable of handling this higher current would be a wise precaution. The CLUE's nRF52840 can only supply low currents, higher currents would need a separate power supply and switching with a transistor. This could aid isolation of the GPIO from the maleffects of the voltage spikes.

Diodes are commonly found [across motors](https://learn.adafruit.com/adafruit-arduino-lesson-13-dc-motors/transistors "Adafruit Learn: Arduino Lesson 13. DC Motors"), relays and solonoids protecting against [back EMF](https://en.wikipedia.org/wiki/Counter-electromotive_force "Wikipedia: Counter electromotive\_force") and are sometimes referred to as ["flyback" diodes](https://en.wikipedia.org/wiki/Flyback_diode "Wikipedia: flyback diode").

# CLUE Metal Detector in CircuitPython

## Circuit

![](https://cdn-learn.adafruit.com/assets/assets/000/090/606/medium800/sensors_coil2-upsidedown-2000x1500.jpg?1587676038 Second version of coil, 28 turns around an 84mm (3.3in) diameter cylinder.)

This page describes how the components are used on the breadboard to make the circuit for the metal detector. It also describes how to make and connect the coil.

## Components

The components in the circuit are:

- **R1** - 1k resistor.
- **D2** - 1N4148 signal diode (there is no **D1** ).
- **C1** - 0.1uF (100nF) ceramic capacitor. These small capacitors are often labelled "104".
- **L1** - home-made coil.

The prototype was made with a 1N4004 rectifier diode and also tested with a germanium diode from a crystal radio set, both worked well and could be used as alternatives to the 1N4148 diode.

![](https://cdn-learn.adafruit.com/assets/assets/000/091/124/medium800/sensors_untitled.jpg?1589390279)

## Coil Construction

A coil with about 4-8m (13-26ft) is a good starting point to avoid using too much wire. Insulated wire will work but ["enamelled" copper wire](https://en.wikipedia.org/wiki/Magnet_wire "Wikipedia: magnet wire") allows a more compact coil. The enamel is a misnomer, the coating will be something like polyurethane varnish. This insulation must be _scraped_ or _burnt off_ with a soldering iron at the ends to expose the copper to connect it to the circuit.

The coil shown at the top of the page is enamelled 0.56mm wire wrapped around an 84mm tube (3.3in). It has 12 coils then 9 more coils over those then 7 coil more coils over those totalling 28. Placing the coils close to the edge improves the effective search range but care needs to be taken to ensure the coil does not fall off! A tiny ridge has been made on end of the tube with masking tape to reduce that risk.

The coil either needs to be very tight or held in place as movement of the wire in the coil will subtly affect the inductance and [parasitic capacitance](https://en.wikipedia.org/wiki/Parasitic_capacitance "Wikipedia:parasitic capacitance") of the coil.

A prototype coil was also made (not shown) with 20 turns around a core of a roll of masking tape with diameter 116mm (4.6in). This worked well too.

## Circuit Construction

The diagrams and pictures below show how the circuit can be implemented on a breadboard for the three different configurations.

### CLUE board
![](https://cdn-learn.adafruit.com/assets/assets/000/090/601/medium800/sensors_clue-metal-detector-v1_bb-43padded.png?1587655181 The breadboard showing the use of the Dragontail breakout board to connect CLUE's #0 (P0) and #1 (P1) pads to circuit. The small inductor coil represents the large coil.)

The coil needs to be connected to the breadboard. The options are:

- Thick solid core wire may be directly inserted into the breadboard. Tinning the end with solder will increase the diameter of a wire and tame multi-strand wire.
- A connector cable with male pins to alligator (crocodile) clips or hooks (shown below). These will be needed for the Adafruit enamelled wire.

![](https://cdn-learn.adafruit.com/assets/assets/000/090/682/medium800/sensors_clue-metal-detector-breadboard-1-2000x1500.jpg?1587924539 Breadboard for metal detector circuit. The CLUE is connected via a KItronik Edge Connector Breakout Board out of shot. The blue and black leads at the bottom go to the coil. The diode is a 1N4148 signal diode.)

The CLUE board can be connected using the Dragontail or alligator clips.

- **#0** ( **P0** ) yellow wire - this is the square wave output.
- **#1** ( **P1** ) green wire - this is an analogue input measuring the voltage across the capacitor.
- **GND** black wire - this is only required if not using the&nbsp; Dragontail. The Dragontail directly connects to the power rails on _one_ side of the breadboard.

Warning: 

Everything can be seen connected together in the picture below. A [Kitronik Edge Connector Breakout Board for BBC micro:bit](https://www.kitronik.co.uk/5601b-edge-connector-breakout-board-for-bbc-microbit-pre-built.html "Kitronik: Edge Connector Breakout Board for BBC micro:bit (assembled)") (over the top half of the breadboard) and [Pimoroni IC hooks with pigtails](https://shop.pimoroni.com/products/ic-hook-with-pigtail "Pimoroni: IC hooks with pigtails") (to connect the coil) have been used for this implementation.

![](https://cdn-learn.adafruit.com/assets/assets/000/090/875/medium800/sensors_clue-metal-detector-everything-1-2000x1500.jpg?1588694802 Metal detector fully assembled. The blue and black wires/hooks to the inductor have been accidentally swapped around for this photo - the electrons will not be concerned about this.)

The circuit can only be tested once the CLUE has the CircuitPython program on it. This is described on the next page.

Warning: 

### **Circuit Playground Bluefruit with TFT Gizmo**

The CPB board pads are not really accessible when the TFT Gizmo is attached and most of them are used for the Gizmo. The Gizmo has 3-pin STEMMA connectors for accessing **A1** and **A2.** A pair of [STEMMA 3-Pin to male cables](https://www.adafruit.com/product/3893 "Adafruit: STEMMA JST PH 3-Pin to Male Header Cable - 200mm") are required to connect this to the breadboard.

![](https://cdn-learn.adafruit.com/assets/assets/000/091/117/medium800/sensors_cpb-gizmo-metal-detector-v1_bb-43padded.png?1589382189 The breadboard showing the Gizmo's STEMMA connections to the circuit. The small inductor coil represents the large coil. Note: 1k resistor is not needed here.)

The connections are:

- **A1 STEMMA** (square wave output):  

  - red - breadboard red (+) rail (not used).
  - white (yellow sleeves) - breadboard b22.
  - black - breadboard black (-) rail.

- **A2 STEMMA** (analogue input):  

  - red - breadboard red (+) rail (not used).
  - white (green sleeves) - breadboard e26.
  - black - breadboard black (-) rail.

![](https://cdn-learn.adafruit.com/assets/assets/000/090/921/medium800/sensors_cpb-gizmo-metal-detector-breadboard-1-2000x1500.jpg?1588783685 Metal Detector fully assembled. The TFT Gizmo is mounted on a Circuit Playground Bluefruit. The STEMMA cables have small sleeves on white signal cable to help distinguish them.)

The TFT Gizmo has its own 1k resistors on the **A1** / **A2** GPIO making the resistor on the breadboard superfluous.

The red power lines are not used but plugging the pins into the breadboard prevents them from accidentally contacting other components or shorting to ground.

Info: 

### **Circuit Playground Bluefruit board only**

The program still runs without a screen on a CPB board in audio/light mode.

The connections are:

- **A1** (square wave output) - yellow wire - breadboard a18.
- **A2** (analogue input) - green wire - breadboard e26.
- **GND** - black wire - breadboard black (-) rail.

![](https://cdn-learn.adafruit.com/assets/assets/000/091/118/medium800/sensors_cpb-metal-detector-v1_bb-43padded.png?1589382219 The breadboard showing the Circuit Playground Bluefruit connections to the circuit. The small inductor coil represents the large coil. Note: 1k resistor is needed here.)

# CLUE Metal Detector in CircuitPython

## CircuitPython on CLUE

[CircuitPython](https://github.com/adafruit/circuitpython) is a derivative of [MicroPython](https://micropython.org) designed to simplify experimentation and education on low-cost microcontrollers. It makes it easier than ever to get prototyping by requiring no upfront desktop software downloads. Simply copy and edit files on the **CIRCUITPY** &nbsp;flash drive to iterate.

The following instructions will show you how to install CircuitPython. If you've already installed CircuitPython but are looking to update it or reinstall it, the same steps work for that as well!

## Set up CircuitPython Quick Start!

Follow this quick step-by-step for super-fast Python power :)

[Download the latest version of CircuitPython for CLUE from circuitpython.org](https://circuitpython.org/board/clue_nrf52840_express/)
 **Click the link above to download the latest version of CircuitPython for the CLUE.**

Download and save it to your desktop (or wherever is handy).

![adafruit_products_CLUE_UF2_Downloaded.png](https://cdn-learn.adafruit.com/assets/assets/000/088/037/medium640/adafruit_products_CLUE_UF2_Downloaded.png?1580840077)

Plug your CLUE into your computer using a known-good USB cable.

**A lot of people end up using charge-only USB cables and it is very frustrating! So make sure you have a USB cable you know is good for data sync.**

Double-click the **Reset** button on the top (magenta arrow) on your board, and you will see the NeoPixel RGB LED (green arrow) turn green. If it turns red, check the USB cable, try another USB port, etc. **Note:** The little red LED next to the USB connector will pulse red. That's ok!

If double-clicking doesn't work the first time, try again. Sometimes it can take a few tries to get the rhythm right!

![adafruit_products_Clue_Reset_NeoPixel_bootloader.png](https://cdn-learn.adafruit.com/assets/assets/000/087/919/medium640/adafruit_products_Clue_Reset_NeoPixel_bootloader.png?1580496467)

You will see a new disk drive appear called **CLUEBOOT**.

Drag the **adafruit-circuitpython-clue-etc.uf2** file to **CLUE**** BOOT.**

![adafruit_products_CLUE_CLUEBOOT.png](https://cdn-learn.adafruit.com/assets/assets/000/088/042/medium640/adafruit_products_CLUE_CLUEBOOT.png?1580841287)

![adafruit_products_CLUE_drag_UF2.png](https://cdn-learn.adafruit.com/assets/assets/000/088/043/medium640/adafruit_products_CLUE_drag_UF2.png?1580841295)

The LED will flash. Then, the **CLUEBOOT** drive will disappear and a new disk drive called **CIRCUITPY** will appear.

If this is the first time you're installing CircuitPython or you're doing a completely fresh install after erasing the filesystem, you will have two files - **boot\_out.txt** , and **code.py** , and one folder - **lib** on your **CIRCUITPY** drive.

If CircuitPython was already installed, the files present before reloading CircuitPython should still be present on your **CIRCUITPY** drive. Loading CircuitPython will not create new files if there was already a CircuitPython filesystem present.

That's it, you're done! :)

![adafruit_products_CLUE_CIRCUITPY.png](https://cdn-learn.adafruit.com/assets/assets/000/088/044/medium640/adafruit_products_CLUE_CIRCUITPY.png?1580841453)

# CLUE Metal Detector in CircuitPython

## CircuitPython on Circuit Playground Bluefruit

# Install or Update CircuitPython

Follow this quick step-by-step to install or update CircuitPython on your Circuit Playground Bluefruit.

[Download the latest version of CircuitPython for this board via circuitpython.org](https://circuitpython.org/board/circuitplayground_bluefruit/)
 **Click the link above and download the latest UF2 file**

Download and save it to your Desktop (or wherever is handy)

![adafruit_products_CPB_Download_UF2.png](https://cdn-learn.adafruit.com/assets/assets/000/080/530/medium640/adafruit_products_CPB_Download_UF2.png?1567715178)

Plug your Circuit Playground Bluefruit into your computer using a known-good data-capable USB cable.

**A lot of people end up using charge-only USB cables and it is very frustrating! So make sure you have a USB cable you know is good for data sync.**

Double-click the small **Reset** button in the middle of the CPB (indicated by the red arrow in the image). The ten NeoPixel LEDs will all turn red, and then will all turn green. If they turn all red and stay red, check the USB cable, try another USB port, etc. The little red LED next to the USB connector will pulse red - this is ok!

If double-clicking doesn't work the first time, try again. Sometimes it can take a few tries to get the rhythm right!

(If double-clicking doesn't do it, try a single-click!)

![adafruit_products_CPB_Front_Reset_Button_Arrow.jpg](https://cdn-learn.adafruit.com/assets/assets/000/080/532/medium640/adafruit_products_CPB_Front_Reset_Button_Arrow.jpg?1567715535)

You will see a new disk drive appear called **CPLAYBTBOOT**.

&nbsp;

&nbsp;

&nbsp;

Drag the **adafruit\_circuitpython\_etc.uf2** file to **CPLAYBTBOOT.**

![adafruit_products_CPB_CPLAYBTBOOT.png](https://cdn-learn.adafruit.com/assets/assets/000/080/533/medium640/adafruit_products_CPB_CPLAYBTBOOT.png?1567715858)

![adafruit_products_CBP_drag_UF2.png](https://cdn-learn.adafruit.com/assets/assets/000/080/534/medium640/adafruit_products_CBP_drag_UF2.png?1567715871)

The LEDs will turn red. Then, the **CPLAYBTBOOT** drive will disappear and a new disk drive called **CIRCUITPY** will appear.

That's it, you're done! :)

![adafruit_products_CBP_CIRCUITPY.png](https://cdn-learn.adafruit.com/assets/assets/000/080/535/medium640/adafruit_products_CBP_CIRCUITPY.png?1567716034)

# CLUE Metal Detector in CircuitPython

## Metal Detector

![](https://cdn-learn.adafruit.com/assets/assets/000/090/922/medium800/sensors_cpb-gizmo-metal-detector-button-guide-1-colourswap-2000x1500.jpg?1588786486 Metal detector start-up screen presenting the button guide shown on a TFT Gizmo attached to a Circuit Playground Bluefruit (CPB).)

## Installing Project Code

To use with CircuitPython, you need to first install a few libraries, into the lib folder on your **CIRCUITPY** drive. Then you need to update **code.py** with the example script.

Thankfully, we can do this in one go. In the example below, click the **Download Project Bundle** button below to download the necessary libraries and the **code.py** file in a zip file. Extract the contents of the zip file, open the directory **CLUE\_Metal\_Detector/** and then click on the directory that matches the version of CircuitPython you're using and copy the contents of that directory to your **CIRCUITPY** drive.

Your **CIRCUITPY** drive should now look similar to the following image:

![CIRCUITPY](https://adafruit.github.io/Adafruit_Learning_System_Guides/CLUE_Metal_Detector.png )

https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/main/CLUE/CLUE_Metal_Detector/code.py

## Example Video
https://www.youtube.com/watch?v=_sYRRU4IB3c

The video shows the CLUE version powered by a lithium polymer battery similar to the [Adafruit 1200mAh Lithium Ion Polymer battery](https://www.adafruit.com/product/258 "Adafruit: Lithium Ion Polymer Battery - 3.7v 1200mAh"). Note: the CLUE and the CPB do not have an integrated charger.

In the video, when no object is being sensed, the voltage shown on the screen is around 1474mV and magnitude of the magnetic flux density difference is 0uT. The five hidden objects, in order, show the following voltages:

- Through a large hardback book
  - a large metallic sticker, 1467mV.

- Through a magazine
  - another Adafruit CLUE board, 1463mV;
  - a ferrite core from an inductor, 1477mV (note the value has _increased_);
  - a neodymium magnet, 1474mV and 28uT;
  - a large silver coin 1469mV.

The voltage will vary based on the inductance of the coil created for the metal detector. It will be about 300mV less if a rectifier diode like a 1N1004 is used. The voltage is about 200mV less on the Circuit Playground Bluefruit with TFT Gizmo for the same coil.

## Troubleshooting

If the metal detector is not working, here's some tips based on observing the voltage.

- Around 2950mV: the coil is not connected or the connection is hampered by insulation left on the enamelled wire.
- Around 0mV: diode may be the wrong way around or something is not connected properly.
- A few tens of mV: the yellow connection is probably from a high (3.3V) pin.
- Voltage jumps around: probably a loose connection and/or ground is not attached. Wiggle and re-insert connections to find problematic one. Using alternate holes/rows on the breadboard can help sometimes.

## Operation

The mV value across the capacitor is shown on screen. This value represents the inductance value. The detection of metal is based on a positive or negative _change_ from the baseline value when no object is being sensed. A difference is indicated by a beeping sound, a bar graph with green for positive and red for negative and flashing of the NeoPixel(s) with a matching colour. The baseline value is assigned when the code first starts. It will also follow any changes after about ten seconds.

The uT reading (CLUE board only) is the magnitude of the difference between the magnetometer's **z** component only and the first value measured at start-up. This value is also shown as a filled blue circle, a slightly different beeping sound and flashing of the NeoPixel(s) in blue alternating with any mV related colour.

The use of the **z** component only is a crude approach to make the detector ignore the Earth's magnetic field. This allows the detector to be rotated as this changes the **x** and **y** values but not the **z** value. Tilting the device, as seen in the video when the metal detector is at the top of the screen, will unfortunately increase the value slightly.

The right button can be used to immediately reset the baseline for the voltage and the magnetic flux density. The left button toggles the audio, NeoPixel(s), screen and Mu output on and off depending on the duration of the button press.

Warning: 

## Code

A [code discussion](https://learn.adafruit.com/clue-metal-detector-circuitpython/metal-detector#code-discussion-8-11 "code discussion") follows the code.

https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/main/CLUE_Metal_Detector/code.py

## Code Discussion

The high level design is straightforward.

1. Output a square wave on a pin.
2. Store a baseline value from the other pin configured as an analogue input which is measuring the voltage across the capacitor.
3. Store a baseline value for the **z** component of the magnetometer (if present).
4. Take the difference from the current analogue input and the baseline and present this value to the user.
5. Take the magnitude of the difference from the current **z** component of the magnetometer and the baseline and present this value to the user.
6. Check the two buttons for user inputs.
7. Go to step 4.

Only the buttons are used for the user interface on the CLUE. There is one spare touch capable pad but this isn't really accessible if an edge connector is used.

### Voltage from ADC Values

The ADC values are easily read in CircuitPython using an [AnalogIn](https://circuitpython.readthedocs.io/en/latest/shared-bindings/analogio/AnalogIn.html "CircuitPython Docs: analogio AnalogIn") object's `value` property. This value ranges from 0 to 65535 (a 16bit value) regardless of the number of bits returned by the ADC. The nRF52840 is configured in 12bit ADC mode by the CircuitPython interpreter. This means values will always be multiples of 16.

One surprise is these values can vary even with a stable voltage source like a battery. An extreme example from some real data for consecutive values is:

1. 25152 = 1266.5mV
2. 28848 = 1452.6mV
3. 28608 = 1440.5mV

In the case of this metal detector, a 3mV difference represents a small metallic object, but the ADC is infrequently producing output which hugely deviates from the actual value. Even the second and third values have a 12.1mV difference.

A common approach is to take multiple samples and then take the average (arithmetic mean) of those values with the aim of reducing the effect of this variance. The `sample_sum()` function below does most of this job, it leaves the division by `num` to the caller.

```python
def sample_sum(pin, num):
    """Sample the analogue value from pin num times and return the sum
       of the values."""
    global samples
    samples[:] = [pin.value for _ in range(num)]
    return sum(samples)
```

This is one of the most efficient ways to read multiple samples with a rate of around 21-22 thousand samples per second (ksps) on an nRF52840. It also stores them in case further data analysis is required. The use of `global` here isn't strictly required but arguably it's useful to indicate the function changes the global list `samples`. The values are intentionally processed here as `int` and not `float` to improve the performance. The use of slice assignment is an attempt. probably unsuccessful, to stop the interpreter generating a temporary list to store all the sample values.

The performance of different approaches to reading many samples is shown in [Adafruit Forums: Analogue Sampling at high rates plus ulab](https://forums.adafruit.com/viewtopic.php?f=60&t=164758 "Adafruit Forums: Analogue Sampling at high rates plus ulab").

The validity of using the average of a number of consecutive samples to accurately represent the real voltage is examined on the next page.

### Using Global Variables in Python

In Python, [global](https://docs.python.org/3/faq/programming.html#what-are-the-rules-for-local-and-global-variables-in-python "Python 3 Programming FAQ: What are the rules for local and global variables in Python?") must be used inside a function (or method) to declare usage of a variable _if assignment occurs_. This prevents Python from creating a new local variable. An example from the program is shown below.

```python
def magnet_circ_set(mag_ut):
    """Display a filled circle to represent the magnetic value mag_ut in microteslas."""
    global magnet_circ_dob
    global last_mag_radius

    radius = min(max(round(math.sqrt(mag_ut) * 4),
                     1),
                 MAG_MAX_RADIUS)

    if radius == last_mag_radius:
        return

    if magnet_circ_dob is not None:
        screen_group.remove(magnet_circ_dob)
    magnet_circ_dob = Circle(60, 180, radius, fill=BLUE)
    screen_group.append(magnet_circ_dob)
```

[Pylint](https://www.pylint.org/ "Pylint - code analysis for Python") picks up on use of `global` and issues a `W0603: Using the global statement (global-statement)` warning. Variables with a large [scope](https://en.wikipedia.org/wiki/Scope_(computer_science) "Wikipedia: scope (computer science)") which are not truly constant can make a program difficult to understand and lead to bugs - [global variables](https://en.wikipedia.org/wiki/Global_variable "Wikipedia: global variable") are the most extreme version of this. In a small program they tend not to be problematic but small programs can _gradually_ become much larger ones. In the above case the variables have:

- a clear, specific, semi-documented purpose
- and a very low probability of being used elsewhere in the code in the future.

The current code does limit the display to a single circle/value. If the program was likely to grow over time or there was a potential need to display multiple circles/values then creating a new [class](https://en.wikipedia.org/wiki/Class_(computer_programming) "Wikipedia: class (computer programming)") would be an attractive option to [encapsulate](https://en.wikipedia.org/wiki/Encapsulation_(computer_programming) "Wikipedia: encapsulation (computer programming)") this data replacing the use of global variables.

In other languages, global variables can cause limitations or bugs from ill-considered use due to [multi-threading](https://en.wikipedia.org/wiki/Thread_(computing)#Multithreading "Wikipedia: thread (computing)") or [re-entrancy](https://en.wikipedia.org/wiki/Reentrancy_(computing) "Wikipedia: reentrancy (computing)") issues. The [evolution of errno](https://stackoverflow.com/questions/1694164/is-errno-thread-safe "StackOverflow: Is errno thread-safe?") is one important example of a global variable used by UNIX libraries which had to be enhanced to support true multi-threading by conversion into a function.

### Positional Arguments

The majority of programming languages use positional arguments (parameters) to functions. An example from the code is show below with the body of the procedure not shown for brevity.

```python
def neopixel_set(pix, d_volt, mag_ut):
    """Set all the NeoPixels to an alternating colour
       based on voltage difference and
       magnitude of magnetic flux density difference."""
```

The three values are clearly very different:

1. `pix` - an object for the NeoPixels, the `fill()` method is used on it.
2. `d_volt` - a difference value which may be positive or negative in _volts_.
3. `mag_ut` - a magnetic value in microteslas which happens to be a magnitude of a difference value so is always non-negative.

A scientist would clearly see there are two quantities with very different units. Python traditionally didn't have any typing that would indicate if the procedure was used with the arguments in the wrong order and during development the numerical arguments were briefly reversed by accident. The use of keyword (named) arguments can make this less likely to occur, particularly with functions which take a huge number of arguments. [Keyword arguments are only mandatory in Python](https://www.python.org/dev/peps/pep-3102/#specification "Python: PEP 3102 -- Keyword-Only Arguments") after `*` in the argument list.

CircuitPython supports [type hints (PEP-484)](https://www.python.org/dev/peps/pep-0484/ "Python.org: PEP 484 -- Type Hints") which improves the results from static analysis tools like pylint. This can reduce bugs in this area but will not eliminate them.

### Practical Issues with displayio Graphics

Drawing items on the TFT LCD screen on these boards is a slow process compared to a modern desktop computer. This is particularly noticeable when drawing _large_ objects using the [adafruit\_display\_shapes library](https://circuitpython.readthedocs.io/projects/display-shapes/en/latest/api.html "CircuitPython Docs: adafruit\_display\_shapes library").

The program uses a variety of techniques to try and keep the main loop executing at a reasonable and approximately constant rate both especially when a significant object is detected.

1. The default automatic screen refresh is replaced by a manual refresh once per loop to CPU cycles are not spent on interim, fruitless, partial screen updates.
2. The `MAG_MAX_RADIUS` seen in the `magnet_circ_set()` procedure above serves to ensure the filled circle fits on screen. It's set slightly smaller than the screen area it occupies to reduce the performance impact of drawing very large circles.
3. Screen objects which are slow to update are reduced in frequency with an "only every N times" approach in the main loop.
4. The number of samples read adapts to other balance other activity in the loop to keep the execution rate more constant.
5. Graphical objects are not updated if the screen has been turned off in the program by the user.
6. The numerical values on screen are split into two [Label](https://circuitpython.readthedocs.io/projects/display_text/en/latest/api.html "CircuitPython Docs: adafruit\_display\_text.label.Label") objects to separate the dynamic value and the static units (`"uT"` and `"mV"`).

The third, fourth and fifth optimisations are shown in an excerpt below from the main loop.

```python
# An excerpt from main loop
    samples_to_read = 500  # About 23ms worth on CLUE
    update_basic_graphics = (screen_on
                             and counter % update_basic_graphics_period == 0)
    if not update_basic_graphics:
        samples_to_read += 150
    update_complex_graphics = (screen_on
                               and counter % update_complex_graphics_period == 0)
    if not update_complex_graphics:
        samples_to_read += 400
    update_median = counter % update_median_period == 0
    if not update_median:
        samples_to_read += 50
```

This is setting three [boolean](https://en.wikipedia.org/wiki/Boolean_data_type "Wikipedia: boolean data type") variables, `update_basic_graphics`, `update_complex_graphics` and `update_median`, which are used to selectively execute certain computationally expensive parts of the loop and to increase the amount of sample reading if those operations are not taking place to balance the loop time and make practical use of this time. The first two values are calculated using `screen_on` to ensure they are `False` if the screen is not being used.

The `displayio` library has a builtin optimisation. Only areas of the screen which have been changed are sent to the TFT LCD screen. Internally these are processed as rectangular areas and marked as "dirty" when they've been changed to indicate the need to send them to the screen on the next refresh.

### Filters with and without ulab Library

The main loop also has an extra level of filtering to try to further reduce any brief, transient variations of voltage - these could give a distracting, false indication. The simple code below shows how two previous `voltage` values can be stored in simple variables. The `_zm1` suffix refers to **z<sup>-1</sup>** which represents the [unit delay in digital filter implementations](https://en.wikipedia.org/wiki/Digital_filter#Filter_realization "Wikipedia: Digital\_filter").&nbsp;

```python
# Store the previous two voltage values
    voltage_zm2 = voltage_zm1
    voltage_zm1 = voltage
```

These are then used to make a "filtered" version of the voltage by a multiplication by weights (coefficients) and summation.

```python
# Make a filtered voltage from three values
    filt_voltage = (voltage * 0.4
                    + voltage_zm1 * 0.3
                    + voltage_zm2 * 0.3)
```

This tiny low-pass, [causal filter](https://en.wikipedia.org/wiki/Causal_filter "Wikipedia: causal filter") was improvised rather than designed but appears to work reasonably well to reduce the effect of transient spikes without introducing obvious delay.

CircuitPython 5.1.0 introduced the [ulab](https://learn.adafruit.com/ulab-crunch-numbers-fast-with-circuitpython "Adafruit Learn: ulab: Crunch Numbers fast in CircuitPython") library for boards with larger CPUs like the nRF52840 on the CLUE/CPB. This library is a cut-down version of [numpy](https://numpy.org/ "NumPy"), providing very fast vector operations and efficient, flexible storage for arrays. The [ulab](https://micropython-ulab.readthedocs.io/en/latest/ulab.html "MicroPython ulab documentation") approach for this can be seen on [Low pass filtering: Measuring barometric Pressure](https://learn.adafruit.com/ulab-crunch-numbers-fast-with-circuitpython/filter-example-measuring-barometric-pressure "Adafruit Learn: ulab: Crunch Numbers fast in CircuitPython: Low pass filtering: Measuring barometric Pressure with a BMP280"). This type of filter is know as a [Finite Impulse Response (FIR)](https://en.wikipedia.org/wiki/Finite_impulse_response "Wikipedia:finite impulse response") filter. There is also a [convolve](https://micropython-ulab.readthedocs.io/en/latest/ulab.html#convolve "MicroPython ulab documentation") function in `ulab` which can be used to perform this type of filtering across arrays.

The program does make some use of `ulab`. The unfiltered `voltage` values are continually stored in a fixed size 201 element `float`-based `ulab` `ndarray`. This is used in the style of a [circular buffer](https://en.wikipedia.org/wiki/Circular_buffer "Wikipedia: circular buffer") storing the _most recent_ 201 values. These values are then used to calculate the [median](https://en.wikipedia.org/wiki/Median "Wikipedia: median") voltage with the code shown below.

```python
# Adjust the reference base_voltage to the median of historical values
    if voltage_hist_complete and update_median:
        voltage_hist_median = ulab.numpy.sort(voltage_hist)[len(voltage_hist) // 2]
        base_voltage = voltage_hist_median
```

The code is updating the baseline voltage used as the datum for calculating the voltage difference used to indicate metal. This allows the code to deal with gradual shifts in the voltage level. An inevitable side-effect of this approach is the detector will incorrectly adjust the baseline if held over a metal object constantly for about ten seconds.

### Magnetometer Baseline and Code Reviews

An informal code review by [Jeff Epler](https://learn.adafruit.com/users/jepler "Adafruit: Jeff Epler") highlighted an inconsistency in the program for setting the baseline value for the magnetometer. The code which initialises the values is shown below.

```python
# Get a baseline value for magnetometer
totals = [0.0] * 3
mag_samples_n = 10
if magnetometer is not None:
    for _ in range(mag_samples_n):
        mx, my, mz = magnetometer()
        totals[0] += mx
        totals[1] += my
        totals[2] += mz
        time.sleep(0.05)
        
base_mx = totals[0] / mag_samples_n
base_my = totals[1] / mag_samples_n
base_mz = totals[2] / mag_samples_n
```

The code used within the loop if the user pressed the right button to "Recalibrate" is a much simpler affair, shown below.

```python
# Excerpt from main loop inside if button_right():
        if magnetometer is not None:
            base_mx, base_my, base_mz = mx, my, mz
```

The issues here could be summarised as:

- There's no explanation in comments or documentation for this inconsistency.
- There's no explanation for the `0.05` (50ms) pause in the `for` loop.
- A developer working on this code in the future is left to guess the reasons for this and possibly duplicate them without being able to justify the difference.&nbsp;

The actual reason for the difference is the calibration feature was added very late in the development process and was not part of any initial design. The metal detector automatically adjusts the baseline for the voltage which represents the inductance and presence of metal. It does not do this for the magnetometer as this is a more stable value. In testing it turned out to be useful sometimes to set a new baseline for the magnetometer so this was added as a feature initiated by pressing the right button.

The small delay in the first code sample was based on prior observations whilst developing the code for [CLUE Sensor Plotter in CircuitPython](https://learn.adafruit.com/clue-sensor-plotter-circuitpython "Adafruit Learn: CLUE Sensor Plotter in CircuitPython"). The magnetometer issues duplicate values if read as fast as possible (~230Hz) in CircuitPython. This suggests it has a fixed rate for producing new values and the library does not wait (block) for a new value to be produced. The [adafruit\_lis3mdl library](https://circuitpython.readthedocs.io/projects/lis3mdl/en/latest/api.html "CircuitPython Docs: CircuitPython helper library for the LIS3MDL 3-axis magnetometer") shows a set of different rates but does not document the default (the code shows it as 155Hz). The `adafruit_clue` library does not set an explicit rate which explains the duplication of results.

There's no particular reason for the difference in the number of samples. This is worth checking particularly on power-up to see if the sensor takes time to stabilise. The [use case](https://en.wikipedia.org/wiki/Use_case "Wikipedia: use case") for user-initiated recalibration may specify it occurs within a certain amount of time - that would limit how many samples could be taken. In practical use, the magnetometer value is fairly stable for tenths of microteslas (uT).

This could be enhanced with:

- A concise explanation in the comments and any documentation.
- For both uses, call a _single_ function which includes a parameter for the number of samples. This also ensures any future modifications ([software maintenance](https://en.wikipedia.org/wiki/Software_maintenance "Wikipedia: software maintenance")) to the code are applied to both.

# CLUE Metal Detector in CircuitPython

## ADC Analysis

![](https://cdn-learn.adafruit.com/assets/assets/000/090/610/medium800/sensors_Big-ben-1858.jpg?1587677048 The normal distribution, also known as a Bell Curve, is a favourite of statisticians. The image is an engraving of second Big Ben Bell from The Illustrated News of the World (1858).)

The CLUE and Circuit Playground Bluefruit boards both use the nRF52840 [System on a Chip (SoC)](https://en.wikipedia.org/wiki/System_on_a_chip "Wikipedia: system on a chip"). This includes an [analogue-to-digital converter (ADC)](https://infocenter.nordicsemi.com/index.jsp?topic=%2Fps_nrf52840%2Fsaadc.html "Nordic SemiConductor: nRF52 Series > nRF52840 > nRF52840 Product Specification > Peripherals: SAADC — Successive approximation analog-to-digital converter") using the [successive approximation](https://en.wikipedia.org/wiki/Successive_approximation_ADC "Wikipedia: successive approximation ADC") design. This is used in this project to measure the voltage across a capacitor. CircuitPython configures this ADC in 12bit mode making each bit equivalent to 0.806mV.

This page explores the consistency of the ADC and the distribution of noise to determine if an average value (arithmetic mean) over a certain number of samples is a valid approach to calculate an accurate voltage.

## Voltage across Capacitor in the Metal Detector

The graph below shows 1000 successive samples from the same function used in the program.

![](https://cdn-learn.adafruit.com/assets/assets/000/090/611/medium800/sensors_md100nFcap4-samples-fitted-lines.png?1587677372)

The samples are shown as dots which grow in size and are coloured relative to their distance from a fitted (straight) **line**. This visualisation appears useful in confirming:

- most values are near the line,
- the distribution looks fairly even above and below the line(s),
- a few values are _significantly_ above or below the line but these also look reasonably evenly distributed either side for this number of samples.

A second **weighted line** is also shown - this is a refinement created by weighting the points based on their distance from the first line on a scale of 4 to 1. This reduces the large effect that [outliers](https://en.wikipedia.org/wiki/Outlier "Wikipedia: outlier") have using the [least squares](https://en.wikipedia.org/wiki/Least_squares "Wikipedia: least squares") approach to line fitting. There's only a 0.2mV difference between this potentially more accurate line's arithmetic mean value and the samples suggesting a basic, quick-to-calculate mean value gives a voltage with good accuracy. If the sampling was reduced to, say 50 samples (over 2.4ms), then this looks more risky for an outlier having a pronounced, adverse effect on the calculated mean voltage.

The **curve** fitting is an unnecessary leftover from when this graphing analysis code was used previously on a capacitor _discharging_. In this case the capacitor is charging and discharging at a 400kHz rate. The samples here have been gathered over ~47ms which covers over 18 thousand charge cycles. This means the voltage will be largely constant with a miniscule amount of ripple.

In this case, it's possible these outliers are genuine but it seems unlikely that the voltage is really jumping around because the:

1. difference is so great,
2. there's not an obvious "trail" of dots joining the spikes and
3. there's a capacitor involved.

The use of weighting for this analysis means they are not ignored, just downplayed based on the previous justification. [Statistics by Jim](https://statisticsbyjim.com/ "Statistics by Jim (Frost)") has a useful guide on distinguishing [outliers](https://statisticsbyjim.com/basics/outliers/ "Statistics by Jim: 5 Ways to Find Outliers in Your Data") and [deciding what to do with them](https://statisticsbyjim.com/basics/remove-outliers/ "Statistics by Jim: Guidelines for Removing and Handling Outliers in Data"). Discarding inconvenient results is not a good justification!

This is a zoomed-in look at the lines. The scale exaggerates the tiny gradient. The discrete ADC levels from 12bit sampling can be see with the clearly defined rows of samples.

The [P-P plot](https://en.wikipedia.org/wiki/P%E2%80%93P_plot "Wikipedia: P-P plot") and [Q-Q plot](https://en.wikipedia.org/wiki/Q%E2%80%93Q_plot "Wikipedia: Q-Q plot") are common plots for visually comparing the data to another distribution, in this case the normal distribution. A matching distribution will overlap the straight line.

The histogram here is more of a bar chart as it's carefully aligned with the quantized sample values. _Only the central portion_ of values is shown on this bar chart. This could show any ADC peculiarities particularly with more graphs of samples. There's nothing that jumps out as concerning here.

![sensors_md100nFcap4-samples-fitted-lines-zoom.png](https://cdn-learn.adafruit.com/assets/assets/000/090/620/medium640/sensors_md100nFcap4-samples-fitted-lines-zoom.png?1587678060)

![sensors_md100nFcap4-fitted-line-residuals-pp.png](https://cdn-learn.adafruit.com/assets/assets/000/090/621/medium640/sensors_md100nFcap4-fitted-line-residuals-pp.png?1587678091)

![sensors_md100nFcap4-fitted-line-residuals-qq.png](https://cdn-learn.adafruit.com/assets/assets/000/090/622/medium640/sensors_md100nFcap4-fitted-line-residuals-qq.png?1587678100)

![sensors_md100nFcap4-central-samples.png](https://cdn-learn.adafruit.com/assets/assets/000/090/623/medium640/sensors_md100nFcap4-central-samples.png?1587678184)

The choice of bucket size (width) for a histogram can have a large effect on the visual representation of the data. If the data is quantised in some way then this effect can be more pronounced. Checking and presenting varying bucket sizes is one way to avoid creating misleading charts. The animated graph below shows different bucket sizes across the full range of sample values (voltages) with the data presented with the mean subtracted making the central voltage 0mV.

![](https://cdn-learn.adafruit.com/assets/assets/000/090/615/medium800thumb/sensors_md100nFcap4-fitted-line-residuals-histogram.jpg?1587677872)

A steady voltage reference source like a battery is a better test to look at the ADC. The [results for two 1000 sample runs against an old alkaline AAA battery](https://github.com/kevinjwalters/mini-projects/tree/master/clue-metal-detector/results/alkalinecell "GitHub: kevinjwalters/mini-projects clue-metal-detector/results/alkalinecell") are very similar to the graphs above.

These tests were all conducted with the CLUE board powered by USB power from a desktop computer. Some further testing would be useful, like:

1. Powering the CLUE from battery power with USB power removed to examine any adverse effects on the ADC from noise on the power supply.
2. Comparing multiple CLUE boards and other boards based on the nRF52840.
3. Checking the distribution on the samples when measuring **GND** and **3.3V**.
4. Checking different ADC acquisition times - this requires use of C++/Arduino.
5. Comparing software over-sampling with nRF52840 hardware over-sampling - this requires use of C++/Arduino.
6. Looking at the sample data in the frequency domain to look for any periodic peculiarities. This will be imperfect as the code in CircuitPython is not taking samples at a precise rate and the [jitter](https://en.wikipedia.org/wiki/Jitter "Wikipedia: jitter") will muddy everything except the very low frequencies.

# CLUE Metal Detector in CircuitPython

## Going Further

## Ideas for Areas to Explore

- Vary the coil size and windings to see how this affects the sensitivity.
- Improve the magnetometer value as it currently only makes use of the **z** dimension.
- Add a recent peak feature to the voltage bar graph and magnetometer circle.
- If you are using the CPB without a screen:
  - Add some audio cues as time passes when the left button is depressed to give an indication of the current menu option.
  - Conditionally disable the screen update code for a faster main loop or for better voltage stability from increased sampling. The TFT Gizmo screen is not designed to be detectable but the approach outlined in [Adafruit Forums: Is it possible to detect presence of Gizmo?](https://forums.adafruit.com/viewtopic.php?f=19&t=165042 "Adafruit Forums: Is it possible to detect presence of Gizmo?") is likely to work.

## Related Projects

- [Adafruit Learn: Wireless Inductive Power Night Light](https://learn.adafruit.com/wireless-inductive-power-night-light "Adafruit Learn: Wireless Inductive Power Night Light")
- [Adafruit Learn: Cell Phone Charging Purse](https://learn.adafruit.com/cell-phone-charging-purse "Adafruit Learn: Cell Phone Charging Purse")
- [Adafruit Learn: Babel Fish](https://learn.adafruit.com/babel-fish "Adafruit Learn: Babel Fish") - RFID language learning toy with sound.
- [Adafruit Learn: Unlock Android Phone with Wearable NFC](https://learn.adafruit.com/unlock-android-with-wearable-nfc "Adafruit Learn: Unlock Android Phone with Wearable NFC")
- [Adafruit Learn: Portal Apple Watch Charger](https://learn.adafruit.com/portable-apple-watch-charger "Adafruit Learn: Portal Apple Watch Charger")
- [Adafruit Blog: How to Build Your Own Metal Detector](https://blog.adafruit.com/2015/07/20/how-to-build-your-own-metal-detector/ "Adafruit Blog: How to Build Your Own Metal Detector") - a project on Instructables which uses a portion of a [Dotstar strip](https://www.adafruit.com/product/2241 "Adafruit DotStar Digital LED Strip - Black 144 LED/m - One Meter - BLACK") to indicate finds.

## Further Reading

- TDK:
  - [Electronics ABC: Inductors](https://www.tdk.com/tech-mag/electronics_primer/1 "TDK Corporation: Electronics ABC: Inductors")
  - [The Wonders of electromagnetism](https://www.tdk.com/tech-mag/inductive/001 "TDK Corporation: The Wonders of electromagnetism ")
  - [Ferrite World](https://www.tdk.com/tech-mag/ferrite02/001 "TDK Corporation: Ferrite World ")

- [UniServeScienceVIDEO: 2D Magnetic Field Demonstrations Simple Wire Coils](https://www.youtube.com/watch?v=V-M07N4a6-Y "YouTube: UniServeScienceVIDEO: PH EM MF DEMO 70001A V1025 2D Magnetic Field Demonstrations Simple Wire Coils") (YouTube) - shows the magnetic field patterns around different types of coils.
- [EEWeb Inductor Calculator](https://www.eeweb.com/tools/coil-inductance "EEWeb Inductor Calculator")
- [Digi-Key: Protecting Inputs in Digital Electronics](https://www.digikey.com/en/articles/protecting-inputs-in-digital-electronics "Digi-Key: Protecting Inputs in Digital Electronics ")
- [Adafruit Learn: Power Supplies](https://learn.adafruit.com/power-supplies "Adafruit Learn: Power Supplies") - talks about how transformers work.
- [Adafruit Learn: Collin's Lab: RFID](https://learn.adafruit.com/collins-lab-rfid/transcript "Adafruit Learn: Collin's Lab: RFID") (YouTube and transcript)
- [Adafruit Learn: Choosing an ADC](https://learn.adafruit.com/choosing-an-adc "Adafruit Learn: Choosing an ADC") - describes internal architecture, operation and imperfections of analogue-to-digital converters.
- [Analog Devices: Which ADC Architecture Is Right for Your Application?](https://www.analog.com/en/analog-dialogue/articles/the-right-adc-architecture.html "Analog Devices: Which ADC Architecture Is Right for Your Application?")
- [Adafruit: Circuit Playground: N is for Noise](https://www.youtube.com/watch?v=_zYT66uEMIQ "YouTube: Adafruit: Circuit Playground: N is for Noise") (YouTube)
- [Andreas Spiess: How good are the ADCs inside Arduinos, ESP8266, and ESP32? And extenal ADCs (ADS1115)](https://www.youtube.com/watch?v=UAJMLTzrM9Q "YouTube: Andres Spiess: #340 How good are the ADCs inside Arduinos, ESP8266, and ESP32? And extenal ADCs (ADS1115)") (YouTube) -&nbsp; a look at how ADCs work.
- [Adafruit SensorLab - Magnetometer Calibration](https://learn.adafruit.com/adafruit-sensorlab-magnetometer-calibration "Adafruit Learn: Adafruit SensorLab - Magnetometer Calibration")
- [Huygens Optics: Metal detector target discrimination explained](https://www.youtube.com/watch?v=EcuTsifSgBs "Huygens Optics: Metal detector target discrimination explained (with a Garret AT Pro)") (YouTube) - explains the double-D coil design and the discrimination by phase and has some examples of different types of magnetic material. Featured on [Hackaday: Progressive or Thrash: How Metal Detectors Discriminate](https://hackaday.com/2019/11/26/progressive-or-thrash-how-metal-detectors-discriminate/ "Hackaday: Progressive or Thrash: How Metal Detectors Discriminate").
- [David Hughes: On an induction-currents balance, and experimental researches made therewith (1879)](https://royalsocietypublishing.org/doi/abs/10.1098/rspl.1879.0012 "Royal Society: David Hughes: On an induction-currents balance, and experimental researches made therewith (1879)") - one of the earliest metal detectors.
- [Duuuani, Boxall, Purvis, Madge, Banerjee: A Pulse Induction Metal Detector (2006?)](http://users.cecs.anu.edu.au/~Salman.Durrani/_teaching/TA5.pdf "Australia National University: Duuuani, Boxall, Purvis, Madge, Banerjee: A Pulse Induction Metal Detector (2006?)") - a university project constructing a metal detector.
- [EEVblog #714 - Metal Detector Reverse Engineering](https://www.youtube.com/watch?v=RqB93K47Phg "YouTube: EEVblog: #714 - Metal Detector Reverse Engineering") (YouTube) - circuit analysis of an inexpensive, hand-held detector.
- [Applied Science: How anti-theft tags work - magnetostriction](https://www.youtube.com/watch?v=KAm7qAKAXwI "YoutTube: Applied Science: How anti-theft tags work - magnetostriction") (YouTube) - a very good demonstration of acousto-magnetic tags.
- [Lecture 20: Inductance and RL Circuit | 8.02 Electricity and Magnetism, Spring 2002 (Walter Lewin)](https://www.youtube.com/watch?v=PMTOVRyPLOI "YouTube: For the Allure of Physics: Lecture 20: Inductance and RL Circuit | 8.02 Electricity and Magnetism, Spring 2002 (Walter Lewin)") (YouTube) - a university lecture on inductance, very detailed but mostly theoretical, demonstrations at 28:56 and 49:20.
- [Professor Eric Laithwaite: Magnetic River 1975](https://www.youtube.com/watch?v=OI_HFnNTfyU "Imperial College London: Professor Eric Laithwaite: Magnetic River 1975") - a practical look at electromagnetism and [magnetic levitation (maglev)](https://en.wikipedia.org/wiki/Magnetic_levitation "Wikipedia: magnetic levitation").
- [Physics Girl: Why outlets spark when unplugging - EMF and Inductors](https://www.youtube.com/watch?v=g1Ld8D2bnJM "YouTube: Physics Girl: Why outlets spark when unplugging - EMF and Inductors") (YouTube) - demonstration and explanation of arcing due to back EMF from very large inductor, plus brief reference to another video on oxygen's paramagnetism.


## Featured Products

### Adafruit CLUE - nRF52840 Express with Bluetooth® LE

[Adafruit CLUE - nRF52840 Express with Bluetooth® LE](https://www.adafruit.com/product/4500)
Do you feel like you just don't have a CLUE? Well, we can help with that - get a CLUE here at Adafruit by picking up this sensor-packed development board. We wanted to build some projects that have a small screen and a lot of sensors. To make it compatible with existing projects, we made...

In Stock
[Buy Now](https://www.adafruit.com/product/4500)
[Related Guides to the Product](https://learn.adafruit.com/products/4500/guides)
### Adafruit DragonTail for micro:bit - Fully Assembled

[Adafruit DragonTail for micro:bit - Fully Assembled](https://www.adafruit.com/product/3695)
Sometimes I dream of having a miniature pet dragon that would sit on my shoulder, while I write code and build projects. Maybe its little snorts of fire could even heat up my soldering iron after I turn it on? An adorable fantasy, I know... So while we're all waiting for genetic...

In Stock
[Buy Now](https://www.adafruit.com/product/3695)
[Related Guides to the Product](https://learn.adafruit.com/products/3695/guides)
### USB cable - USB A to Micro-B

[USB cable - USB A to Micro-B](https://www.adafruit.com/product/592)
This here is your standard A to micro-B USB cable, for USB 1.1 or 2.0. Perfect for connecting a PC to your Metro, Feather, Raspberry Pi or other dev-board or microcontroller

Approximately 3 feet / 1 meter long

Out of Stock
[Buy Now](https://www.adafruit.com/product/592)
[Related Guides to the Product](https://learn.adafruit.com/products/592/guides)
### Circuit Playground Bluefruit - Bluetooth® Low Energy

[Circuit Playground Bluefruit - Bluetooth® Low Energy](https://www.adafruit.com/product/4333)
 **Circuit Playground Bluefruit** is our third board in the Circuit Playground series, another step towards a perfect introduction to electronics and programming. We've taken the popular Circuit Playground Express and made it even better! Now the main chip is an nRF52840...

Out of Stock
[Buy Now](https://www.adafruit.com/product/4333)
[Related Guides to the Product](https://learn.adafruit.com/products/4333/guides)
### STEMMA JST PH 2mm 3-Pin to Male Header Cable - 200mm

[STEMMA JST PH 2mm 3-Pin to Male Header Cable - 200mm](https://www.adafruit.com/product/3893)
This cable will let you turn a JST PH 3-pin cable port into 3 individual wires with high-quality 0.1" male header plugs on the end. We're carrying these to match up with our Hallowing, for extending and connecting sensors or LEDs - and the wires are even color coded!

<a...></a...>

In Stock
[Buy Now](https://www.adafruit.com/product/3893)
[Related Guides to the Product](https://learn.adafruit.com/products/3893/guides)
### 3 x AAA Battery Holder with On/Off Switch and 2-Pin JST

[3 x AAA Battery Holder with On/Off Switch and 2-Pin JST](https://www.adafruit.com/product/727)
This battery holder connects 3 AAA batteries together in series for powering all kinds of projects. We spec'd these out because the box is slim, and 3 AAA's add up to about 3.3-4.5V, a very similar range to Lithium Ion/polymer (Li-Ion) batteries and have an on-off switch. That makes...

In Stock
[Buy Now](https://www.adafruit.com/product/727)
[Related Guides to the Product](https://learn.adafruit.com/products/727/guides)
### Alkaline AAA batteries - 3 pack

[Alkaline AAA batteries - 3 pack](https://www.adafruit.com/product/3520)
Battery power for your portable project! These batteries are good quality at a good price, and work fantastic with any of the kits or projects in the shop that use AAA's. This is a pack of **3 AAA batteries**.  
  
These batteries are Alkaline (MnO2) chemistry, with a...

In Stock
[Buy Now](https://www.adafruit.com/product/3520)
[Related Guides to the Product](https://learn.adafruit.com/products/3520/guides)
### Through-Hole Resistors - 1.0K ohm 5% 1/4W - Pack of 25

[Through-Hole Resistors - 1.0K ohm 5% 1/4W - Pack of 25](https://www.adafruit.com/product/4294)
ΩMG! You're not going to be able to resist these handy resistor packs!&nbsp;Well, axially, they&nbsp;do all of the resisting for you!

This is a **25 Pack of 1.0KΩ Resistors.** More specifically, they are **carbon film** , through-hole...

In Stock
[Buy Now](https://www.adafruit.com/product/4294)
[Related Guides to the Product](https://learn.adafruit.com/products/4294/guides)

## Related Guides

- [Adafruit Circuit Playground Bluefruit](https://learn.adafruit.com/adafruit-circuit-playground-bluefruit.md)
- [Introducing Adafruit CLUE](https://learn.adafruit.com/adafruit-clue.md)
- [Sailor Moon Star Locket](https://learn.adafruit.com/sailor-moon-star-locket.md)
- [Easy No-Soldering Bluetooth Controlled Room Lights](https://learn.adafruit.com/easy-no-solder-bluetooth-controlled-room-lights.md)
- [PyLeap BLE Controlled NeoPixels with CLUE](https://learn.adafruit.com/pyleap-ble-controlled-neopixels-with-clue.md)
- [Now Playing: Bluetooth Apple Media Service Display](https://learn.adafruit.com/now-playing-bluetooth-apple-media-service-display.md)
- [TFT Gizmo Turtle](https://learn.adafruit.com/tft-gizmo-turtle.md)
- [PyLeap Touch NeoPixel Rainbow for Circuit Playground Bluefruit](https://learn.adafruit.com/pyleap-touch-neopixel-rainbow.md)
- [TFT Gizmo Animated Eye](https://learn.adafruit.com/tft-gizmo-animated-eye.md)
- [How to Fuse Motion Sensor Data into AHRS Orientation (Euler/Quaternions)](https://learn.adafruit.com/how-to-fuse-motion-sensor-data-into-ahrs-orientation-euler-quaternions.md)
- [LIS3MDL Triple-axis Magnetometer](https://learn.adafruit.com/lis3mdl-triple-axis-magnetometer.md)
- [Circuit Playground Bluefruit Pumpkin with Lights and Sounds ](https://learn.adafruit.com/pumpkin-with-circuit-playground-bluefruit.md)
- [CLUE Slim Case](https://learn.adafruit.com/clue-slim-case.md)
- [CLUE Vertical Garden Weather Visualizer](https://learn.adafruit.com/clue-vertical-garden-weather-visualizer.md)
- [DIY Quiz Show Controller System](https://learn.adafruit.com/quiz-show-controller-keyboard-bluetooth.md)
- [Bluefruit Luminary Lanterns with Capacitive Touch](https://learn.adafruit.com/bluefruit-luminary-lanterns-with-capacitive-touch.md)
- [Snow Globe with Circuit Playground Bluefruit](https://learn.adafruit.com/snow-globe-bluefruit-cpb.md)
