C-Programm eine Schaltfläche, um eine Aufgabe auszuführen, die einmal, wenn Sie gedrückt werden (latch)
Ich bin relativ neu in c und dem Raspberry Pi und versuche einfache Programme. Was ich möchte ist, wenn die Taste gedrückt wird, es printfs einmal und nicht printf wieder, bis die Taste erneut gedrückt wird, selbst wenn die Taste gedrückt gehalten wird (eine Art Riegel). Ich dachte, vielleicht hinzufügen der zweiten while-Schleife, würde dieses Problem beheben, aber manchmal ist es immer noch nicht erkennen, eine Taste drücken.
#include <bcm2835.h>
#include <stdio.h>
#define PIN RPI_GPIO_P1_11
int main()
{
if(!bcm2835_init())
return 1;
bcm2835_gpio_fsel(PIN, BCM2835_GPIO_FSEL_INPT);
while(1)
{
if(bcm2835_gpio_lev(PIN))
{
printf("The button has been pressed\n");
}
while(bcm2835_gpio_lev(PIN)){}
}
bcm2835_close();
return 0;
}
- Vielleicht finden Sie eine google-Suche nach 'Taste entprellen' hilfreich zu sein.
- Es ist alles zu wissen, was der Fachbegriff, so kann ich schauen Sie. Danke
- Gerne helfen - ich glaube nicht, dass es garantiert eine Antwort, aber mit dem richtigen Begriff zu suchen, hilft wirklich manchmal!
Du musst angemeldet sein, um einen Kommentar abzugeben.
Für ein einfaches Programm wie dieses, mit busy-loops, wie Sie getan haben, ist in Ordnung. Allerdings würde ich vorschlagen, sich aus der Gewohnheit, weil es oft nicht in alles, was mehr als ein Spielzeug-Projekt.
Gibt es so viele Möglichkeiten, um eine debounce-button, es gibt Menschen, code zu schreiben. Tut es in der hardware kann der Weg zu gehen in einigen Fällen, aber es ist nicht ohne seine Nachteile. In jedem Fall, denn dies ist eine Programmierung Website, lassen Sie uns annehmen, Sie können nicht (oder wollen nicht) die hardware ändern.
Einen quick-and-dirty änderung ist zu überprüfen, ob die Schaltfläche in der main-loop und nur handeln, wenn Sie sich geändert hat. Da bist du neu in C-und embedded-Programmierung, werde ich vermeiden, Timer und interrupts, aber wissen, dass Sie machen den code leichter verständlich und wartbar, sobald Sie über Sie zu erfahren.
BUTTON_DEBOUNCE_CHECKS
hängt nicht nur von den Eigenschaften des Schalters, aber auch die Geschwindigkeit für den Prozessor, und der Zeitpunkt der Ausführung der "rest der main-look-code". Es auch "busy-waits" - mit keine anderen blockierenden Aufruf in der main-Schleife, die CPU-Auslastung geht auf 100%, ans hungern andere Prozesse verursacht einen trägen system insgesamt. Wenn Sie wollen in der Lage sein, um andere Arbeit zu erledigen, während Sie die überwachung für eine Taste drücken es vielleicht besser einen separaten thread mit einerusleep()
Anruf zu halten, die CPU-Last minimal.BUTTON_DEBOUNCE_CHECKS
Wert und sagte so viel in text und code. Trotzdem, ich fand es besser, zu vermeiden, zu viel Diskussion über Timer, interrupts und scheduling für jemanden nur zu lernen, über entprellung. Ich Stimme nicht über den code busy waiting. Es gibt nichts verhindern, die "rest of the code" aus nachgiebig oder zu schlafen. Wie geschrieben, es wird saugen bis Sie alle Prozessor-Zyklen nur wenn es ist ein rein kooperatives multitasking-OS oder-es gibt keine anderen Aufgaben. Ich bin nicht vertraut genug mit dem Raspberry Pi zu wissen, was RTOS nutzt es (wenn überhaupt).usleep()
wird die Leistung erheblich verringert oder beseitigt werden, wenn es nicht auch jede andere ausführbare tasks (okay, es kann helfen, den Stromverbrauch und die damit verbundenen Wärmeentwicklung in einigen Systemen). Dies ist ein sehr einfaches test-Programm, die OP möglicherweise nicht plan auf, immer weiter zu laufen, mit anderen Aufgaben. Es wird auf jeden Fall blockiert der aufrufende thread, aber mehr höflich als ein plumper spin-warten. Auch wenn Sie es in einem separaten thread, Ihr Haupt-thread müssten auch noch Rendite oder schlafen, die, wie ich sagte, kann bereits getan werden. By the way, bedeutet dies, dass das Raspberry Pi OS POSIX-konform?Ihre Logik ist richtig und das würde funktionieren, wenn die Tasten waren perfekt. Aber Sie sind es nicht. Sie müssen debounce das signal von der Taste. Zwei Methoden, um zu erreichen, dass (funktioniert am besten, wenn kombiniert):
I. Fügen Sie einen Kondensator zwischen die beiden pins der Taste (oder versuchen eine noch ausgeklügeltere Taste debouncer-Schaltung), und/oder
II. verwenden Sie die software-entprellung (pseudo-C):
etc.
Edit: wie @jerry darauf hingewiesen, dass der oben nicht funktioniert "richtig", wenn die Taste gedrückt wird. Hier sind ein paar professioneller code-snippets Sie verwenden können, um allen Anforderungen gerecht zu werden.
while (elapsed_time < offset)
zuwhile (elapsed_time < offset || button_pressed)
es würde lösen dieses spezielle problemDie folgende Funktion fragt die Schaltfläche auf nominal 1 Millisekunden-Intervallen und verlangten, dass der Staat weiterhin "releases" an 20 aufeinander folgenden Umfragen. Das wird in der Regel ausreichen, um debounce meisten Schalter unter Beibehaltung der Reaktionsfähigkeit.
Ersetzen Sie Ihre
while(bcm2835_gpio_lev(PIN)){}
Schleife mit einem call-towaitButtonRelease()
.Können Sie finden es notwendig, auch die debounce-Taste drückt, sowie releases. Das geschieht in der gleichen Weise, sondern das zählen der entgegengesetzte Zustand:
Oder vielleicht eine einzelne Funktion debounce-Staat:
Gegeben, diese Letzte Funktion, Ihre Haupt-while-Schleife könnte so Aussehen:
Wenn Sie Zugang zu einem digital-Speicher-Oszilloskop, könnten Sie Sonde das Schaltsignal direkt zu sehen, genau das, was die switch bounce aussieht. Es kann Ihnen helfen, das problem zu verstehen und auch, um maßgeschneiderte das debounce auf die Eigenschaften der bestimmten switch.
usleep(1000)
nennen sollte innerhalb der while-Schleife. Ansonsten wirst du nicht viel zu tun entprellung.