Moin Zusammen,
ich versuche mich grad an einem kleinen Arduino Projekt, mein erstes..
Folgende Aufgabenstellung:
Ein oft benutzer Taster soll überwacht werden. Wenn der Taster 5x innerhalb von 2 Sekunden gedrückt wird, soll eine LED an bzw. aus gehen.
Debugger schmeist keine Fehler, funktioniert aber nicht...
Irgendemand einen Tipp für einen "Grünschnabel"
const int BUTTON_PIN = 7; // Arduino pin connected to button's pin
const int LED_PIN = 6; // Arduino pin connected to LED's pin
// variables will change:
int ledState = LOW; // the current state of LED
int w[4];
void setup() {
Serial.begin(9600); // initialize serial
pinMode(BUTTON_PIN, INPUT_PULLUP); // set arduino pin to input pull-up mode
pinMode(LED_PIN, OUTPUT); // set arduino pin to output mode
}
void loop() {
if (BUTTON_PIN== HIGH){
{w[0]=w[1]; w[1]=w[2]; w[2]=w[3]; w[3]=w[4]; w[4]=millis();}
}
if (millis()-w[0] < 2000){
// toggle state of LED
ledState = !ledState;
// control LED arccoding to the toggled state
digitalWrite(LED_PIN, ledState);
}
}
JA.
Einfach mal schauen, wie die letzten 20 Posts den Code hier zeigen.
Der Hoster ist nicht für jeden erreichbar. Und schmeisst Deinen Code raus wann ihm das in den Kragen passt.
Kein Mensch weiss dann, über was Du sprichst.
Du kannst Dein Post noch editieren.
Gehe vorher in der Arduino-IDE auf BEARBEITEN - FÜR FORUM KOPIEREN
Dann in Deinem Post ganz einfach mit der rechten Maustaste einfügen.
Fettig
Hab digitalread geändert. LED geht leider bei jedem drücken an.
const int BUTTON_PIN = 7; // Arduino pin connected to button's pin
const int LED_PIN = 6; // Arduino pin connected to LED's pin
// variables will change:
int ledState = LOW; // the current state of LED
int w[4];
void setup() {
Serial.begin(9600); // initialize serial
pinMode(BUTTON_PIN, INPUT_PULLUP); // set arduino pin to input pull-up mode
pinMode(LED_PIN, OUTPUT); // set arduino pin to output mode
}
void loop() {
if (digitalRead(BUTTON_PIN)== HIGH){
{w[0]=w[1]; w[1]=w[2]; w[2]=w[3]; w[3]=w[4]; w[4]=millis();}
}
if (millis()-w[0] < 2000){
// toggle state of LED
ledState = !ledState;
// control LED arccoding to the toggled state
digitalWrite(LED_PIN, ledState);
}
}
Ja.
Ganz einfach.
Du merkst nicht, wann der Button gedrückt ist.
pinMode(BUTTON_PIN, INPUT_PULLUP); // set arduino pin to input pull-up mode
if (digitalRead(BUTTON_PIN)== HIGH){
Mit dem PULLUP wird der PIN auf 5v gezogen.
Damit ist die Bedingung IMMER erfüllt.
Dein rotierendes Array dreht sich im Kreis - da kannst Du nicht mal zusehen...
TIPP!
Wenn Du schon den Sermon einbindest, dann nutze ihn!
const int BUTTON_PIN = 7; // Arduino pin connected to button's pin
const int LED_PIN = 6; // Arduino pin connected to LED's pin
// variables will change:
int ledState = LOW; // the current state of LED
int w[4];
void setup() {
Serial.begin(9600); // initialize serial
pinMode(BUTTON_PIN, INPUT_PULLUP); // set arduino pin to input pull-up mode
pinMode(LED_PIN, OUTPUT); // set arduino pin to output mode
}
void loop() {
if (digitalRead(BUTTON_PIN)== HIGH){
Serial.println(F("Bedingung erfüllt!"));
{w[0]=w[1]; w[1]=w[2]; w[2]=w[3]; w[3]=w[4]; w[4]=millis();}
}
if (millis()-w[0] < 2000){
Serial.println(F("MILLIS erfüllt"));
// toggle state of LED
ledState = !ledState;
// control LED arccoding to the toggled state
digitalWrite(LED_PIN, ledState);
}
}
Was kommt bei raus?
Wie musst das ändern?
Dann kommt der Rest...
Sieh es mir nach, ich habe echt wenig bis keine Ahnung..
Habe probiert dein geschriebenes zu verstehen und umzusetzten:
INPUT_PULLUP gegen INPUT getausch:
const int BUTTON_PIN = 7; // Arduino pin connected to button's pin
const int LED_PIN = 6; // Arduino pin connected to LED's pin
// variables will change:
int ledState = LOW; // the current state of LED
int w[4];
void setup() {
Serial.begin(9600); // initialize serial
pinMode(BUTTON_PIN, INPUT) ; // set arduino pin to input mode
pinMode(LED_PIN, OUTPUT); // set arduino pin to output mode
}
void loop() {
if (digitalRead(BUTTON_PIN)== HIGH){
Serial.println(F("Bedingung erfüllt!"));
{w[0]=w[1]; w[1]=w[2]; w[2]=w[3]; w[3]=w[4]; w[4]=millis();}
}
if (millis()-w[0] < 2000){
Serial.println(F("MILLIS erfüllt"));
// toggle state of LED
ledState = !ledState;
// control LED arccoding to the toggled state
digitalWrite(LED_PIN, ledState);
}
}
Ein Array w[4] hat 4 Elemente mit dem Index von 0 bis 3. Da gibt es kein 5.tes Element mit Index 4. Da überschreibst Du irgendwas was nach dem Array im Speicher ist.
millis() braucht ein unsigned long. Bei einem int bekommst Du nach ca einer halben Minute ab Einschalten des Arduino Probleme.
Dein Sketch kontrolliert nicht ob die Tasten 5x in 2 Sekunden gedrückt sind sondern ob sie dauernd gedrückt ist oder immer wieder genau dann gedrückt ist wenn der Sketch den Taster abfragt.
Wenn Du 5x Drücken kontrollieren willst dann mußt Du kontrollieren ob der Taster dedrückt und dann wieder losgelasen wurde.
Ne falsch.
Der INPUT_PULLUP war vermutlich schon richtig.
Aber dazu müsste man wissen, wie Du den taster angeschlossen hast.
Um es Dir abzunehmen, noch lange zu suchen:
Wenn PULLUP, dann gehört der Taster zwischen PIN und GND.
Wenn kein PULLUP, gehört der Taster mit einen Widerstand auf der einen Seite an GND auf der anden Seite an 5V und mittig an PIN.
Und dann musst Du überlegen, was für ein Signal der PIN bekommt, wenn die Taste gedrückt wird.
Wenn die Tase nach GND geht, musst Du auf LOW prüfen, geht die Taste nach 5V eben auf HIGH.
Ok - da alle anderen schneller waren:
Wenn der erstmal ne Taste auswertet und das auch funktioniert, sieht er selbst das der buffer nicht geht - aber das sollte ihm als Lernobjekt doch bitte liegen bleiben.
Danke für die erklärung zum Taster - angeschlossen as INPUT
Die Sacher mit dem Buffer evtl. so?
const int BUTTON_PIN = 7; // Arduino pin connected to button's pin
const int LED_PIN = 6; // Arduino pin connected to LED's pin
// variables will change:
int ledState = LOW; // the current state of LED
int w[5];
void setup() {
Serial.begin(9600); // initialize serial
pinMode(BUTTON_PIN, INPUT) ; // set arduino pin to input pull-up mode
pinMode(LED_PIN, OUTPUT); // set arduino pin to output mode
}
void loop() {
unsigned long BUTTON_TIME;
if (digitalRead(BUTTON_PIN)== HIGH){
Serial.println(F("Bedingung erfüllt!"));
BUTTON_TIME = millis();
w[0]=w[1]; w[1]=w[2]; w[2]=w[3]; w[3]=w[4]; w[4]=BUTTON_TIME;
}
if (millis()-w[0] < 2000){
Serial.println(F("MILLIS erfüllt"));
// toggle state of LED
ledState = !ledState;
// control LED arccoding to the toggled state
digitalWrite(LED_PIN, ledState);
}
}
Hm.
Was bekommst Du für eine Ausgabe auf dem SerMon?
Theoretisch dürfte nach dem hochladen / Reset keine Ausgabe erfolgen.
Wenn Du einmal kurz auf die Taste drückst aber schon. Aber nur einmal.
Wie sieht denn die Ausgabe aus?
Na schick...
Wie Du siehst, ist die Umlaufzeit rum "MILLIS erfüllt", bevor Du auf die Taste gedrückt hast.
Wenn der Arduino startet und die Taste nicht gedrückt wird, ist die Bedingung:
if (millis()-w[0] < 2000){
definitiv erfüllt.
Das darf aber nicht passieren.
Du musst also nicht allein auf irgendeine Zeit prüfen, sondern auch auf den TasterStatus.
Mach Dir mal Gedanken. Ganz ohne das W[irgendwas] musst Du erstmal den Start hinbekommen, das Du folgende Aufgabe erfüllst:
Beim Drücken auf eine Taste soll genau einmal der Tastendruck auf dem Seriellen Monitor angezeigt werden.
Merke Dir den Tastenstatus.
Eine erneute Anzeige erst, wenn die Taste zwischendurch losgelassen wurde.
Ist sicher für einen Einsteiger ganz neben der Spur.
Aber: Ich will nicht unbedingt Code sehen. Ich will wissen, wie weit Du logisch ran gehst.
Wenn Du einen Code baust muss er nicht unbedingt funktionieren, aber kommentiert soll er sein. >Schreibe, was Du erwartest. Kommentare in der Art
sind nicht zielführend. Das steht in der Anweisung.
Wenn Du schreibst: // Hier soll der PIN HIGH gehen
dann ist das eine Aussage, auf die reagiert werden kann.
Wenn er nicht fuktioniert, schreib kurz was klemmt.
Dann lese ich Dich gerne morgen hier wieder.
Ich bin etwas weiter gekommen, zugegeben mit etwas fremder hilfe.
Was noch nicht funktioniert wie gewünscht ist, dass ein langer tastendruck scheinbar alle w[i] beschreibt.
Mein erster Versuch dies mit while zu unterbinden brachte leider keinen Erfolg.
Wie würdet ihr diese Herausforderung angehen?
const int BUTTON_PIN = 7; // Arduino pin connected to button's pin
const int LED_PIN = 6; // Arduino pin connected to LED's pin
// variables will change:
int ledState = HIGH; // the current state of LED
#define num_presses 5 //so oft muss gedrückt werden
unsigned long w[num_presses]; //muss unsigned long sein, int ist zu klein.
void setup() {
Serial.begin(9600); // initialize serial
pinMode(BUTTON_PIN, INPUT_PULLUP); // set arduino pin to input pull-up mode
pinMode(LED_PIN, OUTPUT); // set arduino pin to output mode
w[0]= 3000; // damit nach starten die led nicht 2 sek leuchtet
}
void loop() {
while((digitalRead(BUTTON_PIN) == HIGH)) // versuch, einen langen tastendruck zu ignorieren -> funktioniert nicht
if (digitalRead(BUTTON_PIN) == HIGH){ //wenn es sofort auslöst, muss auf LOW geprüft werden.
w[0]=w[1]; w[1]=w[2]; w[2]=w[3]; w[3]=w[4]; w[4]=millis();
delay(200); //eine kleine entprellung
//derzeit kann man den taster einfach gedrückt halten,
}
if (millis()-w[0] < 2000){
// toggle state of LED
ledState = !ledState;
// control LED arccoding to the toggled state
digitalWrite(LED_PIN, ledState);
//löschen des buffers, damit weiterer tastendruck die LED nicht direkt neu umschaltet
for(byte i=0; i < num_presses ;i++) {
w[i] = 0;
}
}
}
Etwas unelegand finde ich noch die Stelle an der ich das initale leuchten unterbinde, aber es funktioniert:
w[0]= 3000; // damit nach starten die led nicht 2 sek leuchtet
Du mußt die Sequenz LOW - HIGH-LOW für einen Tastendruck kontrollieren. Erst dann ist ein darauffolgender LOW-HIGH-LOW der nächste Tastendruck. Wie lange die HIGH bzw LOW Zeiten Dauern isr für die Erkennung des Tasendrucks unwichtig. Zu beachten ist aber auch das Tastaturprellen das einige H-L-H-L Sequenzen sofort nach dem Loslassen oder Betätigen des Tasters ergeben.
Grüße Uwe
Das Suchwort heißt "Flankenerkennung".
Nur wenn Du einen einzelnen Tastendruck richtig erkennen kannst solltest du dich ans Zählen machen.
Im Übrigen brauchst du dann - vermutlich - auch keine fünf Zeitstempel, sondern nur den ersten und den letzten. Da muss ich aber noch mal drüber nachdenken.
Hallo,
Flankenerkennung wurde ja bereits gesagt, zudem kommt aber noch hinzu das Du auch ein prellen des Tasters vermeiden musst. Dazu kannst Du erst erst mal, auch in Deinem Sketch, ein böses delay verwenden da es eigentlich nichts zeitkritisches gibt.
Schau Dir mal den folgenden Sketch an und probiere Ihn aus, wenn Du Ihn verstanden hast versuche das in Deinen Sketch einfließen zu lassen. Man kann in dem Sketch noch einiges an der Schreibweise für logischen Operanden vereinfachen , aber ich will Dich erst mal nicht verwirren das wird Dir so bekannt vorkommen. Da ich den Taster zwischen dem Pin und GND angeschlossen habe , wird der interne PullUp Widerstand verwendet. Damit die Logik bei gedrücktem Taster ein true zu bekommen wieder stimmt wird der Eingang invertiert eingelesen.
Die Ausgabe kannst Du auf dem Monitor verfolgen.
Heinz
const byte btnpin = 2;
bool btnstate; // aktueller Tasterzustand
bool merker; // Merker Taster wurde gedrückt
int count; // Zähler zur Anzeige
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
pinMode(btnpin, INPUT_PULLUP);
}
void loop() {
// put your main code here, to run repeatedly:
delay(10); // entprellen reicht hier so
btnstate = not digitalRead(btnpin);// Eingang lesen und invertieren
//Serial.println(btnstate);
if (btnstate==true && merker== false) {// Flanke erkannt
merker = true;// Zustand merken
count++;
Serial.print(count);Serial.println(" Flanke wurde erkannt");
}
if (btnstate ==false) merker = false;// Merker rücksetzen
}