Why is my PWM timer behaving weirdly

OK. But it happened for me in the sim in the same ~5s place noted in the first post.

If it is the pgm_read_word()'s #define pgm_read_word_near(address_short) __LPM_word((uint16_t)(address_short)) 16 bit address type, it could depend on where the linker puts the the 4 simple 20000 byte arrays relative to the code and the code modifications. My toss-out code only looked for out-of-range values in the first array, since each of the arrays has a separate hard-coded name. If coding changes or linker choices somehow put a different array farther away, it wouldn't detect it.

When I tried:

    if (UseWorkAround) val = pgm_read_word_far(pgm_get_far_address(dutyCycleArray1) + 2 * ii);

... the out-of-range values seemed to resolve and I didn't get the stall at about 5sec.

Enable this with 'true' in the (updated) wokwi sim:

// A fix: 
const bool UseWorkAround = false; // use pgm_get_word_far(pgm_get_address_far(...)...)

See: