I couldn't work out how the interrupt is firing incorrectly but now this makes sense.ozcar wrote: Fri May 08, 2020 1:15 pm The other bad news, is that my explanation is a bit long...
Normally, let's say somewhere in the middle of generating the whole long stream of pulses, the execution of the interrupt routine is synchronised with the timer. That is, the interrupt routine always gets called just after the timer update event, when the count starts back at zero. The previous CCR value has just been latched, so it is then "safe" to set a new CCR value, without overlaying the previous value before it could get used, and you also have a (relatively) long time available to do this before the next update event. I'm mentioning CCR, same thing applies to ARR.
Things are different right at the start of the pulse stream kicked off in show_neopixels by turning on the UIE bit. The timer is already enabled at that point, and has been running, still generating update events which will have set the UIF flag. So, at soon as you clear UIE the interrupt will occur, and the interrupt routine will be called. It is not so much the fact that the interrupt routine gets called, but that this call to the interrupt routine is not synchronised with what is happening in the timer, it just depends on when you happen to call show_neopixels.
Usually, this does not cause a problem, but this is a sequence that might happen, with the original interrupt routine, which cleared UIF and then wrote to CCR1:
Interrupt occurs as soon as show_neopixels clears UIE.
Interrupt routine clears UIF.
Update event happens to occur now - this latches previously set CCR1 (0 for no pulse), and sets UIF again.
Interrupt routine sets CCR1 according to first data bit, to be latched at next update event.
As soon as interrupt routine exits, interrupt occurs again as UIF is set.
Interrupt routine clears UIF.
Interrupt routine sets CCR1 according to second data bit, overwriting the value for the first data bit, which has not been latched yet.
Result - first data bit is simply lost, pulse train starts with the second bit.
A simple fix I think is to reset the timer and clear the UIF flag just before enabling the interrupt flag in void show_neopixels(). Please test the updated version on my github

Another thing that would interest me is that if I left the pin enabled but disabled the timer would the pin still be pulled low??? I know if I disable the pin then it floats.