The Maze/Spring/2019

Controlling a Metal Detecting Sensor

Author/s: Alonso Quintero & Steven Charles Tan
Verification: Steven Charles Tan (Project Manager)
Approval: Steven Charles Tan (Project Manager)

# Introduction

The metal detecting sensor is Mainly influenced by Magnetic fields, or interruptions in Magnetic Fields. When the sensor comes in proximity with metal these interruptions in the magnetic field become strong enough to read.

# Setting up for a reading

The metal Sensor is composed of an inductor, a diode and a capacitor. In order to take a reading of the Magnetic field the inductor needs to be charged first. This is achieved through a series of pulses. Through many calculations and experiments, 100 pulses with a 20us period and a 50% duty cycle was found to be the optimal charging parameters. this allows the inductor to saturate giving the best resolution. On the falling edge of the last cycle is when the reading should be taken at the capacitor side. This reading will be the magnetic field, and this reading will be the one to drop when there is a disturbance i.e. metal under the inductor.

## Procedure for actually reading the sensor

```

/*
* starts a conversion
* does other stuff
* and is interrupted when values are ready
*
* Alonso Quintero 05/01/19
*/

//Sensor Variables
int npulse=100;
const int8_t inttime=10;
int8_t senstate=0;
int8_t sen[2]; //pin Register values
int8_t caps[2]; //input pins
int8_t pulses[2]; //output pins
int8_t pin_cap = A1;
int8_t pin_cap2 = A3; //3DoT
int8_t pin_pulse = A0;
int8_t pin_pulse2 = A2;
int diff; //difference between threhold and the average
int16_t threshold;
int16_t threshold2;
bool inter = false; // Boolean variable to indicate when the robot is in an intersection

//Running Average Variables
uint16_t total=0;
uint16_t total2=0;
const int samples=64;
int average = 0; // the average
int average2 = 0;

void initsen(){
caps[0] = pin_cap;
caps[1] = pin_cap2;
pulses[0] = pin_pulse;
pulses[1] = pin_pulse2;
pinMode(pin_pulse, OUTPUT);
pinMode(pin_cap, INPUT);
pinMode(pin_pulse2, OUTPUT);
pinMode(pin_cap2, INPUT);
for (int i = 0; i < samples; i++) {
}
}

sei(); //Global Interrupt
}
// Initialization
void setup(){
initsen();
Serial.begin(9600);
}

// Interrupt service routine for the ADC completion

runningaverage(senstate);
}
void pulsesen(){
/*Pulses Sensor 1 first for 50% of the pulses
* then it pulses the second sensor and the first at the same
* time and then takes the reading of the first sensor.
* then it pulses the second sensor. and reads second sensor at the end.
*/
for (int ipulse = 0; ipulse < npulse*1.5; ipulse++) {
if(ipulse=npulse*0.5 && ipulse<npulse){ digitalwrite(pulses[0],high);="" digitalwrite(pulses[1],low);="" delaymicroseconds(inttime);="" digitalwrite(pulses[0],low);="" digitalwrite(pulses[1],high);="" }else="" if(ipulse="=npulse){" admux="" &="B11100000;" clears="" the="" pins="" |="sen[0];" sets="" pin="" adcsra="" starts="" conversion="" delaymicroseconds(40);="" pinmode(caps[0],output);="" digitalwrite(caps[0],low);="" delaymicroseconds(20);="" pinmode(caps[0],input);="">npulse){
digitalWrite(pulses[1],HIGH); //takes 3.5 microseconds
delayMicroseconds(inttime);
digitalWrite(pulses[1],LOW);
delayMicroseconds(inttime);
}
}
ADMUX &= B11100000; // clears the pins
ADMUX |= sen[1]; // sets the pin
ADCSRA |= B01000000; // starts the conversion
delayMicroseconds(40);
pinMode(caps[1],OUTPUT);
digitalWrite(caps[1],LOW);
delayMicroseconds(20);
pinMode(caps[1],INPUT);
}
int runningaverage(uint16_t whichsen){
if (whichsen == 0){
// calculate the average:
average = total / samples;
senstate = 1;
} else if(whichsen==1){
average2 = total2 / samples;
senstate = 0;
}
// if we're at the end of the array...
// ...wrap around to the beginning:
}
}
for (int a = 0; a<101;a++){
pulsesen();
delay(10);
}
threshold = average-3;
threshold2 = average2-3;
Serial.println();
Serial.print(threshold);
Serial.println();
Serial.print(threshold2);
}
</npulse){>```

# Some issues that were encountered

The sensors now are configured such that the sensors are being pulsed almost at the same time. one sensor is pulsed for half the total sample duration, if the number of pulses is 100 then the first sensor is pulsed for 50 pulses first, then both sensors are pulsed at opposite intervals for another half. Finally, the second sensor is pulsed for the remaining half while the first sensor is being read, the second sensor will be read at the end of its pulsing. It was configured this way due to the following issues found when both sensors were pulsed at the same time.

1. The voltage dropped for both sensors as they were pulling too much current for the controller to be able to maintain a steady voltage. this meant a loss in resolution and an inaccuracy in the readings.
2. The first part was remedied by alternating the pulsing such that they were only staggered by half a period (10us). This, however, came with its own issue of once the sensors were done, the ADC could only read one sensor at a time. One sensor, therefore, would be discharging for the 200us it takes the ADC to convert the first reading. This lead to one sensor showing a reading lower than the first sensor, Which was not too bad except for the fact that the robot was now slower at responding on the second sensor’s side. This led to the robot veering off course or not updating the second readings fast enough and getting confused thinking it was at an intersection.

The second issue was remedied by implementing the current procedure. as shown in the figure below.

# Conclusion

This Sensor is able to detect a thin line of copper wire fairly accurately. It detects the copper well enough to follow it and stay on course. The sensors were not able to be run simultaneously but rather staggered enough to complete at least one reading before the next sensor is ready to be read.