Pi-Lotus, pinpointer con attiny85

 Pi-Lotus, pinpointer con attiny85.

En este post vengo a explicar como funciona un detector de metales de inducción de pulsos, y mas concretamente el Pi-Lotus Pinpointer.



Decdí hacer pinpointer de éste detector debido a su bajo consumo, alta estabilidad y reducido tamaño, pero es sistema de inducción de pulsos es el mismo que para los mejores detectores de este tipo.

En grandes rasgos la induccion de pulsos consta de hacer pasar pulsos de alta corriente por una bobina y aplificar yanalizar la respuesta de la bonina después de cada pulso.

Hasta ahora los detectores de este tipo eran 100% analogicos  y generaban los pulsos mediande osciladores basados en el 555, luego amplificaban la señan mediante un amplificador operacional y los mas completos hacian una serie de pulsos y retardos para abrir y cerrar llaves electronicas dejado pasar solo la parte de la señal a las siguientes etalas de amplificacion y luego median ancho de pulso o amplitud.

Iremos concretando en el funcionamiento del Pi-Lotus pinpointer para no extenderme en exceso.

El microcontrolador attiny85 realiza una consecución de acciones perfectamente sincronizadas gracias a su reloj interno de 8MHz.

Todo empieza con un pulso que de 100 microsegundos que lanza a la base de un trancistor NPN de media potencia el cual maneja la bobina en su colector.

Después del cierre del pulso espera un tiempo de 25 microsegundos que es el tiempo que terda en responder la bobina, y entonces hace una lectura analogica para medir la amplitud de la respuesta, la compara con lecturas de pulsos anteriores y en ese momento se descubre si hay o no bariación en amplitud.

Y por ultimo hace una pausa de 40000 microsegundos antes de reiniciar el ciclo para completar el tiempo que debe estar apagada la señal antes del siguiente pulso, evidentemente a esos 40000us hay que restarles el tiempo que dura el pulso , el retardo y todo el tiempo que ha empleado en hacer la lectura y los calculos pertinentes y así quede una frecuencia estable de 250Hz.

Hasta aquí he esbozado cómo es que funciona el software, pero ¿que hay del circuito?

Cuando está fluyendo corriente electrica a traves de la bobina se genera un campo magnetico el cual interactúa con los conductores que haya a su alcance induciéndones algunas corrientes y perdiendo un poco de energía en ello. En el momento que se termina el pulso y la corriente deja de circular, el campo magnético cae y en parte se reabsorbe  generando en ésta un pulso envertido de altísima tensión, en los detectores potentes ése pulso alcanzaría varios centenares de voltios negativos, pero en éste no es tan salvaje. 

El primer filtrado es una resistencia de 330 hom en paralelo a la bobina, la cual por ley de ohm atenúa mas las tensiones mas altas.

Luego la señal de encuentra con unos diodos tambien en paralelo a la bobina que la recortan a +-0.7V aproximadamente.

un condensador desacopla la continua y eleva como la mayor parte de la onda es positiva se eleva la parte que se quiere amplificar.

y la ultima etapa del tratamiento de la señal es un amplificador inversor que da vuelta a la señal y la amplifica para poderla medir decentemente con el combersor analogico-digital del micro.


////Pi-Lotus 5V by Yeti-lab  versión Dinámica////

///// Sketch implementado por Hector Santos Yeti-lab////

//// Ultima actualización 7/12/2021////

////https://yeti-lab.blogspot.com/////



int pulso=100; //funciona bien con 50

int sens=100; //Lectura estabilizada

int retardo=25; //funciona bien con 25

int referencia; // referencia de lectura

int limite=8; //Sensibilidad

int LA;   // Lectura Analogica

int Frecuencia=250; // Frecuencia en Hz

int contSleep=0;

unsigned long tiempoPerdido=0;


const int Buzzer=0;   // Pin Buzzer pasivo

const int Led=1;     // Pin Led

const int pinPulso=4; //Pin salidad de pulsos

const int AnalogIn=A3; // Pin de entrada analogica

const int boton=2;



void setup() {

bitWrite(ACSR,ACD,1);//deshabilito el comparador para ahorrar energía

pinMode(boton,INPUT_PULLUP);

pinMode(Led,OUTPUT); 

pinMode(Buzzer,OUTPUT); 

pinMode(pinPulso,OUTPUT); 

Serial.begin(9600);

digitalWrite(pinPulso,LOW);

tiempoPerdido=micros();

 tone(Buzzer,1000,500);

 delay(500);


}


void loop() { 


int p=0;

while(1){

  



if(!digitalRead(boton)){

  contSleep++;

  if(contSleep>Frecuencia/2){ //La Frecuencia corresponde al nº de vuentas que da el loop por segundo

    contSleep=0;

    tone(Buzzer,1000,500);

    delay(2000);

    

    byte adcsra = ADCSRA; //se guarda la configuración de estos registros

    byte mcucr = MCUCR;

    byte prr = PRR;

    bitWrite(ADCSRA,ADEN,0); //Deshabilita el ADC


   PRR= B00001111; ///apaga timers,adc y detector de baja tención

   MCUCR=B00110000;//Habilita la durmia y define el tipo

   attachInterrupt(digitalPinToInterrupt(boton),interrupcion,LOW);//Habilita interrupción externa


   //Instrucciones de ensamblador en linea

   asm( "sei" );//habilita interrupciones

   asm("sleep");//pone a dormir

   


    ////////DESPIERTA///////

     PRR=prr;///enciende timers,adc y detector de baja tención

     MCUCR=mcucr;//Deshabilita la durmia

    ADCSRA=adcsra; //Habilita el ADC

    detachInterrupt(digitalPinToInterrupt(boton)); //Deshabilita la interrupción externa

    analogRead(AnalogIn);//Lectura fallida

    tone(Buzzer,1000,500);

    delay(1000);

    pinMode(Buzzer,OUTPUT);

    digitalWrite(Led,LOW);

    }

  }else contSleep=0;


  

tiempoPerdido=micros(); ///Inicia el contador para ajustar la frecuencia




bitWrite(PORTB,pinPulso,HIGH);

delayMicroseconds(pulso);

bitWrite(PORTB,pinPulso,LOW);



delayMicroseconds(retardo); //Espera para la lectura


LA=analogRead(AnalogIn);

if(LA>sens)sens++;    // estabilización lectura analogica

else if(LA<sens)sens--;

p++;

if(p>3){

  p=0;

  if(sens<referencia-limite){

   digitalWrite(Led,HIGH); //detecta metal

   if(!contSleep) tone(Buzzer,900,100); //Genera tono

    referencia=sens+2; // Balance dinamico

  }

  else digitalWrite(Led,LOW);

  

  if(sens>referencia+limite)referencia=sens-2; // Balance dinamico

 

  }


delayMicroseconds((1000000/Frecuencia)-(micros()-tiempoPerdido)); // 1.000.000/Frecuencia=Periodo en microsegundos

}

}

void interrupcion(){ 

}


////////FIN de la versión dinámica////////

Comentarios