Arduino Millis and Indexing Code

Around here those time frames are considerably smaller. I'm lucky if things I did yesterday make sense tomorrow, or even late enough today. :expressionless:

a7

3 Likes

LarryD, was I right on my answer to your question below?

  • We use Macros to help document our code, HIGH/LOW mean nothing.
    Hence #define LEDon HIGH makes more sense when we read our code.
    .
    digitalWrite(testLED, LEDon); is all we need to document our code.

  • The following lines of code are already documented:

  • When the switch on D02 closes . . .

      //make this TIMER 2 seconds
      commonTIMER.setInterval(2000ul);  //i.e. we are setting a TIMER object called commonTIMER to 2 seconds

      //start this TIMER
      commonTIMER.enableRestartTIMER(); //i.e. we now start the commonTIMER object

      //next state
      mState = STATE1; //i.e. we now set out mState (State Machine variabel) to STATE1 (which is actually equal to 1)
  • Yes you are right :+1: it simply is there to make the LED go to the opposite state.

On this topic (C++ Enumeration), I have not been exposed to this. Will need to take some time to read, absorb and put into practice.




  • We always write our sketches so they are non blocking.
    i.e. we avoid using delay( ) and avoid while( . . . ) as much as possible.

  • We are telling the heartbeat LED to toggle (flash) every 500ms.
    Look at your LED, you should observe this happening.

  • Let's say we update out sketch with new code and now the heartbeat LED stutters or flashes once per 3 seconds.

  • The LED can give us a rough indication things are working properly.

  • Stuttering or or not flashing at 1Hz means our new code has a problem.


  • Do you understand what we are doing is creating a C++ TIMER object ?

  • It has the name heartbeatTIMER, it is a millis based TIMER, its time-out is 500ms (1/2 sec), the TIMER is enabled and it auto-restarts.


The TIMER is now set to expire every 200ms

//========================
makeTIMER heartbeatTIMER =
{
  //.TimerType, .Interval, .TimerFlag, .Restart, .SpeedAdjustPin
  MILLIS, 200ul, ENABLED, YES, 0
};




  • Excellent !

So, are you saying that instead of coding this:

if (mySwitch.lastState == CLOSED)
{digitalWrite(testLED, HIGH);

We should code it this way:

if (mySwitch.lastState == CLOSED)
{digitalWrite(testLED, LEDon);

because we earlier did this:

#define LEDon HIGH

  • We can still carry on, I will be revisiting this later.
  • Yes

  • BTW always place { and } on lines by themselves and always format your sketch with <CTRL><T> or <CMD><T>.

I like the idea of a millis based sketch.
So, it appears that when we create an object called heartbeatTIMER, it has 5 parameters that you list as:

MILLIS, 500ul, ENABLED, YES, 0

Is that correct?

Meaning,

  1. it is MILLIS based
  2. The time period is 500 milliseconds
  3. The timer is ENABLED for now
  4. YES meaning it is to reset after timing out?
  5. 0 means ???
  • Every now and then we need to speed up our code so we don't have to wait for things to happen.

  • Let's say a LED was to toggle every hour.
    There is no way I am going to stay and wait for an hour. (only at the doctors office)

  • The 5th member can be added so a potentiometer can be used to tune/speedup a TIMER.

//========================
makeTIMER heartbeatTIMER =
{
  //.TimerType, .Interval, .TimerFlag, .Restart, .SpeedAdjustPin
  MILLIS, 500ul, ENABLED, YES, A4
};
  • Above, a potentiometer connected to GPIO A4 can be turned to increase the speed that that TIMER runs at.

It's a debugging feature.

1 Like

Got it!

  • How many TIMER objects are we making here ?
//========================
makeTIMER heartbeatTIMER =
{
  //.TimerType, .Interval, .TimerFlag, .Restart, .SpeedAdjustPin
  MILLIS, 500ul, ENABLED, YES, 0
};

//========================  (5ms * s_filter) i.e. 5ms * 10 = 50ms for checking a valid switch operation
makeTIMER switchesTIMER =
{
  //.TimerType, .Interval, .TimerFlag, .Restart, .SpeedAdjustPin
  MILLIS, 5ul, ENABLED, YES, 0
};

//========================
makeTIMER machineTIMER =
{
  //.TimerType, .Interval, .TimerFlag, .Restart, .SpeedAdjustPin
  MICROS, 1000ul, ENABLED, YES, 0
};

//========================
makeTIMER commonTIMER =
{
  //.TimerType, .Interval, .TimerFlag, .Restart, .SpeedAdjustPin
  MILLIS, 1000ul, DISABLED, NO, 0
};

1 Like

4 timers: heartbeatTIMER, switchesTIMER, machineTIMER and commonTIMER

  • Take a look at the loop( ) code in the sketch offered you in Post #17.

  • You should see there are 3 TIMERs that are being examined.

  • Every 500ms we toggle the heartbeat LED.
    Every 5ms we check our switches.
    Every 1ms we service our state machine.

  • Once we service the State Machine, we start things all over again.

  • This all happens in ~28us, the time it takes loop( ) to execute.

  • Yes !
    i.e. 4 TIMER objects.
  • Looking at page 3 in the flow chart and at the sketch offered in Post #17 correlate between them.
    Is there anything that you would like explained ?

There is but I need to run an errand. Let's pick this up again later. Thank you so much for all you have shared thus far! I have already learned alot today!!

  • Correlate between the two images below and the code from Post #17.

  • let’s say we push the switch on GPIO D02.
    The code that monitors the switch sees the switch is closed, it turns ON the testLED and initializes the commonTIMER object.
    .
    i.e. it sets the commonTIMER to 2000ms and it starts the TIMER.
    .
    We then make our State Machine go from the STARTUP state to STATE1

  • In STATE1, we check to see if the commonTIMER object has expired, if not, we just leave the State Machine.
    .
    If the commonTIMER object is expired, we disable the commonTIMER object, turn off the testLED and make our State Machine go back to the STARTUP state.