Problem mit millis !

meine millis kommen etwas durcheinander !
was fehlt, oder ist falsch in meinem code, damit die STEPS nacheinander ausgeführt werden ?

hier der code :

int ExGate = 13;

int ClockSpeed = 0;
unsigned long clockPrev = 0;
#define clockPoti A2

int GateLenght = 0;
unsigned long gatePrev = 0;
#define gatePoti A3

float testteiler = 0;                   // float langsam ??


void setup() {
  Serial.begin(9600);
  pinMode(ExGate, OUTPUT);
  clockPrev = millis();
  gatePrev = millis();
}

void loop() {
  
  ClockSpeed = analogRead(clockPoti);
  GateLenght = analogRead(gatePoti);
  testteiler = ClockSpeed / 512;
  
//-------------------------------------------------------  STEP 1
  if((millis() - clockPrev) > ClockSpeed) {
    clockPrev = millis();
    gatePrev = millis();
    digitalWrite(ExGate,HIGH);
  }
    if((millis() - gatePrev) > (testteiler * GateLenght)) {
    digitalWrite(ExGate,LOW);
  }
  
//-------------------------------------------------------  STEP 2
    if((millis() - clockPrev) > ClockSpeed) {
    clockPrev = millis();
    gatePrev = millis();
    digitalWrite(ExGate,LOW);
  }
    if((millis() - gatePrev) > (testteiler * GateLenght)) {
    digitalWrite(ExGate,LOW);
  }
  
//-------------------------------------------------------  STEP 3  
    if((millis() - clockPrev) > ClockSpeed) {
    clockPrev = millis();
    gatePrev = millis();
    digitalWrite(ExGate,LOW);
  }
    if((millis() - gatePrev) > (testteiler * GateLenght)) {
    digitalWrite(ExGate,LOW);
  }
  
//-------------------------------------------------------  STEP 4
    if((millis() - clockPrev) > ClockSpeed) {
    clockPrev = millis();
    gatePrev = millis();
    digitalWrite(ExGate,HIGH);
  }
    if((millis() - gatePrev) > (testteiler * GateLenght)) {
    digitalWrite(ExGate,LOW);
  }
  
//-------------------------------------------------------
}

danke schon mal für eure hilfe !

Es wird immer nur das erste IF-Statemant wahr also auch die Aktionen dahinter nur augeführt.
Am besten du lässt im ersten If-Statement einen Zähler hochzählen bei jedem mal wenn er Wahr wird.
Also Variable Schritt=Schritt+1

//-------------------------------------------------------  STEP 2
    if((millis() - clockPrev) > ClockSpeed) {
    clockPrev = millis();
    gatePrev = millis();
runone=false; 

Schritt=Schritt+1;  // Hier wird der Zähler addiert

if (Schritt==6){     // Damit er nach dem 5ten Schrit wieder bei 1 anfängt
Schritt=1;}    

if(Schritt==5){
}
  digitalWrite(ExGate,LOW);
  }
 if(Schritt==1 && runone==false){
=>Hier kommst das was du in Schritt 1 Machen willst<= 
runone=true;             // Damit dies nur einmal ausgeführt wird und bis zur nächstn Zeit "gesperrt ist"
   if((millis() - gatePrev) > (testteiler * GateLenght)) {
    digitalWrite(ExGate,LOW);
  }

}


if(Schritt==2 && runone==false){
=>Hier kommst das was du in Schritt 2 Machen willst<= 
runone=true;             // Damit dies nur einmal ausgeführt wird und bis zur nächstn Zeit "gesperrt ist"
   if((millis() - gatePrev) > (testteiler * GateLenght)) {
    digitalWrite(ExGate,LOW);
  }



// und so weiter
}

Mal ein vorschlag so ähnlich müsste das laufen

Gruß

Daniel

Wenn die Bedingung "if((millis() - clockPrev) > ClockSpeed)" in STEP 1 zutrifft setzt Du ja ClockSpeed auf den aktuellen millis() Wert.
Somit ist in den nachfolgenden Abfragen in STEP 2 bis 4 das Ergebnis immer Falsch.

volvodani:
Mal ein vorschlag so ähnlich müsste das laufen

Du hast jetzt aber die beiden Abfragen verschachtelt, im Originalcode kommen sie hintereinander. Somit würde Bedingung 2 [if((millis() - gatePrev) > (testteiler * GateLenght))] nur abgefragt wenn gleichzeitig Bedingung 1 [if((millis() - clockPrev) > ClockSpeed)] zutrifft.

Mein Vorschlag:

int ExGate = 13;

int ClockSpeed = 0;
unsigned long clockPrev = 0;
#define clockPoti A2

int GateLenght = 0;
unsigned long gatePrev = 0;
#define gatePoti A3

int stepCounter = 0;
bool firstRun = true;

float testteiler = 0;                   // float langsam ??

#define STEPS_COUNT 4
int stepsA[STEPS_COUNT] = {HIGH, LOW, LOW, HIGH};
int stepsB[STEPS_COUNT] = {LOW,  LOW, LOW, LOW};


void setup() 
{
  Serial.begin(9600);
  pinMode(ExGate, OUTPUT);
  clockPrev = millis();
  gatePrev = millis();
}

void loop() 
{
  ClockSpeed = analogRead(clockPoti);
  GateLenght = analogRead(gatePoti);
  testteiler = ClockSpeed / 512;
  
  if (firstRun && ((millis() - clockPrev) > ClockSpeed))
  {
    clockPrev = millis();
    gatePrev = millis();
    digitalWrite(ExGate, stepsA[stepCounter]);
    firstRun = false;
  }

  if (!firstRun && ((millis() - gatePrev) > (testteiler * GateLenght)))
  {
    digitalWrite(ExGate, stepsB[stepCounter]);
    stepCounter = (++stepCounter) % STEPS_COUNT;  // Durch Modulo geht stepCounter immer nur von 0 bis STEPS_COUNT - 1 
    firstRun = true;
  }
}

MaFu:
Wenn die Bedingung "if((millis() - clockPrev) > ClockSpeed)" in STEP 1 zutrifft setzt Du ja ClockSpeed auf den aktuellen millis() Wert.
Somit ist in den nachfolgenden Abfragen in STEP 2 bis 4 das Ergebnis immer Falsch.

du meintest sicherlich clockPrev anstatt ClockSpeed (wird ja nur verändert, wenn auch am poti was geändert wird).
ich habe gadacht, das die schritte nacheinander abgefragt werden. dem ist wohl nicht so.

volvodani:
Es wird immer nur das erste IF-Statemant wahr also auch die Aktionen dahinter nur augeführt.

nur zum verstehen, könnt ihr mir das noch mal erklären ?

ich werd mir jetzt mal eure beiden codes genauer anschaun und versuchen die zählerfunktion einzubauen.
danke schon mal für die hilfe :wink:

eldopa:
du meintest sicherlich clockPrev anstatt ClockSpeed (wird ja nur verändert, wenn auch am poti was geändert wird).

Richtig, da hatte ich mich verschrieben.

ich habe gadacht, das die schritte nacheinander abgefragt werden. dem ist wohl nicht so.

Doch, die Schritte werden nacheinander abgefragt.
Aber wenn in STEP 1 die Abfrage "if((millis() - clockPrev) > ClockSpeed)" zutrifft setzt Du ja clockPrev sofort auf den aktuellen millis() Wert. Bei STEP 2 und den nachfolgenden Schritten ist somit "millis() - clockPrev" immer 0 (die paar Funktionen brauchen keine Millisekunde) und somit immer kleiner als ClockSpeed.

ok,
da hab ich wohl noch zu sehr "delay-mäßig" gedacht.
also step 2 wird eigentlich schon ausgeführt während step 1 noch leuchtet, richtig ?

2 fragen hab ich noch :

erstens ist mir noch firstRun etwas unklar.
ist das so eine art bremse, damit der code nicht gleich wieder "durch-rattert" ?

das zweite wäre das hier :

    stepCounter = (++stepCounter) % STEPS_COUNT;  // Durch Modulo geht stepCounter immer nur von 0 bis STEPS_COUNT - 1

was genau bewirkt % STEPS_COUNT ?

ein anfänger dankt :wink:

eldopa:
2 fragen hab ich noch :

erstens ist mir noch firstRun etwas unklar.
ist das so eine art bremse, damit der code nicht gleich wieder "durch-rattert" ?

Nein, keine Bremse. Die Variable dient zur Unterscheidung, welche Abfrage aktiv sein soll.
Ist firstRun true, wird nur die erste Abfrage ausgewertet. Ist sie wahr, geht firstRun auf false und es wird nun die zweite Abfrage berücksichtigt. Sobald diese wahr ist, geht firstRun wieder auf True und es beginnt von vorne.
Es kann ja sein, dass das so nicht korrekt ist. Dazu müsste ich aber wissen, wass Du eigentlich genau bezweckst.

das zweite wäre das hier :

    stepCounter = (++stepCounter) % STEPS_COUNT;  // Durch Modulo geht stepCounter immer nur von 0 bis STEPS_COUNT - 1

was genau bewirkt % STEPS_COUNT ?

Das % ist der Modulo Operator, eine Ganzzahldivision bei der das Ergebnis der Rest der Division ist. Damit kann man ohne weitere Abfrage sehr schön einen Zählbereich einschränken.
Beispiel (stepCounter steht zu Beginn auf 0):
stepCounter = (++stepCounter) % STEPS_COUNT;
stepCounter wird um eins erhöht und steht somit auf 1
1 geteilt durch STEPS_COUNT(=4) ergibt 0 Rest 1
stepCounter steht somit auf 1 (wie gesagt, Modulo liefert den Rest der Division zurück)
Beim nächsten Durchlauf steht stepCounter auf 2, 2/4 ergibt 0 Rest 2, stepCounter ist somit 2.
Beim nächsten Durchlauf steht stepCounter auf 3, 3/4 ergibt 0 Rest 3, stepCounter ist somit 3.
Beim nächsten Durchlauf steht stepCounter auf 4, 4/4 ergibt 1 Rest 0, stepCounter ist somit 0 und es beginnt wieder von vorne.