delay() function not working outside loop()

i am making a rover. I have a ultrasonic sensor attached to a servo, and i am using lookAhead function like this:

void lookAhead(){
 servo1.write(90);
 delay(1000);//doesn't work
}

i am calling this function in another function like this:

lookAhead();
      
      if (distance >= 15){
      motor1.run(FORWARD);
      motor2.run(FORWARD);
      }

i want to have a delay so that the servo is rotated properly to measure the distance by ultrasonic sensor. the distance is continuously calculated in loop(). and if the distance is greater than 15, the rover will go forward.

but the delay() doesn't work, as soon as i give the command to go forward, the servo rotates, and also simultaneously, the motors turn. whereas i would like for the motors to wait for the delay(), and then turn so that the servo is properly at its position.
the delay works in loop() though.

also, i am using the wire library to communicate with esp8266, which is acting as a master, and it is running a web server to take commands to move the rover.
any idea what am i doing wrong?

vikrant47:
any idea what am i doing wrong?

You need to post the complete program.

...R

It is much easier for people if you include short programs in your Post as you did with the snippets in your Original Post.

It is also be more logical to add the new code in your Reply #2 so that it fits naturally in the chronological order of the discussion.

You seem to have posted a .cpp file? Why not a .ino file?

...R

I am using cpp file as i am using platformio in vscode.
Here is the important part of the program:

void lookAhead(){
 servo1.write(90);
delay(1000); //not working
}

void setup()
{
  Serial.begin(115200); 

  Wire.begin(1);                
  Wire.onReceive(receiveEvent); // this is the handler function where i am doing everything
}

void loop()
{
//calculate distance from ultrasonic sensor and store in a global variable
delay(300) //it works
}

void receiveEvent(){
// parse incoming string from master(esp8266) as json, and check for the direction (forward, left, right backward)
 if (strcmp(direction, "forward") == 0)
    {
      lookAhead();  //calling lookAhead function
      
// here the delay in lookAhead should have worked, but immediately the following code executes

      if (distance >= 15){
      motor1.run(FORWARD);
      motor2.run(FORWARD);
      }
    }

i have read somewhere that the delay() will not work in an interrupt handler. is the "onReceive" function which handles the receive event for i2c interface a type of interrupt handler?

vikrant47:
I am using cpp file as i am using platformio in vscode.

what is vscode?

visual studio code.

delay in interrupt context? :o

TheMemberFormerlyKnownAsAWOL:
delay in interrupt context? :o

hmm, i suspected this was the problem, i guess delay() and millis() won't work in interrupt handler. so is it that the "master-slave" arrangement with nodemcu and arduino uno won't work here?. i need the nodemcu for wifi. i am using arduino because the motor driver (adafruit motor shield v 1) has some issues with nodemcu. i can try to make it work with nodemcu or maybe use a wifi module with arduino, instead of using nodemcu as master?

i suspected this was the problem

So why didn't you investigate?

i actually didn't know of this before, only after i posted this question, i did some research and found it out. also, i didn't know that the onReceive method is an interrupt handler.

but even if i use just the nodemcu, which will run a server and listen for the the get requests, isn't that request handler also an interrupt handler?

is there a way to create delay in interrupt handlers, using timers etc?

An interrupt is meant for a processor to record and possibly acknowledge a low-latency signal.
There is no place for delay in such a scheme

TheMemberFormerlyKnownAsAWOL:
An interrupt is meant for a processor to record and possibly acknowledge a low-latency signal.
There is no place for delay in such a scheme

so something like this is not possible with arduino? c - STM32F4 - can I use delays in interrupt routines? - Stack Overflow

Possible?
Yes.
Desirable?
No.
Definitely not.

so how to make sure that a servo has rotated to its position, before executing the next line of code? or is that simply not possible?

What is your loop() function doing?

vikrant47:
so how to make sure that a servo has rotated to its position, before executing the next line of code? or is that simply not possible?

Implement your delay outside of the interrupt routine. It's certainly possible. If you need handshake with processes in the ISR, use shared flags and variables.

Nobody can really help you do that, until you post your entire sketch.

loop() is calculating the distance from ultrasonic sensor, and storing it in a global variable.

vikrant47:
loop() is calculating the distance from ultrasonic sensor, and storing it in a global variable.

It looks like a single comment to me.

aarg:
Implement your delay outside of the interrupt routine. It's certainly possible. If you need handshake with processes in the ISR, use shared flags and variables.

Nobody can really help you do that, until you post your entire sketch.

uploaded the file with question.
" use shared flags and variables" can you give me an example, how do i go about doing that?. i can create a global variable, but as long as i call another function from the handler, it is executing inside the handler.

vikrant47:
attached the entire file with question. someone told me to post the simplified code, so i omitted some parts, here is the entire loop():

Please just post the entire program as a single item as requested in Reply #1.

...R