Weird formatting behavior with sprintf function
Sometimes the sprintf can be used instead of 20 lines of code. In this case an array with integers and a loop with Serial.print would be better as Majenko already wrote.

When you do use the sprintf, a shift in the data means that one of the parameters has too many or too little bytes. The sprintf does not know the size of the parameter and the parameter will not be converted to a different type. When you use "%d", you have to put two bytes on the stack. Since your 'x' is 4 bytes, all those 4 bytes will be put onto the stack. The first "%d" reads two bytes of 'x' and the second "%d" read the other two bytes of 'x'. That is why it is shifted.

For a data rate of 50Hz, I suggest to raise the baudrate to 115200.

Using millis() for the 50Hz will result into the same timing accuracy as you have now. You don't need the timer and you don't need the interrupt.
See the BlinkWithouDelay example and use 20ms as an interval.