Hay una explicación racional: aquí no hay ningún fantasma ;-)
Según tu descripción, supongo que no tienes una resistencia desplegable débil en el pin de entrada del botón, por lo que cuando no se presiona, el pin queda flotando. Dado que una entrada CMOS tiene una impedancia increíblemente alta, recogerá fácilmente los campos eléctricos dispersos (un MOSFET o JFET con una puerta flotante y un LED en el drenaje hacen una buena detector de electricidad estática ) y alternar aleatoriamente entre encendido y apagado.
Cuando acerques la mano, el campo se volverá más fuerte y el LED se encenderá y apagará, pasando más tiempo encendido que más cerca, probablemente debido a algunos efectos de rectificación con los diodos de protección y una parte superior de tiempo con entrada gastada por encima del umbral. Probablemente estará alrededor de la frecuencia de la red eléctrica si lo verifica con un alcance mientras mueve su mano cerca.
Una cosa interesante de intentar es agarrar un cable de alimentación con una mano (uno aislado normal) y colocar la otra mano cerca del pin. Suelte el cable de alimentación (o mueva su mano más cerca / más lejos) mientras mantiene la otra mano estática y observe el efecto, debe ser similar.
Para solucionarlo (suponiendo que tengo razón), coloque una resistencia de 100 k or (o un valor alto similar) desde el pin del botón a tierra. O si su microcontrolador tiene opciones de extracción interna, entonces active esto en el pin de entrada del botón.
Lo que hay que aprender de esto es nunca dejar una entrada flotante. Incluso los pines no utilizados realmente deben configurarse para salir y ser conducidos al riel positivo o al suelo. Aunque es poco probable que causen que el micro se bloquee, la principal razón para hacerlo es porque una entrada flotante puede consumir una corriente extra innecesaria si cambia continuamente de estado.
Experimento
Basándome en los comentarios a continuación, acabo de realizar una prueba rápida utilizando una entrada flotante (con un cable conectado para tocar / poner la mano cerca) y un LED. Tengo los síntomas que menciona, y la salida osciló a la frecuencia de la red eléctrica aquí (50Hz) como se predijo.
Dependiendo de lo cerca que estaba mi mano (o de lo fuerte que presioné el cable al sondear, incluso la impedancia de entrada de 10MΩ de la sonda apagó el LED fácilmente cuando no se tocó el cable, en comparación con sin la sonda) el ciclo de trabajo varió un poco Y también tengo algunos parpadeos. Así que el LED se apagó / apagó / encendió cuando presioné el cable más fuerte (o moví la mano más cerca sin la sonda)
En caso de que alguien quiera probarlo por sí mismo, usé un PIC16F690, con este código (en MPLABX con el compilador XC8) pero cualquier microcontrolador con una entrada CMOS flotante debería hacer lo mismo:
#include <xc.h>
// Turn the Watchdog Timer off
#pragma config WDTE = OFF
int main(int argc, char** argv) {
TRISBbits.TRISB6 = 0; // LED Output pin
TRISBbits.TRISB7 = 1; // Floating pin input
while(1) // Infinite loop
{
if(PORTBbits.RB7 == 1)
{
PORTBbits.RB6 = 1; // Set RB6 pin to logic high (5V)
}
else
{
PORTBbits.RB6 = 0; // Set RB6 pin to logic low (0V)
}
}
}
De todos modos, aquí están los clips de alcance, la traza amarilla es la salida del LED y la traza roja la entrada sondeada 10x.
LED brillante:
Podemosverquelasalidatienecasiun50%deciclodetrabajoylaentradapareceserunaformadeondasinusoidalrectificadadelaredeléctrica(losdiodosdeprotecciónrecortanelgironegativo)
LEDDim:
Menos de la forma de onda de entrada está por encima del umbral de entrada aquí, por lo que el ciclo de trabajo en la salida disminuye y el LED aparece más oscuro.