Trying to get rid of Delay in a for loop. Weird consequences :

Status
Not open for further replies.

laptophead

Well-known member
Better start with the code:

HTML:
static unsigned long _ETimer;
unsigned long  Period;
#include "Keyboard.h"
int StepNo;
static unsigned int i;

String Kbd_Str; // from keyboard string via Serial monitor


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

}

void loop() {

  SwichCaseFun();


  if   (Serial.available () > 0 ) // receiving stuff from keyboard - Serial monitor
  {
    Kbd_Str = Serial.readStringUntil('\n');

    char FirstKbd = Kbd_Str.charAt(0);

    if (FirstKbd == '4')
    { StepNo = 4;
    }

     if (FirstKbd == '0')
    { StepNo = 0;
    }
  }


}

void Mini_Steps(   unsigned long Inc, unsigned long Tm)  //  and Arrivals A , no of increments,  Tm= Time in mS
{
  Period = (Tm / Inc); //Total time divided by no of increments
  //Serial.println (Period);
  if ( millis() - _ETimer >= (Period))
  { _ETimer += (Period);
    //static unsigned int i;
    i++;
    Serial.println(i);
   // /*
    if (i >= 50) // finished trajectory
    { i = 0;  // resetting for next time
     // StepNo = 0;  // do nothing step
    }
 //   */
  }
}


void SwichCaseFun()
{
  switch (StepNo)
  {
    case 0:    // do nothig step
      //Serial.println("zero");
      break;


    case 4:  // Stay put, hold position

      Mini_Steps (  50, 5000);

      break;
  }
}

The weird problems:
If I activate line 50 : StepNo = 0;
There is no more "period" spacing in the count, it goes as fast as possible.

Without that line I am able to start and stop the code with 4 and 0 command from the kbd.
But:
First time I run it there is no time spacing between the increments. then it gets better

From the serial monitor:
1
2
09:41:01.514 -> 3
09:41:01.514 -> 4
09:41:01.514 -> 5
09:41:01.514 -> 6
09:41:01.514 -> 7
09:41:01.514 -> 8
9
10
11
12

What am I doing wrong?
Is there a better way (Library) to do a for loop with spacing without delays?

Thanks a lot,

This is on a Teensy 3.6
 
#laptophead:

You have everything WRT the delay right. The missing piece is this: when you are in state '0', the millis() continue to accumulate, but _Etimer stays at the millis() value from the last time you were in state '4'. As a result, the difference between millis() & _ETimer is much much greater than your calculated Period, so it will cycle very quickly. One simple fix would be to replace the state '4' section in the loop with this:

Code:
    if (FirstKbd == '4')
    { StepNo = 4;
      _ETimer = millis();
    }

This way, every time you enter the Mini_Steps() function, _ETimer has a current value. This also fixes the problem where the first cycle is very short.

Hope that helps !!

Good luck & have fun !!

Mark J Culross
KD5RXT
 
Status
Not open for further replies.
Back
Top