There are different situations when you need to know if there are any metal objects hidden somewhere, it could be you want to drive a nail into the wall or you are going out to search your keys that you lost somewhere in the grass.
The magnetic field generated by a coil will be affected by metal objects nearby. In this project we will use the output of an Arduino to produce such a field, then shut off the current and read the voltage that gets induced.
You can use any kind of coil given the amount of windings should be some hundred and the resistance is below 1 kohm. At any rate the voltage divider must be adjusted properky.
As that pulse will be very short, we need some tricks to get enough samples to be evaluated.
- reduce ADC resolution to get faster readings
- do not use for-loops to avoid the time spent for incrementing an index and accessing an array variable.
The diagram shows the readings (red), left with some metal inside the coil and right after removing the metal. (The blue line indicates the gate time.) As can be seen, after switching off the current we get a very short negative pulse. For better evaluation, the last value is getting extended until the next pulse is sent to the coil.
As the pulse will be negative, you must not connect the cold end of the coil to ground but to a voltage divider. The resistor values you have to use depend on the resistance of the coil you are using.
If you want to use this device outdoors and not connected to a computer, you better add LEDs or a speaker to indicate what results you got.
But do not expect too much; the sensitivity of such a simple device is rather poor.
[code]
/*
reading the self induction when switching-off a coil
the second line indicates the gate time
Hardware:
To adjust the DC offset you need a
voltage divider using two resistors:
| +Vcc
+-+
| |
| | 47 ohms
| |
+-+
| the coil
+-----^^^^^^^^------A0
|
+-+
| |
| | 2.2 kohms
| |
+-+
| GND
*/
char ofs1[] = "10 ";
char ofs2[] = "-10 ";
void setup() {
Serial.begin(115200);
digitalWrite(A0, HIGH);
ADCSRA = B10000000 + 1;
}
void loop() {
pinMode(A0, OUTPUT);
delay(1);
/*
pinMode(A0, INPUT);
unfortunately, pinMode is too slow,
the response pulse is completely lost
*/
DDRC = 0;
// no for-loop to get faster readings:
int x00 = analogRead(A0);
int x01 = analogRead(A0);
int x02 = analogRead(A0);
int x03 = analogRead(A0);
int x04 = analogRead(A0);
int x05 = analogRead(A0);
int x06 = analogRead(A0);
int x07 = analogRead(A0);
int x08 = analogRead(A0);
int x09 = analogRead(A0);
int x10 = analogRead(A0);
int x11 = analogRead(A0);
int x12 = analogRead(A0);
int x13 = analogRead(A0);
int x14 = analogRead(A0);
int x15 = analogRead(A0);
int x16 = analogRead(A0);
int x17 = analogRead(A0);
int x18 = analogRead(A0);
int x19 = analogRead(A0);
int x20 = analogRead(A0);
Serial.print(ofs1); Serial.println(x00);
Serial.print(ofs1); Serial.println(x01);
Serial.print(ofs1); Serial.println(x02);
Serial.print(ofs1); Serial.println(x03);
Serial.print(ofs1); Serial.println(x04);
Serial.print(ofs1); Serial.println(x05);
Serial.print(ofs1); Serial.println(x06);
Serial.print(ofs1); Serial.println(x07);
Serial.print(ofs1); Serial.println(x08);
Serial.print(ofs1); Serial.println(x09);
Serial.print(ofs1); Serial.println(x10);
Serial.print(ofs1); Serial.println(x11);
Serial.print(ofs1); Serial.println(x12);
Serial.print(ofs1); Serial.println(x13);
Serial.print(ofs1); Serial.println(x14);
Serial.print(ofs1); Serial.println(x15);
Serial.print(ofs1); Serial.println(x16);
Serial.print(ofs1); Serial.println(x17);
Serial.print(ofs1); Serial.println(x18);
Serial.print(ofs1); Serial.println(x19);
Serial.print(ofs1); Serial.println(x20);
for (int i = 0; i < 40; i++) {
Serial.print(ofs2);
Serial.println(x20);
}
delay(800);
}
[/code]
As you can see, 21 samples are read as fast as possible one after the other to be printed somewhat later. The for-loop at the end gives only some distance of the readings on the Serial plotter.
Comments
Please log in or sign up to comment.