Intermediate Series Lesson 3: Timers Part II
In this second part of our Timers series, we will learn to create timer based autonomous flight paths.



In the beginners series, we learned how to create autonomous flight paths using the function delay().  Here we will explore the downsides of using delay()  and figure out how to replace it with millis() .


The Problem with Delay()

This has been explained before, but it’s worth noting again.  Using delays such as delay()  is usually frowned upon in programming because of the effect is has on loop speed.  Generally speaking, the faster your program can loop the better your code is.

Compare these two snippets of code.  In both cases, we are trying to accomplish two things:

  1. Every 500 milliseconds, print out “500 milliseconds has passed”.
  2. Perform a sensor check every loop.  This represents functions such as digitalRead() , analogRead() , and other input functions.  It’s important to realize that these functions can only check your sensors every time their specific lines are read by the loop.

Sample 1: Using delay()



Here we use delay.  Our sensor check intervals are 506, 1016, 1525, 2032… intervals of about 500 milliseconds

We accomplish the first goal of printing “500 milliseconds has passed” every 500 milliseconds, but as a result our sensor is only checked once every 500 milliseconds.

It’s clear to see that our delay is dramatically slowing down our loop time (one loop every 500ms).


Sample 2: Using Timers



Here we use timers.  In this case, our sensor check intervals are 219, 240, 261, 282… intervals of about 20 milliseconds.

We still accomplish our goal of printing “500 milliseconds has passed”, but we also check our sensors every 20 milliseconds as opposed to 500 ms.

This method will result in a much quicker loop time (one loop every 20ms).


Autonomous Flight Pathing with Timers

Our previous flight path used delay()  to control our interval lengths

This code initiates our autonomous maneuver when we cover sensor bt1 .  The problem with this is the extremely slow loop time caused by delay() .  Once we activate our maneuver, there is no way to use the kill switch CoDrone.FlightEvent(Stop);  until after the CoDrone finishes the entire flight path.


Instead, we’ll use timers.  Here’s what the same flight path looks like with timers

Let’s break it down

To initialize our maneuver, we use the sensor bt1

This resets the beginning point of our timer to the current millis() , and also sets our StartFlag  to 1.


Now that StartFlag = 1 , our statement will execute

The reason we have a flag check to begin our maneuver is to prevent the maneuver from starting when we first turn on our SmartInventor Board.  Remember that millis()  begins at 0, so the condition

would be true at the start of our program.   We prevent this from executing with the StartFlag statement.


The core of our program uses timer statements from the previous lesson

Notice that each maneuver must add the duration to the previous time.

1.   if (millis() - StartTime < 2000).

This lasts 2000 milliseconds

2.  else if (millis() - StartTime < 4000 )

This also lasts 2000 milliseconds, but takes into account the previous 2000 milliseconds



Adding More Steps

Adding more steps into your maneuver is as easy as adding more ‘else if’ statements

Just remember to keep adding the times too.


Kill Switch

Now you can add a kill-switch into your autonomous programs

Since timers don’t stop the looping of your code, the sensor bt8  will be constantly checked.  This will allow it to Stop your CoDrone at any point in the maneuver.

Be sure to set StartFlag = 0  to prevent your CoDrone from receiving more commands after it lands.


Advanced Resetting Timers

If you don’t want to keep adding the duration of each maneuver, you can utilize flags to create a timer that resets after each stage

In this case, we use StartFlag as the condition for our maneuvers, and our timer as the controller for StartTime

Whenever the timer gets above 2000 milliseconds, StartFlag  is changed to the next step and the timer is reset StartTime = millis(); 

This is a useful method to use when you are creating very long maneuvers and need to adjust the times a lot.



Activity: Square Dancing



Write a program that flies your CoDrone in a square:

  1. Throttle
  2. Roll
  3. Pitch
  4. -Roll
  5. -Pitch
  6. Land

Include a kill switch and make sure that you can Stop your CoDrone at any time