DIY -Spirit PI- ESP32 + Smartphone Sensitive Metal Detector

A sensitive metal detector which is a great example of cooperation between a microcontroller and an Android smartphone.

Pulse Induction (PI) metal detector operates on a principle based on sending short pulses of electrical current through a coil to create a magnetic field. This pulse lasts for a very short period, usually microseconds. When the pulse is transmitted, the magnetic field spreads outward from the coil. If there is a metal object near the coil, it disrupts this magnetic field. The coil then detects the change in the magnetic field caused by the metal object, and that results in a reflected pulse which is different from the normal pulse.

This difference is processed and emitted in the form of a sound or short beeps, with a frequency that changes depending on the distance and dimensions of the detected metal object. In several of my previous videos, I presented ways to make such a metal detector, including one very similar, with an Arduino Nano microcontroller. This time the device uses a more powerful ESP32 microcontroller board that also contains built-in Bluetooth, so now the construction is even simpler.

The creator of the original project is Neco Desarrollo and you can find other great projects on the given page. His idea of ​​symbiosis between a microcontroller and a Smartphone is ingenious. The microcontroller easily accepts and transmits signals from an external electronic circuit, and the smartphone is a powerful tool for processing, as well as audiovisual presentation of the results.

This project is sponsored by PCBWay . This year, PCBWay is organizing the 11th badge design contest from March 3rd to April 31st. Follow the design requirements and Submit your designs in one of the given ways, and become the winner of one of the valuable prizes in cash and cupons. This contest is more than a competition—it’s a celebration of 11 years of innovation and a chance to dream about the boundless possibilities ahead with PCBWay.

The input circuit is almost identical in all PI metal detectors and consists of the following components:
- A search coil consisting of 20 turns of insulated copper wire with a cross section of 0.4mm^2 , in the form of a circle with a diameter of 20cm.
- An operational amplifier IC, I specifically use the TL081, but the circuit worked almost identically with OP07, LM741, and CA3130 IC's.
- A power MOSFET with one or two driver transistors. In this case IRF740 , BC547 and BC557 but approximate replacements can be used
- A 7805 voltage stabilizer to power the microcontroller
- And several resistors, capacitors, and diodes.

The input circuit is almost identical in all PI metal detectors and consists of the following components:
- A search coil consisting of 20 turns of insulated copper wire with a cross section of 0.4mm^2 , in the form of a circle with a diameter of 20cm.
- An operational amplifier IC, I specifically use the TL081, but the circuit worked almost identically with OP07, LM741, and CA3130 IC's.
- A power MOSFET with one or two driver transistors. In this case IRF740 , BC547 and BC557 but approximate replacements can be used
- A 7805 voltage stabilizer to power the microcontroller
- And several resistors, capacitors, and diodes.

After this, the Android application will work normally and we can start testing. First, let me explain how the application works. After the first start, we go to setup and select the metal detector version Spirit PI. Then we go to Bluetooth settings and select ESP32-Spirit PI-2 and go back.

Now I press the refresh button and from this moment the device is ready to work. The interesting fact is that we can very easily change the values ​​for the generated frequency and duty cycle, obtaining different performances depending on whether we want to detect massive or small metal objects.
Next, let's use an oscilloscope to trace the shape and changes of the signal that we bring to the input of the microcontroller for further analysis.
Here's how it should look at the beginning, and now by bringing a metal object closer to the search coil, the amplitude and duty cycle of the signal change.

This change is detected by the microcontroller and transmitted via Bluetooth to the smartphone, which then gives an audio and visual notification.
Now let's see how the detector reacts in approximately realistic conditions in the air, keeping in mind that the detection distance is significantly reduced on the ground.
As for the performance of this metal detector, you can notice that they are almost identical to those of the previously presented metal detector with Arduino Nano, taking into account that they largely depend on the Android application, which in both cases is practically the same.
And finally, a short conclusion: This is a great example of cooperation between a microcontroller that receives data from an external circuit and partially processes it, and an Android smartphone. This ingenious idea by Neco Desarrollo has huge potential not only in this area, but in many other devices in general, considering that nowadays we all own a smartphone that has incredibly high processing power.

CODE
#include "EEPROM.h"
#include "BluetoothSerial.h"
#if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)
#error Bluetooth is not enabled! Please run `make menuconfig` to and enable it
#endif
BluetoothSerial SerialBT;
#define EEPROM_SIZE 64
#define pulsePine 13

#define analogPin A0
#define batLevPin A7
int timer = 200;
bool clientConnected = true;

char dataG;
//**************IMPORTANT*******************
//******************************************
const int delayTime = 60;
//*****************************************
//*****************************************
//EEPROM variables
int addr_duty = 0;
int addr_freq = 1;
int stored_value;
int duty_cycle;
int duty_cycle_temp;
int freq;
int freq_temp;
int duty_def_value = 13;
int freq_def_value = 60;
//Balance variables
int value_count = 0;
int value_count_def = 100;
int balance_value = 0;
int balance_value_temp = 0;

//****
unsigned long startMillis;  
unsigned long currentMillis;
long period = 100000;  //the value is a number of microseconds
//Measuring of level of the battery
float resistencia1 = 100000; //Resistencia de 100K para medir la tencion (Voltios)/Resistance of 100k for test volts
float resistencia2 = 47000; //Resistencia de 47k para medir la tencion (Voltios)/Resistance 47k for test volts
float const arefVolt = 3.6f; //pin "3.3v" SET EXACT VALUE HERE
float voutv;
float vinv;
int raw_bat_data;
unsigned long startMillisVolts;  
unsigned long currentMillisVolts;
long periodVolts = 1000;  //the value is a number of microseconds
int sensorValue = 0.0f;



void setup() {
  SerialBT.begin("ESP32_Spirit_PI-2"); //Bluetooth device name
 Serial.begin(115200);
  SerialBT.register_callback(callback);
 
  if (!EEPROM.begin(EEPROM_SIZE))
  {
    Serial.println("failed to initialise EEPROM"); delay(1000000);
  }
 
    
 readFromStorage(addr_duty);
  duty_cycle = stored_value;
  readFromStorage(addr_freq);
  freq = stored_value;
  if(duty_cycle == 255){
    writeToStorage(duty_def_value,addr_duty);
    readFromStorage(addr_duty);
  duty_cycle = stored_value;
  }
 
  if(freq == 255){
    writeToStorage(freq_def_value,addr_freq);
     readFromStorage(addr_freq);
   freq = stored_value;
  }
  
 
 
 
  pinMode(pulsePine, OUTPUT);
   
 
}


void loop() { 
   
currentMillis = micros();
  currentMillisVolts = millis();  
 
   if(SerialBT.available()>0)
 {
  dataG =  SerialBT.read();
 setDutyAndFreq  (dataG);
 
}

 

  
if (currentMillis - startMillis >= period && clientConnected)
 {
   
  period = 1000000 / freq;
  // Serial.println(period);
 digitalWrite(pulsePine, HIGH);
 duty_cycle_temp = duty_cycle * 10;
 delayMicroseconds(duty_cycle_temp); 
digitalWrite(pulsePine, LOW);
 // sensorValue = analogRead(analogPin);
delayMicroseconds(delayTime);
sensorValue = analogRead(analogPin);
sensorValue = sensorValue / 10;

sendData();
 
   
startMillis = currentMillis;
 }
 // Lectura voltios
 if (currentMillisVolts - startMillisVolts >= periodVolts)
 {
lecturaVoltios();
//Serial.println("Lectura voltios");
startMillisVolts = currentMillisVolts;
 }
 
}      



 void writeToStorage(int valor,int addr)
 {
   EEPROM.write(addr, valor);
   EEPROM.commit();
     
 
 }
 int readFromStorage(int addr)
 {
    stored_value = EEPROM.read(addr);

  return stored_value;
 
 }
 void setDutyAndFreq  (char valor)
 {
   //"n" valor para aumentar duty cycle
   //"m" valor para disminuir duty cycle
   //"j" valor para aumentar la frequencia
   //"k" valor para des,inuir la frequencia
   //"+" valor para aumentar el balance
   //"-" valor para desminuir el balance
   if(valor == 'n')
   {
    // Serial.println("n Recived");
      readFromStorage(addr_duty);
  duty_cycle = stored_value;
  duty_cycle = duty_cycle + 1;
  writeToStorage(duty_cycle,addr_duty);
  
   }
   else if(valor == 'm')
     {
      //  Serial.println("m Recived");
           readFromStorage(addr_duty);
  duty_cycle = stored_value;
  duty_cycle = duty_cycle - 1;
  writeToStorage(duty_cycle,addr_duty);
  
     }
     else if(valor == 'j')
     {
    //    Serial.println("j Recived");
          readFromStorage(addr_freq);
  freq = stored_value;
  freq = freq + 10;
  writeToStorage(freq,addr_freq);
  
     }
     else if(valor == 'k')
     {
     //   Serial.println("k Recived");
                  readFromStorage(addr_freq);
  freq = stored_value;
  freq = freq - 10;
  writeToStorage(freq,addr_freq);

     }
      else if(valor == 'p')
     {
      //  Serial.println("m Recived");
         
  writeToStorage(0,addr_freq);
  writeToStorage(0,addr_duty);
  
     }
    
   
 
 
 }
  //Volt function
void lecturaVoltios(){
  vinv=0.0f;
  voutv=0.0f;
   for (int i=0;i < 10;i++){
  
  voutv = (analogRead(batLevPin)  * arefVolt) / (4095);  //Lee el voltaje de entrada

  vinv += ( (resistencia1 + resistencia2)* voutv) / resistencia2 ;  //Fórmula del divisor resistivo para el voltaje final
  if(vinv < 0.9){
  vinv=0.0f;
  }
  


}
vinv = vinv/10;


}
void sendData()

  {
     /* Serial.print("<");
 Serial.print(sensorValue);
  Serial.print("/");
   Serial.print(freq);
    Serial.print("/");
     Serial.print( duty_cycle);
       Serial.print("/");
     Serial.print( vinv);
 Serial.print(">");
  Serial.println();*/
  String dataG = "<";
  dataG +=sensorValue;
  dataG +="/";
  dataG +=freq;
  dataG +="/";
  dataG +=duty_cycle;
  dataG +="/";
  dataG +=vinv;
  dataG +=">";
 /* bluetooth.print("<");
 bluetooth.print(sensorValue);
  bluetooth.print("/");
   bluetooth.print(freq);
    bluetooth.print("/");
    bluetooth.print( duty_cycle);
       bluetooth.print("/");
     bluetooth.print( vinv);
 bluetooth.print(">");*/
  SerialBT.println(dataG);
  Serial.println(dataG);
    }
    void callback(esp_spp_cb_event_t event, esp_spp_cb_param_t *param){
// Callback function implementation
 if(event == ESP_SPP_SRV_OPEN_EVT){
    Serial.println("Client Connected");
    clientConnected = true;
  }
 
  if(event == ESP_SPP_CLOSE_EVT ){
    Serial.println("Client disconnected");
  //  SerialBT.flush();
 // SerialBT.end();
 clientConnected = false;
 delay(1000);
  ESP.restart();
    
  }
}
License
All Rights
Reserved
licensBg
0