PWM schalten einer LED mit millis() "USA Police"

Hallo,

ich habe hier insges. 4x RGB-LEDs, wobei die einzelnen LEDs gleicher Farbe in Reihe zur PWM steuerbaren Konstantstromquelle geschaltet sind (Hardware-Thread dazu). Diese quasi 4x3 LEDs = 12 LEDs / (2x in Reihe) machen 6 schaltbare Paare.

Um delay() nicht zu verwenden, habe ich mir millis() angeschaut. Eine einzelne LED ist kein Problem. Mit dem u. g. Code sind die beiden in Reihe geschalteten roten LEDs der beiden RGBs ganz kurz an und dann für 2000ms aus.

Das habe ich mir anders gedacht. Ziel wäre es erst einmal so eine Art amerikanisches Blaulicht nachzuempfinden:

  • rote LED links mit nem delay von 60ms 3x an, dann
  • blaue LED rechts mit nem delay von 60ms 3x an, dann loop

Irgendwie stehe ich aber auf dem Schlauch was eine Pause angeht, nach u.g. Code blinkt es ja immer konstant ohne eine Pause dazwischen.

Da stimmt etwas nocht nicht... :frowning:

unsigned long startzeit_R_links = 0;


#define        laufzeit_R_links   2000UL

int R_links=3;
int brightness_R_links = 235;

void setup()
{
    pinMode(R_links, OUTPUT);       //RGB Rot links
    analogWrite(R_links, 255);
}

void loop()
{      
    unsigned long currentMillis = millis();

    if (currentMillis - startzeit_R_links >= laufzeit_R_links) {
        startzeit_R_links = millis();
        analogWrite(R_links, brightness_R_links);
        }
      else {
        analogWrite(R_links, 255);
    }


  
}

Du musst zusätzlich eine Statusvariable mitführen, wo Du gerade bist (An oder Aus) und dann eine neue Zeit starten. Also nicht einfach else benutzen.

Gruß Tommy

Hi

Dazu habe ich vll. was für Dich:
Re: LEDs verschieden flackern lassen #2
Da habe ich einen Sketch vorgestellt, mit Dem man (bis jetzt) 4 LEDs einzeln beliebig blinken/flackern lassen kann.
Die jeweiligen Muster können unterschiedlich lang/kompliziert/whatever sein und werden dann immer wieder wiederholt.

MfG

Hallo,

ja da simmt was nicht.
Wo sind denn Deine 3 mal 60ms verarbeitet, kann ich nicht sehen.

du kannst Blinken lassen , Beispiel blink without delay , und dann mittels einem Zähler mitzählen wie oft rot gebinkt wurde. 3 mal , für die nächsten 3 mal blinken die Ansteuerung für blau verwenden. Also einen Zähler der bis 6 geht und bei 1-3 rot ansteuert und bei 4-6 blau.

Heinz

Einen ähnlichen Blink Automat habe ich in meiner Wühlkiste.
Ohne PWM, aber auf das Problem angepasste Blinkzyklen.

Einfach eine Zahl in den Seriellen Monitor hacken, und so oft wird geblinkt.

Eine 1 blinkt einen Zyklus.
Eine 11 blinkt 2 Zyklen
Eine 9 9 Zyklen
Eine 999 blinkt 27 Zyklen.

Es werden alle Zahlen stumpf addiert.

#include <TaskMacro.h>
// https://forum.arduino.cc/index.php?topic=415229

const byte roteLed          = 13;
const byte blaueLed         = 12;
uint16_t   blinkAnforderung = 0; // Anzahl noch zu erledigender Blinkzyklen

void blinkOmat()
{
  static byte i = 0;  // Wiederholungszaehler
  taskBegin();
  while(1)
  {
    taskWaitFor(blinkAnforderung);
    for(i=0;i<3;i++)
    {
      digitalWrite(roteLed, HIGH); // leuchte an
      taskPause(60);
      digitalWrite(roteLed, LOW); // leuchte aus
      taskPause(60);
    }
    for(i=0;i<3;i++)
    {
      digitalWrite(blaueLed, HIGH); // leuchte an
      taskPause(60);
      digitalWrite(blaueLed, LOW); // leuchte aus
      taskPause(60);
    }
    blinkAnforderung--; // Anforderung konsumieren
  }
  taskEnd();
}

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

void serialEvent()
{
  int c = Serial.read();
  if(isdigit(c)) blinkAnforderung += c-'0';
}

void loop() 
{
  blinkOmat();
}

Hallo,

danke für die Tipps. Das PWM möchte ich nutzen um die Helligkeit anzusteuern.

die 60ms sollen es später werden, also 3x AN-60msAUS-60ms, dann längere Pause AUS usw.

Etwas weiter bin ich hiermit gekommen, aber ich schanlle es noch nicht ganz:

void loop()
{      
    unsigned long currentMillis = millis();


     if (currentMillis - startzeit_R_links_pause >= 1000) {
        startzeit_R_links_pause = millis();       
        if (R_links_flag == HIGH)
           analogWrite(R_links, 255);
           R_links_flag = LOW;
     }

    if (currentMillis - startzeit_R_links >= 4000) {
        startzeit_R_links = millis();   
        
        if (R_links_flag == LOW)
        analogWrite(R_links, brightness_R_links);
        R_links_flag = HIGH;
     }
}

analogWrite 255 -> LED aus

Die LEDs gehen nun 1000ms an, jedoch nur ca. 2000ms aus...

Jetzt wollte ich die unterschiedlichen Zeiten AN und AUS erst einmal in den Griff bekommen. das 3x 60ms würde ich dann schauen..

spel:
...
Da stimmt etwas nocht nicht... :frowning:
...

Sieh Dir vielleicht auch mal an, wie ein endlicher Automat (state machine) funktioniert. Je nach loop()-Durchlaufzeit kannst Du Dir PWM sparen. Die Nachtwächtererklärung ist sehr gut. Außerdem habe ich hierzu etwas ins Netz gekippt.

Gruß

Gregor

Das PWM möchte ich nutzen um die Helligkeit anzusteuern.

Falls du mich meinen solltest: Das kannst du doch einbauen, oder?

spel:
Jetzt wollte ich die unterschiedlichen Zeiten AN und AUS erst einmal in den Griff bekommen. das 3x 60ms würde ich dann schauen..

Möglicherweise magst Du ja Schrittketten:

const uint32_t anZeit = 60, ausZeit = 60, pausenZeit = 60;
uint32_t jetzt, vorhin, intervall;

const byte pinLinks = 3;
const byte hellLinks = 235;
const byte pinRechts = 5;
const byte hellRechts = 235;
const byte aus = 0;
byte schritt = 0;
enum {ANL1, AUSL1, ANL2, PAUSEL, ANR1, AUSR1, ANR2, PAUSER};

void setup()
{
  pinMode(pinLinks, OUTPUT);       //RGB  links
  analogWrite(pinLinks, aus);
  pinMode(pinRechts, OUTPUT);      //RGB rechts
  analogWrite(pinRechts, aus);
}

void loop()
{
  jetzt = millis();

  if (jetzt - vorhin >= intervall) {
    vorhin = jetzt;
    switch (schritt)
    {
      case ANL1:
        analogWrite(pinLinks, hellLinks);
        intervall = anZeit;
        schritt = AUSL1;
        break;
      case AUSL1:
        analogWrite(pinLinks, aus);
        intervall = ausZeit;
        schritt = ANL2;
        break;
      case ANL2:
        analogWrite(pinLinks, hellLinks);
        intervall = anZeit;
        schritt = PAUSEL;
        break;
      case PAUSEL:
        analogWrite(pinLinks, aus);
        intervall = pausenZeit;
        schritt = ANR1;
        break;
      case ANR1:
        analogWrite(pinRechts, hellLinks);
        intervall = anZeit;
        schritt = AUSR1;
        break;
      case AUSR1:
        analogWrite(pinRechts, aus);
        intervall = ausZeit;
        schritt = ANR2;
        break;
      case ANR2:
        analogWrite(pinRechts, hellLinks);
        intervall = anZeit;
        schritt = PAUSER;
        break;
      case PAUSER:
        analogWrite(pinRechts, aus);
        intervall = pausenZeit;
        schritt = ANL1;
        break;
    }
  }
}

Vielen Dank agmue!

So kriege ich das hin, habe noch einen Zähler für die Durchgänge gemacht, um den jweiligen Schritt mehrfach machen zu können.