YFM Arduino Pinpointer

YFM Arduino Pinpointer


YFM es un detector de metales pinpointer que utiliza el sistema de detección BOF.
es básicamente un oscilador LC como el que usa el famoso FM2 y un transistor extra para amplificar esa señal asi puede leerla arduino con la libreria freqcount.h que es capaz de leer la frecuencia con gran precisión.
el sisntema tambien puede fuincionar con otro tipo de osciladores LC como es el Colpitts. este es mas simple y mas sensible, pero en ocasiones fue menos estable.










Lista de materiales para YFM:

resistencias:
3- 10Khom.
1- 100hom.

condensador:
1- 33uF (codigo 333).

bobina:
barra de ferrita.
anambre de cobre esmaltado 0.34mm.

transistores:
1- 2n2222 o bc547, o cualquier NPN de uso general.
2- bc557, o cualquier PNP de uso general.

placa perforada de prototipos, o placa cobreada.


Código fuente para Arduino:

//Detector de metales YFM Pinpointer 2 tonos
// Hardware y software implementados por Hector Santos ("El yeti" en youtube) 
// https://yeti-lab.blogspot.com/
//YFM v1.2 AutoBalance 21/04/2020

// Entrada D5, Buzzer D12
#include <FreqCount.h>
// entrada en el pin 5
// Buzzer en el pin 12
int buff=0;
int frq=0;
int resta=0;
int sens=2; // sensibilidad
int autoBalance=0;
bool AB=true;

void setup() {
  pinMode (13,OUTPUT);
  pinMode (12,OUTPUT);
Serial.begin(9600);
FreqCount.begin(200); //nº ciclos de lectura de frecuencia
delay(100);

frq=FreqCount.read();
                       // Balance
  buff=frq;
  for(int i=0;i<5;i++){
    for(int i=0;i<10;i++){// genera tono
    digitalWrite(12,HIGH);
    delay(2);
    digitalWrite(12,LOW);
    delay(2);
      }
    delay(20);
    frq= FreqCount.read();
    if(frq != buff){i=0; buff=frq;}
    }
      for(int i=0;i<20;i++){ // Genera tono
    digitalWrite(12,HIGH);
    delay(1);
    digitalWrite(12,LOW);
    delay(1);
  }

}

void loop() {
 AB=true;
 frq = FreqCount.read();
  resta=buff-frq;

if(resta>sens){               // Metales ferrosos
  for(int i=0;i<10;i++){ // Genera tono
    digitalWrite(12,HIGH);
    delay(2);
    digitalWrite(12,LOW);
    delay(2);
  }
   delay(40-(constrain(resta*5,10,40)));
   AB=false; //para resetear el autobalance
  }
  
  else if(resta< -sens){        // Metales no-ferrosos
      resta=-resta;
        for(int i=0;i<20;i++){// genera tono
    digitalWrite(12,HIGH);
    delay(1);
    digitalWrite(12,LOW);
    delay(1);
      }
      delay(40-(constrain(resta*5,10,40))); 
      AB=false; //para resetear el autobalance

}
//Serial.print(resta);
//Serial.print("---------");
//Serial.println(buff);

if(true){                     // auto Balance
  digitalWrite(13,HIGH);
  if(AB && resta !=0){   
    if(autoBalance>1000){autoBalance=0; buff=frq;}
    autoBalance++;
    }else autoBalance=0;
 delay(1);
}
}

Comentarios

  1. Olá amigo. Você pode me mostrar como ligar o arduino no Circuito?

    ResponderEliminar
    Respuestas
    1. Olá amigo. Gostei muito desse projeto. Montei ele de novo.Estou usando o arduíno nano.instalei o código ele carrega mais não funciona.Voce poderia me ajudar?/

      Eliminar

  2. Me alegra mucho de ver que todavía quedan jóvenes que en lugar de hacer botellón, se dedican a cosas como ésta.
    Yo quería hacer algo parecido, pensaba que lo había inventado yo, pero parece que no. :)
    TEngo pensadas algunas mejoras. por ejemplo sería interesante controlar la amplitud ya que ésta varía con la proximidad de objetos metálicos. La idea es que se vaya autocalibrando siempre, hasta que la amplitud varíe y en ese momento centrarse en el objeto metálico. igual incluso podríamos pasar de la frecuencia y basarnos sólo en la amplitud. falta hacer pruebas. Eso daría posibilidades infinitas, como incluso usar un timer del propio arduino. Por curiosidad te comento que no entiendo ese if(true), eso es lo mmismo que no poner el if. Saludos.

    ResponderEliminar
    Respuestas
    1. El if(true) está porque quizás en un futuro pongo un botón que al pulsarlo ponga "false", así apoder activar o desactivar el autoajuste.
      Quieres detectar por amplitud, con éste oscilador no podrás ver bien la amplitud, quizás con un colpitts, que también funciona bien

      Eliminar
    2. Uno de los que más varía la amplitud de los que he probado es el Amstrong. Lo malo es que necesita dos devanados. ahora haré un par de experimentos, a ver que sale :)

      Eliminar
    3. He estado jugando un ratillo, ahora a dormir, que ya es hora. Tu código va muy bien, el hardware he usado el mío, porque tenía algo parecido montado y para probar me ha valido. He hecho un pequeño añadido que igual te gusta, nada del otro jueves, pero ahora la velocidad de los pitidos "no el tono en si", va aumentando al a medida que te acercas al objetivo, te pego lo modificado por si te gusta:

      void loop() {
      frq = FreqCount.read();
      int valor;
      resta=buff-frq;


      if(resta>sens){ // Metales ferrosos

      /* Añadido 1 */
      valor = resta; // Asignamos el valor de resta a valor

      // Controlamos la espera entre pitidos según el desplazamiento de frecuencia
      if(valor > 400){valor = 400;}
      else if(valor < 3){valor = 3;}
      valor = map(valor, 400, 3, 0, 100);
      delay(valor);
      /* Fin añadido 1 */

      for(int i=0;i<10;i++){ // Genera tono
      digitalWrite(12,HIGH);
      delay(2);
      digitalWrite(12,LOW);
      delay(2);
      }
      delay(40-(constrain(resta*5,10,40)));
      }

      else if(resta< -sens){ // Metales no-ferrosos
      resta=-resta;



      /* Añadido 2 */
      valor = resta; // Asignamos el valor de resta a valor

      // Controlamos la espera entre pitidos según el desplazamiento de frecuencia
      if(valor > 400){valor = 400;}
      else if(valor < 3){valor = 3;}
      valor = map(valor, 400, 3, 0, 100);
      delay(valor);
      /* Fin añadido 2 */

      Eliminar
  3. me hade mucha ilusión, eres el primero en editar mi código, pero siento decirte que los delay entre pitidos ya están proporcionales al desfase de frecuencia, está en esta linea: delay(40-(constrain(resta*5,10,40)));
    el sierto que tiene poca diferéncia entre cerca y lejos, puedes aumentarla así: delay(150-(constrain(resta*5,10,150)));
    pero no quise aumentar el tiempo entre pitidos porque pierde mucha velocidad.
    Si quieres conversar en privado estoy en Telegram como @el_yeti

    ResponderEliminar
  4. No me di cuenta de eso, de todos modos así como lo he dejado me va bien.
    Me alegra que te haga ilusión que editemos tu código, tú lo pediste en el vídeo y es lo menos que se puede hacer por alguien que regala su trabajo desinteresadamente. En cuanto a Telegram, pues la verdad que no lo uso, lo tenía antes, pero lo desinstalé, porque ya no lo necesitaba, de todos modos, tampoco tengo problema en instalarlo de nuevo. Aprovecho para comentarte otra cosa que he modificado, aunque seguro que ya sabes por donde voy, pero creo que es mejor como te diré. Verás, la línea "if((resta<=sens && resta !=0))", en mi opinión y no soy programador profesional, por lo que no debes tomar mis palabras por misa, tiene un comportamiento algo extraño, como verás, será capaz de corregir las variaciones en los no ferrosos, pero ni se inmutará en los ferrosos. Además, si te fijas, tendrá el offset "2 por defecto" en cuenta. Yo creo que el offset está bien para detección, pero no le veo sentido para calibración, o sea, no es necesario esperar a que el error sea 2 para arreglarlo. Yo personalmente he optado por lo simple "if(buff != frq)". Ahora mismo estoy de pruebas con algún cambio más. Ya te iré comentando y por supuesto que es tu niño y eres bien libre de adoptar los cambios que te proponga o no hacerlo.

    ResponderEliminar
  5. Hola mermelado! cuanta razón, no me di cuenta de eso, contaba que en algún punto del código en el que sabía que es un valor negativo puse "resta=-resta" pero está en un punto en el que supera el umbral de sensibilidad de los metales no ferrosos, así que no se autoajusta para los no ferrosos.
    Voy a solucionarlo, despues del "if()"de los metales ferrosos pondré "else if(resta<0)resta=-resta;"
    y el "if()" de los metales no ferrosos será idéntico al de los metales ferrosos salvo por lo del tono.
    Lo del autoajuste.... haciendo pruebas encima de la mesa no es necesario, pero cuando lo sacas al exterior resulta que cambia la temperatura y eso afecta a la capacidad del condensador... también cambia la permeabilidad magnética de la ferrita según la orientación, eso ultimo es lo que mas te obliga a perder un poco de sensibilidad.
    gracias por tu tiempo. un abrazo!

    ResponderEliminar
    Respuestas
    1. Veo que cambiaste de piel en el blog. Dos cosas. Para los que no se ajustará es para los ferrosos, o eso creo, luego lo repaso, porque por las mañanas no pienso bien. En cuanto a la calibración, creo que no me he expresado bien. Sé que todos y sin excepción, aunque es cierto que existen algunas técnicas de compensación térmica, todos los osciladores libres patinan y hasta que no alcanzan su temperatura de funcionamiento, van aumentando o disminuyendo progresivamente, en la mayoría de casos, al menos en mis pruebas, van subiendo de frecuencia. Por eso me choca cuando veo diseños de detectores VFO, en los que el oscilador de la bobina es comparado con otro controlado a cuarzo. Pues resulta que si usas dos libres, idénticos, las variaciones de uno serán similares a las del otro y la necesidad de ir corrigiendo el batido cero será menor. Por desgracia esto no lo podemos hacer con este diseño, ya que por narices el oscilador de comparación, o sea, el frecuencímetro es bastante estable. Por todo esto entiendo la necesidad de que haya un margen de tolerancia en la detección, pero no veo sentido a que lo haya en la corrección, que son dos temas distintos, no sé si me explico.

      Eliminar
    2. Si, cambié de tema en el blog. No entiendo mucho de blogs, y me di cuenta que con el tema anterior desde la pagina de inicio sale el ultimo post entero, y puesto que tiene un código larguísimo hay que desplazarse mucho para ver el siguiente... además así se ven mejor las letras.
      Es en los metales no ferrosos donde está el problema, quizas a ti te confunde porque en mi código los no ferrosos tienen la variable "resta" un numero negativo. Eso es un pequeño "error" aquí: resta=buff-frq;
      tendría que haber puesto: resta=frq-buff;
      pero bueno, no soy programador y quise compartir el código recién hecho.
      En cuanto al autoajuste. yo también lo probé así, entonces me dí cuenta del error, si permites que se autoajuste aunque esté sonando, en el momento que encuentras el metal dejará de sonar y cuando retiras en detector sonará como loco hasta que se vuelva a ajustar, eso resulta muy incómodo y poco practico

      Eliminar
  6. Con todos mis respetos hacia ti y hacia tu maravilloso trabajo, sigo discrepando y me explico:
    Tú, en el autobalance pones esto: if((resta<=sens && resta !=0)) y eso significa que la condición para que se cumpla, además de tener la variable resta a un valor distinto a cero, dicha variable debe ser menor o igual a sens y por otro lado, en ferrosos tienes esta condición:
    if(resta>sens), por tanto mientras se cumpla esto, o sea, que resta sea mayro que sens, no se cumplirá el autobalance, porque éste exije que resta sea igual o menor que sens. De todos modos da igual, igual soy yo que me lio. LO importante viene ahora. He modificado un poco más el código. Te resumo un poco la idea. Lo ideal es que el autobalance se ejecute cada poco tiempo, pongamos un segundo por ejemplo, pero esto tiene un problema, la detección se interrumpirá al segundo. Si lo que hacemos es impedir que se autobalancee mientras detecta, funcionará, pero como tu oscidador sea perezoso con ferrosos como el mío, tendremos problemas, porque nunca se autobalanceará. Así que he tenido una idea y es aprovecharme de un fenómeno obvio y es el cambio de dirección del oscilador cuando retiras el detector del objeto. Con esto podemos hacer que se calibre cada segundo, con lo que puedes darle sensibilidad por un tubo y que cuando detecte un metal, no se calibre hasta que detecte el contrario. No sé si te gusta la idea. Subiré el código experimental a una de mis webs y te paso enlace de descarga, pues me gustaría pruebes la idea y me comentes. te aviso de que está hecho en minutos, por lo que no es bonito ni comentado a penas. Si me das permiso, subo el enlace aquí.

    ResponderEliminar
    Respuestas
    1. Luego estudiaré mas detalladamente a que te refieres, ahora estoy liado con un video para otro canal y luego me pondré con un video de El yeti, el agregué una pantalla al YFM, es bastante inútil pero sirve para entender mejor eso del autoajuste y algunas cosas mas. Solucionaré ese bug para que se autoajuste tanto si la resta es mayor que 0 como si es menor.
      Puedes pasarme el enlace a tu web, puedes poner el código aquí o lo que quieras. puedes poner en los creditos "deitado por mermelado" o lo que quieras.

      Eliminar
    2. Te explico lo del autobalance:
      el autobalance tiene un contador que incrementa cada vez que se cumple una condición y se pone a cero cada vez que no se cumplen, así que cuando se cumplen las condiciones 1000 veces seguidas el valor de referencia se pondrá a 0 "buff=frq;"
      Dichas condiciones son que la resta no sea =0 y que no esté sonando, osea que no cumpla las condiciones de el if() de ferrosos ni las del if() de no ferrosos.
      Acabo de arreglar el bug para la versión de la pantalla y funciona perfecto.

      Eliminar
    3. Explicándotelo lo vi mucho mas sencillo. acabo de actualizar el código en el blog.
      Gracias de nuevo por encontrar el bug.
      Lasame un link a tu web, puedo comentar que me ayudaste y dar el enlace en el proximo video que haga sobre el detector.

      Eliminar
  7. Yo uso el monitor serie para debug, es lo más rápido. Tu código sé lo que hace y está muy bien pensado. Luego lo subo y pongo enlace para no cargar de basura tu blog, ya que no tiene opción de subir archivos. Ten en cuenta que es una prueba de concepto, para que estudies si te parece interesante tomar ideas de ella. En mi opinión, gana estabilidad, pero reconozco que me he emocionado al escribir lo de subir la sensibilidad, porque al variar la frecuencia sin detección, se quedaría pitando hasta que se invirtiera la frecuencia de oscilación o regresara a su estado inicial. Esa es la razón por la que imagino has tenido que renunciar a la sensibilidad máxima. De todos modos yo lo que he hecho es añadir también un sistema anti cuelgues, balancea por tiempo casa x segundos siempre que no se esté ejecutando la variación primera que te he comentado en mi anterior post. En fin, no te lío más, luego te subo eso y gracias por mencionar una de mis webs, no lo hago por eso, pero se agradece.

    ResponderEliminar
  8. Lo prometido es deuda, ya me contarás si ves algún provecho a mis cambios. Saludos.
    https://beve.mermelado.com.es/Pinpointer_Yeti.zip

    ResponderEliminar
  9. Por cierto, en esa web tengo publicado un proyecto de un transceptor de 4 metros basado en arduino, pos si te interesa.

    ResponderEliminar
  10. Tu modificación está interesante.
    En general es demasiado lento y se auto-balancea demasiado pronto cuando está sonando, pero me gusta el concepto para estabilizarlo cuando se le va la olla por más de 3Hz, que en mi versión se queda loco hasta que le das al reset, lo cual es una mierda si se quiere hacer un detector sumergible sin botones, quizas le daría 5 segundos o mas para ese auto-balance forzado, o un algoritmo que identifique que no hay suficiente desplazamiento de frecuencia como para pensar que está el detector en movimiento

    ResponderEliminar
    Respuestas
    1. Tú puedes poner los tiermpos de autobalanceo y balanceo a tu gusto, para eso lo he definido en una variable global, que por cierto, esto es una muy mala costumbre que tenemos todos, usar variables donde caben constantes. ese error no lo cometí en el tranceptor de 70MHz, pero he vuelto a las andadas :)
      Lo de demasiado lento, no sé a que te refieres, en cuanto a lo del autobalanceo cuando está sonando, estoy de acuerdo contigo. Hay que pensar en como solucionarlo, porque lo suyo es que no se balancee mientras detecta, pero en mi oscilador el problema que tengo es cuando se vuelve tonto y eso ocurre en los ferrosos sobre todo. Lo que voy a hacer es escribir que hace y que no hace y que hace bien y que hace mal, a ver que se me ocurre. Hasta había pensado en un acelerómetro :) pero no tengo claro que sea capaz de encontrar un patrón de detección. En fin, le daré al coco y te digo si se me ocurre algo.

      Eliminar
  11. Ya he meditado y la conclusión a la que he llegado es que el código que te mandé es una basura y me disculpo por ello. me sigue gustando mi idea de detectar la inversión en el cambio de frecuencia, para determinar que es una detección real, pero por desgracia mi implementación no lo hace "sorry". la otra parte de un sistema anti cuelgues, si funciona. Después de pensar he llegado a la conclusión de que intento solucionar con software, lo que es un problema de hardware. Mi oscilador y el tuyo, simplemente no funcionan adecuadamente y dudo que sea por su morfología, sino por la puñetera férrita que sospecho queda temporalmente magnetizada, hasta que recibe suficientes ciclos del oscilador para limpiarla. eso creo que es el problema principal y en donde pienso concentrarme. Luego el software, pero nunca antes de un oscilador fiable. Esa es mi conclusión y en cuanto tenga tiempo, me dedicaré a ello. Si vamos a seguir basándonos en la desviación de frecuencia, hay que o bien pasar de la férrita "cosa no muy recomendable" o lograr que vuelva a su estado natural cada ciclo de trabajo. Te mantendré informado de cualquier avance. Un abrazo.

    ResponderEliminar
  12. Yeti y mermelado ...me saco el sombrero son dos genios.....cargue la version de mermelado y funciona muy bien.....ahora puse la ultima de yeti con el lcd y tambien anda fantastico....gracias a los dos por su tiempo....

    ResponderEliminar
  13. Bonjour !
    Buenos dias!
    Voici mes modifications!
    ¡Aquí están mis modificaciones!
    https://sites.google.com/site/france5ndl/pinpointer-un-detecteur-a-main
    Merci pour votre page.
    Gracias por tu pagina.

    ResponderEliminar
    Respuestas
    1. muy buena modificación, yo también hice algunas pruebas con oscilador colpttis y funcionó bien, pero en ocasiones era inestable. Hice la versión yfm2 que es un poco mejor y además es compatible con attiny85, puedes probarla, solo tienes que poner la entrada de frecuencia al pin 2 y cargar el código.

      Eliminar
    2. Merci pour ta réponse.
      Gracias por tu respuesta.
      Traduction Français Espagnol par google !
      Traducción Francés Español de google!
      La vidéo de mon travail.
      El video de mi trabajo.
      https://www.youtube.com/watch?v=O6REE-lKyrM
      Que Dieu te garde.
      Vaya con dios.

      Eliminar
  14. He visto el video. está bien.
    saludos

    ResponderEliminar
  15. de cuantos voltios es el condensado de
    33uF

    ResponderEliminar
  16. se pude utilizar un condensador electrolítico o necesaria un condensador de cerámica

    ResponderEliminar
  17. Yeti hice todo tal cual el video, pero no suena al contacto de ningun metal, pero si acerco los dedos o toco la ferrita empieza a sonar, que podria ser? Saludos!!

    ResponderEliminar
    Respuestas
    1. Nunca me pasó algo así. No sé qué puede ser. Prueba con más vueltas de alambre en la bobina, ponle 60 por ejemplo y comprueba otra vez que esté todo conectado como en el esquema

      Eliminar
  18. Yeti, ¿Buenas noches! Espero puedas contestar mi comentario. Estuve intentando ejecutar tu código en Arduino Software pero me marca error en void loop() {
    frq = FreqCount.read(); (aquí justamente)
    int valor;
    resta=buff-frq;
    ¿Crees que podrías ayudarme? Estaría muy agradecida puesto que apenas estoy aprendiendo esto y tus videos me han ido ayudando. Saludos desde Ecuador!<3

    ResponderEliminar
    Respuestas
    1. Tienes que instalar la librería FreqCount.h en Arduino IDE, si no no funcionará.
      Mira un tutorial de cómo instalar librerías, es muy fácil

      Eliminar
  19. Saludos. Quisiera saber cuántas vueltas tendría que dar en la ferrita, porque hice una prueba con 45 vuelta con alambre de 0.35mm y no me detecta nada. El funcionamiento del Arduino si está bien. Muchas gracias.

    ResponderEliminar

Publicar un comentario