Laser Focus improvement
Stephan R. from Germany sent us an improvement on the firmware focus code.
It's related to the way we reset the ADC every time the interrupt vector is invoked. Below you can see the code affected including the modification (commented lines in red).
Basically, we were re-starting the conversion using the sentence ADCSRA |= 1<<ADSC and really it is not needed because we configured the ADC to auto-trigger on the init function.
Although we have been focusing without any problem since we wrote that code we tested the modification and we saw that the driver can focus in the same way and probably better.
Stephan said he discovered it because his prototype had problems to focus and when he removed the lines mentioned the driver started to focus well. Probably this different behaviour between prototypes is produced by electric noise on the FE signal and using this modification the firmware is more robust and detects easily the s-curve needed for focusing. Stephan also confirmed us that once focused the laser prints correctly at 600dpi so it means it is really focused.
We will continue to test this improvement but if you experimented difficulties while focusing try to comment those lines (in red). Then compile it and upload the code to the Arduino. You will find the code at focus.cpp file on TwinTeethFirmware.
Thanks very much 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;
}
}