Manufactura industrial
Internet industrial de las cosas | Materiales industriales | Mantenimiento y reparación de equipos | Programación industrial |
home  MfgRobots >> Manufactura industrial >  >> Manufacturing Technology >> Proceso de manufactura

Detector de metales Arduino IB sensible al bricolaje con discriminación

Componentes y suministros

Arduino Nano R3
× 1
LCD estándar Adafruit - 16x2 blanco sobre azul
× 1
TL081 Amplificador operacional IC
× 1
Altavoz:0,25 W, 8 ohmios
× 1
Transistor de uso general NPN
× 1
Bobinas de búsqueda
× 2
Resistencias, condensadores
× 1

Aplicaciones y servicios en línea

Arduino IDE

Acerca de este proyecto

Esta vez te mostraré cómo hacer un detector de metales sensible que también sea capaz de discriminar entre materiales ferrosos y no ferrosos. La sensibilidad es satisfactoria, dado que es un dispositivo relativamente simple.

Este proyecto está patrocinado por PCBgogo:

https://www.pcbgogo.com/promo/from_MirkoPavleskiMK

Esta es una continuación del proyecto de David Crocker presentado en el Arduino CC Forum en 2013. Decidí probar su código porque no encontré ninguna evidencia (imagen o video) de que este detector de metales fue hecho por alguien y funciona bien.

Primero hice una versión básica con el código presentado en GitHub, para asegurarme de la funcionalidad del dispositivo y luego actualicé el código para que tenga una señal audible, y en una pantalla LCD de 16 en 2 información visual sobre el tipo de objeto detectado (material ferroso o no ferroso) y gráfico de barras LCD para la proximidad de los objetos detectados.

El dispositivo es muy simple de construir y consta de solo unos pocos componentes:

- Microcontrolador Arduino Nano

- Amplificador operacional (en mi caso LT1677, pero puedes usar TL081 o 741)

- Pocas resistencias y condensadores

- Pequeño transistor y altavoz

- Pantalla LCD

- 3 interruptores

- Potenciómetro

- Batería

- Y bobinas de búsqueda

Esta es una tecnología de detector de balance de inducción VLF (muy baja frecuencia) y contiene dos bobinas idénticas:bobina transmisora ​​y receptora. Al igual que con todos los detectores de equilibrio por inducción, el equilibrio de la bobina es muy crítico. El potenciómetro se usa para poner a cero el pequeño componente fuera de fase de 90 grados de la señal. (el componente en fase se anula ajustando la ubicación relativa de las bobinas en el estilo típico de detector IB). Cada una de las bobinas se enrolla en un cuerpo de 11 cm utilizando 64 vueltas de alambre de cobre esmaltado de 0,5 mm ^ 2 en forma de D, se envuelve con cinta adhesiva y se apantalla con papel de aluminio unido con alambre de cobre estañado (teniendo cuidado de dejar un pequeño espacio para que la pantalla no se comporta como un giro corto) y amarrarlos a una placa de plástico.

Primero necesitamos determinar la frecuencia de resonancia en paralelo del circuito de condensador de bobina primario usando una de las muchas calculadoras en línea. Lo medí con un osciloscopio, pero si se adhiere a las dimensiones dadas anteriormente, será exactamente 7,64 kHz, por lo que puede ingresar directamente el valor dado en el código. En el caso de otro valor de la frecuencia de resonancia, necesitamos hacer un cambio apropiado en el código en la cola:

#define TIMER1_TOP (249) // ajuste la frecuencia

Como puede ver en el video, los resultados son sorprendentemente buenos. Sin la presencia de un metal, el dispositivo es perfectamente estable. El rango es relativamente grande y, por ejemplo, se detecta una cubierta metálica con un diámetro de 15 cm a una distancia de más de 30 cm. Los objetos metálicos más grandes se detectan a distancias superiores a 40-50 cm. Podemos detectar una pequeña moneda a una distancia de 15 cm en el aire. Utilizo dos baterías de litio para la fuente de alimentación que están conectadas en serie (7,4 voltios) y este voltaje está conectado a la entrada Vin del Arduino. El consumo no supera los 20 mA, por lo que las baterías duran mucho tiempo. El video describe en detalle la construcción de todo el dispositivo.

Estos son solo resultados preliminares. Existe la posibilidad de mejorar significativamente la sensibilidad insertando un transistor MOSFET de potencia para impulsar la bobina Tx, pero lo probaré y lo presentaré en uno de los siguientes videos.

Código

  • Código Arduino
  • LcdBarGraph lib.
Código Arduino Arduino
 // Detector de metales por balance de inducción // Hacemos funcionar la CPU a 16MHz y el reloj ADC a 1MHz. La resolución de ADC se reduce a 8 bits a esta velocidad. // El temporizador 1 se usa para dividir el reloj del sistema por aproximadamente 256 para producir una onda cuadrada de 62,5 kHz. // Esto se usa para impulsar el temporizador 0 y también para activar las conversiones de ADC. // El temporizador 0 se usa para dividir la salida del temporizador 1 entre 8, dando una señal de 7.8125kHz para impulsar la bobina de transmisión .// Esto nos da 16 ADC ciclos de reloj para cada conversión de ADC (en realidad toma 13.5 ciclos), y tomamos 8 muestras por ciclo del voltaje de activación de la bobina. // El ADC implementa cuatro detectores sensibles a la fase a intervalos de 45 grados. Usar 4 en lugar de solo 2 nos permite cancelar el tercer armónico de la // frecuencia de la bobina. // El temporizador 2 se usará para generar un tono para el auricular o los auriculares. // Son posibles otras relaciones de división para el temporizador 1, desde aproximadamente 235 hacia arriba.// Cableado:// Conecte el pin digital 4 (alias T0) al pin digital 9 // Conecte el pin digital 5 a través de la resistencia a la bobina primaria y el condensador de sintonización // Conecte la salida del amplificador de recepción al pin analógico 0. Salida de recepción El amplificador debe estar sesgado a aproximadamente la mitad de la referencia analógica. // Cuando use alimentación USB, cambie la referencia analógica al pin de 3.3V, porque hay demasiado ruido en el riel de + 5V para obtener una buena sensibilidad. # include  #include  #define max_ampAverage 200LiquidCrystal lcd (6, 7, 10, 11, 12, 13); LcdBarGraph lbg (&lcd, 16, 0, 1); #define TIMER1_TOP (259) // puede ajustar esto para afinar la frecuencia para sintonizar la bobina (ver más arriba) #define USE_3V3_AREF (1) // establecer en 1 para ejecutar en un Arduino con alimentación USB, 0 para un incrustado atmega28p sin suministro de 3.3V disponible // Definiciones de pin digital // Pin digital 0 no usado, sin embargo, si estamos usando el puerto serial para depurar entonces es serial inputconst int debugTxPin =1; // pin de transmisión reservado para debuggingconst int encoderButtonPin =2; // botón codificador, también IN0 para despertar del modo de suspensión const int earpiecePin =3; // auricular, también conocido como OCR2B para generación de tonosconst int T0InputPin =4; const int coilDrivePin =5; const int LcdRsPin =6; const int LcdEnPin =7; const int LcdPowerPin =8; // Activación de la luz de fondo y la alimentación del LCDconst int T0OutputPin =9; const int lcdD4Pin =10; const int lcdD5Pin =11; // pines 11-13 también se utilizan para ICSPconst int LcdD6Pin =12; const int LcdD7Pin =13; // Definiciones de pines analógicos const int receptorInputPin =0; const int encoderAPin =A1; const int encoderBpin =A2; // Pines analógicos 3-5 no utilizado // Variables utilizadas solo por los bins ISRint16_t [4]; // bins utilizados para acumular lecturas de ADC, uno para cada una de las 4 fases uint16_t numSamples =0; const uint16_t numSamplesToAverage =1024; // Variables utilizadas por el ISR y fuera de él volátil int16_t promedios [4]; // cuando hemos acumulado suficientes lecturas en los contenedores, el ISR las copia aquí y comienza de nuevo volátil uint32_t ticks =0; // contador de ticks del sistema para cronometraje volátil bool sampleReady =false; // indica que la matriz de promedios se ha actualizado // Variables utilizadas solo fuera del ISRint16_t calib [4]; // valores (establecidos durante la calibración) que restamos del promedio volátil uint8_t lastctr; volátil uint16_t misses =0; // esto cuenta cuántas veces se ha ejecutado el ISR demasiado tarde. Debería permanecer en cero si todo está funcionando correctamente.const double halfRoot2 =sqrt (0.5); const double quarterPi =3.1415927 / 4.0; const double radianesToDegrees =180.0 / 3.1415927; // La muestra y retención de ADC ocurre 2 relojes ADC (=32 system relojes) después de que se establece el indicador de desbordamiento del temporizador 1 .// Esto introduce un ligero error de fase, que ajustamos en los cálculos. 5,0; // menor =mayor sensibilidad. 10 es casi utilizable con una bobina bien equilibrada. // El usuario podrá ajustar esto a través de un potenciómetro o codificador rotatorio.void setup () {lcd.begin (16, 2); // LCD 16X2 pinMode (encoderButtonPin, INPUT_PULLUP); digitalWrite (T0OutputPin, BAJO); pinMode (T0OutputPin, SALIDA); // pin de pulso del temporizador 1 utilizado para alimentar el temporizador 0 digitalWrite (coilDrivePin, LOW); pinMode (coilDrivePin, SALIDA); // salida del temporizador 0, onda cuadrada para impulsar la bobina de transmisión cli (); // Detiene el temporizador 0 que fue configurado por el núcleo Arduino TCCR0B =0; // detiene el temporizador TIMSK0 =0; // deshabilita la interrupción TIFR0 =0x07; // borrar cualquier interrupción pendiente // Configurar ADC para disparar y leer el canal 0 en el desbordamiento del temporizador 1 # if USE_3V3_AREF ADMUX =(1 <> 8); OCR1AL =(TIMER1_TOP / 2 y 0xFF); ICR1H =(TIMER1_TOP>> 8); ICR1L =(TIMER1_TOP y 0xFF); TCNT1H =0; TCNT1L =0; TIFR1 =0x07; // borra cualquier interrupción pendiente TIMSK1 =(1 <
 15000) * p =15000; } más {* p - =val; si (* p <-15000) * p =-15000; } if (ctr ==7) {++ numSamples; if (numSamples ==numSamplesToAverage) {numSamples =0; if (! sampleReady) // si la muestra anterior se ha consumido {memcpy ((void *) promedios, contenedores, tamaño de (promedios)); sampleReady =verdadero; } memset (bins, 0, sizeof (bins)); }}} bucle vacío () {while (! sampleReady) {} uint32_t oldTicks =ticks; if (digitalRead (encoderButtonPin) ==LOW) {// Botón de calibración presionado. Guardamos las salidas del detector de fase actual y las restamos de los resultados futuros. // Esto nos permite usar el detector si la bobina está ligeramente desequilibrada. // Sería mejor aprovechar varias muestras en lugar de tomar solo una. para (int i =0; i <4; ++ i) {calib [i] =promedios [i]; } sampleReady =false; Serial.print ("Calibrado:"); lcd.setCursor (0,0); lcd.print ("Calibrando ..."); para (int i =0; i <4; ++ i) {Serial.write (''); Serial.print (calib [i]); lcd.setCursor (0,1); lcd.print (''); lcd.print (calib [4]); lcd.print (""); } Serial.println (); } else {for (int i =0; i <4; ++ i) {promedios [i] - =calib [i]; } const doble f =200.0; // Masajee los resultados para eliminar la sensibilidad al 3er armónico y divida por 200 double bin0 =(promedios [0] + halfRoot2 * (promedios [1] - promedios [3])) / f; bin1 doble =(promedios [1] + halfRoot2 * (promedios [0] + promedios [2])) / f; bin2 doble =(promedios [2] + halfRoot2 * (promedios [1] + promedios [3])) / f; bin3 doble =(promedios [3] + halfRoot2 * (promedios [2] - promedios [0])) / f; sampleReady =falso; // hemos terminado de leer los promedios, por lo que el ISR puede sobrescribirlos de nuevo double amp1 =sqrt ((bin0 * bin0) + (bin2 * bin2)); doble amp2 =sqrt ((bin1 * bin1) + (bin3 * bin3)); doble ampAverage =(amp1 + amp2) /2.0; // La muestra / retención de ADC tiene lugar 2 relojes después del desbordamiento del temporizador double phase1 =atan2 (bin0, bin2) * radianesToDegrees + 45.0; doble fase2 =atan2 (bin1, bin3) * radianes a grados; si (fase1> fase2) {temperatura doble =fase1; fase1 =fase2; fase2 =temp; } double phaseAverage =((fase1 + fase2) /2.0) - PhaseAdjust; if (fase2 - fase1> 180.0) {if (faseAverage <0.0) {faseAverage + =180.0; } else {PhaseAverage - =180.0; }} // Para fines de diagnóstico, imprima los recuentos de contenedores individuales y las 2 ganancias y fases calculadas de forma independiente. Serial.print (fallas); Serial.write (''); if (bin0> =0.0) Serial.write (''); Serial.print (bin0, 2); Serial.write (''); if (bin1> =0.0) Serial.write (''); Serial.print (bin1, 2); Serial.write (''); if (bin2> =0.0) Serial.write (''); Serial.print (bin2, 2); Serial.write (''); if (bin3> =0.0) Serial.write (''); Serial.print (bin3, 2); Serial.print (""); Serial.print (amp1, 2); Serial.write (''); Serial.print (amp2, 2); Serial.write (''); if (fase1> =0.0) Serial.write (''); Serial.print (fase1, 2); Serial.write (''); if (fase2> =0.0) Serial.write (''); Serial.print (fase2, 2); Serial.print (""); // Imprime la amplitud y fase finales, que usamos para decidir qué (si acaso) hemos encontrado) if (ampAverage> =0.0) Serial.write (''); Serial.print (ampAverage, 1); Serial.write (''); lcd.setCursor (0,0); lcd.print (""); lcd.print (ampAverage); lcd.setCursor (0,1); lbg.drawValue (ampAverage, max_ampAverage); if (PhaseAverage> =0.0) Serial.write (''); Serial.print ((int) phaseAverage); // Decidir lo que hemos encontrado y decirle al usuario si (ampAverage> =umbral) {// Cuando se mantiene en línea con el centro de la bobina:// - los metales no ferrosos dan un cambio de fase negativo, p. Ej. -90 grados para cobre grueso o aluminio, una aceituna de cobre, -30 grados para aluminio delgado. // Los metales ferrosos dan un cambio de fase cero o un pequeño cambio de fase positivo. // Entonces diremos que cualquier cosa con un cambio de fase por debajo de -20 grados no es ferroso. if (phaseAverage <-20.0) {Serial.print ("No ferroso"); lcd.setCursor (0,0); lcd.print ("No feroz"); } else {Serial.print ("Ferroso"); lcd.setCursor (0,0); lcd.print ("Ferroso"); } float temp =ampAverage; int thisPitch =map (temp, 10, 200, 100, 1500); tono (3, thisPitch, 120); while (temp>
 umbral) {Serial.write ('!'); temp - =(umbral / 2); }} Serial.println (); } while (ticks - oldTicks <8000) {}} 
LcdBarGraph lib. C / C ++
 Sin vista previa (solo descarga). 

Esquemas


Proceso de manufactura

  1. Fácil detector de llanto para bebés con Raspberry Pi
  2. El reloj IV9 Numitron más simple de bricolaje con Arduino
  3. Juego de giroscopio Arduino con MPU-6050
  4. Detector de terremotos ADXL335 sensible al bricolaje
  5. Voltímetro de bricolaje con Arduino y una pantalla Nokia 5110
  6. MobBob:Robot Arduino DIY controlado por un teléfono inteligente Android
  7. Rueda de medición simple de bricolaje con codificador giratorio
  8. Medidor de IoT con Arduino, Yaler e IFTTT
  9. Monitor de calidad del aire para bricolaje con sensor Sharp GP2Y1010AU0F
  10. Contador Geiger de mano con Arduino Nano
  11. Juego DIY Arduino 1D Pong con tira de LED WS2812