YFMv2.1 para attiny85 y compatible con arduino uno.
En su momento no publiqué esta versión porque me estuve dedicando a otras cosas y se me pasó, pero ahora hay que me la solicita y aqui la publico.
Mejoras de la versión:
-Si se usa en attiny85 se puede colocar dos leds en un mismo pin y se enciende uno para metales ferrosos y el otro para no-ferrosos, esta mejora no está si se usa con Arduino uno.
-Añadí en el código tiene una constante (Buzzer) y cambiando su valor se puede adaptar el código para usarlo en Arduino o en attiny85, es decir poner Buzzer=0; para attiny y Buzzer=12; para arduino.
Un apunte mas, si se quiere usar con arduino el pin de entrada de la señal es el pin digital 2.
// Funciona con arduino y con attiny85 a 16/20MHZ con cristal y con el gestor de dispositivos ATTinyCore de https://github.com/SpenceKonde/ATTinyCore
//Detector de metales YFM Pinpointer 2 tonos
// Hardware y software implementados por Hector Santos ("El yeti" en youtube)
// https://yeti-lab.blogspot.com/
//YFM v2.1 interrupt 24/8/2020
// Entrada D2, Buzzer D12
const uint8_t ledPin=1; // para arduino uno poner ahi 13 y para attiny85 poner 1
const int Buzzer = 0; // pin del buzzern el 0 para attiny85 y el 12 para arduino
bool start=true;
volatile int buff=0;
unsigned long frq=0;
int resta=0;
int sens=3; // sensibilidad *** cuanto mayor el nmero menor sensibilidad
int autoBalance=0;
bool AB=true;
volatile long frecuencia;
int contador=0;
long unsigned long T;
const int L=2000;//numero de ciclos que mide **** cuanto mayor inductancia mentor el numero
volatile int intensidad=0;
volatile bool Fe=false;
bool Max=false;
volatile bool balanceInicial=true;
const int tonoFe = 300;
const int tonoNoFe = 900;
void interrupcion(){
contador++;
if(contador==1)T=micros();
else if(contador>=L){ //numero de ciclos que mide **** cuanto mayor inductancia mentor el numero
contador=0;
frq=T-micros();
if(start){frecuencia=frq;
start=false;
}
else if(frq <(frecuencia-1)){frecuencia=frecuencia-1; // Esto hace la lectura mucho mas estable pero tiene mucha inercia
if(Max && !balanceInicial)frecuencia=frecuencia-(intensidad/3); // elimina la inercia
}
else if(frq >(frecuencia+1)){frecuencia=frecuencia+1;
if(Max && !balanceInicial)frecuencia=frecuencia+(intensidad/3);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////
resta=buff-frecuencia;
if(resta>=0){ // Metales ferrosos
intensidad=resta; //la variable "intensidad" es para el loop
Fe=true; //la variable "Fe" es para el loop
if(intensidad>3)Max=true;
else Max=false;
}
else if(resta< 0){ // Metales no-ferrosos
intensidad=-resta;
Fe=false;
if(intensidad>3)Max=true;
else Max=false;
}
}
}
void setup() {
bitWrite(ACSR,ACD,1); //Deshabilita el comparador
// bitWrite(ADCSRA,ADEN,0); // Deshabilita el ADC para ahorrar enetgía
// Habilita interrupciones
attachInterrupt(digitalPinToInterrupt(2),interrupcion,FALLING);//flanco de bajada FALLING, flanco de subida RISING
delay(100);
pinMode (Buzzer,OUTPUT); // Buzzer pin
for(int i=0;i<1;i++){
tone(Buzzer,500,40);
delay(60);
if(frecuencia != buff){i=0; buff=frecuencia;}
}
tone(Buzzer,1000,40);
delay(40);
balanceInicial=false;
}
void loop() {
AB=true;
if(intensidad>sens && Fe){ //Metales ferrosos
tone(Buzzer,tonoFe,40);
pinMode(ledPin,OUTPUT);
digitalWrite(ledPin,HIGH); // Enciende led ROJO "a modo de ejemplo"
delay(40);
delay(40-(constrain(intensidad,10,40)));
pinMode(1,INPUT);
AB=false; //para resetear el autobalance
}
else if(intensidad>sens && !Fe){ //Metales no ferrosos
tone(Buzzer,tonoNoFe,40);
pinMode(ledPin,OUTPUT);
digitalWrite(ledPin,LOW); // Enciende led verde "a modo de ejemplo"
delay(40);
delay(40-(constrain(intensidad,10,40)));
pinMode(1,INPUT);
AB=false; //para resetear el autobalance
}
if(true){ // auto Balance
if(AB && intensidad !=0){
if(autoBalance>1000){autoBalance=0; buff=frecuencia;}
autoBalance++;
}else autoBalance=0;
delay(1);
}
}
Comentarios
Publicar un comentario