Led mit Taster einschalten und wieder ausschalten

Hallo.

Ich habe folgendes Programm:

const int buttonPin = 12;
const int ledPin = 2;
 
void setup() {
 pinMode(ledPin, OUTPUT);
 pinMode(buttonPin, INPUT);
}
 
void loop() {
 if (digitalRead(buttonPin) == HIGH) {
 digitalWrite(ledPin, HIGH);
 }
 else {
 digitalWrite(ledPin, LOW);
 }
}

Bei dem Programm leuchtet eine LED wenn man den Taster betätigt. Wenn man ihn auslasst leuchtet die LED nicht mehr.

Ich möchte das Programm so ändern, dass wenn man den Taster einmal betätigt die LED solange leuchtet, bis man erneut den Taster betätigt.

Stehe gerade auf der Leitung, wie sich das realisieren lässt...

Hoffe ihr könnt mir helfen :slight_smile:

mich3499:
Stehe gerade auf der Leitung, wie sich das realisieren lässt...

Hoffe ihr könnt mir helfen :slight_smile:

Nimm dazu eine Statusvariable, diese dann abfragen.

Wenn Variable ist 0, dann einschalten.
Wenn Variable ist 1, dann ausschalten.

Wenn ich dir zeige, wie ich das realisiere, wirst du nichts verstehen....
Aber die grundsätzlichen Vorgänge/Komponenten kannst du erkennen.

Diese Funktionalität kann man auch mit anderen Mitteln, als ich sie verwende, erreichen.

Ein Programm, aus meiner Wühlkiste, welches genau das tut, was du erreichen möchtest:

#include <CombiePin.h>
#include <CombieTimer.h>
#include <CombieTools.h>

using Combie::Tools::FlankenErkennung;
using Combie::Timer::EntprellTimer;


using EingabeTaster = Combie::Pin::TasterGND<2>; // Taster zwischen Pin und GND(invertierend)
using Counter       = Combie::Tools::Counter<byte>;
using BuiltInLed    = Combie::Pin::OutputPin<LED_BUILTIN>;

BuiltInLed        led;
EingabeTaster     taster; 
EntprellTimer     entprellen(20);
FlankenErkennung  flankenerkennung;
Counter           counter;


void setup() 
{
  taster.initPullup();
  led.init();
  counter.onCount([](Counter &){led.toggle();});
}

void loop() 
{
  counter = flankenerkennung = entprellen = taster;
}

CombieLib.zip (66.4 KB)

Du mußt eine Änderung des Schalterzustandes ( zB von L auf H) erkennen und damit die LED schalten.
Eine änderung erkennt man indem der vorherige Status verschieden vom jetzigen Tasterzustand ist und der Taster H ausgibt. Ein 10ms delay entprellt.

Grüße Uwe

Mit dem Befehl:

if (digitalRead(buttonPin) == HIGH) {
 digitalWrite(ledPin, HIGH);
 }
 else {
 digitalWrite(ledPin, LOW);

wird ja der Zustand des Tasters ausgelesen und der Ausgang auf High gesetzt. Aber sobald man auslässt ist der Ausagang wieder auf Low.

Geht das so in etwa:?

if (digitalRead(buttonPin) == HIGH && var = 0) {
digitalWrite(ledPin, HIGH);
var = 1;
}
else {
delay(10);
}
if (digitalRead(buttonPin) == HIGH && var = 1) {
digitalWrite(ledPin, LOW);
var = 0;
}
else {
delay(10);
}

Probier es aus.
Habe nur kurz drauf geschaut, da unterwegs, sieht aber gut aus.

Nein.

if (digitalRead(buttonPin) == HIGH && var = 0) {
digitalWrite(ledPin, HIGH);
var = 1;
...
if (digitalRead(buttonPin) == HIGH && var = 1) {

Das 2. if ist sofort wieder war noch bevor Du den Taster überhaupt loslassen konntest.

Du mußt das Schrittweise machen.

Schritt 1
Taster 1 und Variable 0 und LED aus -> LED ein und Variable 1 und delay (10)
Schritt 2
Taster 0 und Variable 1 -> Variable 0 und delay (10)
Schritt 3
Taster 1 und Variable 0 und LED aus -> LED ein und Variable 1 und delay (10)
Schritt 4
Taster 0 und Variable 1 -> Variable 0 und delay (10)
es folgt Schritt 1

if (digitalRead(buttonPin) == HIGH && var = 0) {

auf doppel == aufpassen!

Grüße Uwe

uwefed:
Nein.

Du hast recht, man sollte eben doch genauer lesen.

Der TO kann es aber dennoch selbst probieren.

Mein Motto, nur durch selbst probieren lernt man besser dazu.

HotSystems:
Der TO kann es aber dennoch selbst probieren.

Mein Motto, nur durch selbst probieren lernt man besser dazu.

Darum schreibe ich ja auch keinen Sketch, sondern nur Erklährungen (Pseudoflußdiagramm) wie's zu programmieren ist.

Grüße Uwe

Mein Motto, nur durch selbst probieren lernt man besser dazu.

Ich sage dazu:

Wir lernen, indem wir es tun!

Darum schreibe ich ja auch keinen Sketch, sondern nur Erklährungen (Pseudoflußdiagramm) wie's zu programmieren ist.

Mir ist das recht egal.

Wenn es schon fertig in der Wühlkiste liegt, dann raus damit.
Nur selten interessiert mich ein Problem so, dass ich selber ein Programm extra dafür schreibe.
Meist müssen sich die Fragenden mit abstrakten Andeutungen/Ansagen zufrieden geben.

Oft als "Testballon" ausgeführt.
An den Antworten/Nachfragen sehe ich dann wie "wach" das Gegenüber ist.

So manchen/manche rüttel ich damit aus der Komfortzone raus.
(naja, das kann auch mal Stimmungsmäßig nach hinten los gehen)

Habe jetzt folgendes Programm geschrieben, welches funktioniert:

int var,x=0;

void setup()
{
  pinMode(4, OUTPUT);   
  pinMode(5, INPUT); 
}

 void loop()   
{

  if (digitalRead(5) == LOW && x==0) {
 digitalWrite(4, LOW);
 x=1;
 }
 else {
 delay(10);
 }


 if (digitalRead(5) == HIGH && x==1) {
  digitalWrite(4, HIGH);
  x=2;
 }
 else {
  delay(10);
 }


 if (digitalRead(5) == LOW && x==2) {
  digitalWrite(4, HIGH);
  x=3;
 }
 else {
  delay(10);
 }


 if (digitalRead(5) == HIGH && x==3) {
  digitalWrite(4, LOW);
  x=0;
 }
 else {
  delay(10);
 }



}

finde auch, dass es viel mehr bringt, wenn man das Programm dann selber schafft, aber es ist ziemlich nervig, wenn man einfach nicht weiterkommt :smiley:

die

 delay(10);

nutzen nichts im else -Teil.

Die braucht es zum Entprellen bei einem Zustandswechsel.

Glaube ich Dir nicht daß es funktioniert.
Jetzt schaltest Du nur Flankengetriggert das LED synchron zum Tasrter ein und aus.
Bei x==1 und x==3 darfst du die LED nicht ein oder ausschalten sondern nur die Variable x hinaufzählen.

Grüße Uwe

Ok Danke.

Was schreibe ich dann in else rein?

die

delay(10);

nutzen nichts im else -Teil.

Die braucht es zum Entprellen bei einem Zustandswechsel.

Na ja, die entprellen schon, indirekt.

Genaugenommen dauern alle loop-Durchläufe 20 ms, ausser wenn ein Flankenwechsel erkannt wird.
( der dauert 10 ms )

Und in dem seltenen Fall, dass ein Prell-Signalwechsel genau synchron mit zwei digitalRead - Aufrufen stattfindet, wird das Spiel eben sofort ohne delay im nächsten loop-Durchlauf nochmal probiert.

Aber natürlich hast du recht, Uwe. So verworren sollte man so simple Logik nicht machen.

Man braucht in den else Zweig gar nichts reinzuschreiben und kann ihn auch ganz weglassen.

Die Zustandsvariable x ist (nur) gut um sich zu merken, wie der Taster-Zustand gerade ist. Und um aus dem Tastenzustand ein Ereignis zu machen. ( Das wäre dann auch im if-Teil )

Wenn einmal drücken einschalten soll und nochmal drücken ausschalten, nimmt man einfach noch so eine Variable.
Und gibt ihnen bessere Namen :wink: