Trying to Replace Multiple Delay Functions

I am flummoxed trying to replace the delay function with millis.

I use an Uno with a servo to move a camera for panoramic pictures. The code works very well. Now I am trying to replace the control box which has a keypad and a 4x20 display with a tablet connected by Bluetooth.Using Bluetooth requires me to eliminate a number of delay functions.

I can use the “millis” technique (i.e. “blink without delay”) to replace one delay, but for some reason I can’t seem to make the technique work with a sequence of operations. It will work in the first instance, but not in subsequent instances.

A panorama requires a number of photos to be taken. The sequence in my program is as follows: Move camera, DELAY, take picture, DELAY,…and the sequence is repeated until the required number of photos has been taken. The delays range from 100 to 4500 milliseconds.

I have tried reading the various articles about the topic. For some reason my decrepit 78 year old brain is missing some key point. Any help will be greatly appreciated.

Here is the code for the function used to take the photos.

//PANO RUN
void PanoRun()
{

  // move to pano start position & begin images
  myLcd.clear();
  myLcd.setCursor(0, 1);
  myLcd.print("Move to Start");
  camPos = (panStart);     // sets the camera position in degrees
  panPos = map(camPos, 0, 180, servoMin, servoMax);     //change degrees to microseconds (truncated)
  myServo.writeMicroseconds(panPos);     // moves camera to start position
  delay(2000);

  // begin the pano imaging sequence (settle-photo-settle-move)
  myLcd.clear();
  myLcd.setCursor(0, 0);
  myLcd.print("Begin pano images");
  delay(2000);
  x = 0;
  for ( x = 0; x <= imgCount; x++) {
    myLcd.clear();
    myLcd.setCursor(0, 0);
    myLcd.print("This Image: "); myLcd.print(x + 1);
    myLcd.setCursor(0, 1);
    myLcd.print("Images To Go: "); myLcd.print(imgCount - x);
    panPos = map(camPos, 0, 180, servoMin, servoMax);     //change degrees to microseconds (truncated)
    myServo.writeMicroseconds(panPos);     // move camera to next image stop
    delay(4500);  // settle camera
    digitalWrite(12, HIGH);     // shutter on
    delay(100);
    digitalWrite(12, LOW);     // shutter off
    delay(3000);
    camPos = (camPos + camTravel);     // increment to next camera position
  }
  delay(1500);
  myLcd.clear();
  myLcd.setCursor(3, 1);
  myLcd.print("PANO COMPLETE!");
  delay(1500);
  myServo.writeMicroseconds(servoHome);
}

See How to use millis() instead of a multiple delay()

I also have problems with using millis() in the beginning.

One technique that might be helpful is to list down all your events in a timeline and create millis() if-conditions from there.

Study how ‘State Machine’ programming works.

Review this example:

Is there anything in the above tutorial that you need help with ?

the basic examples about timing with millis() do blinking which means switch ON after a period of time switch OFF - repeat.

Subsequent waiting needs an additional functionality that controls if this particular has to be "executed" or not.

Therefore the programming technique of the statemachine is very useful

As a short and basic description a statemachine does

Start with executing "startcode" (and only execute startcode)

if conditions to go ahead with step2 are fullfilled switch over to execute code of "step 2" (and only execute code of step2)

if conditions to go ahead with step3 are fullfilled switch over to execute code of "step 3" (and only execute code of step3)

etc. etc.

Study how 'State Machine' programming works.
Review this example:
State Machine and Timers, Medium level tutorial. - Introductory Tutorials - Arduino Forum
Is there anything in the above tutorial that you need help with ?

Yes I have one question about this tutorial as the beginning of this tutorial already mentions

This sketch introduces the concepts of:

  • macros
  • structure
  • enumeration
  • BWD (Blink Without Delay timing) technique
  • timers
  • State Machine

So my question is: does there exist some other tutorial that focuses on statemachines?

I think it will be easier as a first step to have a very simple statemachine that just uses constants instead of enumeration. This tutorial uses enum too
state machine

best regards Stefan

Lots of tutorials out there on FSMs.
Here’s one that works up from Blink Without Delay.

IoT_hobbyist:
See How to use millis() instead of a multiple delay()

IoT_hobbyist – Thanks for this link. While it does show multiple "millis" in place of delays, unfortunately it does not do it in sequence. Using the code results in: Step 1, Step 1, Step 1, Step 2. I am looking for: Step 1, Step 2, Step 1, Step 2

Thanks to larryd – I did go looking into state machines and found a couple of very good videos and a state machine library. My trials with simple instruction indicates that this will solve my problem.

AggieDad:
IoT_hobbyist – Thanks for this link. While it does show multiple "millis" in place of delays, unfortunately it does not do it in sequence. Using the code results in: Step 1, Step 1, Step 1, Step 2. I am looking for: Step 1, Step 2, Step 1, Step 2

Thanks to larryd – I did go looking into state machines and found a couple of very good videos and a state machine library. My trials with simple instruction indicates that this will solve my problem.

HI Aggie,
would you mind to share links to teh videos and the name of the library you found?
I'm always interested in easy to understand material.
Thank you very much
best regards Stefan

Have a look at how the code is organized in Several Things at a Time

Note how each function runs very briefly and returns to loop() so the next one can be called. None of the functions tries to complete a task in one call. And there may be dozens of calls to a function before it is actually time for it to do anything.

...R

Robin2:
Have a look at how the code is organized in Several Things at a Time

Note how each function runs very briefly and returns to loop() so the next one can be called. None of the functions tries to complete a task in one call. And there may be dozens of calls to a function before it is actually time for it to do anything.
...R

This inspired me to expand my own example about nonblocking-timing to "complete tasks distributed over several calls of functions" best regards Stefan

Robin2:
Have a look at how the code is organized in Several Things at a Time

Note how each function runs very briefly and returns to loop() so the next one can be called. None of the functions tries to complete a task in one call. And there may be dozens of calls to a function before it is actually time for it to do anything.

...R

Thank you. I will go through this tomorrow. This has definitely been a learning journey.

StefanL38:
HI Aggie,
would you mind to share links to teh videos and the name of the library you found?
I'm always interested in easy to understand material.
Thank you very much
best regards Stefan

Here are two of the videos. There are others. Just go to YouTube and search Arduino State Machines – that's all I did. You'll find good videos and bad ones.

Multitask Arduino with State Machines (& Switch Debouncing)

Arduino Code - A Simple State Machine Library