Die Schwankung liegt um die 400 Prozessortakte - das erscheint mir auch nicht akzeptabel.
Ich würde mal die gesamte Verarbeitung der Daten aus der ISR rausnehmen - die ISR sollte so kurz wie möglich sein. Dort gehört eigentlich nur die Abfrage des Timers rein. Newcount würde ich ebenfalls als globale Variable definieren. Evtl. ein Flag setzen, damit du weißt, dass ein neuer Wert gelesen wurde. Die Verarbeitung kommt dann in den Hauptteil. Allerdings müsste man mal genauer schauen, welche Variante ggf. schneller ist. Direkter Zugriff auf eine globale Variable oder erst irgendeine Zwischenspeicherung in einem Register zwecks Übergabe an eine lokale Variable... das geht dann doch sehr ins Detail.
Du rechnest newcount-oldcount. Was passiert, wenn der Timer übergelaufen ist und newcount kleiner ist als oldcount? Du hast measure als uint32 und oldcount und newcount als uint16 definiert - kann das probleme geben? Ich denke eigentlich nicht.
Die Lösung mit Loopcount finde ich auch nicht besonders elegant. Ich würde im Hauptteil eine Zeitgesteuerte Ausgabe basierend auf millis machen.
Trotzdem, abgesehen davon, das der größte Teil deiner Programmlogik in der ISR steht, wo er nicht hin gehört, finde ich keinen Grund, warum das nicht halbwegs ordentlich laufen soll.
Probier mal die 8 ms zu erhöhen. 10 x 20ms oder 4 * 50 ms - ob sich dann was ändert.
Übringens - was soll das eigentlich bringen, wenn du 25 Messungen in 8 ms Abstand machst? Dadurch wird es doch nicht genauer... (im Gegenteil) stell den Timer auf 200 ms, messe den Wert und gib ihn aus...
Lesezeichen