@Dédalo:
Bueno pues paso a describirte someramente el algoritmo de roscado (aún así ha salido tocho

).
En mi caso uso dos encoders: uno de 1 paso / rev para sincronizar el inicio del roscado (HRindex)
y otro de 25 pasos/rev para sincronizar el avance de roscado (HR). Con 25 pulsos/rev es suficiente. Si aumentas mucho los pulsos/rev tal vez tengas problemas para atender la rutina adecuadamente.
Es necesario que la velocidad del husillo sea siempre la misma al inicio de cada ciclo
de roscado, luego mientras se va realizando el roscado la velocidad del husillo puede variar ampliamente y el algoritmo la corregirá. Esto debe ser así debido a que el motor arranca en rampa desde cero y el inicio del roscado debe de realizarse en el mismo punto. Si la velocidad del husillo es distinta al anterior ciclo la herramienta no entrará en el mismo punto. Esto no es ningún problema, la aplicación espera un par de segundos antes de iniciar el movimiento para permitir una velocidad estable.
La idea básica es medir la posición de la herramienta cuando se genera un pulso HR respecto a donde debería estar teóricamente. Si vas por detrás tienes que acelerar la herramienta y si vas por delante pues decelerar.
Para hacer bien las cosas los cambios en la velocidad de un motor paso a paso deben realizarse mediante una rampa (una lineal es fácil de implementar)
El otro parámetro es el número de pulsos HR que deben realizarse para alcanzar la posición teórica.
Algo de código en C:
//--------------------------------------------------------------------
//los períodos están en microsec
unsigned long Tm=micros()-Tmold; //tiempo en microsec entre dos pulsos HR
Tmold=Tm;
//pulsos HR de horizonte de regulación, Tact es el período actual de pulsos PWM
unsigned long PulsosHRHorizonte=2500UL/Tact; //constante empírica
if (!PulsosHRHorizonte)
PulsosHRHorizonte++;
//------------------------------------
//donde deberíamos estar ahora, posición teórica (en pulsos)
float AvancePteo=AvancePsincro*gPulsosSincroHR; //avance teórico por pulso HR x pulsos HR realizados
//donde deberemos estar en PulsosHorz pulsos (en pulsos)
float AvancePteonext=AvancePteo+(AvancePsincro*PulsosHRHorizonte);
//pulsos enviados al motor desde el punto inicial de referencia
long AvancePreal=gPulsosSincroT;
//diferencia entre la posición actual y la siguiente posición teórica (en pulsos)
float OffsetPAvance=AvancePteonext-AvancePreal;
gPrecisionSincro=AvancePreal-AvancePteo; //desviación actual real-teórica (en pulsos)
//con esta velocidad lineal alcanzaremos la posición teórica calculada en PulsosHRHorizonte pulsos
//cálculo del nuevo periodo PWM a aplicar
Tmeta=(float)(Tm*PulsosHRHorizonte)/OffsetPAvance;
//--------------------------------------------------------------------
Ahora ya tenemos el nuevo período que alcanzaremos tras una rampa en aceleración o deceleración.
El cálculo exacto de la rampa exige coma flotante pero se puede hacer de una forma aproximada mediante enteros.
En el código fuente tienes todos los detalles. De todas formas si necesitas alguna otra aclaración
pregunta libremente

El cálculo de las rampas de los motores lo he tomado de este documento de Atmel:
http://www.atmel.com/Images/doc8017.pdfAquí hay un link muy interesante sobre el mismo tema:
http://eetimes.com/design/embedded/4006438/Generate-stepper-motor-speed-profiles-in-real-timeUn saludo
Paco