funtion ausfürhung Fehler

combie:
Geltungsbereich von Variablen
Es gibt noch viele weitere C++ Tutorials....

danke und wieder was gelern...

so jetzt habe ich beide LedBlinen und BuzzAlert als funktionen fertig. puhh aber.... wenn ich beide im LOOP aufrufe Blinkt die LED schon mein Buzzer macht aber keinen wechsel... wo habe ich den denkfehler? einzeln angesprochen gehen beide....

//### Starte Setup ###
void setup() {
  Serial.begin(9600); //kann man immer brauchen!
  }
//### Starte Loop ###
void loop() {
  BuzzAlert(8,200); //func wird aufgerufen
  LedBlinken(4,10,200);
}

void LedBlinken (byte LedPin, long anzahl, long intervalLB){    //function diese lässt an #LedPin pin der LED #anzhal der blinkens #interval lange der Pause
//Variablem deklaration   
static unsigned long previousMillisLB = 0;                      // speichert wie viele Sekunden seit derletzten Änderung vergangen sind
static byte valueLB = HIGH;                                     // schalter für an aus. 
pinMode(LedPin, OUTPUT);                                        // LED Pin zum Ausgang machen
//Strat code
for (int i=0; i <= ((anzahl*2)+1);){                            //die led muss immer an und aus deswegen *2 und +1 damit immer auf low steht (start ist HIGH)
if (millis() - previousMillisLB > intervalLB) {                 //wenn millis() Minus das Letztemalmillies größer als das Interval ist schleife durchlaufen
    previousMillisLB = millis();                                // aktuelle Zeit abspeichern für die nächste abfrage 
    digitalWrite(LedPin, valueLB);                              // pin mit LOW/HIGH belegen
    valueLB = !valueLB;                                         // wechsel von valueLB für die nächste runde
    i++;                                                        // schleife eines höher zählen
}
}
}


//### Starte function ###
void BuzzAlert(byte BuzzPin,unsigned long interval) // function #BuzzPin = Ausgabe ping für lautsprecher #Interval Zeit zwischen den wecheln
{    
    // Variablen statisch nur in der func   
   static  boolean value = LOW;                  // Buzzer an aus schalter
   static  boolean value2 = HIGH;                // buzzer hoch tief schalter
   static  unsigned long previousMillis = 0;     // speichert wie viele Sekunden seit derletzten Änderung vergangen sind
   static  long frq = 500;                       // frequenz des buzze Start 500
if (millis() - previousMillis > interval) { //wenn millis() Minus das Letztemalmillies größer als das Interval ist schleife durchlaufen
previousMillis = millis();        // aktuelle Zeit abspeichern für die nächste abfrage 
value = !value; //der Wert wird gedreht damit bei jeder Loop anders ist
Serial.println(value);
if (LOW == value){          // wenn value Low dann ton ein

    if (LOW == value2){     // Abfrage für den frequenz wechsel 500/700
      frq = 500;
    }else{
      frq = 700; 
    }
    value2 = !value2;       // dreht den schalter für frequenz wechsel
  tone(BuzzPin,frq);        // buzz on
}else{
  noTone(BuzzPin);          // buzz of
}   

}
}

danke euch

Einfach gesagt:
Du denkst noch nicht in Nebenläufigkeiten.

Darum bekommst du dein Programm auch noch nicht nebenläufig.

Hier mal deine vorherige Version, in etwa so wie ich sie für mich schreiben würde...
Die Hupe als eigene Task(nach meinem TaskModell)
Und den AlarmSchlager, so wie es hier im Forum häufig gemacht wird.

Der AlarmSchlager veranlasst alle 10 Sekunden ein kleines Hupkonzert, indem er dem Horn eine Nachricht sendet.

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



class Horn
{
  protected:
  const unsigned long freqHigh = 750; // Hz
  const unsigned long freqLow  = 500; // Hz
  unsigned long interval;
  byte hornPin;
  unsigned int zyklen;

  public:
  Horn(byte hornPin, unsigned long interval): hornPin(hornPin),interval(interval),zyklen(0) {}
  void update()
  {
    taskBegin();
    while(1)
    {
      // Start
      noTone(hornPin);

      taskWaitFor(zyklen);

      while(zyklen)
      {
          tone(hornPin,freqHigh);
          taskPause(interval);   
               
          tone(hornPin,freqLow);
          taskPause(interval);        

          zyklen--;
      }
    }
    taskEnd();
  }
  
  void addAlarmZyklen(unsigned int zyklen = 1)
  {
      this->zyklen += zyklen;
  }  
};


Horn horn(8,500);


void alarmSchlager()
{
  static unsigned long  previousMillis = 0;

  if (millis() - previousMillis > 10000) // alle 10 Sec
  {
     previousMillis = millis();
     horn.addAlarmZyklen(2); // anzahl Tonfolgen setzen 
  }
}

// -------------------------------------------

void setup() 
{
}


void loop() 
{
  horn.update();
  alarmSchlager();
}

Dein Fehler liegt in der for-Schleife in 'Led-Blinken'. Letzendlich hast Du da wieder ein delay() reinprogrammiert, in dem Du die Schleifenvariable erst hochzählst, wenn die Zeit abgelaufen ist. Dadurch blockierst Du hier wieder den Programmabllauf bis zum Ablauf der Zeiten - wie in delay().
Deine LedBlinken-Funktion kehrt erst nach dem gesamten Blinken wieder zurück. In der Zeit wird also der Buzzer gar nicht aufgerufen.
Es reicht nicht, die delays durch einen millis-Konstrukt zu ersetzten, der letztendlich das gleich macht wie delay. Der ganze Programmablauf muss auf 'blockadefrei' umgestellt werden.
Dazu eigenet sich auch der im Forum schon oft angesprochene 'endlcher Automat' (einfach mal danach suchen - es gibt einige Beiträge dazu )

N.B. Du solltest die angewöhnen, vernünftig einzurücken.

MicroBahner:
Dein Fehler liegt in der for-Schleife in 'Led-Blinken'. Letzendlich hast Du da wieder ein delay() reinprogrammiert, in dem Du die Schleifenvariable erst hochzählst, wenn die Zeit abgelaufen ist. Dadurch blockierst Du hier wieder den Programmabllauf bis zum Ablauf der Zeiten - wie in delay().
Deine LedBlinken-Funktion kehrt erst nach dem gesamten Blinken wieder zurück. In der Zeit wird also der Buzzer gar nicht aufgerufen.
Es reicht nicht, die delays durch einen millis-Konstrukt zu ersetzten, der letztendlich das gleich macht wie delay. Der ganze Programmablauf muss auf 'blockadefrei' umgestellt werden.
Dazu eigenet sich auch der im Forum schon oft angesprochene 'endlcher Automat' (einfach mal danach suchen - es gibt einige Beiträge dazu )

N.B. Du solltest die angewöhnen, vernünftig einzurücken.

gut das habe ich verstanden ohne die for schleife funktioniert der Sketch auch, die "endliche Automation" habe ich aber noch nicht verstand bzw. weiß nicht ob ich es richtig verstanden habe...

Mit einem solchen sketch frage ich immer wieder zustände aber und reagiere darauf dann mit funtionen usw.... beispiel ob ein button gedrück wurde und dann rufe ich die funtion BuzzAlert auf... oder ein sensor liefert einen wert und ich rufe den auf...
die Abfrage kommt in den loop und darin werden dann funktionen aufgerufen?

oder bin ich da auf dem Holzweg?

Christian

oder bin ich da auf dem Holzweg?

Ich verstehe dich nicht ganz...

Zumindest wirfst du 2 Sachen in einen Topf.

  1. Der endliche Automat
  2. Multitasking

Es ist schon wahr, dass beide häufig gemeinsam anzutreffen sind, aber das ist kein Muss.

Zu 1:
Der endliche Automat kommt immer zu seiner Rolle, wenn bestimmte Abläufe eingehalten werden wollen.

Zu 2:
Damit man 2 oder auch mehr Dinge quasi gleichzeitig erledigen kann

Zu 1+2:
In der Regel müssen viele Dinge parallel abgearbeitet werden. Die Kombination tritt also gerne in Rudeln auf.

Goldene Regel:
Jede Funktion sollte möglichst sofort zurückkehren, damit die anderen Funktionen auch ein Chance haben ihr Ding zu erledigen. Und das ist völlig unabhängig davon, ob diese Funktion einen endlichen Automaten abbildet/implementiert.

combie:
Goldene Regel:
Jede Funktion sollte möglichst sofort zurückkehren, damit die anderen Funktionen auch ein Chance haben ihr Ding zu erledigen. Und das ist völlig unabhängig davon, ob diese Funktion einen endlichen Automaten abbildet/implementiert.

Das ist das A&O wie man den Arduino dazu bringt, mehrere Dinge 'quasi gleichzeitig' zu tun.
Und ein endlicher Automat ist eine elegante Möglichkeit dies zu erreichen: Er prüft bei jedem Durchlauf, ob im momentanen Zustand gerade was zu tun ist, und wenn nicht beendet er sich sofort wieder.

In deinem Beispiel könnte man den Beeper und den Led-Blinker jeweils als (sehr einfachen :wink: ) endlichen Automaten realisieren, der bei jedem Durchlauf prüft, ob er nun gerade den Beeper bzw. die Led ein- oder ausschalten soll. Danach lässt er dann gleich wieder den anderen dran.

ich hoffe nichts das ihr die nerven mit mit verliert ich wollte jetzt zurst mal die endliche Maschiene verstehen und habe mich mal an eine eigene nachtwächter Version versucht

void setup() {
  // put your setup code here, to run once:
Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
static unsigned long letzemalMillisLED = 0;
static unsigned long letzemalMillisBEEP = 0;
static int LedStatus = HIGH;
static int beepStatus = HIGH;
const int LedPin = 4;
const int beepPin = 8;
pinMode(LedPin, OUTPUT);
static int frqStatus = HIGH;
int frq = 500;

//###LED anaus
if(millis()-letzemalMillisLED >400){
  letzemalMillisLED = millis();
   // Serial.println("LED");
    //Serial.println(letzemalMillisLED);
      digitalWrite(LedPin, LedStatus);
        LedStatus = !LedStatus;
  }

//beep anaus
if(millis()-letzemalMillisBEEP >2000){
  letzemalMillisBEEP = millis();
    Serial.println("BEEP");
    Serial.println(letzemalMillisBEEP);
    Serial.println(frqStatus);
            if(frqStatus == HIGH){
              frq = 700;
            }else{
              frq = 500;
            }
      if(beepStatus == HIGH){
          Serial.println(frq);
        tone(beepPin,frq);
      }else{
        noTone(beepPin);
      }
     beepStatus = !beepStatus;
     frqStatus = !frqStatus;
}
}

der Sketch führt auch zwei verschiedene dinge auf einmal aus (Led blinken & beep) das einzige das nicht geht ist der wechsel der Frequenz da will er die else{} einfach nicht durchlaufen? Denkfehler?

if(frqStatus == HIGH){
              frq = 700;
            }else{
              frq = 500;
            }

@MicroBahner
mehr eingerückt dafür keine kommentare :slight_smile: beim nächsten mal beider, ich muss mal verstehen wie die IDE von alleine einrück bei schleifen und abfragen...

ChrisSand:
das einzige das nicht geht ist der wechsel der Frequenz da will er die else{} einfach nicht durchlaufen? Denkfehler?

Doch, er durchläuft den else-Zweig schon. Aber Du schaltest beepStatus und frqStatus immer gleichzeitig um. D.h. frq setzt Du immer dann auf 500, wenn Du gar keinen Ton ausgibst ...

Und die Einrückungen sollten schon auch zur Programmlogik passen. Du kannst die IDE deinen Sketch formatieren/einrückenlassen: Menü->Werkzeuge->Automatisch formatieren

Zusätzlich:

  1. Warum ist frqStatus ein int, obwohl du es doch als bool benutzen möchtest?
    Oder habe ich was übersehen?

if(frqStatus == HIGH){
              frq = 700;
            }else{
              frq = 500;
            }

Das ist gültig, aber tut mir in den Augen weh.. :smiling_imp:

Um solche Dinge abzuhandeln wurde der Ternary Operator erfunden.

frq = frqStatus?750:500;

:o Macht das gleiche :o

vielen dank ( schon wieder ::slight_smile: ),

jetzt habe ich es am laufen

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
}

void loop() {

  static unsigned long letzemalMillisLED = 0;   //Letzte ausführung LED Bling wird beim überschreiben null und nicht in jedem loop neu gesetzt
  static unsigned long letzemalMillisBEEP = 0;  //Letzte ausführung LED Bling wird beim überschreiben null und nicht in jedem loop neu gesetzt
  static bool LedStatus = HIGH;                 //Led Status an oder aus
  static bool beepStatus = HIGH;                //Beep Status an oder aus
  const int LedPin = 4;                         // Pin der LED
  const int beepPin = 8;                        // Pin des Pioezo 
  pinMode(LedPin, OUTPUT);                      // Led Pin auf outputt
  static bool frqStatus = HIGH;                 // Status des hohen oder niedirgen frquens 
        

  //###LED anaus
  if (millis() - letzemalMillisLED > 200) {    // prüfen nach ober X (400) mSec seit der letzten ausführung um sind dann abfrage durchlaufen
    letzemalMillisLED = millis();              // neue letzte ausfürhung aufschreiben
    digitalWrite(LedPin, LedStatus);           // den Pin auf HIGH oder LOW Setzten (aus LedStatus)
    LedStatus = !LedStatus;                    // Status wechseln 
  }

  //beep anaus
  if (millis() - letzemalMillisBEEP > 200) {   // prüfen nach ober X (400) mSec seit der letzten ausführung um sind dann abfrage durchlaufen
    letzemalMillisBEEP = millis();             // neue letzte ausfürhung aufschreiben
    if (beepStatus == HIGH) {                  // Prüft ob er an oder aus schalten soll HIGH = an LOW = aus (else)
      tone(beepPin, frqStatus ? 950 : 700);    // wenn er anschalten soll dann am beepPin und nach dem frwStatus ( frgStatus ? 950 : 700 )
      frqStatus = !frqStatus;                  // Status Frequens wechseln
    } else {
      noTone(beepPin);                         // beepStatus ist LOW dann ausstelen
    }
    beepStatus = !beepStatus;                  // beepStatus wechseln
  }
}

die var. hab ich in bool geändert thx
super vielen dank für die kurze if abfrage das spart viel tipperei und fehler anfälligkeit mit den {}
Einrücken lassen hab ich diesmal das Programm und auch mal wieder was kommentiert

damit ist das jetzt eine endliche Maschiene? und ich habe dsa mit millis() richtig angewenden ? von verstehen will ich noch nicht sprechen dazu muss ich mal ein paar beispiele scripten.

jetzt noch zwei errausforungen oder doch Lernziele ?

  1. ich möchte wiessen wie ich im Loop etwas nur dreimal ausführen lasse ...
    ... mit if und einer static int variablen ?
  2. die ablauf des beep in eine funct packen damit ich das immer mal bei einem problem aufrufen kann
    ...lösung ?

Chris

Du hast eine Reihe von Zuständen die dein Programm annehmen kann. Und fest definierte Übergänge zwischen diesen Zuständen (z.B. Zeit abgelaufen, Taster gedrückt, oder sonstige Ereignisse)

nach dem komplexen (für mich :slight_smile: ) Thema des Alarms ging der schalter jetzt schnell!

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
}

void loop() {

  static unsigned long letzemalMillisLED = 0;   //Letzte ausführung LED Bling wird beim überschreiben null und nicht in jedem loop neu gesetzt
  static unsigned long letzemalMillisBEEP = 0;  //Letzte ausführung LED Bling wird beim überschreiben null und nicht in jedem loop neu gesetzt
  static unsigned long letzemalMillisKlick = 0;  //Letzte ausführung LED Bling wird beim überschreiben null und nicht in jedem loop neu gesetzt
  static bool LedStatus = HIGH;                 //Led Status an oder aus
  static bool beepStatus = HIGH;                //Beep Status an oder aus
  const int LedPin = 4;                         // Pin der LED
  const int beepPin = 8;                        // Pin des Pioezo 
  pinMode(LedPin, OUTPUT);                      // Led Pin auf outputt
  static bool frqStatus = HIGH;                 // Status des hohen oder niedirgen frquens 
  const int tasterPin = 11;                     // Pin des tasters
  pinMode(tasterPin, INPUT);                    // TasterPin als input festlegen
  pinMode(2, OUTPUT);                    // TasterPin als input festlegen
  
  //### Taster abfragen

if(millis()-letzemalMillisKlick > 200 && digitalRead(tasterPin) == HIGH){
  letzemalMillisKlick = millis();
  //jetzt alles zu dem auslösen mit dem taster
}
      

  //###LED anaus
  if (millis() - letzemalMillisLED > 200) {    // prüfen nach ober X (400) mSec seit der letzten ausführung um sind dann abfrage durchlaufen
    letzemalMillisLED = millis();              // neue letzte ausfürhung aufschreiben
    digitalWrite(LedPin, LedStatus);           // den Pin auf HIGH oder LOW Setzten (aus LedStatus)
    LedStatus = !LedStatus;                    // Status wechseln 
  }

  //beep anaus
  if (millis() - letzemalMillisBEEP > 200) {   // prüfen nach ober X (400) mSec seit der letzten ausführung um sind dann abfrage durchlaufen
    letzemalMillisBEEP = millis();             // neue letzte ausfürhung aufschreiben
    if (beepStatus == HIGH) {                  // Prüft ob er an oder aus schalten soll HIGH = an LOW = aus (else)
      tone(beepPin, frqStatus ? 950 : 700);    // wenn er anschalten soll dann am beepPin und nach dem frwStatus ( frgStatus ? 950 : 700 )
      frqStatus = !frqStatus;                  // Status Frequens wechseln
    } else {
      noTone(beepPin);                         // beepStatus ist LOW dann ausstelen
    }
    beepStatus = !beepStatus;                  // beepStatus wechseln
  }
}

functionen & anzahl druchläufe schaue ich mir dann morgen mal an...

christian

Hallo zusammen,

ich habe in zwischenzeit viel gelesen und ein paar videos geschaut.

Ich habe meinen Automatenloop versuch auf ein dreimal Blinken mit einem taster zu bringen.

static bool Taster_Status = 0;
static unsigned int letzte_mal_Taste = 0;
static unsigned int letzte_mal_led_wechsel = 0;
static bool Led_status = 0;
static bool Led_an_aus = 1;
static int i = 0;
const int tasterPin = 11;
const int LedPin = 4;

void setup(){
pinMode(tasterPin,INPUT);
pinMode(LedPin,OUTPUT);
}


void loop()
{

 //taster abfragen
  if (millis() - letzte_mal_Taste > 200 && digitalRead(tasterPin) == HIGH) {  // wenn interval >200 und ein eingang am tasterpin dann...
    letzte_mal_Taste = millis();                                              // letzte ausführung in die var schreiben
    Led_status = 1;                                                           // Led_Status auf 1 dh. bitte dreimal blinken
  }


  //led 3 mal blinken
  if (millis() - letzte_mal_led_wechsel > 100 && Led_status  == 1 && i < 7) { // wenn Interval <100 und i < 7 LED status = 1 dann
    digitalWrite(LedPin, (Led_an_aus= !Led_an_aus));                          // LedPin mit status (LOW/HIGH) beschreiben das wird dann noch jedes mal gedreht
    letzte_mal_led_wechsel = millis();                                        // letzte ausführung in die var schreiben
    i++;                                                                      // dann i eins erhöhen
    if (i == 7) {                                                             // wenn i größer als 7 ist schleife abrechnen 
      Led_status = 0;                                                         // LED Status auf 0 setzten 
      i = 0;                                                                  // i wieder auf 0 für den nächsten druchlauf
    digitalWrite(LedPin, LOW);                                                // Led auf jeden fall ausschalten
    }
  }
}

das Funktioniert auch aber nur wenn ich zum schluss die led auf aus LOW stelle.

wenn ich das richtig verstanden habe ist das jetzt ein endlicher Automat bei dehm ich jetzt weitere taster oder sensoren abfragen kann und diese dann actions auslösen?

chris

PS: Gibt es noch tipps zum Code?

war ja auch zu schön....

static bool Taster_Status = 0;
static unsigned int letzte_mal_Taste = 0;
static unsigned int letzte_mal_led_wechsel = 0;
static bool Led_status = 0;
static bool Led_an_aus = 1;
static int i = 0;
const int tasterPin = 11;
const int LedPin = 4;

void setup(){
pinMode(tasterPin,INPUT);
pinMode(LedPin,OUTPUT);
Serial.begin(9600);
}


void loop()
{

 //taster abfragen
  unsigned long currentMillis = millis();
  if ( currentMillis - letzte_mal_Taste > 300 && digitalRead(tasterPin) == HIGH) {  // wenn interval >200 und ein eingang am tasterpin dann...
    letzte_mal_Taste = currentMillis;                                              // letzte ausführung in die var schreiben
    Led_status = 1;                                                           // Led_Status auf 1 dh. bitte dreimal blinken
  }


  //led 3 mal blinken
  unsigned long currentMillis2 = millis();
  if (currentMillis2 - letzte_mal_led_wechsel > 200 && Led_status  == 1 && i < 7) { // wenn Interval <100 und i < 7 LED status = 1 dann
    digitalWrite(LedPin, Led_an_aus);                                         // LedPin mit status (LOW/HIGH) beschreiben das wird dann noch jedes mal gedreht
    Led_an_aus= !Led_an_aus;                                                  // Status LED wechseln
    letzte_mal_led_wechsel = currentMillis2;                                        // letzte ausführung in die var schreiben
    i++;                                                                      // dann i eins erhöhen
    if (i == 7) {                                                             // wenn i größer als 7 ist schleife abrechnen 
      Led_status = 0;                                                         // LED Status auf 0 setzten 
      i = 0;                                                                  // i wieder auf 0 für den nächsten druchlauf
    digitalWrite(LedPin, LOW);                                                // Led auf jeden fall ausschalten
    }
  }
  if (i==0){
  }else{
    Serial.println(i);
    Serial.println(letzte_mal_led_wechsel);
  }
}

Ich habe noch den " Led_an_aus= !Led_an_aus" aus dem digitalwrit als ! Led_an_aus genommen das wollte der uno so nicht, wenn aber die var letzte_mal_led_wechsel überläuft wird diese wieder auf null gesetzt das ist soweit okay aber dann funktioniert aber die zuweisung nicht mehr "letzte_mal_led_wechsel = currentMillis2;"

was mache ich falsch?

chris

achso die led flackert dann nur noch wenn ich den taster gedrückt halte!

Hmmm...

Ich habe es versucht...
Aber ich verstehe deinen Code nicht.

Mir fehlt eine klare Strukturierung.

Offensichtlich möchtest du da zwei endliche Automaten bauen.
Einer soll die Taster Eingaben verarbeiten, mit entprellen und Wiederholverriegelung.
Und der andere soll irgendwelche Leuchtmeldungen abgeben.

Aus meiner Sicht hast du die beiden Automaten hart miteinander verwoben.
Zu weitgehend.

Weniger, und übersichtliche Bedingungen, würde ich mir wünschen.
Auch eine klare Benennung der Zustände.

habt gedult mit mir, diesen sketch habe ich noch mal neu geschrieben in der hofflung jetzt klarer zu schreiben und weniger komplex habe versucht so viel wie möglich zu beschreiben und gut einzurücken.

der Sketch macht auch das was er soll, auch wenn die var previousMillis & previousMillis2 übergelaufen sind.

was kann ich verbessern?

byte ledPin = 4;                  // LED liegt am (digitalen) Pin 13
static boolean value = HIGH;             // Startwert der LED in der ersten schleife immer anmachen dann 7 mal im wechsel bis aus (HIGH LED an LOW LED aus)
unsigned long previousMillis = 0; // speichert wie viele Sekunden seit derletzten Änderung vergangen sind für den taster
unsigned long previousMillis2 = 0; // speichert wie viele Sekunden seit derletzten Änderung vergangen sind für das LED blinken
unsigned long interval = 300;    // Interval zwischen zwei Änderungen Taster zum entprellen
byte tasterpin = 11;            // Pin an dem der taster abgefragt wird
bool Status_schalter = LOW;     // Status des taster 
byte i = 0;                     // Zähler für die if abfrage zum durchlaufen des blinkens (<7 = weiter blinken >7 stopp kein blingen mehr nötig)

void setup()
{
  pinMode(ledPin, OUTPUT);      // Setzt den ledPin als Ausgang
  pinMode(tasterpin, INPUT);   // setzt den tasterpin auf eingang
  Serial.begin(9600);         // s-monitor gestartet. 
  Serial.println("## Arduino gestartet Serial Montor kann Daten ausgeben ###");
}

void loop()
{

  if (millis() - previousMillis > interval && digitalRead(tasterpin) == HIGH)  // abfrage auf entprellung des tastest und ob er gedrückt wurde
  {
    previousMillis = millis();   // aktuelle Zeit abspeichern
    Status_schalter = HIGH;     // schalter ist gedrückt worden
  }
  // #123 jetzt das led licht wechseln
    if (Status_schalter == HIGH) // wenn der taster gedrückt wurde #Schalter
    { 
        if (millis() - previousMillis2 > 100) // weniger als 100msec vergangen sind seit dem letzten durchlaufen der schleife
         {
          Serial.println("letzte millis"); //ausgaben für den S-Monitor
          Serial.println(previousMillis2);
          Serial.println("status schalter");
          Serial.println(Status_schalter);
          Serial.println("LED value");
          Serial.println(value);
          Serial.println("i");
          Serial.println(i);
            previousMillis2 = millis(); //schleife durchlaufen neue letzte ausfühurng abspeichern
            digitalWrite(ledPin, value); // in der var value steht im start immer High
            value = !value;  // für den nächsten druchlauf schon mal von High <> low wechseln der var. value
            i++;            // für jeden druchlauf i um eines erhöhen
            
              if (i > 7)         // diese abfrage ist für die anzahl der durchläufe wir bei jedem durchlauf mit abgefragt und wenn i > 7....
                                 // dann wird der schalter_status auf LOW gesetzt dann wird die LED abrage nichtmehr durchlaufen bei #schalter 
                                 // damit wird die abfrage  "#123 jetzt das led licht wechseln" verlassen
                {
                    Status_schalter = LOW;
                    i = 0;            // 7 mal erreich var i wieder auf 0 setzte für den nächsten durchlauf
                }
          }
  }
}

danke chris

was kann ich verbessern?

Hab nur mal die erste Zeile gelesen:

byte ledPin = 4; // LED liegt am (digitalen) Pin 13

Fragt sich nur, wie viele Fehler das sind :wink:

Gegenvorschlag:

const byte ledPin = LED_BUILTIN; // Beim Uno  Pin13

Generell schreibe ich an den Anfang eines Sketches gern, welche Pins wie belegt sind (Sowie eine kurze Beschreibung, was der Sketch macht bzw. machen sollte), um eine Übersicht zu haben.
Die Pin-Belegung als echte C++ Definition hat den Vorteil, dass Beschreibung und Wirklichkeit nicht so leicht widersprüchlich sind.

Aber mit byte statt intist da schon viel Gutes drin :wink:

habt gedult mit mir

Aber klar doch...

was kann ich verbessern?

Hier ist noch eine logische Verknüpfung, welche man vereinfachen kann:
if (millis() - previousMillis > interval && digitalRead(tasterpin) == HIGH)

Das durchnummerieren von Variablen betrachte ich als Fehler:
previousMillis & previousMillis2

Die 2 Aufgaben, Blinken und Tasterauswertung lassen sich noch weiter von einander trennen. Wurstbildung in loop() halte ich für vermeidungswürdig.

Deine Variablen donnern dir den globalen Namensraum zu.
Das wird dir auf die Füße fallen, wenn der Code größer wird, oder du Teile wiederverwenden möchtest.

Mit den genannten leichten Umbauten, aber sonst unverändert: (ungetestet)

const byte ledPin = 4;                  // LED liegt am (digitalen) Pin 13
const unsigned long interval = 300;    // Interval zwischen zwei Änderungen Taster zum entprellen
const byte tasterpin = 11;            // Pin an dem der taster abgefragt wird

bool Status_schalter = LOW;     // Status des taster (Übergabe Merker)

void blinkAbhandlung();
void impulsGeber();


void setup()
{
  pinMode(ledPin, OUTPUT);      // Setzt den ledPin als Ausgang
  pinMode(tasterpin, INPUT);   // setzt den tasterpin auf eingang
  Serial.begin(9600);         // s-monitor gestartet. 
  Serial.println("## Arduino gestartet Serial Montor kann Daten ausgeben ###");
}

void loop()
{
    impulsGeber();
    blinkAbhandlung();
}

//-----------------------------



void impulsGeber()
{
  unsigned long previousMillis = 0; // speichert wie viele Sekunden seit derletzten Änderung vergangen sind für den taster
  if(!digitalRead(tasterpin))  previousMillis = millis();
  if (millis() - previousMillis > interval)  // abfrage auf entprellung des tastest und ob er gedrückt wurde
  {
    previousMillis = millis();   // aktuelle Zeit abspeichern
    Status_schalter = HIGH;     // schalter ist gedrückt worden
  }
}


void  blinkAbhandlung()
{
    static boolean value = HIGH;             // Startwert der LED in der ersten schleife immer anmachen dann 7 mal im wechsel bis aus (HIGH LED an LOW LED aus)
    static unsigned long previousMillis = 0; // speichert wie viele Sekunden seit derletzten Änderung vergangen sind für das LED blinken
    static byte i = 0;                     // Zähler für die if abfrage zum durchlaufen des blinkens (<7 = weiter blinken >7 stopp kein blingen mehr nötig)


  // #123 jetzt das led licht wechseln
    if (Status_schalter == HIGH) // wenn der taster gedrückt wurde #Schalter
    { 
        if (millis() - previousMillis > 100) // weniger als 100msec vergangen sind seit dem letzten durchlaufen der schleife
         {
          Serial.println("letzte millis"); //ausgaben für den S-Monitor
          Serial.println(previousMillis);
          Serial.println("status schalter");
          Serial.println(Status_schalter);
          Serial.println("LED value");
          Serial.println(value);
          Serial.println("i");
          Serial.println(i);
            previousMillis = millis(); //schleife durchlaufen neue letzte ausfühurng abspeichern
            digitalWrite(ledPin, value); // in der var value steht im start immer High
            value = !value;  // für den nächsten druchlauf schon mal von High <> low wechseln der var. value
            i++;            // für jeden druchlauf i um eines erhöhen
            
              if (i > 7)         // diese abfrage ist für die anzahl der durchläufe wir bei jedem durchlauf mit abgefragt und wenn i > 7....
                                 // dann wird der schalter_status auf LOW gesetzt dann wird die LED abrage nichtmehr durchlaufen bei #schalter 
                                 // damit wird die abfrage  "#123 jetzt das led licht wechseln" verlassen
                {
                    Status_schalter = LOW;
                    i = 0;            // 7 mal erreich var i wieder auf 0 setzte für den nächsten durchlauf
                }
          }
  }
}