Symbol synchronization with M-QAM. M < 16 I working on M-QAM system using a Cortex-M4 processor. Using a alternating symbol as a preamble, I am able to get carrier lock. Symbol synchronization is then achieved by finding the peak. An early late gate is used to adjust for clock differences between modulator and demodulator. An integrator is used to even out the noise from the error detector. However, I can see the peak slipping from the optimum sampling position. Eventually after 500-600 symbols it loses sync. Are there any superior ways of doing symbol sync? Am I missing something?
Are there any superior ways of doing symbol sync?


Yes! As you've noticed, your initial estimation of timing isn't "valid" forever.
This might be caused by clock jitter, or simply remaining sampling rate offset.

It's a very common problem in communication receivers.

What you can of course do is that you simply do the same estimate you did at the beginning periodically (with the already recovered data instead of a preamble, even!), or even simply for every symbol.

A popular way of doing so is basically using the derivative of the pulse shape to track the "flattest" point in the pulse-shaped receive signal even before applying the (typically matched) filter in the receive chain. You might want to watch this video (slides) of GNU Radio's synchronization expert Andy Walls – I like that talk especially since not only is it clear enough to be used as instructional material, it actually also addresses "how it is actually done".