millis timing help

could anyone help me with this the code will work with delays but i need to change it because it delays my t
timing section of code the way i have it it instantly does the hole pro tree section with out the 400mill delay

unsigned long stageMillis;
unsigned long startMillis;
unsigned long currentMillis;
unsigned long startTime;
unsigned long stopLeft;
unsigned long stopRight;
unsigned long MPHLeftMills;
unsigned long MPHRightMills;
unsigned long MPHLeft;
unsigned long MPHRight;
unsigned long stopMPHLeft;
unsigned long stopMPHRight;
unsigned long stopLeftReaction;
unsigned long stopRightReaction;
long RightReactionTime;
long LeftReactionTime;
unsigned long LeftET;
unsigned long RightET;
unsigned long raceTimeLeft;
unsigned long raceTimeRight;
const unsigned long timeOut = 10000;
const unsigned long minDelay = 400;
const unsigned long maxDelay = 2500;
long proTime = 400;

String val;

void setup()
{

 pinMode(prestageledlPin, OUTPUT);
 pinMode(prestageledrPin, OUTPUT);
 pinMode(stagelPin, OUTPUT);
 pinMode(stagerPin, OUTPUT);
 pinMode(yellow1Pin, OUTPUT);
 pinMode(yellow2Pin, OUTPUT);
 pinMode(yellow3Pin, OUTPUT);
 pinMode(greenlPin, OUTPUT);
 pinMode(greenrPin, OUTPUT);
 pinMode(redlPin, OUTPUT);
 pinMode(redrPin, OUTPUT);
 pinMode(prestagelPin, INPUT_PULLUP);    //left stage sensor
 pinMode(prestagerPin, INPUT_PULLUP);    //right stage sensor
 pinMode(stopLeftPin, INPUT_PULLUP);     //left finish sensor
 pinMode(stopRightPin, INPUT_PULLUP);    //right finish sensor
 pinMode(leftStartPin, INPUT_PULLUP);
 pinMode(rightStartPin, INPUT_PULLUP);
 pinMode(MPHLeftPin, INPUT_PULLUP);     //left mph sensor
 pinMode(MPHRightPin, INPUT_PULLUP);    //right mph sensor
 pinMode(ledPin, OUTPUT);                //timer running led blinks

 Serial.begin(115200);
 Serial1.begin(115200);
 digitalWrite(stagelPin, HIGH);
 digitalWrite(stagerPin, HIGH);
 digitalWrite(yellow1Pin, HIGH);
 digitalWrite(yellow2Pin, HIGH);
 digitalWrite(yellow3Pin, HIGH);
 digitalWrite(greenlPin, HIGH);
 digitalWrite(greenrPin, HIGH);
 digitalWrite(redlPin, HIGH);
 digitalWrite(redrPin, HIGH);
 stageMillis = millis();
}

void loop()
{
 val = "";
 // read input pins:
 stageLeft = digitalRead(prestagelPin);   //left stage/start sensor
 stageRight = digitalRead(prestagerPin);   //right stage/start sensor
 leftStart = digitalRead(leftStartPin);
 rightStart = digitalRead(rightStartPin);
 LeftMPH = digitalRead(MPHLeftPin);
 RightMPH = digitalRead(MPHRightPin);
 timerStopLeftState = digitalRead(stopLeftPin);   //left finish line sensor
 timerStopRightState = digitalRead(stopRightPin);  //right finish line sensor

 
 PcInput();
 Tree();
 Timing();
}
void PcInput()
{
 if (Serial.available())
 {
 val = Serial.readString();
 }
 if (Serial1.available())
 {
 val = Serial1.readString();
 }

 if (val == "AW")
 {
 AutoWin = true;
 }

 if (val == "aw")
 {
 AutoWin = false;
 }

 if (val == "Lwin")
 {
 for (int j = 1; j <= winBlink; j = j + 1)
 {
 digitalWrite(stagelPin, LOW);
 delay(onTime);
 digitalWrite(stagelPin, HIGH);
 delay(offTime);
 }
 }
 if (val == "Rwin")
 {
 for (int j = 1; j <= winBlink; j = j + 1)
 {
 digitalWrite(stagerPin, LOW);
 delay(onTime);
 digitalWrite(stagerPin, HIGH);
 delay(offTime);
 }
 }
 if (val == "I")
 {
 instgreen = true;                // serial signal to start tree
 }
 if (val == "P")                      // serial signal to start tree
 {
 protree = true;
 }
 if (val == "NP")                      // serial signal to start tree
 {
 Nprotree = true;
 }
 if (val == "S")                      // serial signal to start tree
 {
 sportsmantree = true;
 }
}
void Tree()
 {
 if ((stageLeft == LOW) & (leftStart == HIGH))                   //left pre stage light on if car in sensor of if not
 digitalWrite(prestageledlPin, LOW);    //on.
 else
 digitalWrite(prestageledlPin, HIGH);   //off

 if ((stageRight == LOW) & (rightStart == HIGH))                   //right pre stage light on if car in sensor of if not
 digitalWrite(prestageledrPin, LOW);    //on
 else
 digitalWrite(prestageledrPin, HIGH);   //off

 if (instgreen == true)  // start instant green
 {
 digitalWrite(stagelPin, LOW);          //left stage light on by ir
 digitalWrite(stagerPin, LOW);          //right stage light on by ir
 stageMillis = millis();
 instgreen = false;
 delay(random(minDelay, maxDelay));
 currentMillis = millis();
 if (currentMillis - stageMillis >= 400)
 {
 timerStartState = true;
 Start = true;
 }
 }
 if (protree == true)  // start pro tree
 {
 Serial.println("stage1");
 
 digitalWrite(stagelPin, LOW);          //left stage light on by ir
 digitalWrite(stagerPin, LOW);          //right stage light on by ir
 protree = false;
 currentMillis = millis();
 if (currentMillis - stageMillis >= proTime)
 {
 {
 digitalWrite(yellow1Pin, LOW);
 digitalWrite(yellow2Pin, LOW);
 digitalWrite(yellow3Pin, LOW);
 Serial.println("stage2");
 }
 currentMillis = millis();
 if (currentMillis - stageMillis >= proTime)
 {
 Serial.println("stag3");
 timerStartState = true;
 digitalWrite(yellow1Pin, HIGH);
 digitalWrite(yellow2Pin, HIGH);
 digitalWrite(yellow3Pin, HIGH);
 Start = true;
 }
 }
 }

dragtree1.58.ino (14.3 KB)

Please modify your post and give the full sketch. This is not compiling.

It is not possible to replace delay() with millis(). You have to rewrite your sketch.

To use millis(), the loop() has to run as fast and as quick as possible. All waiting and delays have to go.

You need to rewrite the PcInput() function, because the Serial.readString() waits for new data.
Assuming that the loop() is running fast and quick, you can test for Serial.available() and then read one byte and add it to a buffer. There is no need to use a loop to read more than one byte.
I have made an example. It has a timeout, but that timeout uses millis() without waiting. See: millis_serial_timeout.ino. There are other examples for that.

Blinking should be done in the loop(). It is turned on and off with a bool (boolean, true/false) variable.
See my example: millis_within_millis.ino
My example turns the led off at any moment. If you want nice full periods of blinking, then you need more code.

A single delay works in the same way. A bool variable turns it on, and the millis() timer is in the loop() and turns itself off. See my example: millis_single_delay.ino.

sketch added in attachment

i only send input about once a min as far as the inputs everything is working and i am getting my serial prints from the pro tree section but im getting stage1 stage2 and stage3 all at once

Have a look at how millis() is used to manage timing without blocking in Several Things at a Time.

And see Using millis() for timing. A beginners guide if you need more explanation.

...R

@Mikeh23, you have to rewrite the sketch. All the examples in the link by Robin2 and all my examples use millis() in the same way.
I assumed that you had already read about millis() and that I could point you to specific examples that I made.
The place to start is the Blink Without Delay example: https://www.arduino.cc/en/Tutorial/BlinkWithoutDelay

I have read all of the post and rewrote the sketch several time I can get it to work in the timing section where it times out after 10 sec but I don't know what im doing wrong in the section for the lights

Mikeh23:
rewrote the sketch several time I can get it to work in the timing section where it times out after 10 sec

Please post the complete program that represents your best attempt so we can see exactly what you have tried. The devil is in the detail.

...R

I can't post the complete sketch but it's in the attachment it's to long to post

Mikeh23:
I can't post the complete sketch but it's in the attachment it's to long to post

No attachment :slight_smile:

...R

The attachment is on the original post I just rechecked and it there

Mikeh23:
The attachment is on the original post I just rechecked and it there

Please don't add stuff to old Posts - it just confuses the flow of the Thread. I would never have thought of going back to your Original Post for something associated with Reply #7. The attachment would have been immediately obvious if it had been with Reply #7.

...R

The attachment has been there the I added it a few min after I created the post

This is not going to work, and does not make sense

stageMillis = millis();
 instgreen = false;
 delay(random(minDelay, maxDelay));
 currentMillis = millis();
 if (currentMillis - stageMillis >= 400)

If it it weren't for the delay() stageMillis and currentMillis would have the same value and the IF test could never be true

And there is little point in using millis() while there are delay()s in your program.

As it stands all your test is doing is checking whether the random value is >= 400

Separately IMHO you have far too much code in your functions. Keep functions short. Ideally it should be possible to view a complete function on the screen without scrolling. That probably means having a lot more functions. If the functions have meaningful names that will also help with the clarity of the program

It would also be a good idea to learn about arrays and structs as their use would allow the code to be much shorter. For example all of this could probably be reduced to 4 or 5 lines.

pinMode(prestageledlPin, OUTPUT);
 pinMode(prestageledrPin, OUTPUT);
 pinMode(stagelPin, OUTPUT);
 pinMode(stagerPin, OUTPUT);
 pinMode(yellow1Pin, OUTPUT);
 pinMode(yellow2Pin, OUTPUT);
 pinMode(yellow3Pin, OUTPUT);
 pinMode(greenlPin, OUTPUT);
 pinMode(greenrPin, OUTPUT);
 pinMode(redlPin, OUTPUT);
 pinMode(redrPin, OUTPUT);
 pinMode(prestagelPin, INPUT_PULLUP);    //left stage sensor
 pinMode(prestagerPin, INPUT_PULLUP);    //right stage sensor
 pinMode(stopLeftPin, INPUT_PULLUP);     //left finish sensor
 pinMode(stopRightPin, INPUT_PULLUP);    //right finish sensor
 pinMode(leftStartPin, INPUT_PULLUP);
 pinMode(rightStartPin, INPUT_PULLUP);
 pinMode(MPHLeftPin, INPUT_PULLUP);     //left mph sensor
 pinMode(MPHRightPin, INPUT_PULLUP);    //right mph sensor
 pinMode(ledPin, OUTPUT);                //timer running led blinks

...R
Planning and Implementing a Program

Mikeh23:
The attachment has been there the I added it a few min after I created the post

Now I don't know what I have been looking at.

I thought, from your Reply #5, that you had a revised version of the code that took account of comments that had been made in the earlier Replies.

...R

Im not worried about the instant green section I don't really use it as much just the part that's under the if protree is true is what I use the most. I also tried for several months to do this program in a array with some help from someone bon here and never could even get it close to working

this is what i am currently using with the delays but i need to remove them and use mills

if (protree == true)  // start pro tree
		{
			Serial.println("stage1");

			digitalWrite(stagelPin, LOW);          //left stage light on by ir
			digitalWrite(stagerPin, LOW);          //right stage light on by ir
			protree = false;
			delay(800);
			digitalWrite(yellow1Pin, LOW);
			digitalWrite(yellow2Pin, LOW);
			digitalWrite(yellow3Pin, LOW);
			timerStartState = true;            //start timer
			Serial.println("stage2");
			delay(400);
			Serial.println("stag3");
			digitalWrite(yellow1Pin, HIGH);
			digitalWrite(yellow2Pin, HIGH);
			digitalWrite(yellow3Pin, HIGH);
			Start = true;                       //turn on green or red light


		}

I think it needs to be something like this

if (protree == true) { // start pro tree

    if (nextStep == 'A') {
        Serial.println("stage1");

        digitalWrite(stagelPin, LOW);          //left stage light on by ir
        digitalWrite(stagerPin, LOW);          //right stage light on by ir
        protree = false;
        timerStart = millis();
        nextStep = 'B';
    }
    else if (nextStep == 'B' and millis() - timerStart >= 800) {
        //~ delay(800);
        digitalWrite(yellow1Pin, LOW);
        digitalWrite(yellow2Pin, LOW);
        digitalWrite(yellow3Pin, LOW);
        nextStep = 'C';
        timerStart = millis();
        Serial.println("stage2");
    }
    else if (nextStep == 'C' and millis() - timerStart >= 400) { 
        //~ delay(400);
        Serial.println("stag3");
        digitalWrite(yellow1Pin, HIGH);
        digitalWrite(yellow2Pin, HIGH);
        digitalWrite(yellow3Pin, HIGH);
        Start = true;                       //turn on green or red light
    }
}

Because I don't know what you are doing I have just used 'A' 'B' 'C' etc for the steps but you will probably be able to choose more meaningful characters. If you use an ENUM you could give the steps proper names.

The important thing to note is how this code works through a series of steps and ALSO the fact that it will require several (maybe hundreds, if loop() can repeat quickly) iterations through the code to achieve the whole result.

...R

Thanks for your help this worked when I moved the protree = false to the bottom