Led bei Tasten druck an und nach Verzögerung aus.

Schönen guten Abend,
Ich bin der Diter bin neu und beschäftige mich seit kurzem mit einem Arduino Pro Micro.

Ich habe schon ein paar Erfahrungen sammeln können aber nun komme ich nicht weiter.
Momentan habe Ich versucht eine Led so zu Schalten das wenn an Pin9 Spannung anliegt die Led aus ist wird diese aber entfernt soll die Led für einen gewissen Zeitraum Leuchten, Sagen wir 1min., ist das möglich oder schon zu lang?

Alles was Ich bis jetzt hinbekommen habe ist das die Led an und aus geht :o

int LEDrot = 10;
int Switch = 9;
int SwitchStatus = 0;
int delaytime = 60000;
void setup ()
{


pinMode(LEDrot, OUTPUT);
pinMode(Switch, INPUT);  
}

void loop () {
SwitchStatus=digitalRead(Switch); //Schalterstatus abfragen
if (SwitchStatus == HIGH) // Bei Schalter an
{
digitalWrite(LEDrot, LOW);

 }
if (SwitchStatus == LOW) // Bei Schalter aus
{
digitalWrite(LEDrot, HIGH);
delay (delaytime);  
digitalWrite(LEDrot, LOW);

}
}

Liebe Grüsse
Diter

Genau das hast du auch programmiert.

Ich nehme an wenn du deine Taste einfach fest hälts geht die LED nie aus.
Oh Moment -> bei Taste gedrückt setzt du den Ausgang auf LOW. Wenn du die LED
gegen Masse geschaltet hast geht sie auch bei gedrücktem Taster nicht an.

Wie hast du den Taster angeschlossen ?
Mit Pulldown gegen +5 V ?
Dann stimmt erst mal die Tasterlogig.

Aber was hast du programmiert ?
Wenn der Taster aus ist machst du die LED AN !!!
Und dann machst du sie nach einer Minute wieder aus.

Da der Taster immer noch nicht gedrückt ist geht das Spiel dann von Vorne los.
Wenn du in dem Tasteraus-Zweig bist wird eine Minute lang der Taster nicht mehr
abgefragt weil du den Prozessor mit delay ja eine Minute zum Nichtstun verdonnerst.

Such mal hier nach "Statemaschine" und nach "blink without delay".

So geht das nicht.
Noch mal -> dein Ardunio tut genau das was du beschreibst - das hast du auch programmiert.

Der einfachste Fehler ist noch das du die LED ausmachst wenn du den Knopf drückst.

Ulli

Hi

Alles unterhalb 49,7 Tage sollte ohne größere Verrenkungen machbar sein, wenn loop() nicht unnötig aus-gebremst wird.

Was willst Du?

  • LED AUS, wenn Pin 9 HIGH
  • Startzeit merken, wenn Pin 9 von LOW nach HIGH geht (und nur dann)
  • LED AN, wenn Pin 9 LOW oder die Startzeit weniger als 10 Minuten vergangen ist

Du hast momentan, daß die LED HIGH geht, gewartet wird, die LED LOW geht.
Wenn jetzt der Taster noch gedrückt ist, geht die LED DIREKT wieder an - der Dunkel-Blitz ist so kurz, daß Du Das nicht sehen kannst.

Verabschiede Dich von delay().
Schaue Dir die Links an, Die combie dort aufgelistet hat:Klick

MfG

Schaue Dir die Links an, Die combie dort aufgelistet hat:Klick

Oder dieses Beispiel.
Ist zwar nur ein Relais, keine LED, aber das Prinzip sollte passen.
Implementiert, nach der selben Idee, wie hinter den Links ausgebreitet.

Ok vielen Dank. Ich werde mich nachher gleich an die Umsetzung machen.

Hallo,
es ist ja schon angesprochen worden , du solltest dich noch mal mit dem Thema beschäftigen wie der Taster anzuschliessen ist. Es gibt da zwei Möglichkeiten. Bei beiden Varianten ist darauf zu achten das der Eingang nicht offen in der Luft rumhängt, sondern immer einen definierten Pegel hat. Da ein normaler Taster halt einen Kontakt hat ist der im nicht gedrückten Zustand ja geöffent.

  1. Taster mit einem Bein an +5V , das andere Bein am Eingang. Dann ist ein zusätzlicher Pulldown Widerstand erforderlich,(2-10KOhm) Ein Bein ebenfalls am Eingang das andere an GND. Damit hat der Eingang bei offenem Taster 0V über den Widerstand anliegen und bei geschlossenen Taster +5V. Im Sketch dann pinMode(pin,INPUT) verwenden. siehe link.

  2. Taster mit einem Bein am Eingang , das andere Bein an GND angeschlossen. Damit der Pegel des Einganges bei offenen Taster nicht irgendwo in der Luft hängt ist ein Pullup Widerstand erforderlich. Dazu ist im Controller bereits einer eingebaut den man allerdings noch einschalten muß. Dazu im Sketch pinMode(pin,INPUT_PULLUP) verwenden. Bei dieser Variante ist dann allerdings die Funktion invertiert.Bei geöffnetem Taster ist der Eingang H, und bei gerücktem Taster ist der Eingang L. Damit die Logik dann wieder stimmt verwendet man eine Hilfsvariable und ließt den Eingang dann invertiert ein. siehe Beispiel.

Du verwendest in Deinem Sketch delay() um die Zeitverzögerung zu machen. Das kannst Du grundsätzlich machen. Allerdings solltest Du bedenken das bei einem delay() der Programmablauf eine Pause macht und da gewartet wird bist die Zeit abgelaufen ist. Damit passiert nichts mehr, Du kannst nicht mal erkennen ob inzwischen der Taster wieder offen wurde. Wenn Du dann z.B zwei Taster unabhängig voneinander bearbeiten willst , oder eine LED soll z.B blinken, geht das gar nicht auf diese Art. Man verwendet dazu besser millis().

Du solltst dir das Beispiel"BlinkWithoutDelay" ansehen und verstehen. Wenns mit dem Verstehen nicht gleich so klappen will dann suche nach "Nachtwächter".

So jetzt noch das Beispiel zu Thema Taster einlesen.

const byte butonpin=2; // Taster schaltet nach GND
const byte led=13;
bool butonstat; // Hilfsvariable

void setup() {
  
pinMode(butonpin,INPUT_PULLUP); // interner Pullup ein
pinMode(led,OUTPUT);
}

void loop() {

//butonstat=digitalRead(butonpin);  // nicht invertiert
butonstat=!digitalRead(butonpin);   // invertiert
digitalWrite(led,butonstat);
}
int delaytime = 60000;

Den Wertebereich von int solltest du dir auch mal anschauen

void setup() {
  int delaytime = 60000;
  Serial.begin(9600);
  Serial.println(delaytime);
  Serial.println(60000);
}

Ergebnis:

-5536
60000

Selbst bei den Voreinstellungen Warnungen "Alle" und "Ausführliche Meldungen beim Kompilieren" ist kein Gemecker zu sehen.

Auch wenn man in der ersten Zeile 60000L schreibt, ändert sich nichts.

Witzigerweise ergibt

int delaytime = -60000;

warning: overflow in implicit constant conversion [-Woverflow]

(-30000 geht natürlich)

Arduino IDE 1.8.9 für Uno

Warnungen sind nicht im C++ Standard vorgesehen.
Sie sind eine Gnade des Compilers.

Automatische Konvertierungen (implizit cast) allerdings schon.
Die kann man nachlesen und werden auch korrekt befolgt.
In C++ auch Verlustbehaftete.

Oder mit anderen Worten:
Der Programmierer ist für das verantwortlich, was er da anrichtet.

Der Compiler kann nicht zwischen Absicht und Versehen unterscheiden.
Er korrigiert auch keine Dummheiten.

@posmaster-ino
Ja Ich möchte das bei betätigten schalter (GND oder 5V ) das Licht aus ist.
Wird der Taster nun kurzzeitig nicht betätigt so soll die Led für eine Zeit X Leuchten, egal ob der Taster wieder betätigt ist oder nicht. Danach soll sie ausgehen.

Mit dem Code für das Relais konnte Ich jetzt nicht so viel anfangen zumindest ist mir nichts eingefallen.
Statdessen das, aber ich bekomme immer diese Fehlermeldung und Ich erkenne das Problem nicht!

Arduino: 1.8.10 (Windows 7), Board: "Arduino Leonardo"

C:\Users\Home -PC\Desktop\arduino-1.8.10\arduino-builder -dump-prefs -logger=machine -hardware C:\Users\Home -PC\Desktop\arduino-1.8.10\hardware -tools C:\Users\Home -PC\Desktop\arduino-1.8.10\tools-builder -tools C:\Users\Home -PC\Desktop\arduino-1.8.10\hardware\tools\avr -built-in-libraries C:\Users\Home -PC\Desktop\arduino-1.8.10\libraries -libraries C:\Users\Home -PC\Documents\Arduino\libraries -fqbn=arduino:avr:leonardo -vid-pid=0X2341_0X8036 -ide-version=10810 -build-path C:\Users\HOME-P~1\AppData\Local\Temp\arduino_build_937820 -warnings=none -build-cache C:\Users\HOME-P~1\AppData\Local\Temp\arduino_cache_365958 -prefs=build.warn_data_percentage=75 -prefs=runtime.tools.arduinoOTA.path=C:\Users\Home -PC\Desktop\arduino-1.8.10\hardware\tools\avr -prefs=runtime.tools.arduinoOTA-1.3.0.path=C:\Users\Home -PC\Desktop\arduino-1.8.10\hardware\tools\avr -prefs=runtime.tools.avrdude.path=C:\Users\Home -PC\Desktop\arduino-1.8.10\hardware\tools\avr -prefs=runtime.tools.avrdude-6.3.0-arduino17.path=C:\Users\Home -PC\Desktop\arduino-1.8.10\hardware\tools\avr -prefs=runtime.tools.avr-gcc.path=C:\Users\Home -PC\Desktop\arduino-1.8.10\hardware\tools\avr -prefs=runtime.tools.avr-gcc-7.3.0-atmel3.6.1-arduino5.path=C:\Users\Home -PC\Desktop\arduino-1.8.10\hardware\tools\avr -verbose C:\Users\HOME-P~1\AppData\Local\Temp\arduino_modified_sketch_240127\sketch_nov25a.ino
C:\Users\Home -PC\Desktop\arduino-1.8.10\arduino-builder -compile -logger=machine -hardware C:\Users\Home -PC\Desktop\arduino-1.8.10\hardware -tools C:\Users\Home -PC\Desktop\arduino-1.8.10\tools-builder -tools C:\Users\Home -PC\Desktop\arduino-1.8.10\hardware\tools\avr -built-in-libraries C:\Users\Home -PC\Desktop\arduino-1.8.10\libraries -libraries C:\Users\Home -PC\Documents\Arduino\libraries -fqbn=arduino:avr:leonardo -vid-pid=0X2341_0X8036 -ide-version=10810 -build-path C:\Users\HOME-P~1\AppData\Local\Temp\arduino_build_937820 -warnings=none -build-cache C:\Users\HOME-P~1\AppData\Local\Temp\arduino_cache_365958 -prefs=build.warn_data_percentage=75 -prefs=runtime.tools.arduinoOTA.path=C:\Users\Home -PC\Desktop\arduino-1.8.10\hardware\tools\avr -prefs=runtime.tools.arduinoOTA-1.3.0.path=C:\Users\Home -PC\Desktop\arduino-1.8.10\hardware\tools\avr -prefs=runtime.tools.avrdude.path=C:\Users\Home -PC\Desktop\arduino-1.8.10\hardware\tools\avr -prefs=runtime.tools.avrdude-6.3.0-arduino17.path=C:\Users\Home -PC\Desktop\arduino-1.8.10\hardware\tools\avr -prefs=runtime.tools.avr-gcc.path=C:\Users\Home -PC\Desktop\arduino-1.8.10\hardware\tools\avr -prefs=runtime.tools.avr-gcc-7.3.0-atmel3.6.1-arduino5.path=C:\Users\Home -PC\Desktop\arduino-1.8.10\hardware\tools\avr -verbose C:\Users\HOME-P~1\AppData\Local\Temp\arduino_modified_sketch_240127\sketch_nov25a.ino
Using board 'leonardo' from platform in folder: C:\Users\Home
Using core 'arduino' from platform in folder: C:\Users\Home
Detecting libraries used...
"C:\\Users\\Home -PC\\Desktop\\arduino-1.8.10\\hardware\\tools\\avr/bin/avr-g++" -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega32u4 -DF_CPU=16000000L -DARDUINO=10810 -DARDUINO_AVR_LEONARDO -DARDUINO_ARCH_AVR -DUSB_VID=0x2341 -DUSB_PID=0x8036 "-DUSB_MANUFACTURER=\"Unknown\"" "-DUSB_PRODUCT=\"Arduino Leonardo\"" "-IC:\\Users\\Home -PC\\Desktop\\arduino-1.8.10\\hardware\\arduino\\avr\\cores\\arduino" "-IC:\\Users\\Home -PC\\Desktop\\arduino-1.8.10\\hardware\\arduino\\avr\\variants\\leonardo" "C:\\Users\\HOME-P~1\\AppData\\Local\\Temp\\arduino_build_937820\\sketch\\sketch_nov25a.ino.cpp" -o nul
Generating function prototypes...
"C:\\Users\\Home -PC\\Desktop\\arduino-1.8.10\\hardware\\tools\\avr/bin/avr-g++" -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega32u4 -DF_CPU=16000000L -DARDUINO=10810 -DARDUINO_AVR_LEONARDO -DARDUINO_ARCH_AVR -DUSB_VID=0x2341 -DUSB_PID=0x8036 "-DUSB_MANUFACTURER=\"Unknown\"" "-DUSB_PRODUCT=\"Arduino Leonardo\"" "-IC:\\Users\\Home -PC\\Desktop\\arduino-1.8.10\\hardware\\arduino\\avr\\cores\\arduino" "-IC:\\Users\\Home -PC\\Desktop\\arduino-1.8.10\\hardware\\arduino\\avr\\variants\\leonardo" "C:\\Users\\HOME-P~1\\AppData\\Local\\Temp\\arduino_build_937820\\sketch\\sketch_nov25a.ino.cpp" -o "C:\\Users\\HOME-P~1\\AppData\\Local\\Temp\\arduino_build_937820\\preproc\\ctags_target_for_gcc_minus_e.cpp"
"C:\\Users\\Home -PC\\Desktop\\arduino-1.8.10\\tools-builder\\ctags\\5.8-arduino11/ctags" -u --language-force=c++ -f - --c++-kinds=svpf --fields=KSTtzns --line-directives "C:\\Users\\HOME-P~1\\AppData\\Local\\Temp\\arduino_build_937820\\preproc\\ctags_target_for_gcc_minus_e.cpp"
Sketch wird kompiliert...
"C:\\Users\\Home -PC\\Desktop\\arduino-1.8.10\\hardware\\tools\\avr/bin/avr-g++" -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -MMD -flto -mmcu=atmega32u4 -DF_CPU=16000000L -DARDUINO=10810 -DARDUINO_AVR_LEONARDO -DARDUINO_ARCH_AVR -DUSB_VID=0x2341 -DUSB_PID=0x8036 "-DUSB_MANUFACTURER=\"Unknown\"" "-DUSB_PRODUCT=\"Arduino Leonardo\"" "-IC:\\Users\\Home -PC\\Desktop\\arduino-1.8.10\\hardware\\arduino\\avr\\cores\\arduino" "-IC:\\Users\\Home -PC\\Desktop\\arduino-1.8.10\\hardware\\arduino\\avr\\variants\\leonardo" "C:\\Users\\HOME-P~1\\AppData\\Local\\Temp\\arduino_build_937820\\sketch\\sketch_nov25a.ino.cpp" -o "C:\\Users\\HOME-P~1\\AppData\\Local\\Temp\\arduino_build_937820\\sketch\\sketch_nov25a.ino.cpp.o"
C:\Users\HOME-P~1\AppData\Local\Temp\arduino_modified_sketch_240127\sketch_nov25a.ino: In function 'void loop()':

sketch_nov25a:16:1: error: expected primary-expression before '}' token

 }

 ^

sketch_nov25a:16:1: error: expected ')' before '}' token

sketch_nov25a:16:1: error: expected primary-expression before '}' token

C:\Users\HOME-P~1\AppData\Local\Temp\arduino_modified_sketch_240127\sketch_nov25a.ino: At global scope:

sketch_nov25a:17:1: error: expected unqualified-id before '{' token

 {

 ^

sketch_nov25a:20:1: error: expected unqualified-id before '{' token

 {

 ^

sketch_nov25a:24:1: error: expected unqualified-id before '{' token

 {

 ^

exit status 1
expected primary-expression before '}' token
const byte butonpin=9; // Taster schaltet nach GND
const byte led=10;
bool butonstat; // Hilfsvariable
void setup() {
 
pinMode(butonpin,INPUT_PULLUP); // interner Pullup ein
pinMode(led,OUTPUT);
}

void loop() {

//butonstat=digitalRead(butonpin);  // nicht invertiert
butonstat=!digitalRead(butonpin);   // invertiert
if 
(digitalWrite(butonpin,butonstat == HIGH);
}
{
 digitalWrite(led,butonstat LOW);
}
{
if
digitalWrite(butonpin,butonstat == LOW);
}
{
digitalWrite(led,butonstat HIGH);
delay (5000);
digitalWrite(led,butonstat LOW);

}

Formatier deinen Code vernünftig so dass die Klammern korrekt eingerückt sind. Dann erkennst du auch solche Fehler

Ansonsten fehlt bei "if" die eigentliche Bedingung

Bitte C++ Grundlagen lernen und auch anwenden.

Tipp:
Das if Statement ist wirklich gut dokumentiert.

Mit dem Code für das Relais konnte Ich jetzt nicht so viel anfangen zumindest ist mir nichts eingefallen.

Schade eigentlich....

Den Klammer Fehler habe ich behoben aber es funktioniert nicht wie erhofft :frowning:

Hallo,

da du in Deinem letzten Post ein paar Zeilen von meinem Beispiel übernommen hast, fühle ich mich noch mal angesprochen Dir auf die Sprünge zu helfen. Ich hab jetzt mal mein Beispiel mit einem delay erweitert. :cry: Ich hatte ja bereits geschrieben das das eigendlich nicht der Weisheit letzter Schluss ist. Dennoch !!

Nun es wird ein Flanke benötigt die erkennt das der Taster von betätigt auf nicht betätigt wechselt. Nur dann soll die LED angehen und die Zeit ablaufen. Bleibt der Taster offen soll die LED nach der Zeit wieder ausgehen.

Wenn Du ein bischen vertrauter mit dem syntax geworden bist solltest Du das delay durch millis ersetzen , ist eine schöne Übung. :wink:

Heinz

const byte butonpin = 2;// Taster schaltet nach GND
const byte led = 13; // uno interne LED
bool butonstat;
bool lastbutonstat; //hilfsmerker für Flanke

void setup() {
  pinMode(butonpin, INPUT_PULLUP);
  pinMode(led, OUTPUT);
}

void loop() {
  butonstat = digitalRead(butonpin);
  //butonstat = !digitalRead(butonpin);// invertiert einlesen

  if (butonstat & !lastbutonstat) { // Flanke erkannt
    lastbutonstat = true; // Flankenmerker setzten
    digitalWrite(led, HIGH);
    delay(5000);
    digitalWrite(led, LOW);
  }
  if (!butonstat) lastbutonstat = false; // Flankenmerker zurück
}

Mal ein Schnellschuss aus der Hüfte :

#define LED_OFF 0
#define LED_ON  1
#define LED_GODOWN 2

const int LED = 10;
const int BUTTON = 9;

unsigned long int ledTime = 0;
char LedState = LED_OFF;


void setup()
{
    pinMode(BUTTON,INPUT_PULLUP);
    pinMode(LED,OUTPUT);
}

void loop()
{

   if (! digitalRead(BUTTON))
   {
      if (LedState != LED_ON)
      {
          digitalWrite(LED,HIGH);
          LedState = LED_ON;
      }
   }
   else // Taste nicht gedrückt
   {
       if (LedState == LED_ON)
       {
           LedState = LED_GODOWN;
           ledTime = millis();
       }
       else
       {
           if ( (LedState == LED_GODOWN) && ((millis() - ledTime) >= 60000) )
           {
               digitalWrite(LED,LOW);
               LedState = LED_OFF;
           }
       }
    }
}

Compiliert mit 0 Fehlern.
Das Prinzip sollte klar werden auch wenn ich eventuell da noch einen Bug drin habe.
Kein Delay. Prozessor wird nicht sinnlos angehalten !

Wenn die eine Minute Wartezeit bis zum Abschalten läuft und der Knopf wieder gedrückt wird ist
die Wartezeit vorbei und die LED bleibt an.
Ach so : Die Taste ist natürlich nicht entprellt. Kann sein das du damit nicht viel Spaß hast !

Ulli

Hallo,

basierend auf #13 mit millis(), ist eigendlich ganz einfach :slight_smile:

Heinz

const byte butonpin = 2;// Taster schaltet nach GND
const byte led = 13; // uno interne LED
bool butonstat;
bool lastbutonstat; //hilfsmerker für Flanke
unsigned long altzeit;

void setup() {
  pinMode(butonpin, INPUT_PULLUP);
  pinMode(led, OUTPUT);
  
}

void loop() {
  butonstat = digitalRead(butonpin);
  //butonstat = !digitalRead(butonpin);// invertiert einlesen

  if (butonstat & !lastbutonstat) { // Flanke erkannt
    lastbutonstat = true; // Flankenmerker setzten
    altzeit = millis();   // Zeit starten
    digitalWrite(led, HIGH);
  }
  if (!butonstat) lastbutonstat = false; // Flankenmerker zurück

  if (millis() - altzeit > 5000UL) { // led für 5s ein
    digitalWrite(led, LOW);
  }
  
}

@Diter
Drücke in der IDE Mal STRG+T - Das rückt den Code auf Klammer-Ebene ein.
Wenn Du dann mehrere Klammern direkt ganz vorne untereinander hast - oder gaaanz unten steht KEINE Klammer ganz vorne - ist wohl was faul.

Auch sind die ganzen Klammern in und um Deine IFs ... äh ... verwirrend - nicht zwingend für mich, für Dich aber mit Sicherheit!
Auch hat ein ; hinter der IF-Abfrage NICHTS verloren - dort ist die IF nämlich zu Ende - die Klammer drunter hat nur den Zweck, daß der Bereich eben vom Rest abgekapselt ist (eigene lokale Variablen z.B.) - mehr aber nicht.

mfG

Hallo,

wegen den fehlenden Warnungen. Deshalb sollte man nach dem aktuell möglichen Syntax programmieren.
Bsp.

int a {60000};

void setup(void) {
  Serial.begin(250000);
}

void loop(void) {
  Serial.println(a);
}

Deshalb sollte man nach dem aktuell möglichen Syntax programmieren.

Danke für den Tip. Ja.

  int delaytime {60000};

warning: narrowing conversion of '60000l' from 'long int' to 'int' inside { } [-Wnarrowing]
Ist übrigens keine 600001 sondern 60000L und zeigt, dass das Aufweiten entsprechend dem Standard super funktioniert. 60000 wird (beim Uno/Nano/Mega) übrigens auf long und nicht auf unsigned int aufgeweitet.

Hallo,

wie meinst du das mit "wird aufgeweitet"? Missverständnis? Dein Compiler ändert doch nicht etwa eigenmächtig den Datentyp? Die Warnung lese ich wie folgt. Die 60.000, was eigentlich long ist, wird fälschlicherweise in ein int gepresst was nicht rein paßt. Davor wird man gewarnt. from long to int. Wenn man das testet erhält man auch falsche -5536.
Oder habe ich dich falsch verstanden? Soll ja vorkommen. :wink: