Ich versuche, Code zu schreiben, um eine LED einzuschalten, wenn sie ausgeschaltet ist, und um sie auszuschalten, wenn sie eingeschaltet ist, indem ich einen taktilen Druckknopfschalter verwende. Ich habe geschrieben, was ich für den richtigen Code mit der wiringPi-Bibliothek halte, aber ich kann ihn nur einschalten, wenn er ausgeschaltet ist, und kann ihn danach nicht mehr ausschalten. In sehr seltenen Fällen und nach vielen wiederholten Drücken wird die LED ausgeschaltet, wenn sie eingeschaltet ist, und ich drücke die Taste, aber ich bin sicher, dass dies nicht der Fall sein soll.
#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;
}
Ich habe ein Bild beigefügt, wie die Schaltung verdrahtet ist.
Antworten:
Die Verkabelung sieht für den Code korrekt aus.
Das Problem ist, dass sich der Code in einer sehr engen Schleife befindet. Theoretisch schaltet der Schleifenkörper beim Drücken der Taste die LED wiederholt ein und aus. Theoretisch besteht eine 50/50-Wahrscheinlichkeit, dass die LED beim Loslassen der Taste an (oder aus) bleibt. Bemerken Sie eine Helligkeitsänderung, wenn Sie die Taste drücken? Möglicherweise ist nicht genug vorhanden, um bemerkt zu werden.
In der Praxis ist der Grund für die Tendenz, die LED eingeschaltet zu lassen, die Art und Weise, wie Sie testen, ob sie bereits leuchtet. Beim Schreiben von Pin 0 HIGH werden 3,3 V an den Ausgang angelegt. Dieser Draht ist jedoch mit der LED verbunden und der Pin ist als Ausgang konfiguriert. Die LED senkt möglicherweise die Spannung so niedrig, dass sie beim Lesen nicht als HIGH registriert wird, aber manchmal, weil sie sich in der Nähe der Abschaltung befindet.
In der Praxis würde ein Code zum Ein- und Ausschalten der LED bei jedem Tastendruck einen durch eine fallende Flanke ausgelösten Interrupt verwenden. Wie in den Kommentaren erwähnt, möchten Sie den Interrupt in diesem Fall entprellen. Sie können dasselbe auch ohne Unterbrechungen tun, indem Sie den vorherigen Status der Taste aufzeichnen und die LED nur ändern, wenn sich der Status der Taste geändert hat. Das Entprellen, während der Code geschrieben wird, macht jetzt keinen Sinn.
quelle
Es ist wahrscheinlich einfacher, den "Status" in normalen Variablen beizubehalten, als zu versuchen, ihn aus dem aktuellen GPIO-Status abzuleiten.
Außerdem verbraucht die "Busy-Loop" jeden CPU-Zyklus, den das Betriebssystem zulässt. Bei einem so einfachen Vorgang werden Sie feststellen, dass Ihre CPU-Auslastung auf 100% steigt! Sie sollten dem Prozess erlauben, die CPU
usleep()
beispielsweise mit einem Aufruf an andere Aufgaben abzugeben. Die Verzögerung dient auch dazu, den Schalter zu entprellen.quelle