RC Einsatzfahrzeugbeleuchtung

Moin :slight_smile: ,
ich benötige einen Sketch für den Arduino UNO Rev.3 der es ermöglicht an 5 Ausgängen Led’s Blinken zu lassen.
Die Led’s sollen dabei eine leichte zeitliche Versetzung haben sodass sie mal gleichzeitig und mal versetz blinken.
Das Blinkmuster sieht wie folgt aus: -1-1—1-1—1-1—1-1—…
Die Intervalle sind: 1= 150ms - 0 = 60ms - 1 = 20ms - 0 = 400ms.
Falls sich jemand dem annimmt schon mal ein Danke von mir im voraus :smiley: .

Mario_Breier:
Falls sich jemand dem annimmt schon mal ein Danke von mir im voraus :smiley: .

Hast du schon mal versucht, das selbst zu programmieren ?
Oder den Sketch bei ebay zu kaufen ?

Interessante Art, delays einzusetzen

Schöner Versuch, aber mit "delay()" wird das nie funktionieren.
Du musst delay() ersetzen durch die Funktion mit "millis()".
Aber nicht stumpf ersetzen sondern Funktionen einbauen wie du sie in BlinkWithoutDelay findest.
Jede Zeit muss für sich laufen, ohne durch andere beeinflusst zu werden.

Das wird sicher eine Herausforderung, ist aber lösbar.

Und warum löschst du den Post wieder ?
Das ist natürlich die blödeste Art um Hilfe zu betteln.

So wie Du das vorhast wird das Sch.... aussehen.

Bei den alten analogen Lichtern dreht sich ein Spiegel und die Motoren laufen nicht ganz synchron. Deshalb hast Du mal zwei Lichter im Takt und ein paar Momente später sind sie wieder ganz aus dem Takt. Dieses Leuchtbild erreicht man nicht, wenn man die LEDs einfach nur versetzt ansteuert - jede braucht ihr eigenes Muster.

Dein Sketch ist ein erster Anfang - immerhin.

Ich empfehle:

  • die Vereinbarung der ledPinX Variablen als const int ledPinX = YY; aufzuschreiben
  • im setup() auch die definierten Pin-Nummern ledPin1...ledPin5 zu verwenden
  • und - das ist der Standard-Tip - "BlinkWIthoutDelay" mal zu suchen und zu verinnerlichen

Die Blinkfolge bei Dir ist 1010ms an, 310ms aus, 110ms an. 2010ms. Korrekt?

Ja bei eBay finde ich nichts der gleichen :frowning: .
JA habe ich versucht allerdings blinken bei mir alle Led’s gleichzeitig :confused: .
Hier einmal der von mir geschriebene Sketch:

int ledPin1 = 13;
int ledPin2 = 12;
int ledPin3 = 11;
int ledPin4 = 10;
int ledPin5 = 9;

void setup() {
pinMode(ledPin1,OUTPUT);
pinMode(ledPin2,OUTPUT);
pinMode(ledPin3,OUTPUT);
pinMode(ledPin4,OUTPUT);
pinMode(ledPin5,OUTPUT);
}

void loop() 
{
digitalWrite(ledPin1,HIGH);
delay(200);
digitalWrite(ledPin2,HIGH);
delay(201);
digitalWrite(ledPin3,HIGH);
delay(202);
digitalWrite(ledPin4,HIGH);
delay(203);
digitalWrite(ledPin5,HIGH);
delay(204);
digitalWrite(ledPin1,LOW);
delay(60);
digitalWrite(ledPin2,LOW);
delay(61);
digitalWrite(ledPin3,LOW);
delay(62);
digitalWrite(ledPin4,LOW);
delay(63);
digitalWrite(ledPin5,LOW);
delay(64);
digitalWrite(ledPin1,HIGH);
delay(20);
digitalWrite(ledPin2,HIGH);
delay(21);
digitalWrite(ledPin3,HIGH);
delay(22);
digitalWrite(ledPin4,HIGH);
delay(23);
digitalWrite(ledPin5,HIGH);
delay(24);
digitalWrite(ledPin1,LOW);
delay(400);
digitalWrite(ledPin2,LOW);
delay(401);
digitalWrite(ledPin3,LOW);
delay(402);
digitalWrite(ledPin4,LOW);
delay(403);
digitalWrite(ledPin5,LOW);
delay(404);
}

ich habe deine Intervalbedingungen zwar nicht verstanden, aber versuch es mal so und setze deine Intervalle ein.

void setup()
{

}

void loop()
{
 blink(9,150,60);//Led Pin, Anzeit, Auszeit
 blink(10,20,400);
 blink(11,151,61);
 blink(12,152,62);
 blink(13,153,63);
}
 void blink(const uint8_t ledPin, const uint16_t onZeit, const uint16_t offZeit)
 {
 pinMode(ledPin,OUTPUT);
 digitalWrite(ledPin,(millis()%(onZeit+offZeit))<onZeit);
 
 }

Aus welchem Land soll die Blinkfolge denn sein?

Bei Fahrzeugen mit Motor betriebenen Rundumkennleuchten (RKL) muss laut StVZO sichergestellt sein das diese nicht synchron laufen, dies gilt aber nicht mehr für LED RKL. Hier ist alles zulässig, nur nicht bei der Blink- bzw. Blitzfolge. Hier gibt es die am meisten verwendete 10100 wie auch 1010100. Auch die Zeiten sind fest vorgegeben, nur habe ich die gerade nicht mehr im Gedächtnis. Dies gilt übrigens für beide Farben.

Abgesehen davon, solche Schaltungen gibt es fertig für kleines Geld zu kaufen, bei manchen kann man sogar Länderabhängige Blinkmuster einstellen. Einen Arduino, nur für die LEDs, halte ich hier für übertrieben und zu störanfällig, schließlich scheint das ganze in ein RC Fahrzeug zu kommen.

Gruß

MiReu

Die Blinkfolge soll für deutsche Einsatzfahrzeuge sein.

Hier einmal der link zu einem Video von dem Fahrzeug, welches von mir nachgebaut wird:

0:33 - 0:53

Mario_Breier:
Die Blinkfolge soll für deutsche Einsatzfahrzeuge sein.

Hier einmal der link zu einem Video von dem Fahrzeug, welches von mir nachgebaut wird:

[BMA Altersheim] Löschzug Berufsfeuerwehr Delmenhorst - YouTube

0:00 - 0:53

Sehr interessant, ins Besondere die hintere runde RKL an der LB. So lange Pausen sind doch gar nicht zulässig??? Oder mein Wissen ist veraltet :frowning:

du kannst ja auch mit Zufallszeiten arbeiten. Und das Ganze passt auch auf einen Attiny 25

void setup()
{

}

void loop()
{
 blink(9,random(140,170),random(40,80));//Led Pin, Anzeit(Zufallswert zwischen 140 und 170 ms), Auszeit (Zufallswert zwischen 40 und 80 ms)
 blink(10,random(10,30),random(350,450));//Led Pin, Anzeit, Auszeit
 blink(11,500,500);
 blink(12,500,500);
 blink(13,500,500);
}
 void blink(const uint8_t ledPin,  const uint16_t onZeit, const uint16_t offZeit)
 {
 pinMode(ledPin,OUTPUT);
 digitalWrite(ledPin,(millis()%(onZeit+offZeit))<onZeit);
 
 }

MiReu:
Sehr interessant, ins Besondere die hintere runde RKL an der LB. So lange Pausen sind doch gar nicht zulässig??? Oder mein Wissen ist veraltet :frowning:

Die lange Pause kommt daher das dieses Fahrzeug noch mit Xenonblitz ausgestattet ist und die Kamera nicht alle Einphasen erfasst hat.

ca so könnte es mit einer definierten Zeitfolge funktionieren:

/* Blink a LED in a specific rhythm

 Turns on and off up to 13 light emitting diode (LED) connected to a digital pin,
  without using the delay() function. This means that other code can run at the
  same time without being interrupted by the LED code.

  
*/

class BlinkLed {
  
    byte state = 0;
    unsigned long previousMillis;
    uint16_t on = 500;
    uint16_t off = 1000;
    const byte ledPin;

  public:
    BlinkLed(byte attachTo):
      ledPin(attachTo)
    {}

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

    void set(uint16_t _on, uint16_t _off)
    {
      on = _on;
      off = _off;
    }

    void loop()
    {
      uint32_t currentMillis = millis();
      if (digitalRead(ledPin) && currentMillis - previousMillis >= on) {
        // save the last time you blinked the LED
        previousMillis = currentMillis;
        digitalWrite(ledPin, LOW);
      }
      if (!digitalRead(ledPin) && currentMillis - previousMillis >= off) {
        // save the last time you blinked the LED
        previousMillis = currentMillis;
        digitalWrite(ledPin, HIGH);
      }
    }
};

class RhythmLed {
    byte state = 1;
    unsigned long previousMillis;
    // the intervall pattern
    //                          ON    OFF  ON   OFF 
    //                          1     2    3    4    
    uint16_t intervall[5] = {0, 150,  60, 20, 400};
    const byte ledPin;

  public:
    RhythmLed(byte attachTo):
      ledPin(attachTo)
    {}

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

    void setState(byte _state)
    {
      state = _state;
    }

    void loop()
    {
      uint32_t currentMillis = millis();
      if (state > 0)                            // iterate through the states 1 to 5, we don't use state 0 because state 0 is reserved to "switch off" the light
      {
        if (currentMillis - previousMillis > intervall[state])
        {
          if (state % 2==1)    // all uneven states are ON
          
             digitalWrite(ledPin, LOW);
         

          else
            digitalWrite(ledPin, HIGH);
          state++;
          if (state > 4) state = 1;
          previousMillis = currentMillis;
        }
      }
    }
};

//BlinkLed led1(13);  // a simple blink led

RhythmLed topRKL(13);  // define an output PIN for your LED

void setup()
{
  topRKL.setup();
}

void loop()
{
  topRKL.loop();
}

der loop für die topRKL geht durch die Status 1 bis 4.
0 habe ich ausgelassen, damit man die RKL über ein

topRKL.set(0);

aus bzw. mit 1 einschalten könnte.

Ein Objekt ist es geworden, damit du so viele LED's wie du brauchst separat einschalten kannst, sind nur jeweils die 3 Zeilen für PIN, Setup und Loop.

der einfache blink-Code ist drinnen zum Vergleichen.

Okay dann muss ich jetzt nur mal schauen wie ich es hin bekomme das ich mit dem Code 5 Ausgänge ansteuern kann. :slight_smile:

Kommt mit der Nummer 485 bei mir in die Sammlung schöner Programme :slight_smile:

Mario_Breier:
Okay dann muss ich jetzt nur mal schauen wie ich es hin bekomme das ich mit dem Code 5 Ausgänge ansteuer. :slight_smile:

Für die Asynchronität braucht es noch eine Erweiterung, läßt sich aber machen.

naja, die "Asyncronität" war ja nicht gewünscht, es gab eine genaue Blinkfolge einzuhalten. Man könnte aber einfach die einzelnen Leuchten etwas zeitversetzt einschalten, dann weichen die Schaltzeiten auch ab.

Das schöne an der Objektorientierung ist aber, dass man relativ einfach weitere Objekte (im Anwendungsfall = Rundumleuchten) hinzufügen kann.

Zum Beispiel eine etwas ältere RKL die wegen eines Massefehlers ein wenig aus dem Takt ist.
Einfach eine weitere Methode hinzufügen und die Intervall-Werte von außen veränderen:

/* Blink a LED in a specific rhythm

  Turns on and off light emitting diodes (LED) connected to a digital pin,
  without using the delay() function. This means that other code can run at the
  same time without being interrupted by the LED code.


*/

class BlinkLed {
    byte state = 1;  // 1 blink, 0 off
    unsigned long previousMillis;
    uint16_t on = 500;
    uint16_t off = 1000;
    const byte ledPin;

  public:
    BlinkLed(byte attachTo):
      ledPin(attachTo)
    {}

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

    void set(uint16_t _on, uint16_t _off)  // modify on/off times during runtime
    {
      on = _on;
      off = _off;
    }

    void setState(byte _state)            // 1 Switch on blinking; 0 switch off blinking
    {
      state = _state;
    }

    void loop()
    {
      if (state)
      {
        uint32_t currentMillis = millis();
        if (digitalRead(ledPin) && currentMillis - previousMillis >= on) {
          // save the last time you blinked the LED
          previousMillis = currentMillis;
          digitalWrite(ledPin, LOW);
        }
        if (!digitalRead(ledPin) && currentMillis - previousMillis >= off) {
          // save the last time you blinked the LED
          previousMillis = currentMillis;
          digitalWrite(ledPin, HIGH);
        }
      }
    }
};

class RhythmLed {
    byte state = 1;
    unsigned long previousMillis;
    // the intervall pattern
    //                          ON    OFF  ON   OFF
    //                          1     2    3    4
    uint16_t intervall[5] = {0, 150,  60, 20, 400};
    const byte ledPin;

  public:
    RhythmLed(byte attachTo):
      ledPin(attachTo)
    {}

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

    void setState(byte _state)
    {
      state = _state;
    }

    void setIntervall(uint16_t _intervall1, uint16_t _intervall2, uint16_t _intervall3, uint16_t _intervall4)       // Modify the intervalls to your needs
    {
      intervall[1] = _intervall1;
      intervall[2] = _intervall2;
      intervall[3] = _intervall3;
      intervall[4] = _intervall4;
    }

    void loop()
    {
      uint32_t currentMillis = millis();
      if (state > 0)                            // iterate through the states 1 to 4, we don't use state 0 because state 0 is reserved to "switch off" the light
      {
        if (currentMillis - previousMillis > intervall[state])
        {
          if (state % 2 == 1)  // all uneven states are ON, at the end of an intervall we switch to the oposite pin state
          {
            digitalWrite(ledPin, LOW);
          }
          else
          {
            digitalWrite(ledPin, HIGH);
          }
          state++;
          if (state > 4) state = 1;
          previousMillis = currentMillis;
        }
      }
    }
};

BlinkLed myBlinkLed(12);      // a simple blink led
RhythmLed topRKL(11);         // define an output PIN for your LED
RhythmLed outOffSyncRKL(13);  // eine Rundumleuchte die wegen eines "Massefehlers" am Originalfahrzeugs eine leicht verschobene Blinkfrequenz hat ;-)

void setup()
{
  //Serial.begin(115200);
  myBlinkLed.setup();
  topRKL.setup();
  outOffSyncRKL.setup();
  outOffSyncRKL.setIntervall(250,  90, 30, 400);
}

void loop()
{
  myBlinkLed.loop();  // each object has to be called once in the loop
  topRKL.loop(); 
  outOffSyncRKL.loop();
  
  // put here other code which needs to run:

}

hätte gar nicht gedacht, wie lang man sich mit einem "Blink"-Sketch beschäftigen kann, brauch jetzt ein paar LEDs :wink:

noiasca:
naja, die "Asyncronität" war ja nicht gewünscht, es gab eine genaue Blinkfolge einzuhalten.

Das hatte ich anders verstanden, weil fünf genau gleich blinkende LEDs keinen Sinn ergeben, die kann man auch an einen Transistor anschließen.

noiasca:
hätte gar nicht gedacht, wie lang man sich mit einem "Blink"-Sketch beschäftigen kann, brauch jetzt ein paar LEDs :wink:

Blinkende LEDs werden gemeinhin unterschätzt.

Letztlich egal, aber mein Ansatz wäre die Übergabe eines Zeigers mit den Blinkzeiten:

/* Blink a LED in a specific rhythm

 Turns on and off up to 13 light emitting diode (LED) connected to a digital pin,
  without using the delay() function. This means that other code can run at the
  same time without being interrupted by the LED code.


*/

class BlinkLed {

    byte state = 0;
    unsigned long previousMillis;
    uint16_t on = 500;
    uint16_t off = 1000;
    const byte ledPin;

  public:
    BlinkLed(byte attachTo):
      ledPin(attachTo)
    {}

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

    void set(uint16_t _on, uint16_t _off)
    {
      on = _on;
      off = _off;
    }

    void loop()
    {
      uint32_t currentMillis = millis();
      if (digitalRead(ledPin) && currentMillis - previousMillis >= on) {
        // save the last time you blinked the LED
        previousMillis = currentMillis;
        digitalWrite(ledPin, LOW);
      }
      if (!digitalRead(ledPin) && currentMillis - previousMillis >= off) {
        // save the last time you blinked the LED
        previousMillis = currentMillis;
        digitalWrite(ledPin, HIGH);
      }
    }
};

class RhythmLed {
    byte state = 1;
    unsigned long previousMillis;
    const byte ledPin;
    uint16_t * intervall;
    byte laenge;

  public:
    RhythmLed(byte attachTo):
      ledPin(attachTo)
    {}

    void setup(uint16_t * _intervall, byte _laenge)
    {
      pinMode(ledPin, OUTPUT);
      intervall = _intervall;
      laenge = _laenge;
    }

    void setState(byte _state)
    {
      state = _state;
    }

    void loop()
    {
      uint32_t currentMillis = millis();
      if (state > 0)                            // iterate through the states 1 to 5, we don't use state 0 because state 0 is reserved to "switch off" the light
      {
        if (currentMillis - previousMillis > intervall[state])
        {
          if (state % 2 == 1)  // all uneven states are ON
            digitalWrite(ledPin, LOW);
          else
            digitalWrite(ledPin, HIGH);
          state++;
          if (state > laenge) state = 1;
          previousMillis = currentMillis;
        }
      }
    }
};

//BlinkLed led1(13);  // a simple blink led
// the intervall pattern
//                           ON    OFF ON   OFF
//                            1     2   3    4
uint16_t intervall1[] = {0, 150,  60, 20, 400};
uint16_t intervall2[] = {0, 151,  61, 21, 401};

RhythmLed topRKL1(13);  // define an output PIN for your LED
RhythmLed topRKL2(2);  // define an output PIN for your LED

void setup()
{
  topRKL1.setup(intervall1, sizeof(intervall1) / sizeof(intervall1[0]) - 1);
  topRKL2.setup(intervall2, sizeof(intervall2) / sizeof(intervall2[0]) - 1);
}

void loop()
{
  topRKL1.loop();
  topRKL2.loop();
}

:o Geil, das ist genau das was ich gesucht habe.
Danke für die schnelle Hilfe. :wink: :smiley:

Mario_Breier:
:o Geil, das ist genau das was ich gesucht habe. (y)
Danke für die schnelle Hilfe. :wink: :smiley:

Dann darfst Du bei noiasca auf das Karma+ Knöpfchen drücken.

noiasca:
dein sizeof/sizeof klau ich mir, das hat mir noch gefehlt.

Das ist natürlich nicht von mir, ich habe es von jurs, leider in "Rente".

noiasca:
Aber ich finde das gehört in die Klasse hinein, damit soll sich ein Anwender nicht rumschlagen müssen.

Ja, mach mal, ich habe gelernt, das geht nicht, bezog sich aber auf Funktionen, da zerfällt was oder so. Von OOP habe ich aber nix Ahnung.

noiasca:
die Namensgebung setup und loop ist eigentlich auch nicht so optimal, wäre nicht begin und do besser?

Das habe ich von Dir übernommen, bin für alle Namen offen :wink: