Kein Delay() benutzen - Problem

Ich baue einen Microcontroller für das Auto.
Jetzt habe ich folgende Sache:

Ich habe mehrere Funktionen die allerdings brauchen.

Jetzt hab ich zum Beispiel eine Funktion in der vorhandenen ZV für die Fensterheber. Dieses Signal ist nur kurzzeitig. Es geht auf den Microcontroller. Dieser verarbeitet es dann mit dem Fenster Hoch bzw Runter.

Allerdings Soll er ja natürlich nicht länger laufen als nötig. Somit Öffnet das Fenster und bekommt einen Delay von 4 Sekunden dass er danach den PIN auf LOW setzt.

Nebenbei soll man aber noch Auf und zu schließen können also das quitieren etc.

Was ich gerne hätte diese millis Funktionen in den einzelnen void's, da ich wenn alles direkt im loop() steht, keine Übersicht mehr habe.

Würde mich sehr freuen wenn mir jemand dabei helfen könnte das mit mehreren Funktionen zu machen.

void loop() 
{
  //unsigned long currentMillis = millis();
  AufPINStatus = digitalRead(AufPIN);
  ZuPINStatus = digitalRead(ZuPIN);
  FensterPINStatus = digitalRead(FensterPIN);

  if(AufPINStatus == HIGH) 
  {
    ZVAufLauft = 1;
    ZVAuf();
  }
  else if(ZuPINStatus == HIGH) 
  {
    ZVZuLauft = 1;
    ZVZu();
  }
  else if(FensterPINStatus == HIGH) 
  {
    if(FensterUnten == 0)
    {
      FensterUntenLauft = 1;
      CFensterRunter();
      FensterRunter();
      FensterUnten = 1;
      if(AlarmTest < 2)
      {
        AlarmTest++;
      }
      else
      {
      }
    }
    else if(FensterUnten != 0)
    {
      FensterHochLauft = 1;
      CFensterHoch();
      FensterHoch();
      FensterUnten = 0;
      if(AlarmTest < 2)
      {
        AlarmTest++;
      }
      else
      {
      }
    }
  }
  else if(AlarmTest == 3)
  {
    AlarmAktiv = 1;
    AlarmTest = 0;
  }
  else 
  {

  }
}
void ZVAuf()
{
  if(ZVAufLauft == 1)
  {
    tone(ChirpPIN, Frequenz, Delay1);
    delay(Delay2);
    noTone(ChirpPIN);
    tone(ChirpPIN, Frequenz, Delay1);
    delay(Delay2);
    noTone(ChirpPIN);
    ZVAufLauft = 0;
    if(AlarmTest >= 2)
    {
      AlarmTest = 2;
      AlarmTest++;
    }
    //delay(1000);
  }
}
void ZVZu()
{
  if(ZVZuLauft == 1)
  {
    tone(ChirpPIN, Frequenz, Delay1);
    delay(Delay2);
    noTone(ChirpPIN);
    ZVZuLauft = 0;
    AlarmTest = 0;
    AlarmAktiv = 0;
    //delay(1000);
  }
}
void CFensterRunter()
{
  if(FensterUntenLauft == 1 && FensterHochLauft == 0)
  {
    tone(ChirpPIN, FrequenzFenster, DelayFensterRunter1);
    delay(DelayFensterRunter2);
    noTone(ChirpPIN);
    FensterUntenLauft = 0;
  }
}
void CFensterHoch()
{  
  if(FensterHochLauft == 1 && FensterUntenLauft == 0)
  {
    tone(ChirpPIN, FrequenzFenster, DelayFensterHoch1);
    delay(DelayFensterHoch2);
    noTone(ChirpPIN);
    FensterHochLauft = 0;
  }
}

Setze bitte deinen Sketch in Code-Tags (Schaltfläche </>) , so ist dieser sehr schwer zu lesen.

Und anstatt der delays kannst du die millis-Funktion einsetzen. Sieh die BlinkWithoutDelays an.
http://playground.arduino.cc/Learning/BlinkWithoutDelayDe

Ist im Code.

Ja das habe ich mir ja schon 100 mal durchgelesen und auch überall mich bei Google durchgeschaut und hier.

Trotzdem verstehe ich das ganze nicht.

Zum Beispiel wie ich das ganze ja nur einmal mache. und nicht im Loop wie die LED die geht ja permanent an und aus.

Und das ganze mit mehreren Sachen kriege ich auch nicht hin.

Stehe noch am Anfang und das ist schon für mich ein großer Schritt den ich nicht verstehe.

Wenn mir das einer anhand dieser Funktion vorführt verstehe ich das. Dann kann ich das auf den Rest auch anwenden.

MfG

Schau Dir mal das StateChangeDetection Beispiel an. Du brauchst eine Variable, in der Du den alten Zustand speicherst. Dann kannst Du feststellen, ob sich der Zustand geändert hat.

Also ich habe das jetzt mal irgendwie selber versucht. Jetzt ist nur folgendes:

Ich betätige den Fenster PIN kurz. er soll 4 Sekunden an sein nach dem Quitieren und dann aus.

Wenn ich dies mache und dabei noch den AUF und ZU Pin belege wie man lustig ist, bleibt der Fenster PIN aber viel länger an als es soll. Wieso ist das so ? Was ist da falsch ?

Würde mich über Hilfe freuen.

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

  /*AufPINStatus = digitalRead(AufPIN);
    ZuPINStatus = digitalRead(ZuPIN);
    FensterPINStatus = digitalRead(FensterPIN);*/
  if (digitalRead(AufPIN) == HIGH)
  {
    AufPINStatus = 1;
  }
  else if (digitalRead(ZuPIN) == HIGH)
  {
    ZuPINStatus = 1;
  }
  else if (digitalRead(FensterPIN) == HIGH)
  {
    FensterPINStatus = 1;
  }

  if (AufPINStatus == HIGH)
  {
    if (millis() - VTime > ZVDelayAuf)
    {
      ZVSchrittAuf++;
      switch (ZVSchrittAuf)
      {
        case 1:
          tone(ChirpPIN, Frequenz, Delay1);
          ZVDelayAuf = 500;
          break;
        case 2:
          tone(ChirpPIN, Frequenz, Delay1);
          ZVDelayAuf = 500;
          break;
        default:
          ZVAuf();
          AufPINStatus = 0;
          ZVSchrittAuf = 0;
          ZVDelayAuf = 1;
      }
      VTime = millis();
    }
  }
  else if (ZuPINStatus == HIGH)
  {
    if (millis() - VTime > ZVDelayZu)
    {
      ZVSchrittZu++;
      switch (ZVSchrittZu)
      {
        case 1:
          tone(ChirpPIN, Frequenz, Delay1);
          ZVDelayZu = 500;
          break;
        /*case 2:
          tone(ChirpPIN, Frequenz, Delay1);
          ZVDelayZu = 500;
          break;*/
        default:
          ZVZu();
          ZuPINStatus = 0;
          ZVSchrittZu = 0;
          ZVDelayZu = 1;
      }
      VTime = millis();
    }
  }
  else if (FensterPINStatus == HIGH)
  {
    if (FensterUnten == 0)
    {
      if (millis() - VTime > ZVDelayFensterRunter)
      {
        ZVSchrittFensterRunter++;
        switch (ZVSchrittFensterRunter)
        {
          case 1:
            if (AlarmTest < 2)
            {
              AlarmTest++;
            }
            else
            {
            }
            ZVSchrittFensterHoch = 0;
            ZVDelayFensterHoch = 0;
            tone(ChirpPIN, FrequenzFenster, DelayFensterRunter);
            ZVDelayFensterRunter = 650;
            break;
          case 2:
            digitalWrite(FRunterPIN, HIGH);
            ZVDelayFensterRunter = 4000;
            VTime = millis();
            break;
          default:
            digitalWrite(FRunterPIN, LOW);
            ZVSchrittFensterRunter = 0;
            ZVDelayFensterRunter = 1;
            FensterPINStatus = 0;
            FensterUnten = 1;
        }
        VTime = millis();
      }
    }
    if (FensterUnten != 0)
    {
      if (millis() - VTime > ZVDelayFensterHoch)
      {
        ZVSchrittFensterHoch++;
        switch (ZVSchrittFensterHoch)
        {
          case 1:
            if (AlarmTest < 2)
            {
              AlarmTest++;
            }
            else
            {
            }
            ZVSchrittFensterRunter = 0;
            ZVDelayFensterRunter = 0;
            tone(ChirpPIN, FrequenzFenster, DelayFensterHoch);
            ZVDelayFensterHoch = 650;
            break;
          case 2:
            digitalWrite(FHochPIN, HIGH);
            ZVDelayFensterHoch = 5000;
            break;
          default:
            digitalWrite(FHochPIN, LOW);
            ZVSchrittFensterHoch = 0;
            ZVDelayFensterHoch = 1;
            FensterPINStatus = 0;
            FensterUnten = 0;
        }
        VTime = millis();
      }
    }
  }
  else if (AlarmTest == 3)
  {
    AlarmAktiv = 1;
    AlarmTest = 0;
  }
  else if (AlarmAktiv == 1)
  {
    if (millis() - VTime > DelayAlarm)
    {
      AlarmSchritt++;
      switch (AlarmSchritt)
      {
        case 1:
          for (AlarmFrequenz = 1000; AlarmFrequenz < 2000; AlarmFrequenz += 1)
          {
            tone(ChirpPIN, AlarmFrequenz, 100);     // Beep pin, freq, time
            DelayAlarm = 1;
          }
          break;
        /*case 2:
          tone(ChirpPIN, Frequenz, Delay1);
          ZVDelayZu = 500;
          break;*/
        default:
          AlarmSchritt = 0;
          DelayAlarm = 0;
      }
      VTime = millis();
    }
    if (millis() - VTime > DelayAlarmBlinker)
    {
      AlarmSchrittBlinker++;
      switch (AlarmSchrittBlinker)
      {
        case 1:
          digitalWrite(BlinkPIN, HIGH);
          DelayAlarmBlinker = 500;
          break;
        case 2:
          digitalWrite(BlinkPIN, LOW);
          DelayAlarmBlinker = 500;
          AlarmSchrittBlinker = 1;
          break;
        default:
          AlarmSchrittBlinker = 0;
          DelayAlarmBlinker = 0;
      }
      VTime = millis();
    }
    /*tone(ChirpPIN, 1225, 650);
      delay(650);
      tone(ChirpPIN, 1900, 650);
      delay(650);*/
  }
  else
  {
  }
  Serial.println(ZVDelayFensterRunter);
  //AlarmanlagenLoop();
}
void ZVAuf()
{
  AlarmSchritt = 0;
  AlarmSchrittBlinker = 0;
  AlarmTest = 0;
  AlarmAktiv = 0;
}
void ZVZu()
{
  if (AlarmTest >= 2)
  {
    AlarmTest = 2;
    AlarmTest++;
  }
}

Du weisst aber schon, dass das Ganze gefährlich werden kann, so zwecks einklemmen und so. Du solltest dir unbedingt über ein Sicherheitssystem Gedanken machen. Z.B. mit Stromüberwachen. Dann nimmst du die Zeit eh nur als Timeout, falls mal was an der Mechanik kaputt geht.

P.S.: Mach dich noch auf alle möglichen Warnungen gefasst, wenn das Kfz im Bereich der StVZO betrieben wird. Idealerweise baut man solche Dinge nur als Anschauungsmaterial für Standmodelle :wink:
Aber das mit den Sicherheitsmaßnahmen meine ich ernst. Und verkauf das Auto nicht mit dem System.

MaxPed:
Ich betätige den Fenster PIN kurz. er soll 4 Sekunden an sein nach dem Quitieren und dann aus.

Wenn ich dies mache und dabei noch den AUF und ZU Pin belege wie man lustig ist, bleibt der Fenster PIN aber viel länger an als es soll. Wieso ist das so ? Was ist da falsch ?

Vermutlich startest du mit jedem Tastendruck den 4s-Timer neu. Ich kapituliere allerdings vor deinem Code-Monster.
Mach dir (Fluss-)diagramme um dich nicht in der Logik zu verheddern. Überlege, was passieren soll, wenn widerspüchliche Befehle wie oben angesprochen kommen.
Überlege welche Funktionen (z.B. Pipsen) du in Unterprogramme auslagern kannst.

Die Taster sollten die Status-Variable nur setzen (auf/ab), zurücksetzen wenn die Aktion ausgeführt ist.

Ganz WICHTIG: Beim drücken während des Schließens MUSS die Scheibe stehen bleiben. Bei längerem drücken (0,75sek.?) sogar wieder öffnen.

Weiterer Komfort: Beim langen drücken von Anfang an läuft die Scheibe nur solange gedrückt wird.

Das ganze ist nicht trivial, wenn man es richtig machen will.

Die Blockierstromabschaltung sollte man selbstlernend machen und mit Orangen testen. Kannst auch Schweinefüsse nehmen.