Blink Sketch mit unterschiedlichen An/Auszeitende

Servus,
Ich würde gerne zwei LEDs blinken lassen und die Einschalt bzw Ausschaltzeiten unterschiedlich gestalten. Das funktioniert auch teilweise. Problem ist nur das die Leds manchmal korrekt blinken und zeitweise nur kurz aufblitzen. Wo liegt der Fehler?...ich komm einfach nicht drauf ...
(Leds sind korrekt angeschlossen mit 200ohm Wiederstand an der Anode. Blink Sketch mit delay funktioniert auch einwandfrei)

unsigned long aktzeit1;
unsigned long vergzeit1 = 0;
unsigned long aktzeit2;
unsigned long vergzeit2 = 0;
unsigned long aktzeit3;
unsigned long vergzeit3 = 0;
unsigned long aktzeit4;
unsigned long vergzeit4 = 0;
int taster = 2;
int tasterst;
int ledgruen = 8;
int ledgelb = 4;
int ledrot = 6;

void setup() {

pinMode (taster, INPUT);
pinMode (ledgruen, OUTPUT);
pinMode (ledgelb, OUTPUT);
pinMode (ledrot, OUTPUT);
Serial.begin (9600);
}

void loop() {

blinkgelb();
blinkgruen();

}
void blinkgelb()
{
aktzeit1 = millis ();
if (aktzeit1-vergzeit1 >= 1000)
{vergzeit1=aktzeit1;
digitalWrite (ledgelb, HIGH);}

aktzeit2 = millis ();
if (aktzeit2-vergzeit2 >= 1000)
{vergzeit2=aktzeit2;
digitalWrite (ledgelb, LOW);}
}

void blinkgruen()
{
aktzeit3 = millis();
if (aktzeit3-vergzeit3 >= 5000)
{vergzeit3 = aktzeit3;
digitalWrite (ledgruen, HIGH);}

aktzeit4 = millis();
if (aktzeit4-vergzeit4 >= 5000)
{vergzeit4 = aktzeit4;
digitalWrite (ledgruen, LOW);}
}

Hallo benjixx
Schaue dir dazu am Besten das BLINKWITHOUTDELAY Beispiel aus dem IDE an.
Ich wünsche einen geschmeidigen Abend und viel Spass beim Programmieren in C++.

Hallo benjixx,

aktzeitX=ergzeitX=millis(); im setup() aufrufen um eine gemeinsame Systemzeit zu setzen.

Probier das man und bedenke der millis läuft in ca 55 Tagen über.

bei mir sieht das dann immer so aus:
// Prüfe ob BH1750 Timer Speicherzelle einen Überlauf hatte? Passiert ca alle 50 Tage
if (SYS_tiActBH1750 >= SYS_tiOldBH1750) //KEIN Überlauf der unsigned long Timer Speicherzelle vorhanden
{
if (SYS_tiActBH1750 - SYS_tiOldBH1750 >= SYS_TIDELTA_BH1750) // Prüfen ob Detazeit vergangen ist
{
BH_stTimerElapst = true; // Timerzeit ist erreicht
}
}
else // Überlauf der unsigned long Timer Speicherzelle hat stattgefunden: SYS_tiAct ist kleiner als SYS_tiOld
{
if ((ULONGMAX - SYS_tiOldBH1750 + SYS_tiActBH1750) >= SYS_TIDELTA_BH1750) // Prüfe ob Detazeit vergabgen. Berechnung: max Zählerstand 2^32-1 - letzte System + aktuelle Systemzeit ergibt die vergangene Systemzeit
{
BH_stTimerElapst = true; // Timerzeit ist erreicht
}

Gruß Mascho

Setze Deinen Code bitte in Codetags. Wie das geht, steht hier.

Gruß Tommy

OK, Sorry :grimacing: Bin neu hier und irgendwie geht des mit den millis nicht in meinen Schädel :sweat_smile:


unsigned long aktzeit1;
unsigned long vergzeit1 = 0;
unsigned long aktzeit2;
unsigned long vergzeit2 = 0;
unsigned long aktzeit3;
unsigned long vergzeit3 = 0;
unsigned long aktzeit4;
unsigned long vergzeit4 = 0;
int taster = 2;
int tasterst;
int ledgruen = 8;
int ledgelb = 4;
int ledrot = 6;

void setup() {

pinMode (taster, INPUT);
pinMode (ledgruen, OUTPUT);
pinMode (ledgelb, OUTPUT);
pinMode (ledrot, OUTPUT);
Serial.begin (9600);
}

void loop() {

blinkgelb();
blinkgruen();

}    
void blinkgelb()
{  
aktzeit1 = millis ();
if (aktzeit1-vergzeit1 >= 5000)
{vergzeit1=aktzeit1;
 digitalWrite (ledgelb, HIGH);}
 
aktzeit2 = millis (); 
if (aktzeit2-vergzeit2 >= 1000)
{vergzeit2=aktzeit2;
 digitalWrite (ledgelb, LOW);}  
}

void blinkgruen()
{
aktzeit3 = millis();
if (aktzeit3-vergzeit3 >= 5000)
{vergzeit3 = aktzeit3;
 digitalWrite (ledgruen, HIGH);} 
 
aktzeit4 = millis();
if (aktzeit4-vergzeit4 >= 5000)
{vergzeit4 = aktzeit4;
 digitalWrite (ledgruen, LOW);} 
}
unsigned long aktzeit1;
unsigned long vergzeit1 = 0;
unsigned long aktzeit2;
unsigned long vergzeit2 = 0;
unsigned long aktzeit3;
unsigned long vergzeit3 = 0;
unsigned long aktzeit4;
unsigned long vergzeit4 = 0;
int taster = 2;
int tasterst;
int ledgruen = 8;
int ledgelb = 4;
int ledrot = 6;

void setup() {

  pinMode (taster, INPUT);
  pinMode (ledgruen, OUTPUT);
  pinMode (ledgelb, OUTPUT);
  pinMode (ledrot, OUTPUT);
  Serial.begin (9600);
}

void loop() {

  blinkgelb();
  blinkgruen();
}
void blinkgelb()
{
  aktzeit1 = millis ();
  if (aktzeit1 - vergzeit1 >= 5000)
  { 
    vergzeit1 = aktzeit1;
    digitalWrite (ledgelb, !digitalRead(ledgelb));
  }
}

void blinkgruen()
{
  aktzeit3 = millis();
  if (aktzeit3 - vergzeit3 >= 5000)
  {
    vergzeit3 = aktzeit3;
    digitalWrite (ledgruen, !digitalRead(ledgruen));
  }
}

Meinst du so?
Dann geht gar nix mehr


unsigned long aktzeit1;
unsigned long vergzeit1 = 0;
unsigned long aktzeit2;
unsigned long vergzeit2 = 0;
unsigned long aktzeit3;
unsigned long vergzeit3 = 0;
unsigned long aktzeit4;
unsigned long vergzeit4 = 0;
int taster = 2;
int tasterst;
int ledgruen = 8;
int ledgelb = 4;
int ledrot = 6;

void setup() {

pinMode (taster, INPUT);
pinMode (ledgruen, OUTPUT);
pinMode (ledgelb, OUTPUT);
pinMode (ledrot, OUTPUT);
Serial.begin (9600);
aktzeit1 = millis ();
aktzeit2 = millis (); 
aktzeit3 = millis();
aktzeit4 = millis();
}

void loop() {

blinkgelb();
blinkgruen();

}    
void blinkgelb()
{  

if (aktzeit1-vergzeit1 >= 5000)
{vergzeit1=aktzeit1;
 digitalWrite (ledgelb, HIGH);}
 
if (aktzeit2-vergzeit2 >= 1000)
{vergzeit2=aktzeit2;
 digitalWrite (ledgelb, LOW);}  
}

void blinkgruen()
{

if (aktzeit3-vergzeit3 >= 5000)
{vergzeit3 = aktzeit3;
 digitalWrite (ledgruen, HIGH);} 
 

if (aktzeit4-vergzeit4 >= 5000)
{vergzeit4 = aktzeit4;
 digitalWrite (ledgruen, LOW);} 
}

Danke. Aber mit dem Sketch kann ich die An bzw Ausphasen nicht steuern. Ich will eine led z.B. 3 sec anschalten und 5 sec auschalten. :wink:

Hallo
Wenn du unterschiedliche Ein und Aus Zeiten haben willst, dann must du eine Abfrage mit einbauen ob die LED Grade ein oder aus ist damit du auf die richtige Zeit abfragen kannst.

If LED ein
Abfrage auf Hellzeit
Else
Abfrage auf Dunkelzeit

In etwa so

Ersetze:

void blinkgelb()
{
  aktzeit1 = millis ();
  if ((aktzeit1 - vergzeit1 >= 5000) && (digitalRead(ledgelb) == LOW))
  { vergzeit1 = aktzeit1;
    digitalWrite (ledgelb, HIGH);
  }

  if ((aktzeit1 - vergzeit1 >= 5000) && (digitalRead(ledgelb) == HIGH))
  { vergzeit1 = aktzeit1;
    digitalWrite (ledgelb, LOW);
  }
}

Baue Deine Zeiten.
geht?

Hallo benjixx
Bist du vertraut mit der Formulierung eigner Datentypen?
Diese Aufgabenstellung läßt sich sehr gut über ein Objekt, für die Led und Zeiten, und einem Timerservice abfrühstücken.
Ich wünsche einen geschmeidigen Abend und viel Spass beim Programmieren in C++.

Ich bin Anfänger in der Materie :grimacing: :sweat_smile: also Nein. Ich will Programmieren lernen , aber nicht mit Copy and Paste. Ich will es verstehen. Deswegen Step by Step :slightly_smiling_face:

#10 probiert?
Die Zeiten (5000) für an und aus verändert?
Fragen dazu?

Danke für die Antwort. Dein Code hat Funktioniert :slightly_smiling_face:
Hab auch noch eine andere Lösung :grimacing:


unsigned long aktzeit1;
unsigned long vergzeit1 = 0;
unsigned long aktzeit2;
unsigned long vergzeit2 = 0;

int taster = 2;
int tasterst;
int ledgruen = 8;
int ledgelb = 4;
int ledrot = 6;

void setup() {

pinMode (taster, INPUT);
pinMode (ledgruen, OUTPUT);
pinMode (ledgelb, OUTPUT);
pinMode (ledrot, OUTPUT);
Serial.begin (9600);


}

void loop() {

blinkgelb();
blinkgruen();

}    
void blinkgelb()
{  
if (digitalRead (ledgelb) == LOW){
aktzeit1 = millis ();
if (aktzeit1-vergzeit1 >= 1000) 
{vergzeit1=aktzeit1;
  digitalWrite (ledgelb, HIGH);}}

else {
aktzeit1 = millis ();
if (aktzeit1-vergzeit1 >= 5000) 
{vergzeit1=aktzeit1;
  digitalWrite (ledgelb, LOW);}}
}

void blinkgruen()
{
if (digitalRead (ledgruen) == LOW){
aktzeit2 = millis();
if (aktzeit2-vergzeit2 >= 5000)
{vergzeit2 = aktzeit2;
 digitalWrite (ledgruen, HIGH);}} 

else {
aktzeit2 = millis();
if (aktzeit2-vergzeit2 >= 1000)
{vergzeit2 = aktzeit2;
 digitalWrite (ledgruen, LOW);}} 
}

Lust auf lokale Variablen?

const uint16_t EINZEIT_GELB = 1000;
const uint16_t AUSZEIT_GELB = 5000;
const uint16_t EINZEIT_GRUEN = 5000;
const uint16_t AUSZEIT_GRUEN = 1000;

const byte ledgruen = 8;
const byte ledgelb = 4;

void setup()
{
  pinMode (ledgruen, OUTPUT);
  pinMode (ledgelb, OUTPUT);
}

void loop()
{
  blinkgelb();
  blinkgruen();
}

void blinkgelb()
{
  unsigned long aktzeit = millis();
  static unsigned long vergzeit = 0;
  static bool ausEIN = false;

  if (ausEIN)
  {
    if (aktzeit - vergzeit >= EINZEIT_GELB)
    {
      vergzeit = aktzeit;
      ausEIN = !ausEIN;
      digitalWrite (ledgelb, ausEIN);
    }
  } else {
    if (aktzeit - vergzeit >= AUSZEIT_GELB)
    {
      vergzeit = aktzeit;
      ausEIN = !ausEIN;
      digitalWrite (ledgelb, ausEIN);
    }
  }
}

void blinkgruen()
{
  unsigned long aktzeit = millis();
  static unsigned long vergzeit = 0;
  static bool ausEIN = false;

  if (ausEIN)
  {
    if (aktzeit - vergzeit >= EINZEIT_GRUEN)
    {
      vergzeit = aktzeit;
      ausEIN = !ausEIN;
      digitalWrite (ledgruen, ausEIN);
    }
  } else {
    if (aktzeit - vergzeit >= AUSZEIT_GRUEN)
    {
      vergzeit = aktzeit;
      ausEIN = !ausEIN;
      digitalWrite (ledgruen, ausEIN);
    }
  }
}

Lust auf Felder und Funktionsparameter?

enum {GELB, GRUEN};
const byte FARBEN = 2;
const uint16_t EINZEIT[FARBEN] = {1000, 5000};
const uint16_t AUSZEIT[FARBEN] = {5000, 1000};
const byte led[FARBEN] = {4, 8};  // GELB, GRUEN

void setup()
{
  pinMode (led[GELB], OUTPUT);
  pinMode (led[GRUEN], OUTPUT);
}

void loop()
{
  blinken(GELB);
  blinken(GRUEN);
}

void blinken(const byte farbe)
{
  unsigned long aktzeit = millis();
  static unsigned long vergzeit[FARBEN] = {0, 0};
  static bool ausEIN[FARBEN] = {false, false};

  if (ausEIN[farbe])
  {
    if (aktzeit - vergzeit[farbe] >= EINZEIT[farbe])
    {
      vergzeit[farbe] = aktzeit;
      ausEIN[farbe] = !ausEIN[farbe];
      digitalWrite (led[farbe], ausEIN[farbe]);
    }
  } else {
    if (aktzeit - vergzeit[farbe] >= AUSZEIT[farbe])
    {
      vergzeit[farbe] = aktzeit;
      ausEIN[farbe] = !ausEIN[farbe];
      digitalWrite (led[farbe], ausEIN[farbe]);
    }
  }
}

Puhhh...sieht interessant aus :sweat_smile: :grimacing: Danke für die Antwort :smiley:

Wenn man möchte, daß zusammengehörige Informationen auch zusammenstehen, bieten sich anstelle von Funktionen Methoden in Klassen an:

class Blink {
    const byte led;
    const unsigned long EINZEIT, AUSZEIT;
    unsigned long vergzeit;
    bool ausEIN = false;
  public:
    Blink(const byte led, const unsigned long EINZEIT, const unsigned long AUSZEIT) :
      led(led), EINZEIT(EINZEIT), AUSZEIT(AUSZEIT) {}

    void init()
    {
      pinMode (led, OUTPUT);
    }

    void blinken()
    {
      unsigned long aktzeit = millis();
      if (ausEIN)
      {
        if (aktzeit - vergzeit >= EINZEIT)
        {
          vergzeit = aktzeit;
          ausEIN = !ausEIN;
          digitalWrite (led, ausEIN);
        }
      } else {
        if (aktzeit - vergzeit >= AUSZEIT)
        {
          vergzeit = aktzeit;
          ausEIN = !ausEIN;
          digitalWrite (led, ausEIN);
        }
      }
    }
};

const byte FARBEN = 2;
Blink blink[FARBEN] =
{
  //led, EINZEIT, AUSZEIT
  {4, 1000, 5000},  // Gelb
  {8, 5000, 1000},  // Gruen
};

void setup()
{
  for (Blink &b : blink) b.init();
}

void loop()
{
  for (Blink &b : blink) b.blinken();
}

Fragen sind möglich :wink:

1 Like

Richtig so....

Jetzt fehlt noch die Variante mit dem Multitaskingsystem
Die Datenflussorientierte.
Die mit switch/case, die mit goto, die mit Funktionspointern

Habe ich noch welche vergessen?

1 Like

jepp, "branchless coding"

Du meinst das so in etwa:

#include <Streaming.h> // die Lib findest du selber ;-)
Print &cout = Serial; // cout Emulation für "Arme"

// die neueste CombieLib.zip findest du mit der Forensuche

#include <CombieTypeMangling.h>
using namespace Combie::Millis;


#include <CombiePin.h>
using RoteLed  = Combie::Pin::OutputPin<13>;
using BlaueLed = Combie::Pin::OutputPin<12>;

#include <CombieTimer.h>
Combie::Timer::PpmGenerator rotTimer  {3_Sekunden, 1_Sekunde};
Combie::Timer::PpmGenerator blauTimer {1_Sekunde, 3_Sekunden};


void setup()
{
  Serial.begin(9600);
  cout << F("Start: ") << F(__FILE__) << endl;
  RoteLed{}  .init();
  BlaueLed{} .init();
}

void loop()
{
  RoteLed{}  = rotTimer;
  BlaueLed{} = blauTimer;
}

Wobei ich das gerne als Datenflusssichtweise bezeichne. Denn der Datenfluss kennt eher keine Entscheidungen oder Schleifen.