[Projekt] INTERVAL

Hi hier möchte ich euch meine kleine Abwandlung von “BlinkWithoutDelay” vorstellen.

Sie befindet sich im Form einer ZIP Library im Anhang.
Installation, z.B. mit dem Library Manager.

Bedingung:
Interval Blöcke dürfen nicht geschachtelt werden.

Ansonsten steht einer Mehrfachverwendung nichts entgegen.

Blink.ino:

#include <INTERVAL.h>

const byte LED = 13;

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

void loop() 
{
   INTERVAL(500UL)  // 500ms
   {
     digitalWrite(LED,!digitalRead(LED));
   }
}

Nachtrag:
Einen herzlichen Dank an https://www.mikrocontroller.net für die Inspiration, solche Macros zu schreiben.

INTERVAL.zip (1.67 KB)

Hallo combie,

Super Teil, auch wenn ich aktuell noch keine direkte Anwendung dafür habe, mir fällt bestimmt bald was ein. Das einfache "blinken" wird dadurch noch einfacher.

Und es funktioniert (4fach Blinken) bei mir sehr gut, gleich getestet. ;)

Danke dafür.

Und ich danke dir, für die Blumen, und den Test!

Hallo,

sehr schön. :)

Vielleicht kannste noch den Blinker einbauen der damals mit deiner Hilfe entstanden ist. ;)

#ifndef LedFolgeBlinker_H
#define LedFolgeBlinker_H

#include 

class LedFolgeBlinker
{
  private:
  unsigned long lastTimeLED;
  unsigned int on_time;
  unsigned int off_time;
  unsigned int PulseAnzahl;      // Pulse Anzahl
  unsigned int PulsePause;       // Pause zwischen Pulse Sequence [ms]
  byte pinLED;
  boolean state_LED;
  unsigned int Counter_Pulse;   // Zähler der durchgelaufenden Pulse
  boolean state_Pause;          // Zustandspeicher ob Pause zwischen der Pulsefolgen oder nicht
  unsigned long lastTimePause;
  
  
  public:
  LedFolgeBlinker(byte pin, unsigned int on, unsigned int off, unsigned int Anzahl, unsigned int Pause); 
  
  void update();
};
#endif
#include 

  LedFolgeBlinker::LedFolgeBlinker(byte pin, unsigned int on, unsigned int off, unsigned int Anzahl, unsigned int Pause)
  {
    pinMode(pin, OUTPUT);
    state_LED = false;
    digitalWrite(pin, state_LED);
    Counter_Pulse = 0;            // Zähler der durchgelaufenden Pulse
    state_Pause= false;           // Zustandspeicher ob Pause aktiv oder nicht
    lastTimeLED = millis();
    lastTimePause = millis();

    pinLED = pin;
    on_time = on;
    off_time = off;
    PulseAnzahl = Anzahl;    // Pulse Anzahl
    PulsePause = Pause;      // Pause zwischen Pulse Sequence [ms]
    
  }
  
  void LedFolgeBlinker::update()
  {  
    if (state_LED == LOW && millis() - lastTimeLED > off_time && state_Pause == false )  {  
      digitalWrite(pinLED, HIGH);       // LED einschalten für x ms
      lastTimeLED = millis();             
      state_LED = HIGH;
    }
    if (state_LED == HIGH && millis() - lastTimeLED > on_time )  { 
      digitalWrite(pinLED, LOW);         // LED ausschalten für x ms
      lastTimeLED = millis();  
      state_LED = LOW;
      Counter_Pulse++;                    // ein Pulsetakt fertig, Zähler erhöhen
    }
    if (Counter_Pulse >= PulseAnzahl)  {
      state_Pause = true;                 // Pause aktivieren 
      Counter_Pulse = 0;                  // Zähler zurücksetzen
      lastTimePause = millis();
    }  
    if (state_Pause == true && millis() - lastTimePause > PulsePause)  {
      state_Pause = false;
    }  
    
  }

Sehr hübsch, schöne Macro-Programmierung. Geschickt, wie du beliebig viele unabhängige     static lastHit  Variable auf eine globale bool DoINTERVAL umsetzt, und das Makro sich syntaktisch wie ein if(DoINTERVAL) verhält, so dass danach alles von

  ;

bis   { /* ... */ }  zulässig ist.

C++ oder gar templates werden deutlich überbewertet. ;)

Aber eine class Interval wäre natürlich immer eine Alternative, wenn man Erweiterbarkeit auf sowas wie eine class LedFolgeBlinker im Sinne hätte ;)

Sehr hübsch, schöne Macro-Programmierung.

;-)

Einen erheblichen Teil der Blumen muss ich an https://www.mikrocontroller.net weiter geben. Denn da habe ich ein Macro dieser Art entdeckt. Nach dem das erst mal verstanden war, war die Umsetzung auf unser "BlinkWithoutDelay" Umfeld kein ganz großes Problem.

(habe oben mal einen Nachtrag gemacht)

Hallo,

ich staune auch immer wieder was ihr so an Code raus haut. Das nenne ich die "Kunst des Programmierens". Hut ab.

Ist das nicht im Prinzip das gleiche wie Simpletimer.h oder wie das heisst?

Das hab ich schon lange in Einsatz und läuft perfekt.

Kann man den Intervall als Variable angeben und innerhalb des Intervalls ändern?

Edit: Man kann

#include 

const byte LED = 13;
uint32_t dauer = 1000;

void setup()
{
  Serial.begin(9600);
  pinMode(LED, OUTPUT);
}

void loop()
{
//  uint32_t zufall = random(100, 600);

  INTERVAL(dauer)  // 500ms
  {
    digitalWrite(LED, !digitalRead(LED));
    if (dauer == 200) dauer = 1000;
    else dauer = 200;
    // dauer = zufall;
    //  Serial.println(zufall);
  }
}

Somit hat man unterschiedliche Hell-/Dunkelfasen

Oder noch kürzer:

#include 

const byte LED = 13;
uint32_t dauer[] = {1000, 200};

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

void loop()
{
  INTERVAL(dauer[digitalRead(LED)]) digitalWrite(LED, !digitalRead(LED));
}

Edit: Man kann

!
:wink:

1:0 für interval.h

Thumbs up! Karma++

Flackereffekt mit wenigen Zeilen:

#include 

long dauer[2];
const byte LED = 13;


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

void loop()
{
  INTERVAL(dauer[digitalRead(LED)])
  {
    
    dauer[0] = random(500) % 43 * 5;
    dauer[1] = random(500) % 43 * 2;
    digitalWrite(LED, !digitalRead(LED));
  }
}

Flackereffekt mit wenigen Zeilen:

Fein!

Ist es dir recht, wenn ich das bei den Beispielen mit aufnehme?

PS: Eine winzige Änderung ist nötig um ein Warning des Compilers zu vermeiden:

unsigned long dauer[2];

ElEspanol: random(500) % 43 * 5

beeindruckt ! 8) Was ist der wesentliche Unterschied zu random(215) ?

  • deins ist "grobkörniger" ?
  • Werte ( 0 .. 27 ) * 5 sind ca. 9% häufiger als (28 .. 42) * 5 ?

Macht das einen wichtigen Unterschied beim Flackern, hab ich was übersehen ? ;)

michael_x: Macht das einen wichtigen Unterschied beim Flackern, hab ich was übersehen ? ;)

Keine Ahnung, ich hab mal ein paar Tests gemacht und so hat es mir gefallen. Sieht irgendwie nach dem Geflacker der Netzwerkaktivitäten am Switch aus.

Klar kannst du das in die Beispiele mit aufnehmen, mach noch ein paar passende Komentare rein, damit auch Neulinge es auf Anhieb verstehen.

Wem es gefällt, der Karmalink ist links ;)

mach noch ein paar passende Komentare rein, damit auch Neulinge es auf Anhieb verstehen.

Ein Optimist, du bist!

Und Danke, lokal habe ich es schon drin.

combie: Ist es dir recht, wenn ich das bei den Beispielen mit aufnehme?

Ich bewerbe mich mit dieser vereinfachten Variante:

#include 

unsigned long dauer;
const byte LED = 13;

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

void loop()
{
  INTERVAL(dauer)
  {
    dauer = random(500) % 43 * 5;
    digitalWrite(LED, !digitalRead(LED));
  }
}

Ich schließe mich dem Lob der anderen gerne an :)

auch die einfache Variante ist genehm.

Vielleicht solltest du in die Beispiele noch das mit aufnehmen, wo man unterschiedliche Hell-/Dunkelfasen hat. Das bereitet Anfängern auch gerne Probleme, wenn die von delay auf nicht blockierend umsteigen

ElEspanol: auch die einfache Variante ist genehm.

Freut mich :)

ElEspanol: Vielleicht solltest du in die Beispiele noch das mit aufnehmen, wo man unterschiedliche Hell-/Dunkelfasen hat. Das bereitet Anfängern auch gerne Probleme, wenn die von delay auf nicht blockierend umsteigen

Meinst Du sowas:

#include 

const byte LED = 8;
const unsigned long dauer[] = {200, 50, 50, 50};
const byte anzahlDauer = sizeof(dauer) / sizeof(dauer[0]);
byte index;

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

void loop()
{
  INTERVAL(dauer[index])
  {
    digitalWrite(LED, !digitalRead(LED));
    index = ++index % anzahlDauer;
  }
}

Es ist übrigens nicht erforderlich, die Intervall-Dauer mit einem unsigned long Datentyp zu versehen.

Wenn man nicht eigentlich ein Beispiel für den % Operator machen will, flackert auch

#include 

const byte LED = 13;

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

byte dauer;
void loop() {
  INTERVAL(dauer)  {
     dauer = random(200);
     digitalWrite(LED, !digitalRead(LED));
  }
}

agmue:
Meinst Du sowas:

#include <INTERVAL.h>

const byte LED = 8;
const unsigned long dauer = {200, 50, 50, 50};
const byte anzahlDauer = sizeof(dauer) / sizeof(dauer[0]);
byte index;

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

void loop()
{
  INTERVAL(dauer[index])
  {
    digitalWrite(LED, !digitalRead(LED));
    index = ++index % anzahlDauer;
  }
}

das ist schon fast zuviel des guten und von Anfängern nicht gleich nachzuvollziehen.

einfach mit

if(dauer==200) dauer=1000 else dauer=200;

das es jeder gleich blickt