Led gewisse Zeit mit button ansteuern

Hallo zusammen
hab da nen Problem mit meiem Sketch...

const int led = 1;

const int Knopf = 2;
const int count = 0;

void setup()
{
  pinMode(led, OUTPUT);
  
  pinMode(Knopf, INPUT);
}

void loop()
{
  static int Knopf_last=0;
  int Knopf_state=digitalRead(Knopf);

    while (Knopf_state != Knopf_last)
  {
    count++;
    Knopf_last = knopf_state;
    if (count >= 4) {
       count = 0;
    }
  }

  switch (count) {
     case 1:
        digitalWrite(led, HIGH);
        delay(1800000);
        break;
     case 2:
        digitalWrite(led, HIGH);
        delay(3600000);
        break;
     case 3:
        digitalWrite(led, HIGH);
        delay(5400000);
        break;
  }
}

Fehler:increment of read-only variable 'count'

Ich blick es gerade nicht.

Plan ist es eigentlich nach
1xdrücken vom knopf 30minuten LED
2xdrücken vom knopf 60minuten LED
3xdrücken vom knopf 90minuten LED
Im idealfall auch das er wechselt bzw aus geht wenn man nochmal drückt...

Jemand ne idee=?

kkz89:

const int count = 0;

Hallo kkz89,

Du kannst eine Konstante nicht ändern. Das "const" steht für Kontante.
Mach das mal weg und versuche es dann.

Lesestoff: const - Arduino Reference

Edit:
Du musst auch delay durch millis ersetzen. In der Zeit in der das delay läuft, wird Deine Taste nicht abgefragt!
Siehe "Nachtwächtererklärung" hier im Forum (BlinkwithoutDelay - Die Nachtwächtererklärung - Deutsch - Arduino Forum) und natürlich in der IDE in den Beispielen "BlinkWithoutDelay".

Hast Du an Deinem Taster einen pulldown oder pullup Widerstand? Das könnte sonst zu komischen Dingen führen.

Und das mit Deinem "While" dürfte so auch nicht sauber funktionieren.

Deine Taste zählt auch beim Drücken und loslassen.

Gruß, Jürgen

Hallo
Deine Auswahl der Pins ist für einen Arduino ungünstig definiert.
Die Pins D0 und D1 werden von der USB-Schnittstelle verwendet um den Arduino zu programmieren.

Hi.
Ist ein kleiner digispark...
Muss ich mir mit den Millis mal genauer angucken...
Angeschlossen ist noch nichts. Erstmal code schreiben

Hallo
Der digispark ist aber sehr lütt :slight_smile:

Am Besten zu beginnst mit einem Zeitgeber, auf der Basis der millis()-Funktion, den Du danach für die Tasterabfrage und für die eigentliche Zeitfunktion, 30,60, 90 Minuten, erweitern kannst.

So sieht der Code jetzt aus..
Wobei er noch nicht wirklich macht was gewünscht ist..
Da bin ich jetzt mit dem Latein am Ende langsam

const int buttonPin = 2;     // the number of the pushbutton pin
const int ledPin =  4;      // the number of the LED pin
int count = 0;
unsigned long off_time;

boolean ledState=false;

int buttonState = 0;         // variable for reading the pushbutton status


void setup() {
 // initialize the LED pin as an output:
 pinMode(ledPin, OUTPUT);      
 // initialize the pushbutton pin as an input:
 pinMode(buttonPin, INPUT);  
 digitalWrite(ledPin, LOW);

}

void loop(){

{
  static int buttonPin_last=0;
  int buttonPin_state=digitalRead(buttonPin);

    while (buttonPin_state != buttonPin_last)
  {
    count++;
    buttonPin_last = buttonPin_state;
    if (count >= 4) {
       count = 0;
    }
  }



if ((ledState) && (millis()>=off_time)) /* is it on and is it later or equal to off_time */
{
   digitalWrite(ledPin,LOW);
   ledState = false;
}
else if (!ledState) /* is it off? */
{
  
   switch (count) {
     case 1:
        digitalWrite(ledPin, HIGH);
        ledState = true;
        off_time = millis() + 1000;
        break;
     case 2:
        digitalWrite(ledPin, HIGH);
        ledState = true;
        off_time = millis() + 5000;
        break;
     case 3:
        digitalWrite(ledPin, HIGH);
        ledState = true;
        off_time = millis() + 10000;
        break;
   
 
   
  
}
}
}
}

kkz89:
So sieht der Code jetzt aus..

Wie?

Geändert.. Hat den Code raus gehauen...
Zeiten sind erstmal klein zum testen..
Aber bei einmaligem druck ist led Dauer an...
Beim erneutem geht sie aus..

Hallo,
für die Fehlersuche im Sketch hat sich die Verwendung von Serial.println(wasIchSchonImmerWissenWollte) ; sehr bewährt.

Fällt beim digispark aus...

Hab leider keinen..
Und dafür jetzt extra einen holen...
Mh..

off_time = millis() + 1000;

Das ist falsch.
Wird zumindest nach ca 49 Tagen eine Fehlfunktion zur Folge haben.

kkz89:
Plan ist es eigentlich nach
1xdrücken vom knopf 30minuten LED
2xdrücken vom knopf 60minuten LED
3xdrücken vom knopf 90minuten LED
Im idealfall auch das er wechselt bzw aus geht wenn man nochmal drückt...

Jemand ne idee=?

Ja.

Zwischenfrage: heisst
1x Drücken == Beim ersten Tastendruck
2x Drücken == Beim zweiten Tastendruck
3x Drücken == Beim dritten Tastendruck

jeweils und unabhängig von anderen Variablen?
Also z.B. NICHT folgender Ablauf:
1x Drücken == erster Tastendruck erkannt

2x Drücken:
Wenn (erster Tastendruck und weniger als xx Zeit um)
Dann (zweiter Tastendruck erkannt)
Sonst (erster Tastendruck erkannt)

3x Drücken:
Wenn (zweiter Tastendruck und weniger als xx Zeit um)
Dann (dritter Tastendruck erkannt)
Sonst (erster Tastendruck erkannt)

Hallo
hast du zum Lernen das IDE Beispiel BLINKWITHOUTDELAY angeschaut und geladen.
Dieses Beispiel ist die MOAS - Mutter aller Arduino Sketche :slight_smile:

2x Drücken:
Wenn (erster Tastendruck und weniger als xx Zeit um)
Dann (zweiter Tastendruck erkannt)
Sonst (erster Tastendruck erkannt)

Meine Glaskugel sagt: xx ist die Zeit solange die LED noch leuchtet.
Wenn nicht der kryptische Zusatz mit
"Im idealfall auch das er wechselt bzw aus geht wenn man nochmal drückt... "
wäre, könnte man einfach mit jedem Drücken die LED-Dauer um 30 Minuten erhöhen und käme ohne Zählen der Tastendrücke aus.

Und delay(5400000); oder ähnliches geht natürlich überhaupt nicht, da man ja weiter Tastendrücke zählen will, während "das Programm" schon läuft.

Richtig, PaulPaulson: Bei BlinkWithoutDelay geht es nicht um Blink, sondern um WithoutDelay

kkz89:
Hab leider keinen..
Und dafür jetzt extra einen holen...
Mh..

Ich habe selbst mit einem ATtiny85 angefangen, das gestaltet sich doch recht mühselig, gerade am Anfang. Solltest Du noch mehr mir Arduinos vorhaben, dann ganz klar ja!

Es darf aber auch ein Nano oder ProMini sein, der hat einen ATmega328 drauf und kann mit dem CP2102.Modul auch den seriellen Monitor ansprechen.

Ich habe Deine Schrittkette mal etwas aufgeräumt (getestet mit UNO):

const uint16_t INTERVALL = 5000; // zum Probieren verkürzt
const int buttonPin = 2;     // the number of the pushbutton pin
const int ledPin =    4;     // the number of the LED pin

void setup() {
  pinMode(ledPin, OUTPUT);
  pinMode(buttonPin, INPUT_PULLUP);
}

void loop() {
  uint32_t jetzt = millis();
  static uint32_t vorhin = jetzt, intervall = 0;
  static byte schritt = 0;
  bool buttonStateakt = !digitalRead(buttonPin), weiter = false;
  static bool buttonStatealt = buttonStateakt;

  if (buttonStatealt != buttonStateakt) {
    if (buttonStateakt) {
      weiter = true;
    }
    buttonStatealt = buttonStateakt;
    delay(30); // simples Entprellen
  }
  switch (schritt) {
    case 0:
      if (weiter) {
        vorhin = jetzt;
        intervall = INTERVALL;
        digitalWrite(ledPin, HIGH);
        schritt++;
      }
      break;
    case 1:
      if (weiter) {
        intervall += INTERVALL;
        schritt++;
      }
      break;
    case 2:
      if (weiter) {
        intervall += INTERVALL;
        schritt++;
      }
      break;
    case 3:
      if (weiter) {
        intervall = 0;
        schritt = 0;
      }
      break;
  }

  if (jetzt - vorhin >= intervall) {
    digitalWrite(ledPin, LOW);
    schritt = 0;
  }
}

Hallo agmue,
das

weiter = false;

hast du gut versteckt :slight_smile:

"Was bin ich wieder für ein Schelm!" Heinz Erhardt

Hi michael_x

michael_x:
Meine Glaskugel sagt: xx ist die Zeit solange die LED noch leuchtet.

Nein, das war nicht die Idee dahinter.
Also meine rudimentäre Lösung wäre wie folgt:

const int buttonPin = 2;     // the number of the pushbutton pin
const int ledPin = LED_BUILTIN;

unsigned int count = 0;
const unsigned long ontime = 30000;
unsigned long ontime_start; // Merker Output ein
bool lastbuttonState = HIGH; // Merker Tastenstatus - Vorbelegt
unsigned long bouncemillis = 0; // Zeit Merker für Abfragesperre
const int bouncetime = 30; // Zeit in ms für Abfragesperre

void setup()
{
  // initialize the LED pin as an output:
  pinMode (ledPin, OUTPUT);
  digitalWrite (ledPin, LOW);
  pinMode (buttonPin, INPUT_PULLUP); // Taste schliesst nach GND ohne externen Widerstand
}

void loop()
{
  if (millis() - bouncemillis > bouncetime)
  {
    if (!digitalRead (buttonPin))
    {
      if (lastbuttonState)
      {
        // Taste (neu) gedrückt
        bouncemillis = millis();
        ontime_start = millis();
        lastbuttonState = LOW;
        count++;
      }
    }
    else
    {
      lastbuttonState = HIGH;
    }
  }
  if ((millis() - ontime_start > (ontime * count)) || (count > 3))count = 0;  // Soll aus? JA!
  digitalWrite (ledPin, count);
}

Der schaltet nach jedem Tastendruck eins weiter.
Ist er am Ende angekommmen, gehts bei 0 los und LED geht aus.

Die andere Variante ist, das mit jedem Tastendruck weitergeschaltet wird, solange eine bestimmte Zeit nicht abgelaufen ist.
Im Folgenden Beispiel wäre das 1sek.
Wird also zum zweiten Mal auf die Taste gedrückt, wenn die sekunde um ist, geht de Lampe erstmal aus.
Ist sie aus, drückst Taste, geht sie in Stufe 1.
schaffst Du es jetzt innerhalb sekunde erneut zu drücken, geh in Stufe 2.
Und beim nächsten mal drücken ist die Sekunde vorbei - dann wieder aus.
usw.

// Forensketch - ungetestet aber kompiliert
// Die Idee dahinter dürfte klar sein.
const int buttonPin = 2;     // the number of the pushbutton pin
const int ledPin = LED_BUILTIN;

int count = 0;
const unsigned long ontime = 30000;
unsigned long ontime_start; // Merker Output ein
unsigned long zaehltime; // Merker für Tastendruckzeit
bool lastbuttonState = HIGH; // Merker Tastenstatus - Vorbelegt
unsigned long bouncemillis = 0; // Zeit Merker für Abfragesperre
const int bouncetime = 30; // Zeit in ms für Abfragesperre

void setup()
{
  // initialize the LED pin as an output:
  pinMode (ledPin, OUTPUT);
  digitalWrite (ledPin, LOW);
  pinMode (buttonPin, INPUT_PULLUP); // Taste schliesst nach GND ohne externen Widerstand
}

void loop()
{
  if (millis() - bouncemillis > bouncetime)
  {
    if (!digitalRead (buttonPin))
    {
      if (lastbuttonState)
      {
        // Taste (neu) gedrückt
        bouncemillis = millis();
        ontime_start = millis();
        lastbuttonState = LOW;
        if (count == 0) zaehltime = millis();
        if (millis() - zaehltime < 1000)
        {
          count++;
          zaehltime = millis();
        }
        else
        {
          count = 0;
        }
      }
    }
    else
    {
      // Taste nicht (mehr) gedrückt
      lastbuttonState = HIGH;
    }
  }
  if ((millis() - ontime_start > (ontime * count)) || (count > 3))count = 0;  // Soll aus? JA!
  digitalWrite (ledPin, count);
}

Ich hab das Ganze auch noch in schick und lauffähig sowohl für uno und ähnliches sowie für den vom TO rumzuliegen...

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.