Hupe, Blinker, Fernlicht steuern für Cafe Racer

Ich nicht, hatte aber auch schon was angesetzt.
Es beginnt bei auslösen immer zwingend mit aufleuchten des Blinkers.
Ein erneutes auslösen beendet das blinken erst, wenn die Taste losgelassen.
Taste gedrückt: Blinken fängt an mit leuchten
Taste losgelassen
Taste gedrückt: es passiert noch nichts
Taste losgelassen: Blinker geht aus.
Zudem habe ich eine Mindestblinkzeit drin.
Der Code sieht etwas anders aus, aber vielleicht schaut wer mal drüber.

// fuer den Blinker
enum {aus, rechts, links};
byte richtung = aus;
const unsigned long blinktime = 666;
const unsigned long mindestblinkzeit = blinktime * 5; //3mal ein + 2mal aus
//EINGÄNGE
const byte IN_Hupe = 2;
const byte IN_Blink_L = 3;
const byte IN_Blink_R = 4;
const byte IN_Fernlicht = 5;

//AUSGÄNGE
const byte OUT_Fern_Kontroll = 7;         //Kontrolleuchte für Fernlicht
const byte OUT_Hupe = 8;
const byte OUT_Blink_L = 9;
const byte OUT_Blink_R = 10;
const byte OUT_Fernlicht = 11;
const byte OUT_Blink_Kontroll = 12;      //Kontrolleuchte für Blinker links+rechts

const unsigned long bounceTime = 40;

void setup()
{
  Serial.begin(115200);
  Serial.println(F("Start..."));
  pinMode(IN_Hupe, INPUT_PULLUP);
  pinMode(IN_Blink_L, INPUT_PULLUP);
  pinMode(IN_Blink_R, INPUT_PULLUP);
  pinMode(IN_Fernlicht, INPUT_PULLUP);
  pinMode(OUT_Hupe, OUTPUT); // HUPE OUT
  pinMode(OUT_Blink_L, OUTPUT); // BLINKER LINKS OUT 1,5HZ
  pinMode(OUT_Blink_R, OUTPUT); // ,,      RECHTS OUT 1,5HZ
  pinMode(OUT_Fernlicht, OUTPUT); // FERNLICHT OUT
  pinMode(OUT_Blink_Kontroll, OUTPUT); // BLINKER KONTROLLEUCHTE
  pinMode(OUT_Fern_Kontroll, OUTPUT); // Fernlicht Kontrolleuchte
}

void loop()
{
  Fernlicht();
  Hupe();
  setBlinker();
  kontrol();
}

void setBlinker()
{
  static unsigned long lastmillis = 0;
  static bool geschalten = false;
  static bool lastswitch = false;
  if (!digitalRead(IN_Blink_R))          // Taste rechts gedrueckt?
  {
    if (richtung != rechts)              // Vorher andere Richtung oder aus?
    {
      richtung = rechts;                 // Setze Richtung
      digitalWrite(OUT_Blink_R, true);   // Pins setzen
      digitalWrite(OUT_Blink_L, false);
      geschalten = true;                 // Merken, das ausgeloest
      lastmillis = millis();             // Ausloesezeitpunkt merken
    }
    else if ((!geschalten) &&      // nochmal ausgelöst?
             (millis() - lastmillis > mindestblinkzeit))  // und SperrZeit abgelaufen? (Mindestblinkzeit)
    {
      lastswitch = true;                 // Merker setzen
      lastmillis = millis();             // Bouncetimer setzen
    }
  }
  if (!digitalRead(IN_Blink_L))          // Taste rechts gedrueckt?
  {
    if (richtung != links)               // Vorher andere Richtung oder aus?
    {
      richtung = links;                  // Setze Richtung
      digitalWrite(OUT_Blink_L, true);   // Pins setzen
      digitalWrite(OUT_Blink_R, false);
      geschalten = true;                 // Merken, das ausgeloest
      lastmillis = millis();             // Ausloesezeitpunkt merken
    }
    else if ((!geschalten) &&            // nochmal ausgelöst?
             (millis() - lastmillis > mindestblinkzeit))  // und SperrZeit abgelaufen? (Mindestblinkzeit)
    {
      lastswitch = true;                 // Merker setzen
      lastmillis = millis();             // Bouncetimer setzen
    }
  }
  if (digitalRead(IN_Blink_L) && digitalRead(IN_Blink_R))
  {
    if (lastswitch && (richtung == rechts || richtung == links))
    {
      lastswitch = false; richtung = aus;
    }
    if (millis() - lastmillis > bounceTime)// bouncetime abgelaufen?
    {
      geschalten = false;                  // Merker zurücksetzen
    }
  }
  richtung = blinken(richtung);            // links rechts aus senden
}
byte blinken(const byte linksRechtsAus)
{
  const unsigned long blinkFreq = 666;
  static byte lastRichtung = aus;
  static unsigned long lastmillis = 0;
  if (linksRechtsAus == aus)
  {
    digitalWrite(OUT_Blink_L, false);
    digitalWrite(OUT_Blink_R, false);
    lastRichtung = aus;
    return lastRichtung;
  }
  if (lastRichtung != linksRechtsAus)
  {
    lastmillis = millis();
    lastRichtung = linksRechtsAus;
  }
  else
  {
    if (millis() - lastmillis > blinkFreq)
    {
      lastmillis = millis();
      if (linksRechtsAus == links) digitalWrite(IN_Blink_L, !digitalRead(IN_Blink_L));
      if (linksRechtsAus == rechts) digitalWrite(OUT_Blink_R, !digitalRead(OUT_Blink_R));
    }
  }
  return lastRichtung;
}
void kontrol()
{
  digitalWrite(OUT_Blink_Kontroll, digitalRead(OUT_Blink_L) || digitalRead(OUT_Blink_R));
  digitalWrite(OUT_Fern_Kontroll, digitalRead(OUT_Fernlicht));
}
void Fernlicht()
{
  static unsigned long lastmillis = 0;
  static bool geschalten = false;
  if (!digitalRead(IN_Fernlicht) && !geschalten)
  {
    lastmillis = millis();
    geschalten = true;
    digitalWrite(OUT_Fernlicht, !digitalRead(OUT_Fernlicht));
    Serial.print(F("Fernlicht: "));
    Serial.println(digitalRead(OUT_Fernlicht));
  }
  if (digitalRead(IN_Fernlicht) && millis() - lastmillis > bounceTime)
  {
    geschalten = false;
  }
}
void Hupe()
{
  digitalWrite(OUT_Hupe, !digitalRead(IN_Hupe));
}

Ganz mutig habe ich Dein Programm auf meine Hardware gespielt:

  1. rechts blinkt
  2. links geht an, aber blinkt nicht
  3. Die Umschaltung der Richtung funktioniert manchmal
  4. Das Fernlicht geht an, aber manchmal als Lichthupe, manchmal bleibt es an.

:slight_smile:

Ah ich hab nachher ne Hardware, dann kann ich das mal spielen.
Danke.

Ich traue mich nicht, sowas ohne Probieren rauszugeben, da bin ich dann doch ein Kind der Praxis.

Du wirst die Problemchen schneller als ich finden, sonst rufe bitte, dann grübeln wir gemeinsam :thinking:

Einen habe ich schon - da war vermutlich ein autovervollständigen bei.

Auf einen Eingang schreiben ist nicht schick..
:wink:

Das ist hier nicht aufgefallen.
Ich hab mal umgebaut, damit die Hardware noch was zu tun hat :wink:

// fuer den Blinker
enum {aus, rechts, links};
byte richtung = aus;

//EINGÄNGE
const byte IN_Hupe = 2;
const byte IN_Blink_L = 3;
const byte IN_Blink_R = 4;
const byte IN_Fernlicht = 5;

//AUSGÄNGE
const byte OUT_Fern_Kontroll = 7;         //Kontrolleuchte für Fernlicht
const byte OUT_Hupe = 8;
const byte OUT_Blink_L = 9;
const byte OUT_Blink_R = 10;
const byte OUT_Fernlicht = 11;
const byte OUT_Blink_Kontroll = 12;      //Kontrolleuchte für Blinker links+rechts

const unsigned long bounceTime = 40;

void setup()
{
  Serial.begin(115200);
  Serial.println(F("Start..."));
  Serial.println(F("Kontrollausgabe: 10000000"));
  Serial.println(F("Immer 1 ---------+|||||||"));
  Serial.println(F("Fernlicht --------+||||||"));
  Serial.println(F("Hupe --------------+|||||"));
  Serial.println(F("Blink L-------------+||||"));
  Serial.println(F("Blink R -------------+|||"));
  Serial.println(F("FernlichtKontolle ----+||"));
  Serial.println(F("Blinkkontrolle --------+|"));
  pinMode(IN_Hupe, INPUT_PULLUP);
  pinMode(IN_Blink_L, INPUT_PULLUP);
  pinMode(IN_Blink_R, INPUT_PULLUP);
  pinMode(IN_Fernlicht, INPUT_PULLUP);
  pinMode(OUT_Hupe, OUTPUT); // HUPE OUT
  pinMode(OUT_Blink_L, OUTPUT); // BLINKER LINKS OUT 1,5HZ
  pinMode(OUT_Blink_R, OUTPUT); // ,,      RECHTS OUT 1,5HZ
  pinMode(OUT_Fernlicht, OUTPUT); // FERNLICHT OUT
  pinMode(OUT_Blink_Kontroll, OUTPUT); // BLINKER KONTROLLEUCHTE
  pinMode(OUT_Fern_Kontroll, OUTPUT); // Fernlicht Kontrolleuchte
}

void loop()
{
  Fernlicht();
  Hupe();
  setBlinker();
  kontrol();
}

void setBlinker()
{
  static unsigned long lastmillis = 0;
  static bool geschalten = false;
  static bool lastswitch = false;
  if (!digitalRead(IN_Blink_R))          // Taste rechts gedrueckt?
  {
    if (richtung != rechts)              // Vorher andere Richtung oder aus?
    {
      richtung = rechts;                 // Setze Richtung
      digitalWrite(OUT_Blink_R, true);   // Pins setzen
      digitalWrite(OUT_Blink_L, false);
      geschalten = true;                 // Merken, das ausgeloest
      lastmillis = millis();             // Ausloesezeitpunkt merken
    }
    else if (!geschalten)                // nochmal ausgelöst?
    {
      lastswitch = true;                 // Merker setzen
      geschalten = true;
    }
  }
  if (!digitalRead(IN_Blink_L))          // Taste rechts gedrueckt?
  {
    if (richtung != links)               // Vorher andere Richtung oder aus?
    {
      richtung = links;                  // Setze Richtung
      digitalWrite(OUT_Blink_L, true);   // Pins setzen
      digitalWrite(OUT_Blink_R, false);
      geschalten = true;                 // Merken, das ausgeloest
      lastmillis = millis();             // Ausloesezeitpunkt merken
    }
    else if (!geschalten)                // nochmal ausgelöst?
    {
      lastswitch = true;                 // Merker setzen
      lastmillis = millis();             // Bouncetimer setzen
    }
  }
  if (digitalRead(IN_Blink_L) && digitalRead(IN_Blink_R))
  {
    if (lastswitch && (richtung != aus) && !digitalRead(OUT_Blink_Kontroll))
    {
      lastswitch = false; richtung = aus;
    }
    if (millis() - lastmillis > bounceTime)// bouncetime abgelaufen?
    {
      geschalten = false;                  // Merker zurücksetzen
    }
  }
  richtung = blinken(richtung);            // links rechts aus senden
}
byte blinken(const byte linksRechtsAus)
{
  const unsigned long blinktime = 666;
  static byte lastRichtung = aus;
  static unsigned long lastmillis = 0;
  static unsigned long laufzeitmillis = 0;
  switch (linksRechtsAus)
  {
    case aus:
      digitalWrite(OUT_Blink_L, false);
      digitalWrite(OUT_Blink_R, false);
      break;
    case links:
      if (millis() - lastmillis > blinktime)
      {
        digitalWrite(OUT_Blink_L, !digitalRead(OUT_Blink_L));
        lastmillis = millis();
      }
      break;
    case rechts:
      if (millis() - lastmillis > blinktime)
      {
        digitalWrite(OUT_Blink_R, !digitalRead(OUT_Blink_R));
        lastmillis = millis();
      }
      break;
  }
  if (lastRichtung != linksRechtsAus)
  {
    if (linksRechtsAus != aus)
      laufzeitmillis = millis();
    lastmillis = millis();
    lastRichtung = linksRechtsAus;
  }
  return linksRechtsAus;
}
void kontrol()
{
  digitalWrite(OUT_Blink_Kontroll, digitalRead(OUT_Blink_L) || digitalRead(OUT_Blink_R));
  digitalWrite(OUT_Fern_Kontroll, digitalRead(OUT_Fernlicht));
  byte x = 250;
  static byte y = 0;
  for (byte b = 7; b <= 12; b++)
  {
    x = (x + digitalRead(b)) << 1;
  }
  if (x != y)
  {
    Serial.println(x, BIN);
    y = x;
  }
}
void Fernlicht()
{
  static unsigned long lastmillis = 0;
  static bool geschalten = false;
  if (!digitalRead(IN_Fernlicht) && !geschalten)
  {
    lastmillis = millis();
    geschalten = true;
    digitalWrite(OUT_Fernlicht, !digitalRead(OUT_Fernlicht));
    Serial.print(F("Fernlicht: "));
    Serial.println(digitalRead(OUT_Fernlicht));
  }
  if (digitalRead(IN_Fernlicht) && millis() - lastmillis > bounceTime)
  {
    geschalten = false;
  }
}
void Hupe()
{
  digitalWrite(OUT_Hupe, !digitalRead(IN_Hupe));
}

Jetzt könnte man noch die Blionker zusammenfassen - na mal schaun.

108:24: warning: variable 'laufzeitmillis' set but not used

Jetzt blinkt es, schaltet die Richtung um, aber das Entprellen scheint nicht zu wirken. Ich verwende keine Knackfrösche.

ja, noch ein relikt - ich hatte da die Zeit gemerkt für die Mindestlaufzeit. - ich beende jetzt, wenn der blinker aus ist.

Zum prellen schau ich mal - das sollte nicht sein.

Hallo knifezange
Hier kommt eine Sketch für deinen Cafe Racer.
Ich habe eine Ausflug in die OOP unternommen und die Aufgabenstellung klassenlos in Objekte und Methoden überführt. Jedes ARRAY und STRUCT bildet ein Objekt, das jeweils durch eine Methode zum Bearbeiten der Button und Blinker abgefakelt wird.
Die Aktionen für Hupe, Blinker und Fernlicht sind in User Functions programmiert, die über FunctionPointer aus dem Buttonhandler angesprungen werden. So kannst du einfach die benötigten Funktionen annpassen ohne das weitere Änderungen im Code notwendig sind.
Viel Spass beim Ausprobieren und Spielen.

// https://forum.arduino.cc/t/hupe-blinker-fernlicht-steuern-fur-cafe-racer/913534
enum {Hupe, BlinkerLinks, BlinkerRechts, Fernlicht, BlinkerKontrolle, FernlichtKontrolle};
constexpr byte InputPins[] {A0, A1, A2, A3};
constexpr byte OutputPins[] {2, 3, 4, 5, 6, 7};
constexpr byte ButtonStates {2};
constexpr unsigned long DebounceTime {20};
enum {LinksBlink, RechtsBlink, KontrollBlink};
constexpr unsigned long BlinkTime {666};
unsigned long currentTime;
struct TIMER {
  unsigned long stamp;
  unsigned long duration;
};
struct BUTTON {
  byte name_;
  byte pin;
  bool statusQuo;
  TIMER time_;
} buttons[] {
  {Hupe, InputPins[Hupe], false, 0, DebounceTime,},
  {BlinkerLinks, InputPins[BlinkerLinks], false, 0, DebounceTime},
  {BlinkerRechts, InputPins[BlinkerRechts], false, 0, DebounceTime},
  {Fernlicht, InputPins[Fernlicht], false, 0, DebounceTime},
};
struct BLINK {
  byte pin;
  bool control_;
  TIMER time_;
} blinker[] {
  {OutputPins[BlinkerLinks], false, 0, BlinkTime},
  {OutputPins[BlinkerRechts], false, 0, BlinkTime},
  {OutputPins[BlinkerKontrolle], false, 0, BlinkTime},
};
void start_(int name_) {
  blinker[name_].time_.stamp = currentTime;
  blinker[name_].control_ = true;
  digitalWrite(blinker[name_].pin, HIGH);
}
void stopp_(int name_) {
  blinker[name_].control_ = false;
  digitalWrite(blinker[name_].pin, LOW);
}
void (*userFunctions[sizeof(InputPins)][ButtonStates])() {
  {hupeReleased, hupePressed},
  {blinkerLinksReleased, blinkerLinksPressed},
  {blinkerRechtsReleased, blinkerRechtsPressed},
  {fernlichtReleased, fernlichtPressed},
};
//
// ------------------- USER FUNCTIONS -------------------
//
void hupePressed() {
  digitalWrite(OutputPins[Hupe], HIGH);
}
void hupeReleased() {
  digitalWrite(OutputPins[Hupe], LOW);
}
void blinkerLinksPressed() {
  start_(LinksBlink);
  start_(KontrollBlink);
}
void blinkerLinksReleased() {
  stopp_(LinksBlink);
  stopp_(KontrollBlink);
}
void blinkerRechtsPressed() {
  start_(RechtsBlink);
  start_(KontrollBlink);
}
void blinkerRechtsReleased() {
  stopp_(RechtsBlink);
  stopp_(KontrollBlink);
}
void fernlichtPressed() {
  digitalWrite(OutputPins[Fernlicht], !digitalRead(OutputPins[Fernlicht]));
  digitalWrite(OutputPins[FernlichtKontrolle], !digitalRead(OutputPins[FernlichtKontrolle]));
}
void fernlichtReleased() {
}
//
// -------------------------------------------------------
//
void setup() {
  Serial.begin(9600);
  Serial.println(F("Begin"));
  for (auto InputPin : InputPins) pinMode(InputPin, INPUT_PULLUP);
  for (auto OutputPin : OutputPins) pinMode(OutputPin, OUTPUT);
  // LED test
  for (auto OutputPin : OutputPins) digitalWrite(OutputPin, HIGH), delay(100);
  for (auto OutputPin : OutputPins) digitalWrite(OutputPin, LOW), delay(100);
}
void loop() {
  currentTime = millis();
  digitalWrite(LED_BUILTIN,(millis()/500)%2); 
  for (auto &button_ : buttons) {
    if (currentTime - button_.time_.stamp >= button_.time_.duration) {
      button_.time_.stamp = currentTime;
      bool stateNew = !digitalRead(button_.pin);
      if (button_.statusQuo != stateNew) {
        button_.statusQuo = stateNew;
        userFunctions[button_.name_][stateNew]();
      }
    }
  }
  for (auto &blink_ : blinker) {
    if ((currentTime - blink_.time_.stamp >= blink_.time_.duration) && blink_.control_) {
      blink_.time_.stamp = currentTime;
      digitalWrite(blink_.pin, !digitalRead(blink_.pin));
    }
  }
}

Ich wünsche ein geschmeidiges Wochenende und viel Spass beim Programmieren in C++.

Hallo,

na dann zeige ich meinen auch. :wink:

Für die Blinkerkontrollanzeige kann jeweils der gleiche Pin angegeben werden oder verschiedene wie im Auto. Wird ein Blinker spontan umgeschalten, weil vergessen auszuschalten etc., wird die alte Blinksequence erst beendet und danach der neue Blinker aktiviert.

Was ich noch anmerken möchte. Die Blinkfrequenz von 1,5Hz seitens @knifezange empfinde ich für zu schnell, weil das 333ms ein und 333ms aus sind. Das kann irgendwie nicht so ganz stimmen. So schnell blinkte es am Moped wenn die Batterie müde war. :wink: Ich würde max. 1Hz wählen bzw. noch etwas drunter.

DocTimer.zip (18,3 KB)

/*
  https://forum.arduino.cc/t/hupe-blinker-fernlicht-steuern-fur-cafe-racer/913534
  Doc_Arduino - german Arduino Forum
  IDE 1.8.16
  Arduino Mega2560
  15.10.2021

  >> originale Pin Belegung -- ggf. ab Zeile 236 ändern <<
  tasterHupe            2  
  tasterBlinkerLinks    3
  tasterBlinkerRechts   4
  tasterFernlicht       5
  outFernlichtKontrolle 7         
  outHupe               8
  outBlinkerLinks       9
  outBlinkerRechts     10
  outFernlicht         11
  outBlinkerKontrolle  12
*/

#include <DocTimer.h>
#include <TimeUnits.h>
using namespace TimeUnits;

constexpr bool DEBUG {true};  // Serielle Ausgaben ja/nein

class Taster
{
  private:
    const uint8_t pin;
    const uint8_t debounceTime;
    bool state {false};
    bool oldRead {true};
    uint32_t lastMillis {0};

    bool updateDebounce() {
      bool status {false};
      if (millis() - lastMillis >= debounceTime) {  
        lastMillis += debounceTime;
        status = true;
      }
      return status;
    }

  public:
    Taster(uint8_t p, uint8_t dT) :
      pin {p},
      debounceTime {dT}
    {}

    void init (void) {
      pinMode(pin, INPUT_PULLUP);
    }

    bool updateNoRetrigger (void)
    {
      state = false;
      if (updateDebounce() )
      {
        const bool read = digitalRead(pin);
        if (!read && oldRead ) {
          state = true;
        }
        oldRead = read;
      }
      return state;
    }
};

class Blinker
{
  private:
    Taster taster;
    const uint8_t blinker;
    const uint8_t kontrolle;
    const uint32_t halbePeriode;
    DocTimer timer;
    bool schalter;
    bool enableBlinker;
    bool request;
    enum class BlinkStatus : uint8_t {IDLE, ON, WAITON, OFF, WAITOFF} blinkStatus;

    void readTaster (void)
    {
      if (taster.updateNoRetrigger() ) {
        schalter = !schalter;
      }
    }
    
  public:
    Blinker(uint8_t pinT, uint8_t dT, uint8_t pinB, uint8_t pinK, uint32_t t) :
      taster {pinT, dT},
      blinker {pinB},
      kontrolle {pinK},
      halbePeriode {t/2},
      schalter {false},
      enableBlinker {false},
      request {false},
      blinkStatus {BlinkStatus::IDLE}
    {}

    void init (void)
    {
      taster.init();
      pinMode(blinker, OUTPUT);
      pinMode(kontrolle, OUTPUT);
      timer.setTime(halbePeriode);
    }

    void switchControl (void)
    {
      readTaster();
      
      if (schalter && (!enableBlinker)) {
        request = true; // ohne !enableBlinker ansonsten immer wieder neu aktiviert
      }

      if (!schalter) {
        request = false;
        enableBlinker = false;
      }
    }
    
    bool isThereRequest (void)
    { 
      if (DEBUG) { if (request) Serial.println(F("isThereRequest true")); }
      return request;
    }

    void switchOff (void)
    {
      schalter = false;
      if (DEBUG) { Serial.println(F("switchOff")); }
    }

    // für 
    bool waitUntilOff (void)
    {    
      // wenn komplette Blinksequence beendet -> 'true'
      if (!schalter && (blinkStatus == BlinkStatus::IDLE) ) return true;
      else return false;
    }
    
    void switchOn (void)
    {
      if (request) {
        enableBlinker = true;
        request = false;
      }
      if (DEBUG) { Serial.println(F("switchOn")); }
    }
    
    void blinkControl (void)
    {                 
      switch(blinkStatus)
      {
        case BlinkStatus::IDLE:     if (enableBlinker) {
                                      blinkStatus = BlinkStatus::ON;
                                      if (DEBUG) Serial.println(F("ON"));
                                    }
                                    break;
                                  
        case BlinkStatus::ON:       digitalWrite(blinker, HIGH);
                                    digitalWrite(kontrolle, HIGH);
                                    timer.start();
                                    blinkStatus = BlinkStatus::WAITON;
                                    if (DEBUG) Serial.println(F("WAITON"));
                                    break;
                                  
        case BlinkStatus::WAITON:   if (timer.expired() ) {
                                      blinkStatus = BlinkStatus::OFF;
                                      if (DEBUG) Serial.println(F("OFF"));
                                    }
                                    break;  
                                                         
        case BlinkStatus::OFF:      digitalWrite(blinker, LOW);
                                    digitalWrite(kontrolle, LOW);
                                    timer.start();
                                    blinkStatus = BlinkStatus::WAITOFF;
                                    if (DEBUG) Serial.println(F("WAITOFF"));
                                    break;
                                  
        case BlinkStatus::WAITOFF:  if (timer.expired() ) {
                                      blinkStatus = BlinkStatus::IDLE;
                                      if (DEBUG) Serial.println(F("IDLE"));
                                    }
                                    break;                         
      }
    }
};

class Fernlicht
{
  private:
    Taster taster;
    const uint8_t licht;
    const uint8_t kontrolle;
    bool schalter;
   
    void readTaster (void)
    {
      if (taster.updateNoRetrigger() ) { schalter = !schalter; }
    }
  
  public:
    Fernlicht(uint8_t pinT, uint8_t dT, uint8_t pinL, uint8_t pinK) :
      taster {pinT, dT},
      licht {pinL},
      kontrolle {pinK},
      schalter {false}
    {}

    void init (void)
    {
      taster.init();
      pinMode(licht, OUTPUT);
      pinMode(kontrolle, OUTPUT);
    }
    
    void control (void)
    {
      readTaster();
      
      if (schalter) {
        digitalWrite(licht, HIGH);
        digitalWrite(kontrolle, HIGH);
      }
      else {
        digitalWrite(licht, LOW);
        digitalWrite(kontrolle, LOW);
      }
    }
};

// ###### KONFIGURATION ####################################

const byte tasterHupe {2};  
const byte pinHupe {34};  

/*                     Tasterpin
                       |   Entprellzeit
                       |   |   Blinkerpin
                       |   |   |   Kontrollpin
                       |   |   |   |   Periodendauer Blinkfrequenz     
                       |   |   |   |   |                        */
Blinker blinkerLinks  (3, 30, 28, 30, 666_ms); 
Blinker blinkerRechts (4, 30, 29, 30, 666_ms);

/*                   Tasterpin
                     |   Entprellzeit
                     |   |   Lichtpin
                     |   |   |   Kontrollpin
                     |   |   |   |        */
Fernlicht fernlicht (5, 30, 31, 32);

// ###### GEHT LOS #########################################

void setup(void)
{
  Serial.begin(9600);
  Serial.println(F("\nuC RESET ### ### ###"));

  pinMode(tasterHupe, INPUT_PULLUP);
  pinMode(pinHupe, OUTPUT);

  blinkerLinks.init();
  blinkerRechts.init();

  fernlicht.init();
}

void loop(void)
{
  blinkerLinks.switchControl();  
  blinkerRechts.switchControl();

  // Gibt es ein neue Blinkanforderung wird gepüft ob der Andere aus ist.
  // Ist der Andere aktiv wird gewartet bis er aus.
  // Erst dann wird der neue Blinker eingeschalten.
  if (blinkerLinks.isThereRequest() ) 
  {
    blinkerRechts.switchOff();
    if (blinkerRechts.waitUntilOff() ) {
      blinkerLinks.switchOn();
      if (DEBUG) { Serial.println(F("R off und L on")); }
    }
  }

  if (blinkerRechts.isThereRequest() ) 
  {
    blinkerLinks.switchOff();
    if (blinkerLinks.waitUntilOff() ) {
      blinkerRechts.switchOn();
      if (DEBUG) { Serial.println(F("L off und R on")); }
    }
  }

  blinkerLinks.blinkControl();  
  blinkerRechts.blinkControl();

  fernlicht.control();
  
  hupe(); 
}

void hupe (void)
{
  digitalWrite(pinHupe, !digitalRead(tasterHupe) );
}

Edit:
Ja ich weiß, mein Mischmasch deutsch englisch gefällt mir auch nicht richtig. :thinking:

Beim Einschalten blinkt er in Deutschland nach § 54 StVZO bzw. ECE-R 48, in der Schweiz nach Art. 79 Abs. 2 VTS auf der jeweiligen Seite phasengleich mit einer Frequenz von 1,5 Hz ± 0,5 Hz (90 Lichterscheinungen pro Minute ± 30). Nach Betätigen des Fahrtrichtungsschalters muss das erste Aufleuchten des Blinklichtes nach spätestens einer Sekunde und das Verlöschen nach spätestens eineinhalb Sekunden erfolgen.

Der Blinkgeber muss nach ECE-R 6 so takten, dass die Hellzeit der Blinkleuchten gemessen bei 95 % der maximalen Lichtstärke mehr als 0,3 Sekunden beträgt. Es ist nicht erforderlich, dass der Blinkrhythmus mit der sogenannten Hellphase beginnt.

aus:
https://de.wikipedia.org/wiki/Fahrtrichtungsanzeiger

Die 1,5Hz passen schon, weil §54 STVZO
Was nicht passt, sind 333 - denn es sind 666. Hat er auch drin...
Und da ist auch:

Die müssen mit hell anfangen.
Also, wenn eingeschaltet wird, sofort mit hell starten.
Wenn vorher die andere Seite an war, muss die sofort ausgehen.

Hallo,

aha, Danke.

Quelle?

Moment.
1,5Hz = Periodendauer 666ms.
Sprich bei 50% Duty Cycle 333ms ein und 333ms aus.

Sie müssen zwischen hell und dunkel - nicht zwischen dunkel und hell. Ebenda.

Ja.
(90 Impulse ± 30 Impulse in der Minute) zwischen hell und dunkel

Passt doch. 60s durch 0,666s = 90,09 Pulse pro Minute.

zwischen

kennzeichnet eine Wechselbeziehung. Nicht die Reihenfolge des Auftretens oder welches der Objekte als erstes auftritt.

Ist aber nur eine Diskussion zwischen dir und mir.
Wer ist jetzt erster :wink: ?

Ich. :slight_smile:
Ok, das soll wohl so sein.

Was mich mehr nervt und wo ich @Doc_Arduino zugeben muss, ist die Geschichte mit der Periodendauer.

Die ist dann natürlich 333 ms für eine Halbe, weil die Frequenz auf 666 ms abgebildet wird. Allerdings bin ich mir nicht sicher, ob das duty auf 50% gesetzt ist. Ich kann mich dran erinnern, das irgendwo bis zu 20/80 möglich waren. Villeicht altes Fahrzeug.
Ich schau mal, was die ECE R von sich geben, bzw. ob es irgendwo was in den Verodrnungen gibt...

Ich bin grad am überlegen, wie das mit den "neuartigen" tasten der Blinker ist. Die machen 3(?) Zyklen an.
Wenn ich jetzt zwischendurch die Richtung wechsel, machen die die Umschaltung sofort, oder erst wenn die "falsche" Seite aus ist.

Ach, ich lese ja auch so einiges und hab den einen oder anderen Umbau besprochen, aber das ist wieder so speziell... - spezieller als die Ausrichtung ob der Blinker nach Vorne oder Hinten gehört und wo oben und wo unten ist. - Das steht nämlich auf den Gläsern drauf :slight_smile: