Estou tentando escrever um código para que um LED acenda quando está apagado e quando está aceso usando um botão de pressão tátil. Eu escrevi o que acredito ser o código certo com a biblioteca de fiaçãoPi, mas só consigo ligá-lo quando está desligado e depois não consigo. Em casos muito raros e após muitas repetidas repetições, o LED apaga quando está ligado e eu pressiono o botão, mas tenho certeza de que não é assim que deve 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;
}
Anexei uma imagem de como o circuito está conectado.
Respostas:
A fiação parece correta para o código.
O problema é que o código está em um loop muito restrito. Em teoria, quando o botão é pressionado, o corpo do loop liga e desliga repetidamente o LED. Em teoria, haveria uma chance de 50/50 de o LED permanecer aceso (ou apagado) quando o botão for liberado. Você percebe uma alteração no brilho quando o botão é pressionado. Pode não haver o suficiente para ser notado.
Na prática, o motivo da tendência de deixar o LED aceso é a maneira como você testa para verificar se ele já está aceso. O pino de escrita 0 HIGH aplica 3,3 V à saída. Mas esse fio está conectado ao LED e o pino configurado para ser uma saída. O LED pode estar reduzindo a voltagem baixa o suficiente para não se registrar como ALTO quando é lido, mas às vezes ocorre porque está próximo do ponto de corte.
Na prática, o código para desligar e ligar o LED a cada pressionamento de botão usaria uma interrupção acionada pela borda descendente. Como apontado nos comentários, você deseja renunciar à interrupção nesse caso. Você também pode fazer o mesmo sem interrupções gravando o estado anterior do botão e alterando o LED apenas quando o estado do botão tiver sido alterado. A renúncia à medida que o código é escrito agora não faz sentido.
fonte
Provavelmente, é mais simples manter o "estado" em variáveis normais do que tentar deduzi-lo do estado atual do GPIO.
Além disso, o "loop ocupado" consumirá todos os ciclos da CPU que o sistema operacional permitirá ao processo; para um processo tão simples, você verá que sua carga de CPU aumentará para 100%! Você deve permitir que o processo renuncie à CPU para outras tarefas com uma
usleep()
chamada, por exemplo. O atraso também servirá para cancelar a troca.fonte