Próbuję napisać kod, aby dioda LED zaświeciła się, gdy jest wyłączona, i wyłącza się, gdy jest włączona za pomocą dotykowego przełącznika przyciskowego. Napisałem, co moim zdaniem jest właściwym kodem z biblioteką wiringPi, ale mogę go włączyć tylko wtedy, gdy jest wyłączony, a potem nie mogę go wyłączyć. W bardzo rzadkich przypadkach i po wielu powtarzających się naciśnięciach dioda LED zgaśnie, gdy jest włączona i nacisnę przycisk, ale jestem pewien, że nie tak powinno to działać.
#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;
}
Dołączyłem obraz okablowania obwodu.
Odpowiedzi:
Okablowanie wygląda poprawnie dla kodu.
Problem polega na tym, że kod jest w bardzo ciasnej pętli. Teoretycznie po naciśnięciu przycisku korpus pętli wielokrotnie włącza i wyłącza diodę LED. Teoretycznie istnieje ryzyko 50/50, że dioda LED pozostanie włączona (lub wyłączona) po zwolnieniu przycisku. Czy zauważysz zmianę jasności po naciśnięciu przycisku. Być może nie wystarczy być zauważonym.
W praktyce przyczyną pozostawienia włączonej diody LED jest sposób, w jaki testujesz, czy jest już włączona. Zapisywanie pin 0 WYSOKIE doprowadza do wyjścia 3,3 V. Ale ten przewód jest podłączony do diody LED, a pin skonfigurowany jako wyjście. Dioda LED może obniżać napięcie na tyle niskie, aby nie rejestrować się jako WYSOKA podczas odczytu, ale czasami dzieje się tak, ponieważ znajduje się w pobliżu wartości granicznej.
W praktyce kod wyłączania i włączania diody LED przy każdym naciśnięciu przycisku używałby przerwania wyzwalanego zboczem. Jak wskazano w komentarzach, w takim przypadku chciałbyś ogłosić przerwanie. Możesz również zrobić to samo bez przerw, rejestrując poprzedni stan przycisku i zmieniając diodę LED tylko wtedy, gdy stan przycisku się zmienił. Odrzucanie w trakcie pisania kodu nie ma teraz sensu.
źródło
Prawdopodobnie łatwiej jest utrzymać „stan” w zmiennych normalnych niż próbować wywnioskować to z bieżącego stanu GPIO.
Również „pętla zajętości” będzie zużywać każdy cykl procesora, na który system operacyjny zezwoli; w przypadku tak prostego procesu zobaczysz, że obciążenie procesora wzrośnie do 100%! Powinieneś pozwolić procesowi zrezygnować z procesora na inne zadania,
usleep()
na przykład przez wywołanie. Opóźnienie służy również do odbicia przełącznika.źródło