millis() state change issue

Hi,

I'm trying to save button presses (on and off times) into two arrays, then "play them back" using a millis timer. The code below is a simplified version with defined array elements so I can tell whether it's working or not.

The general idea is that the millis if statement flip flops back and forth between the on and off arrays stored in the gateTimes array (struct?). I can see on my oscilloscope that the sequence is correct however the on times are significantly shorter than they should be.

unsigned long gateTime = 0;
int gap = 0;
int gatePos = 0;
int gateTimes[2][10] {
  {100, 700, 600, 500, 400, 500, 300, 700, 600, 200},
  {100, 200, 100, 200, 100, 200, 300, 100, 200, 100}
};


void setup()
{
  Serial.begin(9600);
  pinMode(13, OUTPUT);

}

void loop()
{

  if (millis() - gateTime > gateTimes[gap][gatePos]) {
    if(gap == 0){
      Serial.println("on");
    }else{
       Serial.println("bye");
    }
    gateTime = millis();
    gatePos += 1;
    if (gatePos >= 10) {
      gatePos = 0;
    }

    if (gap == 0) {
      gap = 1;
    } else {
      gap = 0;
    }

    
  }
  digitalWrite(13, gap);
}

my guess is this part of the code is to blame but I do not know how to go about changing it. Any ideas appreciated!

    if (gap == 0) {
      gap = 1;
    } else {
      gap = 0;
    }

the on times are significantly shorter than they should be

How much shorter ?

I would start by reading millis() and storing the value just once at the start of loop() and using the value later as the current time in the program rather than reading millis() again.

Why are gap and gatePos ints when a byte would be sufficient ?

You can invert the value of gap in several ways, one of which is

gap = !gap

Thus removing the need to test its current value

Can you post a picture of that scope image?

Except for some overhead I see noting weird at first sight.