With another motor available for testing, I decided to configure my controller to run two motors. I also mounted the motors, so they wouldn't roll under acceleration and fall on the floor (again).
Ooh... two motors. Yeah... my servo controller can run more than a single servo. The Pololu driver board I have has two H-bridges, so with 1 controller board and 1 driver board, I can control two motors.
I also fixed a bug in the quadrature decoding routines that was causing incorrect amounts of movement to be calculated. To see if something had changed, I was incorrectly comparing the current raw quadrature state against the previous decoded state. Whoops!
With my 1,200 step encoder, now moving 1,200 steps now gives one clean rotation. Do 120,000 steps and you get 100 rotations, stopping at the exact same spot.
The PID parameters still aren't tuned. Hence the overshoot and slow final approach. I'm yet to even start working out a simple reliable tuning method. I don't want to hand tune the free-standing motors through trial and error, only to do it again once they're fitted.
Much more testing still needed...