Estoy tratando de escribir código para que un LED se encienda cuando está apagado y para apagarlo cuando está encendido usando un interruptor táctil. Escribí lo que creo que es el código correcto con la biblioteca cableadoPi, pero solo puedo encenderlo cuando está apagado y no puedo apagarlo después de eso. En casos muy raros y después de muchas pulsaciones repetidas, el LED se apaga cuando está encendido y presiono el botón, pero estoy seguro de que no es así como debería funcionar.
#include <wiringPi.h>
int main (void)
{
wiringPiSetup ();
pinMode (0, OUTPUT);
pinMode (1, INPUT);
digitalWrite (0, LOW);
for(;;)
{
if(digitalRead (1) == LOW)
{
if(digitalRead (0) == HIGH)
digitalWrite (0, LOW);
else if(digitalRead (0) == LOW)
digitalWrite (0, HIGH);
}
}
return 0;
}
He adjuntado una imagen de cómo está conectado el circuito.
Respuestas:
El cableado se ve correcto para el código.
El problema es que el código está en un circuito muy cerrado. En teoría, cuando se presiona el botón, el cuerpo del bucle enciende y apaga el LED repetidamente. En teoría, habría una probabilidad de 50/50 de que el LED se deja encendido (o apagado) cuando se suelta el botón. ¿Notas un cambio en el brillo cuando se presiona el botón? Puede que no haya suficiente para ser notado.
En la práctica, la razón de la tendencia a dejar encendido el LED es la forma en que realiza la prueba para ver si ya está encendido. El pin de escritura 0 ALTO aplica 3,3 V a la salida. Pero ese cable está conectado al LED y el pin está configurado para ser una salida. El LED puede estar bajando el voltaje lo suficiente como para no registrarse como ALTO cuando se lee, pero a veces lo hace porque está cerca del límite.
En la práctica, el código para apagar y encender el LED con cada pulsación de botón utilizaría una interrupción activada por un borde descendente. Como se señaló en los comentarios, querrás eliminar la interrupción en ese caso. También puede hacer lo mismo sin interrupciones registrando el estado anterior del botón y solo cambiando el LED cuando el estado del botón haya cambiado. El rebote cuando se escribe el código ahora no tiene sentido.
fuente
Probablemente sea más simple mantener el "estado" en variables normales en lugar de tratar de inferirlo del estado GPIO actual.
Además, el "bucle ocupado" consumirá cada ciclo de CPU que el sistema operativo permitirá el proceso; ¡para un proceso tan simple, verá que la carga de su CPU aumentará al 100%! Debe permitir que el proceso entregue la CPU a otras tareas con una
usleep()
llamada, por ejemplo. La demora también servirá para eliminar el interruptor.fuente