Trying to Replace "delay"

I know this is simple but I’d like to replace the delay(1000); with the millis; code with minimal modification to the rest of the code but nothing I’ve tried works. This Code just drives a 7 Segment display that start’s at 0 and counts up to 9 and then infinitely repeats the 0 - 9 Count.

const int NumLEDs = 8;
const int LEDPins[NumLEDs] = {6,7,8,9,10,11,12,13};
byte SegCount = 0;
byte Digit = 0;
byte Pin = 0;
int LoopTime = 0;
int LoopTimeB = 0;
unsigned long CurrentTime = 0;

byte SevenSegDigits[10][7] =
{
  { 1,1,1,1,1,1,0 },  // = 0
  { 0,1,1,0,0,0,0 },  // = 1
  { 1,1,0,1,1,0,1 },  // = 2
  { 1,1,1,1,0,0,1 },  // = 3
  { 0,1,1,0,0,1,1 },  // = 4
  { 1,0,1,1,0,1,1 },  // = 5
  { 1,0,1,1,1,1,1 },  // = 6
  { 1,1,1,0,0,0,0 },  // = 7
  { 1,1,1,1,1,1,1 },  // = 8
  { 1,1,1,1,0,1,1 }   // = 9
};


void setup()
{                
  for(int i = 0; i < NumLEDs; i++)
  {
    pinMode(LEDPins[i], OUTPUT);
    digitalWrite(LEDPins[i], LOW);
  }
}

void loop()
{
CurrentTime = millis();

  for (Digit = 0; Digit < 10; ++Digit)                      //Select Seven Segment Digit to Display (0 - 9) from Array
  {
    Pin = 6;                                                //Select Segment A Pin
    for (SegCount = 0; SegCount < 7; ++SegCount)            //Count through Segemnts A - G
      {
      digitalWrite(Pin, SevenSegDigits[Digit][SegCount]);   //Turn the Pin HIGH or LOW based on [Digit][SegCount] position in the Array
      ++Pin;                                                //Increment the Pin
      }
    delay(1000);                                            //Delay 1 Second
  }

Please show me why I’m so stupid and Thanks in advance

Set a number in your loop.
Note the time,
Go outside and smoke a cigarette.
Look through the window at the clock, is it time yet? No? Have a beer then..
Look through the window at the clock, is it time yet? Yes!
Go back inside and set the next number in your loop.
Note the time..

You fall through the loop() function over and over. Its all about saving your state when your there, and doing something quick. Then every time you pass through, just check to see if its time to do anything. If not, go on.

Hope this helps.

-jim lee

Please show me why I'm so stupid

Please show us what you tried.

By the way, the code that you posted does not compile, probably due to a problem when you copy/pasted it into the post.

I think the trick that you're missing is demonstrated by your for loop. You step through a complete count sequence in a single pass of the loop. Because it has all been happening inside the for loop you didn't need to remember any state information and just start the whole 10 second process over again each loop pass.

Remember the current state of your display with a global/static variable.
Remember the millis() time when you last incremented the display with a global/static variable.

Each loop test millis() against the remembered previous increment time and if it's time to act update the display.
AND update both the remembering variables.

Sorry about that now it compiles.

const int NumLEDs = 8;
const int LEDPins[NumLEDs] = {6,7,8,9,10,11,12,13};
byte SegCount = 0;
byte Digit = 0;
byte Pin = 0;
int LoopTime = 0;
int LoopTimeB = 0;
unsigned long CurrentTime = 0;

byte SevenSegDigits[10][7] =
{
  { 1,1,1,1,1,1,0 },  // = 0
  { 0,1,1,0,0,0,0 },  // = 1
  { 1,1,0,1,1,0,1 },  // = 2
  { 1,1,1,1,0,0,1 },  // = 3
  { 0,1,1,0,0,1,1 },  // = 4
  { 1,0,1,1,0,1,1 },  // = 5
  { 1,0,1,1,1,1,1 },  // = 6
  { 1,1,1,0,0,0,0 },  // = 7
  { 1,1,1,1,1,1,1 },  // = 8
  { 1,1,1,1,0,1,1 }   // = 9
};


void setup()
{                
  for(int i = 0; i < NumLEDs; i++)
  {
    pinMode(LEDPins[i], OUTPUT);
    digitalWrite(LEDPins[i], LOW);
  }
}

void loop()
{
CurrentTime = millis();

  for (Digit = 0; Digit < 10; ++Digit)                      //Select Seven Segment Digit to Display (0 - 9) from Array
  {
    Pin = 6;                                                //Select Segment A Pin
    for (SegCount = 0; SegCount < 7; ++SegCount)            //Count through Segemnts A - G
      {
      digitalWrite(Pin, SevenSegDigits[Digit][SegCount]);   //Turn the Pin HIGH or LOW based on [Digit][SegCount] position in the Array
      ++Pin;                                                //Increment the Pin
      }
    delay(1000);                                            //Delay 1 Second
  }
}

Every time you change the value being displayed, you need to record the time.

unsigned long lastDigitChange = 0;

void loop()
{
   unsigned long now = millis();
   if(now - lastDigitChange >= 1000)
   {
       showDigit(Digit++);
       lastDigitChange = now;
   }
}

void showDigit(byte digit)
{
    Pin = 6;
    for (SegCount = 0; SegCount < 7; ++SegCount)
    {
      digitalWrite(Pin, SevenSegDigits[digit][SegCount]);
      ++Pin;
    }
}

I’ll leave it to you to stop the code when Digit gets to 10.

Ok so I’ve tried.

if(CurrentTime - LoopTime >= 1000)

with

LoopTime = CurrenTime

in multiple spots both together one line after another or with the “if” at the start of a Code Loop and the LoopTime designation at the end in at least a dozen ways. I’ve also tried sending the Code to a Subroutine where “delay(1000)” is. All I get is either a 0 or an 8.

I’ve also tried.

While(CurrentTime - LoopTime >=1000)

and

While(CurrentTime - LoopTime < 1000)

with

LoopTime = CurrentTime

It’s just not clicking in properly because I run into the same problem in every sketch I write.
I can never seem to get this to work but I’m sure this is the way to do it by examples like Blink without Delay and many other Sketches where it does.

Thanks[/code]
[/code]

If you want us to analyze your code, and explain why it doesn’t do what you expect, you need to pick one variation of the code and post that. Snippets, completely out of context, are useless.

Did you get rid of the for loop, as I did? If not, you are wasting your time.

PaulS:
Every time you change the value being displayed, you need to record the time.

I’ll leave it to you to stop the code when Digit get

Thank you, I just thought I would be able to keep the “for loop”.
It’s so nice and tidy because it’s contained in just one line of code.

The loop() function is already called by a “for loop” that you cannot see (unless you look for it), so a “for loop” is not as nice and tidy as it may seem.

CurrenTime is not the same as CurrentTime . This is part of the reason why we want your code copied and pasted and properly posted. We want to see the real code, not incorrect snippets.

To post code and/or error messages:

  1. Use CTRL-T in the Arduino IDE to autoformat your complete code.
  2. Paste the complete autoformatted code between code tags (the </> button)
    so that we can easily see and deal with your code.
  3. Paste the complete error message between code tags (the </> button)
    so that we can easily see and deal with your messages.
  4. If you already posted without code tags, you may add the code tags by
    editing your post. Do not change your existing posts in any other way.
    You may make additional posts as needed.

Before posting again, you should read the three locked topics at the top of the Programming Questions forum, and any links to which these posts point.

If your project involves wiring, please provide a schematic and/or a wiring diagram and/or a clear photograph of the wiring.

Good Luck!

If i want to replace the delay and i want to run it every 25ms for example i do this:

if((millis() % 25) == 0)
{
// Do this
}

The statement is only true when he millis counter is a multiple of 25ms.
Changing the 25 for whatever time delay you want to achieve should give you delays without using the delay function.

uobstudent:
If i want to replace the delay and i want to run it every 25ms for example i do this:

if((millis() % 25) == 0)
{
// Do this
}

The statement is only true when he millis counter is a multiple of 25ms.
Changing the 25 for whatever time delay you want to achieve should give you delays without using the delay function.

Yes, however if you use this method, every 4 days the delay interval will be something other than 25ms.

Yes that's true, however, for most hobbyists purposes this few ms out wont make any major difference to the program. Only in time critical control applications.

uobstudent:
If i want to replace the delay and i want to run it every 25ms for example i do this:

if((millis() % 25) == 0)
{
// Do this
}

The statement is only true when he millis counter is a multiple of 25ms.
Changing the 25 for whatever time delay you want to achieve should give you delays without using the delay function.

Damn! That’s brilliant! Karma for you!

I must really be gettin’ old to never to have seen that one.

-jim lee

Because it's awful:
If some part of your code consistently takes more than a millisecond to run, then it will skip intervals for sometimes many seconds.
If some part of your code occasionally takes more than a millisecond then it will randomly skip intervals.
If the rest of your code takes less than a millisecond, then it will double-hit some or all intervals.

It's also using a division operator on a long, which is absurdly slow on an 8-bit Arduino.

It's not a good general-purpose solution to timing with millis(), even though it looks neat.

+1 to that. It looks nice, but it has some serious bugs.