How to shorten the program by using the millis() when there is many delays needed

hi there. i have question about millis(), i want to change delay to millis(), but i have too many delays. this is a part of the code

int delaytime =5
void turn_anti1() {
  digitalWrite(C1_1, HIGH);
  digitalWrite(C1_2, LOW);
  delay(delaytime);
  digitalWrite(C1_1, LOW);
  digitalWrite(C1_2, LOW);
  delay(delaytime);
  digitalWrite(C1_1, LOW);
  digitalWrite(C1_2, HIGH);
  delay(delaytime);
  digitalWrite(C1_1, HIGH);
  digitalWrite(C1_2, HIGH);
  delay(delaytime);
}
void turn_anti2() {
  digitalWrite(C2_1, HIGH);
  digitalWrite(C2_2, LOW);
  delay(delaytime);
  digitalWrite(C2_1, LOW);
  digitalWrite(C2_2, LOW);
  delay(delaytime);
  digitalWrite(C2_1, LOW);
  digitalWrite(C2_2, HIGH);
  delay(delaytime);
  digitalWrite(C2_1, HIGH);
  digitalWrite(C2_2, HIGH);
  delay(delaytime);
}

void turn_clock1() {
  digitalWrite(C1_1, HIGH);
  digitalWrite(C1_2, HIGH);
  delay(delaytime);
  digitalWrite(C1_1, LOW);
  digitalWrite(C1_2, HIGH);
  delay(delaytime);
  digitalWrite(C1_1, LOW);
  digitalWrite(C1_2, LOW);
  delay(delaytime);
  digitalWrite(C1_1, HIGH);
  digitalWrite(C1_2, LOW);
  delay(delaytime);
}

void turn_clock2() {
  digitalWrite(C2_1, HIGH);
  digitalWrite(C2_2, HIGH);
  delay(delaytime);
  digitalWrite(C2_1, LOW);
  digitalWrite(C2_2, HIGH);
  delay(delaytime);
  digitalWrite(C2_1, LOW);
  digitalWrite(C2_2, LOW);
  delay(delaytime);
  digitalWrite(C2_1, HIGH);
  digitalWrite(C2_2, LOW);
  delay(delaytime);
}

Well either learn to program properly. Or use a search and replace in your text editor.

What advantage do you think replacing the delays with some code with millis() would give you.
Unless you are a bit clever a delay made by using millis() has exactly the same effect as using delay.

Hello kksua4

Do you have experience with programming in C++?

The task can easily be realised with an object.
A structured array contains all the information, such as the pin addresses for the I/O devices, as well as the information for the timing.
A single service takes care of this information and initiates the intended action.
The structured array makes the sketch scalable until all I/O pins are used up without having to adapt the code for the service.
It is cool stuff, isn´t it?

just a student doing a small project

perhaps not exactly want you want to do

// output sequencer

const byte PinOuts [] = { 10, 11, 12, 13 };
const byte PinBut  = A1;
      byte butLst;

enum { Off = HIGH, On = LOW };

struct Seq {
    byte    zero;
    byte    one;
};
Seq seq [] = {
    {On, Off }, {Off,  Off  }, {Off,  On}, {On, On},
};
const int Nseq = sizeof(seq) / sizeof(Seq);
int seqIdx;
int seqDir;

byte pinIdx;
int  state;

// -----------------------------------------------------------------------------
unsigned long msecPeriod = 5;
unsigned long msecLst;

void
loop (void)
{
    unsigned long msec = millis ();
    if (msecPeriod && msec - msecLst >= msecPeriod)  {
        msecLst = msec;

        digitalWrite (PinOuts [pinIdx],   seq [seqIdx].zero);
        digitalWrite (PinOuts [pinIdx+1], seq [seqIdx].one);

        seqIdx += seqDir;
        seqIdx  = 0 > seqIdx     ? Nseq-1 : seqIdx;
        seqIdx  = Nseq <= seqIdx ? 0      : seqIdx;
    }

    byte but = digitalRead (PinBut);
    if (butLst != but)  {
        butLst = but;
        delay (20);     // debounce
        if (LOW == but)
            switch (++state)  {
            case 1:
                msecPeriod = 200;
                pinIdx =  0;
                seqDir =  1;
                break;

            case 2:
                pinIdx =  2;
                seqDir =  1;
                break;

            case 3:
                pinIdx =  0;
                seqDir = -1;
                break;

            case 4:
                pinIdx =  2;
                seqDir = -1;
                break;

            default:
                state = 0;
                msecPeriod = 0;
                break;
        }
    }
}

// -----------------------------------------------------------------------------
void
setup (void)
{
    Serial.begin (9600);

    pinMode (PinBut, INPUT_PULLUP);
    butLst = digitalRead (PinBut);
    
    for (unsigned n = 0; n < sizeof(PinOuts); n++)  {
        pinMode      (PinOuts [n], OUTPUT);
        digitalWrite (PinOuts [n], Off);
    }
}

seems like your interested in non-blocking timers. you could have multiple timers, each defined by a structure and indexed within each iteration of loop by an index.

not clear what your trying to do

// you need a semicolon line termination
int delaytime =5;

// I think you can use two passes of this "turn()" function
// for all the anti-x and clock-x functions.

void turn(int pin1, bool level1, int pin2, bool level2)
{
  digitalWrite(pin1, level1);
  digitalWrite(pin2, level2);
  delay(delaytime);
}

/***********************************************

     The following patterns show how you can use 
     two passes of the "turn" function above.

***********************************************/

// The pattern in ANTI-1 is: 
// FIRST is always 11
// Second is 1, 0, 0, 1
// Third is always 12
// Fourth is 0, 0, 1, 1

void turn_anti1() {
  digitalWrite(C1_1, HIGH); // 11, 1, 12, 0
  digitalWrite(C1_2, LOW);
  delay(delaytime);
  digitalWrite(C1_1, LOW); // 11, 0, 12, 0
  digitalWrite(C1_2, LOW);
  delay(delaytime);
  digitalWrite(C1_1, LOW); // 11, 0, 12, 1
  digitalWrite(C1_2, HIGH);
  delay(delaytime);
  digitalWrite(C1_1, HIGH); // 11, 1, 12, 1
  digitalWrite(C1_2, HIGH);
  delay(delaytime);
}

// The pattern in ANTI-2 is: 
// FIRST is always 21
// Second is 1, 0, 0, 1 - exactly like ANTI-1
// Third is always 22
// Fourth is 0, 0, 1, 1 - exactly like ANTI-1

void turn_anti2() {
  digitalWrite(C2_1, HIGH); // 21, 1, 22, 0
  digitalWrite(C2_2, LOW);
  delay(delaytime);
  digitalWrite(C2_1, LOW); // 21, 0, 22, 0
  digitalWrite(C2_2, LOW);
  delay(delaytime);
  digitalWrite(C2_1, LOW); // 21, 0, 22, 1
  digitalWrite(C2_2, HIGH);
  delay(delaytime);
  digitalWrite(C2_1, HIGH); // 21, 1, 22, 1
  digitalWrite(C2_2, HIGH);
  delay(delaytime);
}

// The pattern in CLOCK-1 is: 
// FIRST is always 11 - exactly like ANTI-1
// Second is 1, 0, 0, 1 - exactly like ALL movements
// Third is always 12 - exactly like ANTI-1
// Fourth is 1, 1, 0, 0

void turn_clock1() {
  digitalWrite(C1_1, HIGH); // 11, 1, 12, 1
  digitalWrite(C1_2, HIGH);
  delay(delaytime);
  digitalWrite(C1_1, LOW); // 11, 0, 12, 1
  digitalWrite(C1_2, HIGH);
  delay(delaytime);
  digitalWrite(C1_1, LOW); // 11, 0, 12, 0
  digitalWrite(C1_2, LOW);
  delay(delaytime);
  digitalWrite(C1_1, HIGH); // 11, 1, 12, 0
  digitalWrite(C1_2, LOW);
  delay(delaytime);
}

// The pattern in CLOCK-2 is: 
// FIRST is always 21 - exactly like CLOCK-1
// Second is 1, 0, 0, 1 - exactly like ALL movements
// Third is always 22 - exactly like CLOCK-1
// Fourth is 1, 1, 0, 0  - exactly like CLOCK-1

void turn_clock2() {
  digitalWrite(C2_1, HIGH); // 21, 1, 22, 1
  digitalWrite(C2_2, HIGH);
  delay(delaytime);
  digitalWrite(C2_1, LOW); // 21, 0, 22, 1
  digitalWrite(C2_2, HIGH);
  delay(delaytime);
  digitalWrite(C2_1, LOW); // 21, 0, 22, 0
  digitalWrite(C2_2, LOW);
  delay(delaytime);
  digitalWrite(C2_1, HIGH); // 21, 1, 22, 0
  digitalWrite(C2_2, LOW);
  delay(delaytime);
}

This is it... clumsy, but effective. I abandoned the pass-array-to-function mentioned in Post #6 and went with embedded loops and an algorithm. I would be grateful to whomever for showing how to cleanly pass an array to the "old" turn() function (as I intended, above). The output of this sketch will show "pin" "level" "pin" "level" to set up two motors to drive them anti-clockwise or clockwise, in the pattern I mentioned before.

How to play:

  • Run as-is to see the patterns I mentioned above on the Serial monitor.
    or
  • Un-comment the digitalWrite() lines to drive the motors (and comment-out the Serial.print() lines?)
// @kksua4 - you need a semicolon line termination here
int delaytime = 5;

// PIN assignments - use any pins
int C1_1 = 10;
int C1_2 = 11;
int C2_1 = 12;
int C2_2 = 13;

int anti1[] = {
  C1_1, HIGH, C1_2,  LOW,  // 10 1 11 0
  C1_1,  LOW, C1_2,  LOW,  // 10 0 11 0
  C1_1,  LOW, C1_2, HIGH,  // 10 0 11 1
  C1_1, HIGH, C1_2, HIGH   // 10 1 11 1
};

int anti2[] = {
  C2_1, HIGH, C2_2,  LOW,  // 12 1 13 0
  C2_1,  LOW, C2_2,  LOW,  // 12 0 13 0
  C2_1,  LOW, C2_2, HIGH,  // 12 0 13 1
  C2_1, HIGH, C2_2, HIGH   // 12 1 13 1
};

int clock1[] = {
  C1_1, HIGH, C1_2, HIGH,  // 10 1 11 1
  C1_1,  LOW, C1_2, HIGH,  // 10 0 11 1
  C1_1,  LOW, C1_2,  LOW,  // 10 0 11 0
  C1_1, HIGH, C1_2,  LOW   // 10 1 11 0
};

int clock2[] = {
  C2_1, HIGH, C2_2, HIGH,  // 12 1 13 1
  C2_1,  LOW, C2_2, HIGH,  // 12 0 13 1
  C2_1,  LOW, C2_2,  LOW,  // 12 0 13 0
  C2_1, HIGH, C2_2,  LOW   // 12 1 13 0
};

void turn(int array[])
{
  for (int j = 0; j < 4; j++)
  {
    // for (int i = 0; i < 4; i++)
    for (int i = 0; i < 4; i += 2)
    {
      Serial.print(array[i + j * 4]);
      // digitalWrite(array[i + j * 4]);
      Serial.print(" ");
      Serial.print(array[i + 1 + j * 4]);
      // digitalWrite(array[i + 1 + j * 4]);
      Serial.print(" ");
    }
    Serial.println();
  }
  delay(200);
  Serial.println();
}

void setup()
{
  Serial.begin(115200);
  turn(anti1);
  turn(anti2);
  turn(clock1);
  turn(clock2);
}

void loop() {}

a little more compact if you use a struct

// @kksua4 - you need a semicolon line termination here
int delaytime = 5;

// PIN assignments - use any pins
const byte C1_1 = 10;
const byte C1_2 = 11;
const byte C2_1 = 12;
const byte C2_2 = 13;

struct Anti {
    byte    pin0;
    byte    st0;
    byte    pin1;
    byte    st1;
};

Anti anti1[] = {
    { C1_1, HIGH, C1_2,  LOW },  // 10 1 11 0
    { C1_1,  LOW, C1_2,  LOW },  // 10 0 11 0
    { C1_1,  LOW, C1_2, HIGH },  // 10 0 11 1
    { C1_1, HIGH, C1_2, HIGH },   // 10 1 11 1
};


Anti anti2[] = {
    { C2_1, HIGH, C2_2,  LOW },  // 12 1 13 0
    { C2_1,  LOW, C2_2,  LOW },  // 12 0 13 0
    { C2_1,  LOW, C2_2, HIGH },  // 12 0 13 1
    { C2_1, HIGH, C2_2, HIGH },   // 12 1 13 1
};


Anti clock1[] = {
    { C1_1, HIGH, C1_2, HIGH },  // 10 1 11 1
    { C1_1,  LOW, C1_2, HIGH },  // 10 0 11 1
    { C1_1,  LOW, C1_2,  LOW },  // 10 0 11 0
    { C1_1, HIGH, C1_2,  LOW },   // 10 1 11 0
};


Anti clock2[] = {
    { C2_1, HIGH, C2_2, HIGH },  // 12 1 13 1
    { C2_1,  LOW, C2_2, HIGH },  // 12 0 13 1
    { C2_1,  LOW, C2_2,  LOW },  // 12 0 13 0
    { C2_1, HIGH, C2_2,  LOW },   // 12 1 13 0
};


void turn (
    Anti arr[] )
{
    for (int j = 0; j < 4; j++) {
        digitalWrite (arr [j].pin0, arr [j].st0);
        digitalWrite (arr [j].pin1, arr [j].st1);
        delay (250);
    }
}


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

    pinMode (C1_1, OUTPUT);
    pinMode (C1_2, OUTPUT);
    pinMode (C2_1, OUTPUT);
    pinMode (C2_2, OUTPUT);
}

void loop()
{
    turn(anti1);
    turn(anti2);
    turn(clock1);
    turn(clock2);
}
1 Like

and then a little more compact

// @kksua4 - you need a semicolon line termination here
int delaytime = 5;

// PIN assignments - use any pins
const byte C1_1 = 10;
const byte C1_2 = 11;
const byte C2_1 = 12;
const byte C2_2 = 13;

enum { Off = HIGH, On = LOW };

struct Seq {
    byte    zero;
    byte    one;
};
Seq seq0 [] = { {On, Off}, {Off,  Off}, {Off,  On }, {On, On } };
Seq seq1 [] = { {On, On }, {Off,  On }, {Off,  Off}, {On, Off} };
const int Nseq = sizeof(seq0) / sizeof(Seq);

void turn (
    byte pin0,
    byte pin1,
    Seq  seq[] )
{
    for (int j = 0; j < Nseq; j++) {
        digitalWrite (pin0, seq [j].zero);
        digitalWrite (pin1, seq [j].one);
        delay (250);
    }
}


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

    pinMode (C1_1, OUTPUT);
    pinMode (C1_2, OUTPUT);
    pinMode (C2_1, OUTPUT);
    pinMode (C2_2, OUTPUT);
}

void loop()
{
    turn (C1_1, C1_2, seq0);
    turn (C2_1, C2_2, seq0);
    turn (C1_1, C1_2, seq1);
    turn (C2_1, C2_2, seq1);
}
2 Likes

Thank you, truly, for showing your work two ways. I just need to ask a school nun to beat it into me. Nice result.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.