Mejora en el enfoque del láser
Stephan R. de Alemania nos ha enviado una mejora en el código del firmware de enfoque del láser
Está relacionada con la forma en que usamos el ADC cada vez que el vector de interrupción se invoca. Más abajo podéis ver el código afectado que incluye la modificación (líneas comentadas en rojo).
Básicamente estábamos arrancando la conversión mediante la sentencia ADCSRA != 1 << ADSC y realmente no es necesario porque en la función de inicialización configuramos el ADC en modo automático.
Aunque no hemos encontrado ningún problema al enfocar desde que escribimos el código, hemos probado la modificación y hemos visto que el driver sigue enfocando de la misma manera e incluso mejor, al menos en nuestro prototipo.
Stephan nos dijo que lo descubrió porque su prototipo tenía problemas para enfocar y cuando quitó las líneas mencionadas el driver comenzó a enfocar bien. Este comportamiento tan diferente entre prototipos probablemente es producido por ruido eléctrico en la señal de FE y con esta modificación el firmware es más robusto y detecta mejor la curva-S necesaria para enfocar. Stephan también nos confirmó que el láser, una vez enfocado, imprime correctamente a 600dpi, lo que significa que realmente está enfocado.
Vamos a seguir probando esta mejora pero si tienes dificultades para enfocar, pruebala comentando las líneas (en rojo). Luego compila el firmware y cargalo de nuevo en el Arduino. Encontrarás el código en el archivo focus.cpp de TwinTeethFirmware.
!Muchas gracias Stephan!
/**
** Interrupt vector
**/
ISR(ADC_vect) {//when new ADC value ready
static int FEVal;
static int FEtimeout;
//ADCSRB = 0;
//ADMUX = ((1 << REFS0) | ((FE_SIGNAL_PIN-PIN_A0) & 0x07));
// State machine
switch (fe_state){
case FE_WAIT_ST:
FEtimeout=0;
break;
case FE_AMPLITUD_ST:
//ADCSRA |= 1<<ADSC; // Start conversion
FEVal = ADC;
if ( FEVal > fe_max_val)
fe_max_val = FEVal;
if (FEVal < fe_min_val)
fe_min_val = FEVal;
break;
case FE_FOCUS_ST:
//ADCSRA |= 1<<ADSC; // Start conversion
FEVal = ADC;
if (abs(REF_FE_VALUE - FEVal) > fe_amplitud/FE_NOISE_DIVIDER){
FEtimeout=0;
fe_state = FE_SCURVE_ST;
}
else if (FEtimeout++ > FOCUS_TIMEOUT){
fe_state = FE_ERROR_ST;
}
break;
case FE_SCURVE_ST:
//ADCSRA |= 1<<ADSC; // Start conversion
FEVal = ADC;
if (abs(REF_FE_VALUE - FEVal) <= fe_amplitud/AMPLITUD_DIVIDER){
fe_focus_pos = fe_servo_pos;
fe_state = FE_FOCUSED_ST;
}
else if (FEtimeout++ > FOCUS_TIMEOUT){
fe_state = FE_ERROR_ST;
}
break;
case FE_FOCUSED_ST:
break;
case FE_ERROR_ST:
break;
}
}
- Inicie sesión o regístrese para comentar